Skip to content

Commit d2b183e

Browse files
crisbetommalerba
authored andcommitted
fix(overlay): handle OnDestroy in FullscreenOverlayContainer and use document injection token (#10773)
* Fixes the `fullscreenchange` event handler not being cleared from the `FullscreenOverlayContainer` once it's destroyed. * Uses the `DOCUMENT` token to avoid potential server-side rendering errors.
1 parent 4e48cf4 commit d2b183e

File tree

2 files changed

+53
-18
lines changed

2 files changed

+53
-18
lines changed

Diff for: src/cdk/overlay/fullscreen-overlay-container.ts

+52-17
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,10 @@
66
* found in the LICENSE file at https://angular.io/license
77
*/
88

9-
import {Injectable} from '@angular/core';
9+
import {Injectable, Inject, OnDestroy} from '@angular/core';
1010
import {OverlayContainer} from './overlay-container';
11+
import {DOCUMENT} from '@angular/common';
12+
1113

1214
/**
1315
* Alternative to OverlayContainer that supports correct displaying of overlay elements in
@@ -17,7 +19,22 @@ import {OverlayContainer} from './overlay-container';
1719
* Should be provided in the root component.
1820
*/
1921
@Injectable()
20-
export class FullscreenOverlayContainer extends OverlayContainer {
22+
export class FullscreenOverlayContainer extends OverlayContainer implements OnDestroy {
23+
private _fullScreenEventName: string | undefined;
24+
private _fullScreenListener: () => void;
25+
26+
constructor(@Inject(DOCUMENT) _document: any) {
27+
super(_document);
28+
}
29+
30+
ngOnDestroy() {
31+
super.ngOnDestroy();
32+
33+
if (this._fullScreenEventName && this._fullScreenListener) {
34+
this._document.removeEventListener(this._fullScreenEventName, this._fullScreenListener);
35+
}
36+
}
37+
2138
protected _createContainer(): void {
2239
super._createContainer();
2340
this._adjustParentForFullscreenChange();
@@ -28,32 +45,50 @@ export class FullscreenOverlayContainer extends OverlayContainer {
2845
if (!this._containerElement) {
2946
return;
3047
}
31-
let fullscreenElement = this.getFullscreenElement();
32-
let parent = fullscreenElement || document.body;
48+
49+
const fullscreenElement = this.getFullscreenElement();
50+
const parent = fullscreenElement || this._document.body;
3351
parent.appendChild(this._containerElement);
3452
}
3553

3654
private _addFullscreenChangeListener(fn: () => void) {
37-
if (document.fullscreenEnabled) {
38-
document.addEventListener('fullscreenchange', fn);
39-
} else if (document.webkitFullscreenEnabled) {
40-
document.addEventListener('webkitfullscreenchange', fn);
41-
} else if ((document as any).mozFullScreenEnabled) {
42-
document.addEventListener('mozfullscreenchange', fn);
43-
} else if ((document as any).msFullscreenEnabled) {
44-
document.addEventListener('MSFullscreenChange', fn);
55+
const eventName = this._getEventName();
56+
57+
if (eventName) {
58+
if (this._fullScreenListener) {
59+
this._document.removeEventListener(eventName, this._fullScreenListener);
60+
}
61+
62+
this._document.addEventListener(eventName, fn);
63+
this._fullScreenListener = fn;
4564
}
4665
}
4766

67+
private _getEventName(): string | undefined {
68+
if (!this._fullScreenEventName) {
69+
if (this._document.fullscreenEnabled) {
70+
this._fullScreenEventName = 'fullscreenchange';
71+
} else if (this._document.webkitFullscreenEnabled) {
72+
this._fullScreenEventName = 'webkitfullscreenchange';
73+
} else if ((this._document as any).mozFullScreenEnabled) {
74+
this._fullScreenEventName = 'mozfullscreenchange';
75+
} else if ((this._document as any).msFullscreenEnabled) {
76+
this._fullScreenEventName = 'MSFullscreenChange';
77+
}
78+
}
79+
80+
return this._fullScreenEventName;
81+
}
82+
4883
/**
4984
* When the page is put into fullscreen mode, a specific element is specified.
5085
* Only that element and its children are visible when in fullscreen mode.
5186
*/
5287
getFullscreenElement(): Element {
53-
return document.fullscreenElement ||
54-
document.webkitFullscreenElement ||
55-
(document as any).mozFullScreenElement ||
56-
(document as any).msFullscreenElement ||
57-
null;
88+
return this._document.fullscreenElement ||
89+
this._document.webkitFullscreenElement ||
90+
(this._document as any).mozFullScreenElement ||
91+
(this._document as any).msFullscreenElement ||
92+
null;
5893
}
5994
}

Diff for: src/cdk/overlay/overlay-container.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ import {
2222
export class OverlayContainer implements OnDestroy {
2323
protected _containerElement: HTMLElement;
2424

25-
constructor(@Inject(DOCUMENT) private _document: any) {}
25+
constructor(@Inject(DOCUMENT) protected _document: any) {}
2626

2727
ngOnDestroy() {
2828
if (this._containerElement && this._containerElement.parentNode) {

0 commit comments

Comments
 (0)