Skip to content
This repository was archived by the owner on Jan 6, 2025. It is now read-only.

Commit 6d0cd00

Browse files
authored
fix(print-hook): unregister event listeners on destroy (#1235)
1 parent 7a22fba commit 6d0cd00

File tree

1 file changed

+23
-8
lines changed

1 file changed

+23
-8
lines changed

src/lib/core/media-marshaller/print-hook.ts

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
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

1010
import {mergeAlias} from '../add-alias';
1111
import {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

Comments
 (0)