Bug 1669961: Return null from `.contentWindow` when inner window is inactive. r=nika

Differential Revision: https://phabricator.services.mozilla.com/D93853
This commit is contained in:
Kris Maglione 2020-10-22 19:05:04 +00:00
Родитель 27b1fa7259
Коммит 3cf334a80a
10 изменённых файлов: 103 добавлений и 15 удалений

Просмотреть файл

@ -360,10 +360,14 @@ async function unregisterServiceWorker(tab, expectedPageUrl) {
async function waitForRegistrationReady(tab, expectedPageUrl) {
await asyncWaitUntil(() =>
SpecialPowers.spawn(tab.linkedBrowser, [expectedPageUrl], function(_url) {
const win = content.wrappedJSObject;
const isExpectedUrl = win.location.href === _url;
const hasRegistration = !!win.registration;
return isExpectedUrl && hasRegistration;
try {
const win = content.wrappedJSObject;
const isExpectedUrl = win.location.href === _url;
const hasRegistration = !!win.registration;
return isExpectedUrl && hasRegistration;
} catch (e) {
return false;
}
})
);
}

Просмотреть файл

@ -31,7 +31,6 @@ add_task(async function() {
"History listener got called after a content viewer was evicted"
);
legacySHistory.removeSHistoryListener(historyListener);
delete content._testListener;
// 6. Resolve the promise when we got our 'content viewer evicted' event
resolve();
},

Просмотреть файл

@ -125,9 +125,17 @@ nsIDocShell* JSWindowActorChild::GetDocShell(ErrorResult& aRv) {
Nullable<WindowProxyHolder> JSWindowActorChild::GetContentWindow(
ErrorResult& aRv) {
if (BrowsingContext* bc = GetBrowsingContext(aRv)) {
return WindowProxyHolder(bc);
if (!mManager) {
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
return nullptr;
}
if (nsGlobalWindowInner* window = mManager->GetWindowGlobal()) {
if (window->IsCurrentInnerWindow()) {
return WindowProxyHolder(window->GetBrowsingContext());
}
}
return nullptr;
}

Просмотреть файл

@ -2,6 +2,7 @@
support-files =
head.js
[browser_contentWindow.js]
[browser_crash_report.js]
[browser_destroy_callbacks.js]
skip-if = !debug && (os == 'mac') #Bug 1604538

Просмотреть файл

@ -0,0 +1,47 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
declTest("contentWindow null when inner window inactive", {
matches: [TEST_URL + "*"],
url: TEST_URL + "?1",
async test(browser) {
{
let parent = browser.browsingContext.currentWindowGlobal;
let actorParent = parent.getActor("TestWindow");
await actorParent.sendQuery("storeActor");
}
{
let url = TEST_URL + "?2";
let loaded = BrowserTestUtils.browserLoaded(browser, false, url);
await BrowserTestUtils.loadURI(browser, url);
await loaded;
}
let parent = browser.browsingContext.currentWindowGlobal;
let actorParent = parent.getActor("TestWindow");
let result = await actorParent.sendQuery("checkActor");
if (SpecialPowers.useRemoteSubframes) {
is(
result.status,
"error",
"Should get an error when bfcache is disabled for Fission"
);
is(
result.errorType,
"InvalidStateError",
"Should get an InvalidStateError without bfcache"
);
} else {
is(result.status, "success", "Should succeed when bfcache is enabled");
ok(
result.valueIsNull,
"Should get a null contentWindow when inner window is inactive"
);
}
},
});

Просмотреть файл

@ -35,7 +35,7 @@ declTest("sendQuery Error", {
is(error.name, "SyntaxError", "Error should have the correct name");
is(
error.stack,
"receiveMessage@resource://testing-common/TestWindowChild.jsm:33:31\n" +
"receiveMessage@resource://testing-common/TestWindowChild.jsm:35:31\n" +
asyncStack,
"Error should have the correct stack"
);
@ -63,7 +63,7 @@ declTest("sendQuery Exception", {
);
is(
error.stack,
"receiveMessage@resource://testing-common/TestWindowChild.jsm:36:22\n" +
"receiveMessage@resource://testing-common/TestWindowChild.jsm:38:22\n" +
asyncStack,
"Error should have the correct stack"
);

Просмотреть файл

@ -50,9 +50,10 @@ async function openPage(enableDialogs) {
const { Services } = ChromeUtils.import(
"resource://gre/modules/Services.jsm"
);
let win = content;
Services.obs.addObserver(doc => {
if (content && doc == content.document) {
content.windowUtils[name]();
if (doc == win.document) {
win.windowUtils[name]();
}
}, "document-element-inserted");
});

Просмотреть файл

@ -8,6 +8,8 @@ const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
var EXPORTED_SYMBOLS = ["TestWindowChild"];
var docShellThunks = new Map();
class TestWindowChild extends JSWindowActorChild {
constructor() {
super();
@ -41,6 +43,31 @@ class TestWindowChild extends JSWindowActorChild {
case "noncloneReply":
// Return a value which is non-cloneable, like a WindowProxy.
return this.contentWindow;
case "storeActor":
docShellThunks.set(this.docShell, this);
break;
case "checkActor": {
let actor = docShellThunks.get(this.docShell);
docShellThunks.delete(this.docShell);
let contentWindow;
let error;
try {
contentWindow = actor.contentWindow;
} catch (e) {
error = e;
}
if (error) {
return {
status: "error",
errorType: error.name,
};
}
return {
status: "success",
valueIsNull: contentWindow === null,
};
}
}
return undefined;

Просмотреть файл

@ -267,10 +267,10 @@ async function submitForm(browser) {
await SpecialPowers.spawn(browser, [], async function() {
content.document.querySelector("form").submit();
let win = content;
await ContentTaskUtils.waitForCondition(() => {
return (
content.location.pathname == "/" &&
content.document.readyState == "complete"
win.location.pathname == "/" && win.document.readyState == "complete"
);
}, "Wait for form submission load");
});

Просмотреть файл

@ -457,10 +457,11 @@ async function submitForm(browser, action = "") {
info("Submitting form to:" + form.action);
form.submit();
let win = content;
await ContentTaskUtils.waitForCondition(() => {
return (
content.location.pathname == actionPathname &&
content.document.readyState == "complete"
win.location.pathname == actionPathname &&
win.document.readyState == "complete"
);
}, "Wait for form submission load");
});