UNPKG

@angular/cdk

Version:

Angular Material Component Development Kit

1 lines 15.4 kB
{"version":3,"file":"observers.mjs","sources":["../../../../../darwin_arm64-fastbuild-ST-fdfa778d11ba/bin/src/cdk/observers/observe-content.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 */\n\nimport {NumberInput, coerceElement, coerceNumberProperty} from '../coercion';\nimport {\n AfterContentInit,\n Directive,\n ElementRef,\n EventEmitter,\n Injectable,\n Input,\n NgModule,\n NgZone,\n OnDestroy,\n Output,\n booleanAttribute,\n inject,\n} from '@angular/core';\nimport {Observable, Observer, Subject, Subscription} from 'rxjs';\nimport {debounceTime, filter, map} from 'rxjs/operators';\n\n// Angular may add, remove, or edit comment nodes during change detection. We don't care about\n// these changes because they don't affect the user-preceived content, and worse it can cause\n// infinite change detection cycles where the change detection updates a comment, triggering the\n// MutationObserver, triggering another change detection and kicking the cycle off again.\nfunction shouldIgnoreRecord(record: MutationRecord) {\n // Ignore changes to comment text.\n if (record.type === 'characterData' && record.target instanceof Comment) {\n return true;\n }\n // Ignore addition / removal of comments.\n if (record.type === 'childList') {\n for (let i = 0; i < record.addedNodes.length; i++) {\n if (!(record.addedNodes[i] instanceof Comment)) {\n return false;\n }\n }\n for (let i = 0; i < record.removedNodes.length; i++) {\n if (!(record.removedNodes[i] instanceof Comment)) {\n return false;\n }\n }\n return true;\n }\n // Observe everything else.\n return false;\n}\n\n/**\n * Factory that creates a new MutationObserver and allows us to stub it out in unit tests.\n * @docs-private\n */\n@Injectable({providedIn: 'root'})\nexport class MutationObserverFactory {\n create(callback: MutationCallback): MutationObserver | null {\n return typeof MutationObserver === 'undefined' ? null : new MutationObserver(callback);\n }\n}\n\n/** An injectable service that allows watching elements for changes to their content. */\n@Injectable({providedIn: 'root'})\nexport class ContentObserver implements OnDestroy {\n private _mutationObserverFactory = inject(MutationObserverFactory);\n\n /** Keeps track of the existing MutationObservers so they can be reused. */\n private _observedElements = new Map<\n Element,\n {\n observer: MutationObserver | null;\n readonly stream: Subject<MutationRecord[]>;\n count: number;\n }\n >();\n\n private _ngZone = inject(NgZone);\n\n constructor(...args: unknown[]);\n constructor() {}\n\n ngOnDestroy() {\n this._observedElements.forEach((_, element) => this._cleanupObserver(element));\n }\n\n /**\n * Observe content changes on an element.\n * @param element The element to observe for content changes.\n */\n observe(element: Element): Observable<MutationRecord[]>;\n\n /**\n * Observe content changes on an element.\n * @param element The element to observe for content changes.\n */\n observe(element: ElementRef<Element>): Observable<MutationRecord[]>;\n\n observe(elementOrRef: Element | ElementRef<Element>): Observable<MutationRecord[]> {\n const element = coerceElement(elementOrRef);\n\n return new Observable((observer: Observer<MutationRecord[]>) => {\n const stream = this._observeElement(element);\n const subscription = stream\n .pipe(\n map(records => records.filter(record => !shouldIgnoreRecord(record))),\n filter(records => !!records.length),\n )\n .subscribe(records => {\n this._ngZone.run(() => {\n observer.next(records);\n });\n });\n\n return () => {\n subscription.unsubscribe();\n this._unobserveElement(element);\n };\n });\n }\n\n /**\n * Observes the given element by using the existing MutationObserver if available, or creating a\n * new one if not.\n */\n private _observeElement(element: Element): Subject<MutationRecord[]> {\n return this._ngZone.runOutsideAngular(() => {\n if (!this._observedElements.has(element)) {\n const stream = new Subject<MutationRecord[]>();\n const observer = this._mutationObserverFactory.create(mutations => stream.next(mutations));\n if (observer) {\n observer.observe(element, {\n characterData: true,\n childList: true,\n subtree: true,\n });\n }\n this._observedElements.set(element, {observer, stream, count: 1});\n } else {\n this._observedElements.get(element)!.count++;\n }\n return this._observedElements.get(element)!.stream;\n });\n }\n\n /**\n * Un-observes the given element and cleans up the underlying MutationObserver if nobody else is\n * observing this element.\n */\n private _unobserveElement(element: Element) {\n if (this._observedElements.has(element)) {\n this._observedElements.get(element)!.count--;\n if (!this._observedElements.get(element)!.count) {\n this._cleanupObserver(element);\n }\n }\n }\n\n /** Clean up the underlying MutationObserver for the specified element. */\n private _cleanupObserver(element: Element) {\n if (this._observedElements.has(element)) {\n const {observer, stream} = this._observedElements.get(element)!;\n if (observer) {\n observer.disconnect();\n }\n stream.complete();\n this._observedElements.delete(element);\n }\n }\n}\n\n/**\n * Directive that triggers a callback whenever the content of\n * its associated element has changed.\n */\n@Directive({\n selector: '[cdkObserveContent]',\n exportAs: 'cdkObserveContent',\n})\nexport class CdkObserveContent implements AfterContentInit, OnDestroy {\n private _contentObserver = inject(ContentObserver);\n private _elementRef = inject<ElementRef<HTMLElement>>(ElementRef);\n\n /** Event emitted for each change in the element's content. */\n @Output('cdkObserveContent') readonly event = new EventEmitter<MutationRecord[]>();\n\n /**\n * Whether observing content is disabled. This option can be used\n * to disconnect the underlying MutationObserver until it is needed.\n */\n @Input({alias: 'cdkObserveContentDisabled', transform: booleanAttribute})\n get disabled(): boolean {\n return this._disabled;\n }\n set disabled(value: boolean) {\n this._disabled = value;\n this._disabled ? this._unsubscribe() : this._subscribe();\n }\n private _disabled = false;\n\n /** Debounce interval for emitting the changes. */\n @Input()\n get debounce(): number {\n return this._debounce;\n }\n set debounce(value: NumberInput) {\n this._debounce = coerceNumberProperty(value);\n this._subscribe();\n }\n private _debounce: number;\n\n private _currentSubscription: Subscription | null = null;\n\n constructor(...args: unknown[]);\n constructor() {}\n\n ngAfterContentInit() {\n if (!this._currentSubscription && !this.disabled) {\n this._subscribe();\n }\n }\n\n ngOnDestroy() {\n this._unsubscribe();\n }\n\n private _subscribe() {\n this._unsubscribe();\n const stream = this._contentObserver.observe(this._elementRef);\n\n this._currentSubscription = (\n this.debounce ? stream.pipe(debounceTime(this.debounce)) : stream\n ).subscribe(this.event);\n }\n\n private _unsubscribe() {\n this._currentSubscription?.unsubscribe();\n }\n}\n\n@NgModule({\n imports: [CdkObserveContent],\n exports: [CdkObserveContent],\n providers: [MutationObserverFactory],\n})\nexport class ObserversModule {}\n"],"names":["shouldIgnoreRecord","record","type","target","Comment","i","addedNodes","length","removedNodes","MutationObserverFactory","create","callback","MutationObserver","deps","i0","ɵɵFactoryTarget","Injectable","ɵprov","ɵɵngDeclareInjectable","minVersion","version","ngImport","decorators","providedIn","ContentObserver","_mutationObserverFactory","inject","_observedElements","Map","_ngZone","NgZone","constructor","ngOnDestroy","forEach","_","element","_cleanupObserver","observe","elementOrRef","coerceElement","Observable","observer","stream","_observeElement","subscription","pipe","map","records","filter","subscribe","run","next","unsubscribe","_unobserveElement","runOutsideAngular","has","Subject","mutations","characterData","childList","subtree","set","count","get","disconnect","complete","delete","CdkObserveContent","_contentObserver","_elementRef","ElementRef","event","EventEmitter","disabled","_disabled","value","_unsubscribe","_subscribe","debounce","_debounce","coerceNumberProperty","_currentSubscription","ngAfterContentInit","debounceTime","Directive","ɵdir","ɵɵngDeclareDirective","booleanAttribute","outputs","exportAs","args","selector","Output","Input","alias","transform","ObserversModule","NgModule","imports","exports","providers"],"mappings":"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"}