@@ -33,9 +33,10 @@ export class MutationObserverFactory {
3333}
3434
3535
36- /** A factory that creates ContentObservers . */
36+ /** An injectable service that allows watching elements for changes to their content . */
3737@Injectable ( { providedIn : 'root' } )
38- export class ContentObserver {
38+ export class ContentObserver implements OnDestroy {
39+ /** Keeps track of the existing MutationObservers so they can be reused. */
3940 private _observedElements = new Map < Element , {
4041 observer : MutationObserver | null ,
4142 stream : Subject < MutationRecord [ ] > ,
@@ -44,19 +45,30 @@ export class ContentObserver {
4445
4546 constructor ( private _mutationObserverFactory : MutationObserverFactory ) { }
4647
47- observe ( element : Element , debounce ?: number ) : Observable < MutationRecord [ ] > {
48+ ngOnDestroy ( ) {
49+ this . _observedElements . forEach ( ( _ , element ) => this . _cleanupObserver ( element ) ) ;
50+ }
51+
52+ /**
53+ * Observe content changes on an element.
54+ * @param element The element to observe for content changes.
55+ */
56+ observe ( element : Element ) : Observable < MutationRecord [ ] > {
4857 return Observable . create ( observer => {
4958 const stream = this . _observeElement ( element ) ;
50- const subscription =
51- ( debounce ? stream . pipe ( debounceTime ( debounce ) ) : stream ) . subscribe ( observer ) ;
59+ const subscription = stream . subscribe ( observer ) ;
5260
5361 return ( ) => {
5462 subscription . unsubscribe ( ) ;
5563 this . _unobserveElement ( element ) ;
56- }
64+ } ;
5765 } ) ;
5866 }
5967
68+ /**
69+ * Observes the given element by using the existing MutationObserver if available, or creating a
70+ * new one if not.
71+ */
6072 private _observeElement ( element : Element ) : Subject < MutationRecord [ ] > {
6173 if ( ! this . _observedElements . has ( element ) ) {
6274 const stream = new Subject < MutationRecord [ ] > ( ) ;
@@ -75,14 +87,20 @@ export class ContentObserver {
7587 return this . _observedElements . get ( element ) ! . stream ;
7688 }
7789
90+ /**
91+ * Un-observes the given element and cleans up the underlying MutationObserver if nobody else is
92+ * observing this element.
93+ */
7894 private _unobserveElement ( element : Element ) {
7995 if ( this . _observedElements . has ( element ) ) {
80- if ( ! -- this . _observedElements . get ( element ) ! . count ) {
96+ this . _observedElements . get ( element ) ! . count -- ;
97+ if ( ! this . _observedElements . get ( element ) ! . count ) {
8198 this . _cleanupObserver ( element ) ;
8299 }
83100 }
84101 }
85102
103+ /** Clean up the underlying MutationObserver for the specified element. */
86104 private _cleanupObserver ( element : Element ) {
87105 if ( this . _observedElements . has ( element ) ) {
88106 const { observer, stream} = this . _observedElements . get ( element ) ! ;
@@ -149,9 +167,9 @@ export class CdkObserveContent implements AfterContentInit, OnDestroy {
149167
150168 private _subscribe ( ) {
151169 this . _unsubscribe ( ) ;
152- this . _currentSubscription =
153- this . _contentObserver . observe ( this . _elementRef . nativeElement , this . debounce )
154- . subscribe ( mutations => this . event . next ( mutations ) ) ;
170+ const stream = this . _contentObserver . observe ( this . _elementRef . nativeElement ) ;
171+ this . _currentSubscription = ( this . debounce ? stream . pipe ( debounceTime ( this . debounce ) ) : stream )
172+ . subscribe ( mutations => this . event . next ( mutations ) ) ;
155173 }
156174
157175 private _unsubscribe ( ) {
0 commit comments