Source code

Revision control

Other Tools

1
/* vim: set ts=2 sw=2 sts=2 et tw=80: */
2
/* This Source Code Form is subject to the terms of the Mozilla Public
3
* License, v. 2.0. If a copy of the MPL was not distributed with this
4
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5
"use strict";
6
7
var EXPORTED_SYMBOLS = ["DOMFullscreenParent"];
8
9
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
10
11
class DOMFullscreenParent extends JSWindowActorParent {
12
receiveMessage(aMessage) {
13
let topBrowsingContext = this.browsingContext.top;
14
let browser = topBrowsingContext.embedderElement;
15
16
if (!browser) {
17
// No need to go further when the browser is not accessible anymore
18
// (which can happen when the tab is closed for instance),
19
return;
20
}
21
22
let window = browser.ownerGlobal;
23
switch (aMessage.name) {
24
case "DOMFullscreen:Request": {
25
this.requestOrigin = this;
26
this.addListeners(window);
27
window.windowUtils.remoteFrameFullscreenChanged(browser);
28
break;
29
}
30
case "DOMFullscreen:NewOrigin": {
31
// Don't show the warning if we've already exited fullscreen.
32
if (window.document.fullscreen) {
33
window.PointerlockFsWarning.showFullScreen(
34
aMessage.data.originNoSuffix
35
);
36
}
37
break;
38
}
39
case "DOMFullscreen:Entered": {
40
window.FullScreen.enterDomFullscreen(browser, this);
41
break;
42
}
43
case "DOMFullscreen:Exit": {
44
window.windowUtils.remoteFrameFullscreenReverted();
45
break;
46
}
47
case "DOMFullscreen:Exited": {
48
window.FullScreen.cleanupDomFullscreen(this);
49
break;
50
}
51
case "DOMFullscreen:Painted": {
52
Services.obs.notifyObservers(window, "fullscreen-painted");
53
this.sendAsyncMessage("DOMFullscreen:Painted", {});
54
TelemetryStopwatch.finish("FULLSCREEN_CHANGE_MS");
55
break;
56
}
57
}
58
}
59
60
handleEvent(aEvent) {
61
let window = aEvent.currentTarget.ownerGlobal;
62
switch (aEvent.type) {
63
case "MozDOMFullscreen:Entered": {
64
// The event target is the element which requested the DOM
65
// fullscreen. If we were entering DOM fullscreen for a remote
66
// browser, the target would be the browser which was the parameter of
67
// `remoteFrameFullscreenChanged` call. If the fullscreen
68
// request was initiated from an in-process browser, we need
69
// to get its corresponding browser here.
70
let browser;
71
if (aEvent.target.ownerGlobal == window) {
72
browser = aEvent.target;
73
} else {
74
browser = aEvent.target.ownerGlobal.docShell.chromeEventHandler;
75
}
76
77
// Addon installation should be cancelled when entering fullscreen for security and usability reasons.
78
// Installation prompts in fullscreen can trick the user into installing unwanted addons.
79
// In fullscreen the notification box does not have a clear visual association with its parent anymore.
80
if (window.gXPInstallObserver) {
81
window.gXPInstallObserver.removeAllNotifications(browser);
82
}
83
84
TelemetryStopwatch.start("FULLSCREEN_CHANGE_MS");
85
window.FullScreen.enterDomFullscreen(browser, this);
86
break;
87
}
88
case "MozDOMFullscreen:Exited": {
89
TelemetryStopwatch.start("FULLSCREEN_CHANGE_MS");
90
91
// Make sure that the actor has not been destroyed before
92
// accessing its browsing context. Otherwise, a error may
93
// occur and hence cleanupDomFullscreen not executed, resulting
94
// in the browser window being in an unstable state.
95
// (Bug 1590138).
96
if (!this.hasBeenDestroyed() && !this.requestOrigin) {
97
this.requestOrigin = this;
98
}
99
window.FullScreen.cleanupDomFullscreen(this);
100
this.removeListeners(window);
101
break;
102
}
103
}
104
}
105
106
addListeners(aWindow) {
107
aWindow.addEventListener(
108
"MozDOMFullscreen:Entered",
109
this,
110
/* useCapture */ true,
111
/* wantsUntrusted */
112
false
113
);
114
aWindow.addEventListener(
115
"MozDOMFullscreen:Exited",
116
this,
117
/* useCapture */ true,
118
/* wantsUntrusted */ false
119
);
120
}
121
122
removeListeners(aWindow) {
123
aWindow.removeEventListener("MozDOMFullscreen:Entered", this, true);
124
aWindow.removeEventListener("MozDOMFullscreen:Exited", this, true);
125
}
126
127
/**
128
* Get the actor where the original fullscreen
129
* enter or exit request comes from.
130
*/
131
get requestOrigin() {
132
let requestOrigin = this.browsingContext.top.fullscreenRequestOrigin;
133
return requestOrigin && requestOrigin.get();
134
}
135
136
/**
137
* Store the actor where the original fullscreen
138
* enter or exit request comes from in the top level
139
* browsing context.
140
*/
141
set requestOrigin(aActor) {
142
if (aActor) {
143
this.browsingContext.top.fullscreenRequestOrigin = Cu.getWeakReference(
144
aActor
145
);
146
} else {
147
delete this.browsingContext.top.fullscreenRequestOrigin;
148
}
149
}
150
151
hasBeenDestroyed() {
152
// The 'didDestroy' callback is not always getting called.
153
// So we can't rely on it here. Instead, we will try to access
154
// the browsing context to judge wether the actor has
155
// been destroyed or not.
156
try {
157
return !this.browsingContext;
158
} catch {
159
return true;
160
}
161
}
162
}