UNPKG

@angular/cdk

Version:

Angular Material Component Development Kit

1 lines 9.64 kB
{"version":3,"file":"observers-private.mjs","sources":["../../../../../k8-fastbuild-ST-199a4f3c4e20/bin/src/cdk/observers/private/shared-resize-observer.ts"],"sourcesContent":["/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.dev/license\n */\nimport {inject, Injectable, NgZone, OnDestroy, RendererFactory2} from '@angular/core';\nimport {Observable, Subject} from 'rxjs';\nimport {filter, shareReplay, takeUntil} from 'rxjs/operators';\n\n/**\n * Handler that logs \"ResizeObserver loop limit exceeded\" errors.\n * These errors are not shown in the Chrome console, so we log them to ensure developers are aware.\n * @param e The error\n */\nconst loopLimitExceededErrorHandler = (e: unknown) => {\n if (e instanceof ErrorEvent && e.message === 'ResizeObserver loop limit exceeded') {\n console.error(\n `${e.message}. This could indicate a performance issue with your app. See https://github.com/WICG/resize-observer/blob/master/explainer.md#error-handling`,\n );\n }\n};\n\n/**\n * A shared ResizeObserver to be used for a particular box type (content-box, border-box, or\n * device-pixel-content-box)\n */\nclass SingleBoxSharedResizeObserver {\n /** Stream that emits when the shared observer is destroyed. */\n private _destroyed = new Subject<void>();\n /** Stream of all events from the ResizeObserver. */\n private _resizeSubject = new Subject<ResizeObserverEntry[]>();\n /** ResizeObserver used to observe element resize events. */\n private _resizeObserver?: ResizeObserver;\n /** A map of elements to streams of their resize events. */\n private _elementObservables = new Map<Element, Observable<ResizeObserverEntry[]>>();\n\n constructor(\n /** The box type to observe for resizes. */\n private _box: ResizeObserverBoxOptions,\n ) {\n if (typeof ResizeObserver !== 'undefined') {\n this._resizeObserver = new ResizeObserver(entries => this._resizeSubject.next(entries));\n }\n }\n\n /**\n * Gets a stream of resize events for the given element.\n * @param target The element to observe.\n * @return The stream of resize events for the element.\n */\n observe(target: Element): Observable<ResizeObserverEntry[]> {\n if (!this._elementObservables.has(target)) {\n this._elementObservables.set(\n target,\n new Observable<ResizeObserverEntry[]>(observer => {\n const subscription = this._resizeSubject.subscribe(observer);\n this._resizeObserver?.observe(target, {box: this._box});\n return () => {\n this._resizeObserver?.unobserve(target);\n subscription.unsubscribe();\n this._elementObservables.delete(target);\n };\n }).pipe(\n filter(entries => entries.some(entry => entry.target === target)),\n // Share a replay of the last event so that subsequent calls to observe the same element\n // receive initial sizing info like the first one. Also enable ref counting so the\n // element will be automatically unobserved when there are no more subscriptions.\n shareReplay({bufferSize: 1, refCount: true}),\n takeUntil(this._destroyed),\n ),\n );\n }\n return this._elementObservables.get(target)!;\n }\n\n /** Destroys this instance. */\n destroy() {\n this._destroyed.next();\n this._destroyed.complete();\n this._resizeSubject.complete();\n this._elementObservables.clear();\n }\n}\n\n/**\n * Allows observing resize events on multiple elements using a shared set of ResizeObserver.\n * Sharing a ResizeObserver instance is recommended for better performance (see\n * https://github.com/WICG/resize-observer/issues/59).\n *\n * Rather than share a single `ResizeObserver`, this class creates one `ResizeObserver` per type\n * of observed box ('content-box', 'border-box', and 'device-pixel-content-box'). This avoids\n * later calls to `observe` with a different box type from influencing the events dispatched to\n * earlier calls.\n */\n@Injectable({\n providedIn: 'root',\n})\nexport class SharedResizeObserver implements OnDestroy {\n private _cleanupErrorListener: (() => void) | undefined;\n\n /** Map of box type to shared resize observer. */\n private _observers = new Map<ResizeObserverBoxOptions, SingleBoxSharedResizeObserver>();\n\n /** The Angular zone. */\n private _ngZone = inject(NgZone);\n\n constructor() {\n if (typeof ResizeObserver !== 'undefined' && (typeof ngDevMode === 'undefined' || ngDevMode)) {\n this._ngZone.runOutsideAngular(() => {\n const renderer = inject(RendererFactory2).createRenderer(null, null);\n this._cleanupErrorListener = renderer.listen(\n 'window',\n 'error',\n loopLimitExceededErrorHandler,\n );\n });\n }\n }\n\n ngOnDestroy() {\n for (const [, observer] of this._observers) {\n observer.destroy();\n }\n this._observers.clear();\n this._cleanupErrorListener?.();\n }\n\n /**\n * Gets a stream of resize events for the given target element and box type.\n * @param target The element to observe for resizes.\n * @param options Options to pass to the `ResizeObserver`\n * @return The stream of resize events for the element.\n */\n observe(target: Element, options?: ResizeObserverOptions): Observable<ResizeObserverEntry[]> {\n const box = options?.box || 'content-box';\n if (!this._observers.has(box)) {\n this._observers.set(box, new SingleBoxSharedResizeObserver(box));\n }\n return this._observers.get(box)!.observe(target);\n }\n}\n"],"names":["loopLimitExceededErrorHandler","e","ErrorEvent","message","console","error","SingleBoxSharedResizeObserver","_box","_destroyed","Subject","_resizeSubject","_resizeObserver","_elementObservables","Map","constructor","ResizeObserver","entries","next","observe","target","has","set","Observable","observer","subscription","subscribe","box","unobserve","unsubscribe","delete","pipe","filter","some","entry","shareReplay","bufferSize","refCount","takeUntil","get","destroy","complete","clear","SharedResizeObserver","_cleanupErrorListener","_observers","_ngZone","inject","NgZone","ngDevMode","runOutsideAngular","renderer","RendererFactory2","createRenderer","listen","ngOnDestroy","options","deps","i0","ɵɵFactoryTarget","Injectable","ɵprov","ɵɵngDeclareInjectable","minVersion","version","ngImport","type","decorators","args","providedIn"],"mappings":"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"}