mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-23 21:01:08 +00:00
4f39423c44
Differential Revision: https://phabricator.services.mozilla.com/D159015
165 lines
6.4 KiB
JavaScript
165 lines
6.4 KiB
JavaScript
/* vim: set ts=2 sw=2 sts=2 et tw=80: */
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
export class DOMFullscreenChild extends JSWindowActorChild {
|
|
receiveMessage(aMessage) {
|
|
let window = this.contentWindow;
|
|
let windowUtils = window?.windowUtils;
|
|
|
|
switch (aMessage.name) {
|
|
case "DOMFullscreen:Entered": {
|
|
if (!windowUtils) {
|
|
// If we are not able to enter fullscreen, tell the parent to just
|
|
// exit.
|
|
this.sendAsyncMessage("DOMFullscreen:Exit", {});
|
|
break;
|
|
}
|
|
|
|
let remoteFrameBC = aMessage.data.remoteFrameBC;
|
|
if (remoteFrameBC) {
|
|
let remoteFrame = remoteFrameBC.embedderElement;
|
|
if (!remoteFrame) {
|
|
// This could happen when the page navigate away and trigger a
|
|
// process switching during fullscreen transition, tell the parent
|
|
// to just exit.
|
|
this.sendAsyncMessage("DOMFullscreen:Exit", {});
|
|
break;
|
|
}
|
|
this._isNotTheRequestSource = true;
|
|
windowUtils.remoteFrameFullscreenChanged(remoteFrame);
|
|
} else {
|
|
this._waitForMozAfterPaint = true;
|
|
this._lastTransactionId = windowUtils.lastTransactionId;
|
|
if (
|
|
!windowUtils.handleFullscreenRequests() &&
|
|
!this.document.fullscreenElement
|
|
) {
|
|
// If we don't actually have any pending fullscreen request
|
|
// to handle, neither we have been in fullscreen, tell the
|
|
// parent to just exit.
|
|
this.sendAsyncMessage("DOMFullscreen:Exit", {});
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case "DOMFullscreen:CleanUp": {
|
|
let isNotTheRequestSource = !!aMessage.data.remoteFrameBC;
|
|
// If we've exited fullscreen at this point, no need to record
|
|
// transaction id or call exit fullscreen. This is especially
|
|
// important for pre-e10s, since in that case, it is possible
|
|
// that no more paint would be triggered after this point.
|
|
if (this.document.fullscreenElement) {
|
|
this._isNotTheRequestSource = isNotTheRequestSource;
|
|
// Need to wait for the MozAfterPaint after exiting fullscreen if
|
|
// this is the request source.
|
|
this._waitForMozAfterPaint = !this._isNotTheRequestSource;
|
|
// windowUtils could be null if the associated window is not current
|
|
// active window. In this case, document must be in the process of
|
|
// exiting fullscreen, it is okay to not ask it to exit fullscreen.
|
|
if (windowUtils) {
|
|
this._lastTransactionId = windowUtils.lastTransactionId;
|
|
windowUtils.exitFullscreen();
|
|
}
|
|
} else if (isNotTheRequestSource) {
|
|
// If we are not the request source and have exited fullscreen, reply
|
|
// Exited to parent as parent is waiting for our reply.
|
|
this.sendAsyncMessage("DOMFullscreen:Exited", {});
|
|
} else {
|
|
// If we've already exited fullscreen, it is possible that no more
|
|
// paint would be triggered, so don't wait for MozAfterPaint.
|
|
// TODO: There might be some way to move this code around a bit to
|
|
// make it easier to follow. Somehow handle the "local" case in
|
|
// one place and the isNotTheRequestSource case after that.
|
|
this.sendAsyncMessage("DOMFullscreen:Painted", {});
|
|
}
|
|
break;
|
|
}
|
|
case "DOMFullscreen:Painted": {
|
|
Services.obs.notifyObservers(window, "fullscreen-painted");
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
handleEvent(aEvent) {
|
|
if (this.hasBeenDestroyed()) {
|
|
// Make sure that this actor is alive before going further because
|
|
// if it's not the case, any attempt to send a message or access
|
|
// objects such as 'contentWindow' will fail. (See bug 1590138)
|
|
return;
|
|
}
|
|
|
|
switch (aEvent.type) {
|
|
case "MozDOMFullscreen:Request": {
|
|
this.sendAsyncMessage("DOMFullscreen:Request", {});
|
|
break;
|
|
}
|
|
case "MozDOMFullscreen:NewOrigin": {
|
|
this.sendAsyncMessage("DOMFullscreen:NewOrigin", {
|
|
originNoSuffix: aEvent.target.nodePrincipal.originNoSuffix,
|
|
});
|
|
break;
|
|
}
|
|
case "MozDOMFullscreen:Exit": {
|
|
this.sendAsyncMessage("DOMFullscreen:Exit", {});
|
|
break;
|
|
}
|
|
case "MozDOMFullscreen:Entered":
|
|
case "MozDOMFullscreen:Exited": {
|
|
if (this._isNotTheRequestSource) {
|
|
// Fullscreen change event for a frame in the
|
|
// middle (content frame embedding the oop frame where the
|
|
// request comes from)
|
|
|
|
delete this._isNotTheRequestSource;
|
|
this.sendAsyncMessage(aEvent.type.replace("Moz", ""), {});
|
|
break;
|
|
}
|
|
|
|
if (this._waitForMozAfterPaint) {
|
|
delete this._waitForMozAfterPaint;
|
|
this._listeningWindow = this.contentWindow.windowRoot;
|
|
this._listeningWindow.addEventListener("MozAfterPaint", this);
|
|
}
|
|
|
|
if (!this.document || !this.document.fullscreenElement) {
|
|
// If we receive any fullscreen change event, and find we are
|
|
// actually not in fullscreen, also ask the parent to exit to
|
|
// ensure that the parent always exits fullscreen when we do.
|
|
this.sendAsyncMessage("DOMFullscreen:Exit", {});
|
|
}
|
|
break;
|
|
}
|
|
case "MozAfterPaint": {
|
|
// Only send Painted signal after we actually finish painting
|
|
// the transition for the fullscreen change.
|
|
// Note that this._lastTransactionId is not set when in pre-e10s
|
|
// mode, so we need to check that explicitly.
|
|
if (
|
|
!this._lastTransactionId ||
|
|
aEvent.transactionId > this._lastTransactionId
|
|
) {
|
|
this._listeningWindow.removeEventListener("MozAfterPaint", this);
|
|
delete this._listeningWindow;
|
|
this.sendAsyncMessage("DOMFullscreen:Painted", {});
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
hasBeenDestroyed() {
|
|
// The 'didDestroy' callback is not always getting called.
|
|
// So we can't rely on it here. Instead, we will try to access
|
|
// the browsing context to judge wether the actor has
|
|
// been destroyed or not.
|
|
try {
|
|
return !this.browsingContext;
|
|
} catch {
|
|
return true;
|
|
}
|
|
}
|
|
}
|