55 * Use of this source code is governed by an MIT-style license that can be
66 * found in the LICENSE file at https://angular.io/license
77 */
8- import { Inject , Injectable } from '@angular/core' ;
8+ import { Inject , Injectable , OnDestroy } from '@angular/core' ;
99
1010import { mergeAlias } from '../add-alias' ;
1111import { MediaChange } from '../media-change' ;
@@ -37,7 +37,7 @@ export const BREAKPOINT_PRINT = {
3737 * Used in MediaMarshaller and MediaObserver
3838 */
3939@Injectable ( { providedIn : 'root' } )
40- export class PrintHook {
40+ export class PrintHook implements OnDestroy {
4141 constructor (
4242 protected breakpoints : BreakPointRegistry ,
4343 @Inject ( LAYOUT_CONFIG ) protected layoutConfig : LayoutConfigOptions ,
@@ -97,6 +97,9 @@ export class PrintHook {
9797 // browsers which support `beforeprint` and `afterprint` events.
9898 private isPrintingBeforeAfterEvent : boolean = false ;
9999
100+ private beforePrintEventListeners : Function [ ] = [ ] ;
101+ private afterPrintEventListeners : Function [ ] = [ ] ;
102+
100103 // registerBeforeAfterPrintHooks registers a `beforeprint` event hook so we can
101104 // trigger print styles synchronously and apply proper layout styles.
102105 // It is a noop if the hooks have already been registered or if the document's
@@ -109,30 +112,36 @@ export class PrintHook {
109112
110113 this . registeredBeforeAfterPrintHooks = true ;
111114
112- // Could we have teardown logic to remove if there are no print listeners being used?
113- this . _document . defaultView . addEventListener ( 'beforeprint' , ( ) => {
115+ const beforePrintListener = ( ) => {
114116 // If we aren't already printing, start printing and update the styles as
115117 // if there was a regular print `MediaChange`(from matchMedia).
116118 if ( ! this . isPrinting ) {
117119 this . isPrintingBeforeAfterEvent = true ;
118120 this . startPrinting ( target , this . getEventBreakpoints ( new MediaChange ( true , PRINT ) ) ) ;
119121 target . updateStyles ( ) ;
120122 }
121- } ) ;
123+ } ;
122124
123- this . _document . defaultView . addEventListener ( 'afterprint' , ( ) => {
125+ const afterPrintListener = ( ) => {
124126 // If we aren't already printing, start printing and update the styles as
125127 // if there was a regular print `MediaChange`(from matchMedia).
126128 this . isPrintingBeforeAfterEvent = false ;
127129 if ( this . isPrinting ) {
128130 this . stopPrinting ( target ) ;
129131 target . updateStyles ( ) ;
130132 }
131- } ) ;
133+ } ;
134+
135+ // Could we have teardown logic to remove if there are no print listeners being used?
136+ this . _document . defaultView . addEventListener ( 'beforeprint' , beforePrintListener ) ;
137+ this . _document . defaultView . addEventListener ( 'afterprint' , afterPrintListener ) ;
138+
139+ this . beforePrintEventListeners . push ( beforePrintListener ) ;
140+ this . afterPrintEventListeners . push ( afterPrintListener ) ;
132141 }
133142
134143 /**
135- * Prepare RxJs filter operator with partial application
144+ * Prepare RxJS filter operator with partial application
136145 * @return pipeable filter predicate
137146 */
138147 interceptEvents ( target : HookTarget ) {
@@ -213,6 +222,12 @@ export class PrintHook {
213222 }
214223 }
215224
225+ /** Teardown logic for the service. */
226+ ngOnDestroy ( ) {
227+ this . beforePrintEventListeners . forEach ( l => this . _document . defaultView . removeEventListener ( 'beforeprint' , l ) ) ;
228+ this . afterPrintEventListeners . forEach ( l => this . _document . defaultView . removeEventListener ( 'afterprint' , l ) ) ;
229+ }
230+
216231 /** Is this service currently in Print-mode ? */
217232 private isPrinting = false ;
218233 private queue : PrintQueue = new PrintQueue ( ) ;
0 commit comments