Bug 1620341 - Add didDestroy() in DOMFullscreenParent.jsm to avoid the window stays in fullscreen problem r=Gijs,smaug

Differential Revision: https://phabricator.services.mozilla.com/D75915
This commit is contained in:
Alphan Chen 2020-06-08 15:24:54 +00:00
parent b0d58c5da3
commit 4210fb7d00
3 changed files with 129 additions and 0 deletions

View File

@ -9,6 +9,33 @@ var EXPORTED_SYMBOLS = ["DOMFullscreenParent"];
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
class DOMFullscreenParent extends JSWindowActorParent {
updateFullscreenWindowReference(aWindow) {
if (aWindow.document.documentElement.hasAttribute("inDOMFullscreen")) {
this._fullscreenWindow = aWindow;
} else {
delete this._fullscreenWindow;
}
}
didDestroy() {
let window = this._fullscreenWindow;
if (!window) {
return;
}
// Need to resume Chrome UI if the window is still in fullscreen UI
// to avoid the window stays in fullscreen problem. (See Bug 1620341)
if (window.document.documentElement.hasAttribute("inDOMFullscreen")) {
if (window.FullScreen) {
window.FullScreen.cleanupDomFullscreen(this);
}
if (window.windowUtils) {
window.windowUtils.remoteFrameFullscreenReverted();
}
}
this.updateFullscreenWindowReference(window);
}
receiveMessage(aMessage) {
let topBrowsingContext = this.browsingContext.top;
let browser = topBrowsingContext.embedderElement;
@ -38,6 +65,7 @@ class DOMFullscreenParent extends JSWindowActorParent {
}
case "DOMFullscreen:Entered": {
window.FullScreen.enterDomFullscreen(browser, this);
this.updateFullscreenWindowReference(window);
break;
}
case "DOMFullscreen:Exit": {
@ -46,6 +74,7 @@ class DOMFullscreenParent extends JSWindowActorParent {
}
case "DOMFullscreen:Exited": {
window.FullScreen.cleanupDomFullscreen(this);
this.updateFullscreenWindowReference(window);
break;
}
case "DOMFullscreen:Painted": {
@ -83,6 +112,7 @@ class DOMFullscreenParent extends JSWindowActorParent {
TelemetryStopwatch.start("FULLSCREEN_CHANGE_MS");
window.FullScreen.enterDomFullscreen(browser, this);
this.updateFullscreenWindowReference(window);
break;
}
case "MozDOMFullscreen:Exited": {
@ -97,6 +127,7 @@ class DOMFullscreenParent extends JSWindowActorParent {
this.requestOrigin = this;
}
window.FullScreen.cleanupDomFullscreen(this);
this.updateFullscreenWindowReference(window);
this.removeListeners(window);
break;
}

View File

@ -8,6 +8,8 @@ skip-if = os == 'linux' # Bug 1561973
skip-if = debug && os == 'mac' # Bug 1568570
[browser_fullscreen_cross_origin.js]
support-files = fullscreen.html fullscreen_frame.html
[browser_bug1620341.js]
support-files = fullscreen.html fullscreen_frame.html
[browser_fullscreen_enterInUrlbar.js]
run-if = os != 'mac' # Tests non-Mac full screen
skip-if = (fission && os == 'linux' && bits == 64 && os_version == '18.04') # bug 1615477 for Ubuntu 18.04.

View File

@ -0,0 +1,96 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
const tab1URL = `data:text/html,
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8"/>
<title>First tab to be loaded</title>
</head>
<body>
<button>JUST A BUTTON</button>
</body>
</html>`;
const ORIGIN =
"https://example.com/browser/browser/base/content/test/fullscreen/fullscreen_frame.html";
add_task(async function test_fullscreen_cross_origin() {
async function requestFullscreenThenCloseTab() {
await BrowserTestUtils.withNewTab(ORIGIN, async function(browser) {
info("Start fullscreen on iframe frameAllowed");
// Make sure there is no attribute "inDOMFullscreen" before requesting fullscreen.
await TestUtils.waitForCondition(
() => !document.documentElement.hasAttribute("inDOMFullscreen")
);
// Request fullscreen from iframe
await SpecialPowers.spawn(browser, [], async function() {
let frame = content.document.getElementById("frameAllowed");
frame.focus();
await SpecialPowers.spawn(frame, [], async () => {
let frameDoc = content.document;
const waitForFullscreen = new Promise(resolve => {
const message = "fullscreenchange";
function handler(evt) {
frameDoc.removeEventListener(message, handler);
Assert.equal(evt.type, message, `Request should be allowed`);
resolve();
}
frameDoc.addEventListener(message, handler);
});
// In fission, we may not have docShell active automatically,
// Force docShell active manually
content.docShell.isActive = true;
frameDoc.getElementById("request").click();
await waitForFullscreen;
});
});
// Make sure there is attribute "inDOMFullscreen" after requesting fullscreen.
await TestUtils.waitForCondition(() =>
document.documentElement.hasAttribute("inDOMFullscreen")
);
});
}
await SpecialPowers.pushPrefEnv({
set: [
["full-screen-api.enabled", true],
["full-screen-api.allow-trusted-requests-only", false],
["full-screen-api.transition-duration.enter", "0 0"],
["full-screen-api.transition-duration.leave", "0 0"],
["dom.security.featurePolicy.enabled", true],
["dom.security.featurePolicy.header.enabled", true],
["dom.security.featurePolicy.webidl.enabled", true],
],
});
// Open a tab with tab1URL.
let tab1 = await BrowserTestUtils.openNewForegroundTab(
gBrowser,
tab1URL,
true
);
// 1. Open another tab and load a page with two iframes.
// 2. Request fullscreen from an iframe which is in a different origin.
// 3. Close the tab after receiving "fullscreenchange" message.
// Note that we don't do "doc.exitFullscreen()" before closing the tab
// on purpose.
await requestFullscreenThenCloseTab();
// Wait until attribute "inDOMFullscreen" is removed.
await TestUtils.waitForCondition(
() => !document.documentElement.hasAttribute("inDOMFullscreen")
);
// Remove the remaining tab and leave the test.
let tabClosed = BrowserTestUtils.waitForTabClosing(tab1);
BrowserTestUtils.removeTab(tab1);
await tabClosed;
});