{"version":3,"file":"scion-toolkit-observable.mjs","sources":["../../../../projects/scion/toolkit/observable/src/resize.observable.ts","../../../../projects/scion/toolkit/observable/src/intersection.observable.ts","../../../../projects/scion/toolkit/observable/src/mutation.observable.ts","../../../../projects/scion/toolkit/observable/src/bounding-client-rect.observable.ts","../../../../projects/scion/toolkit/observable/src/public_api.ts","../../../../projects/scion/toolkit/observable/src/scion-toolkit-observable.ts"],"sourcesContent":["/*\n * Copyright (c) 2018-2024 Swiss Federal Railways\n *\n * This program and the accompanying materials are made\n * available under the terms of the Eclipse Public License 2.0\n * which is available at https://www.eclipse.org/legal/epl-2.0/\n *\n *  SPDX-License-Identifier: EPL-2.0\n */\n\nimport {Observable} from 'rxjs';\n\n/**\n * Wraps the native {@link ResizeObserver} in an RxJS Observable to observe resizing of an element.\n *\n * Upon subscription, emits the current size, and then continuously when the size changes. The Observable never completes.\n *\n * For more details, see https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserver.\n *\n * @param element - Specifies the element to observe.\n * @param options - Configures {@link ResizeObserver}.\n *                  For more details, see https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserver.\n */\nexport function fromResize$(element: Element, options?: ResizeObserverOptions): Observable<ResizeObserverEntry[]> {\n  return new Observable(observer => {\n    const resizeObserver = new ResizeObserver(entries => observer.next(entries));\n    resizeObserver.observe(element, options);\n    return () => resizeObserver.disconnect();\n  });\n}\n","/*\n * Copyright (c) 2018-2024 Swiss Federal Railways\n *\n * This program and the accompanying materials are made\n * available under the terms of the Eclipse Public License 2.0\n * which is available at https://www.eclipse.org/legal/epl-2.0/\n *\n *  SPDX-License-Identifier: EPL-2.0\n */\n\nimport {Observable} from 'rxjs';\n\n/**\n * Wraps the native {@link IntersectionObserver} in an RxJS Observable to observe intersection of an element.\n *\n * Upon subscription, emits the current intersection state, and then continuously when the intersection state changes. The Observable never completes.\n *\n * For more details, see https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API.\n *\n * @param element - Specifies the element to observe.\n * @param options - Configures {@link IntersectionObserver}.\n *                  For more details, see https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API.\n */\nexport function fromIntersection$(element: Element, options?: IntersectionObserverInit): Observable<IntersectionObserverEntry[]> {\n  return new Observable(observer => {\n    const intersectionObserver = new IntersectionObserver(entries => observer.next(entries), options);\n    intersectionObserver.observe(element);\n    return () => intersectionObserver.disconnect();\n  });\n}\n","/*\n * Copyright (c) 2018-2024 Swiss Federal Railways\n *\n * This program and the accompanying materials are made\n * available under the terms of the Eclipse Public License 2.0\n * which is available at https://www.eclipse.org/legal/epl-2.0/\n *\n *  SPDX-License-Identifier: EPL-2.0\n */\n\nimport {Observable} from 'rxjs';\n\n/**\n * Wraps the native {@link MutationObserver} in an RxJS Observable to observe mutations of an element.\n *\n * For more details, see https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver.\n *\n * @param element - Specifies the element to observe.\n * @param options - Configures {@link MutationObserver}.\n *                  For more details, see https://developer.mozilla.org/en-US/docs/Web/API/MutationObserverInit.\n */\nexport function fromMutation$(element: Node, options?: MutationObserverInit): Observable<MutationRecord[]> {\n  return new Observable(observer => {\n    const mutationObserver = new MutationObserver((mutations: MutationRecord[]): void => observer.next(mutations));\n    mutationObserver.observe(element, options);\n    return () => mutationObserver.disconnect();\n  });\n}\n","/*\n * Copyright (c) 2018-2024 Swiss Federal Railways\n *\n * This program and the accompanying materials are made\n * available under the terms of the Eclipse Public License 2.0\n * which is available at https://www.eclipse.org/legal/epl-2.0/\n *\n *  SPDX-License-Identifier: EPL-2.0\n */\n\nimport {distinctUntilChanged, fromEvent, Observable, Subject, switchMap, takeUntil} from 'rxjs';\nimport {fromIntersection$} from './intersection.observable';\nimport {fromResize$} from './resize.observable';\nimport {observeIn} from '@scion/toolkit/operators';\n\n/**\n * Observes changes to the bounding box of a specified element.\n *\n * The bounding box includes the element's position relative to the top-left of the viewport and its size.\n * Refer to https://developer.mozilla.org/en-US/docs/Web/API/Element/getBoundingClientRect for more details.\n *\n * Upon subscription, emits the current bounding box, and then continuously when the bounding box changes. The Observable never completes.\n *\n * The element and the document root (`<html>`) must be positioned `relative` or `absolute`.\n * If not, positioning is changed to `relative`.\n\n * Note:\n * There is no native browser API to observe the position of an element. The observable uses {@link IntersectionObserver} and\n * {@link ResizeObserver} to detect position changes. For tracking only size changes, use {@link fromResize$} instead.\n *\n * @param element - The element to observe.\n * @returns {Observable<DOMRect>} An observable that emits the bounding box of the element.\n */\nexport function fromBoundingClientRect$(element: HTMLElement): Observable<DOMRect> {\n  return new Observable(observer => {\n    const clientRectObserver = new BoundingClientRectObserver(element, clientRect => observer.next(clientRect));\n    return () => clientRectObserver.destroy();\n  });\n}\n\n/**\n * Observes the position and size of an element using {@link IntersectionObserver} and {@link ResizeObserver}.\n *\n * Since there is no native browser API to observe element position, we create four vertices and set up\n * an {@link IntersectionObserver} for each vertex. Configured with root margins aligned to the vertices'\n * bounding boxes, we can detect when the element (specifically its vertices) moves. We then emit the changed\n * bounding box of the element, recompute the root margins for each vertex, and restart observations.\n *\n * Observing vertices instead of the element itself enables position change detection even if the element is partially\n * scrolled out of the viewport.\n */\nclass BoundingClientRectObserver {\n\n  private readonly _destroy$ = new Subject<void>();\n  private readonly _disposables = new Array<DisposeFn>();\n  private readonly _clientRect$ = new Subject<DOMRect>();\n  private readonly _vertices: {\n    topLeft: Vertex;\n    topRight: Vertex;\n    bottomRight: Vertex;\n    bottomLeft: Vertex;\n  };\n\n  constructor(private _element: HTMLElement, onChange: (clientRect: DOMRect) => void) {\n    this._disposables.push(positionElement(this._element));\n\n    this._vertices = {\n      topLeft: new Vertex(this._element, {top: 0, left: 0}, () => this.emitClientRect()),\n      topRight: new Vertex(this._element, {top: 0, right: 0}, () => this.emitClientRect()),\n      bottomRight: new Vertex(this._element, {bottom: 0, right: 0}, () => this.emitClientRect()),\n      bottomLeft: new Vertex(this._element, {bottom: 0, left: 0}, () => this.emitClientRect()),\n    };\n\n    this.installElementResizeObserver();\n    this.installDocumentResizeObserver();\n    this.installChangeEmitter(onChange);\n  }\n\n  /**\n   * Monitors changes to the element's size.\n   */\n  private installElementResizeObserver(): void {\n    fromResize$(this._element, {box: 'border-box'})\n      .pipe(\n        // Run in animation frame to prevent 'ResizeObserver loop completed with undelivered notifications' error.\n        // Do not use `animationFrameScheduler` because the scheduler does not necessarily execute in the current execution context, such as inside or outside Angular.\n        // The scheduler always executes tasks in the context (e.g. zone) where the scheduler was first used in the application.\n        observeIn(fn => requestAnimationFrame(fn)),\n        takeUntil(this._destroy$),\n      )\n      .subscribe(() => {\n        this.emitClientRect(); // emit for instant update\n        this.forEachVertex(vertex => vertex.computeRootMargin());\n      });\n  }\n\n  /**\n   * Monitors changes to the document's size.\n   */\n  private installDocumentResizeObserver(): void {\n    fromEvent(window, 'resize')\n      .pipe(takeUntil(this._destroy$))\n      .subscribe(() => {\n        this.emitClientRect(); // emit for instant update\n        this.forEachVertex(vertex => vertex.computeRootMargin());\n      });\n  }\n\n  private installChangeEmitter(onChange: (clientRect: DOMRect) => void): void {\n    this._clientRect$\n      .pipe(\n        distinctUntilChanged(isEqualDomRect),\n        takeUntil(this._destroy$),\n      )\n      .subscribe(boundingBox => {\n        onChange(boundingBox);\n      });\n  }\n\n  private emitClientRect(): void {\n    this._clientRect$.next(this._element.getBoundingClientRect());\n  }\n\n  private forEachVertex(fn: (vertex: Vertex) => void): void {\n    Object.values(this._vertices).forEach(fn);\n  }\n\n  public destroy(): void {\n    this.forEachVertex(vertex => vertex.destroy());\n    this._disposables.forEach(disposable => disposable());\n    this._destroy$.next();\n  }\n}\n\nclass Vertex {\n\n  private readonly _element: HTMLElement;\n  private readonly _rootMargin$ = new Subject<string>();\n  private readonly _destroy$ = new Subject<void>();\n\n  constructor(parent: HTMLElement,\n              position: {top?: 0; right?: 0; bottom?: 0; left?: 0},\n              private _onPositionChange: () => void) {\n    this._element = parent.appendChild(this.createVertexElement(position));\n    this.installIntersectionObserver();\n    this.computeRootMargin();\n  }\n\n  /**\n   * Computes the negative margins (\"top right bottom left\") to clip this vertex's bounding box.\n   */\n  public computeRootMargin(): void {\n    const documentRoot = document.documentElement;\n    const documentClientRect = documentRoot.getBoundingClientRect();\n    const elementClientRect = this._element.getBoundingClientRect();\n\n    const top = elementClientRect.top;\n    const left = elementClientRect.left;\n    const right = documentClientRect.width - elementClientRect.right;\n    const bottom = documentClientRect.height - elementClientRect.bottom;\n    this._rootMargin$.next(`${Math.ceil(-1 * top)}px ${Math.ceil(-1 * right)}px ${Math.ceil(-1 * bottom)}px ${Math.ceil(-1 * left)}px`);\n  }\n\n  private installIntersectionObserver(): void {\n    this._rootMargin$\n      .pipe(\n        distinctUntilChanged(),\n        switchMap(rootMargin => fromIntersection$(this._element, {rootMargin, threshold: 1, root: document})),\n        takeUntil(this._destroy$),\n      )\n      .subscribe((entries: IntersectionObserverEntry[]) => {\n        const isIntersecting = entries.at(-1)?.isIntersecting ?? false;\n        if (!isIntersecting) {\n          this._onPositionChange();\n          this.computeRootMargin();\n        }\n      });\n\n    // Recompute the root margin when the element re-enters the viewport.\n    fromIntersection$(this._element, {threshold: 1, root: document})\n      .pipe(takeUntil(this._destroy$))\n      .subscribe((entries: IntersectionObserverEntry[]) => {\n        const isIntersecting = entries.at(-1)?.isIntersecting ?? false;\n        if (isIntersecting) {\n          this._onPositionChange();\n          this.computeRootMargin();\n        }\n      });\n  }\n\n  private createVertexElement(position: {top?: 0; right?: 0; bottom?: 0; left?: 0}): HTMLElement {\n    const element = document.createElement<'div'>('div');\n    setStyle(element, {\n      'position': 'absolute',\n      'top': position.top === 0 ? '0' : null,\n      'right': position.right === 0 ? '0' : null,\n      'bottom': position.bottom === 0 ? '0' : null,\n      'left': position.left === 0 ? '0' : null,\n      'width': '1px',\n      'height': '1px',\n      'visibility': 'hidden',\n      'pointer-events': 'none',\n    });\n    return element;\n  }\n\n  public destroy(): void {\n    this._element.remove();\n    this._destroy$.next();\n  }\n}\n\n/**\n * Ensures that the given HTML element is positioned, setting its position to `relative` if it is not already positioned.\n *\n * Positioning is set using a constructable CSS stylesheet with a CSS layer. CSS layers have lower priority than \"normal\"\n * CSS declarations, and the layer name indicates the styling originates from `@scion/toolkit`.\n *\n * This function adds a data attribute to the element to locate it from the stylesheet.\n *\n * The function returns a {@link DisposeFn}, that when called, removes the attribute from the element.\n */\nconst positionElement: PositionElementFn = (() => {\n  const styleSheet = new CSSStyleSheet({});\n\n  // Add styles to position the document root element, required by BoundingClientRectObserver.\n  // - Ensures the document root element is positioned to support `@scion/toolkit/observable/fromBoundingClientRect$` for observing element bounding boxes.\n  // - Aligns the document root with the page viewport so the top-level positioning context fills the page viewport (as expected by applications).\n  styleSheet.insertRule(`\n    @layer sci-toolkit {\n      :root {\n        position: absolute;\n        inset: 0;\n      }\n    }`,\n  );\n\n  // Add styles to change the element's position to relative, required by BoundingClientRectObserver.\n  const elementIdentifier = 'data-sci-bounding-client-rect';\n  const elementIdentifierImportant = 'data-sci-bounding-client-rect-important';\n  styleSheet.insertRule(`\n    @layer sci-toolkit {\n      [${elementIdentifier}] {\n        position: relative;\n      }\n      [${elementIdentifierImportant}] {\n        position: relative !important;\n      }\n    }`,\n  );\n  document.adoptedStyleSheets.push(styleSheet);\n\n  return (element: Element): DisposeFn => {\n    const disposables = new Array<DisposeFn>();\n\n    // Add attribute to locate the element from the stylesheet.\n    element.setAttribute(elementIdentifier, '');\n    disposables.push(() => element.removeAttribute(elementIdentifier));\n\n    // If CSS layer styles have no effect due to 'static' positioning or unset styles, enforce positioning with !important.\n    const animationFrame = requestAnimationFrame(() => {\n      if (getComputedStyle(element).position === 'static') {\n        element.setAttribute(elementIdentifierImportant, '');\n        disposables.push(() => element.removeAttribute(elementIdentifierImportant));\n      }\n    });\n    disposables.push(() => cancelAnimationFrame(animationFrame));\n\n    return () => disposables.forEach(disposable => disposable());\n  };\n})();\n\n/**\n * Signature of a function to position specified element, if necessary.\n */\ntype PositionElementFn = (element: Element) => DisposeFn;\n\n/**\n * Signature of a function to clean up allocated resources.\n */\ntype DisposeFn = () => void;\n\n/**\n * Apples specified styles for given element.\n */\nfunction setStyle(element: HTMLElement, styles: {[style: string]: string | null}): void {\n  Object.entries(styles).forEach(([name, value]) => {\n    if (value === null) {\n      element.style.removeProperty(name);\n    }\n    else {\n      element.style.setProperty(name, value);\n    }\n  });\n}\n\nfunction isEqualDomRect(a: DOMRect, b: DOMRect): boolean {\n  return a.top === b.top && a.right === b.right && a.bottom === b.bottom && a.left === b.left;\n}\n","/*\n * Copyright (c) 2018-2019 Swiss Federal Railways\n *\n * This program and the accompanying materials are made\n * available under the terms of the Eclipse Public License 2.0\n * which is available at https://www.eclipse.org/legal/epl-2.0/\n *\n *  SPDX-License-Identifier: EPL-2.0\n */\n\n/*\n * Secondary entrypoint: '@scion/toolkit/observable'\n * This module does not depend on Angular.\n *\n * @see https://github.com/ng-packagr/ng-packagr/blob/master/docs/secondary-entrypoints.md\n */\nexport {fromResize$} from './resize.observable';\nexport {fromIntersection$} from './intersection.observable';\nexport {fromMutation$} from './mutation.observable';\nexport {fromBoundingClientRect$} from './bounding-client-rect.observable';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public_api';\n"],"names":[],"mappings":"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"}