{"version":3,"file":"observers.js","sources":["../../../../../../src/cdk/observers/observe-content.ts","../../../../../../src/cdk/observers/public-api.ts","../../../../../../src/cdk/observers/index.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.io/license\n */\n\nimport {\n coerceBooleanProperty,\n coerceNumberProperty,\n coerceElement,\n BooleanInput,\n NumberInput\n} from '@angular/cdk/coercion';\nimport {\n AfterContentInit,\n Directive,\n ElementRef,\n EventEmitter,\n Injectable,\n Input,\n NgModule,\n NgZone,\n OnDestroy,\n Output,\n} from '@angular/core';\nimport {Observable, Subject, Subscription, Observer} from 'rxjs';\nimport {debounceTime} from 'rxjs/operators';\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\n/** An injectable service that allows watching elements for changes to their content. */\n@Injectable({providedIn: 'root'})\nexport class ContentObserver implements OnDestroy {\n /** Keeps track of the existing MutationObservers so they can be reused. */\n private _observedElements = new Map,\n count: number\n }>();\n\n constructor(private _mutationObserverFactory: MutationObserverFactory) {}\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;\n\n /**\n * Observe content changes on an element.\n * @param element The element to observe for content changes.\n */\n observe(element: ElementRef): Observable;\n\n observe(elementOrRef: Element | ElementRef): Observable {\n const element = coerceElement(elementOrRef);\n\n return new Observable((observer: Observer) => {\n const stream = this._observeElement(element);\n const subscription = stream.subscribe(observer);\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 {\n if (!this._observedElements.has(element)) {\n const stream = new Subject();\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 * 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/**\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 /** Event emitted for each change in the element's content. */\n @Output('cdkObserveContent') readonly event = new EventEmitter();\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('cdkObserveContentDisabled')\n get disabled() { return this._disabled; }\n set disabled(value: any) {\n this._disabled = coerceBooleanProperty(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 { return this._debounce; }\n set debounce(value: number) {\n this._debounce = coerceNumberProperty(value);\n this._subscribe();\n }\n private _debounce: number;\n\n private _currentSubscription: Subscription | null = null;\n\n constructor(private _contentObserver: ContentObserver,\n private _elementRef: ElementRef,\n private _ngZone: NgZone) {}\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 // TODO(mmalerba): We shouldn't be emitting on this @Output() outside the zone.\n // Consider brining it back inside the zone next time we're making breaking changes.\n // Bringing it back inside can cause things like infinite change detection loops and changed\n // after checked errors if people's code isn't handling it properly.\n this._ngZone.runOutsideAngular(() => {\n this._currentSubscription =\n (this.debounce ? stream.pipe(debounceTime(this.debounce)) : stream).subscribe(this.event);\n });\n }\n\n private _unsubscribe() {\n this._currentSubscription?.unsubscribe();\n }\n\n static ngAcceptInputType_disabled: BooleanInput;\n static ngAcceptInputType_debounce: NumberInput;\n}\n\n\n@NgModule({\n exports: [CdkObserveContent],\n declarations: [CdkObserveContent],\n providers: [MutationObserverFactory]\n})\nexport class ObserversModule {}\n","/**\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.io/license\n */\n\nexport * from './observe-content';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}