function frameScript() { Components.utils.import("resource://gre/modules/Services.jsm"); function eventHandler(e) { if (!docShell) { sendAsyncMessage("Test:Fail", "docShell is null"); } sendAsyncMessage("Test:Event", [e.type, e.target === content.document, e.eventPhase]); } let outerID = content.QueryInterface(Components.interfaces.nsIInterfaceRequestor). getInterface(Components.interfaces.nsIDOMWindowUtils).outerWindowID; function onOuterWindowDestroyed(subject, topic, data) { if (docShell) { sendAsyncMessage("Test:Fail", "docShell is non-null"); } let id = subject.QueryInterface(Components.interfaces.nsISupportsPRUint64).data; sendAsyncMessage("Test:Event", ["outer-window-destroyed", id == outerID]); if (id == outerID) { Services.obs.removeObserver(onOuterWindowDestroyed, "outer-window-destroyed"); } } let url = "https://example.com/browser/dom/base/test/file_messagemanager_unload.html"; content.location = url; addEventListener("load", (e) => { if (e.target.location != url) { return; } addEventListener("unload", eventHandler, false); addEventListener("unload", eventHandler, true); addEventListener("pagehide", eventHandler, false); addEventListener("pagehide", eventHandler, true); Services.obs.addObserver(onOuterWindowDestroyed, "outer-window-destroyed", false); sendAsyncMessage("Test:Ready"); }, true); } const EXPECTED = [ // Unload events on the TabChildGlobal. These come first so that the // docshell is available. ["unload", false, 2], ["unload", false, 2], // pagehide and unload events for the top-level page. ["pagehide", true, 1], ["pagehide", true, 3], ["unload", true, 1], // pagehide and unload events for the iframe. ["pagehide", false, 1], ["pagehide", false, 3], ["unload", false, 1], // outer-window-destroyed for both pages. ["outer-window-destroyed", false], ["outer-window-destroyed", true], ]; function test() { waitForExplicitFinish(); var newTab = gBrowser.addTab("about:blank"); gBrowser.selectedTab = newTab; let browser = newTab.linkedBrowser; let frameLoader = browser.frameLoader; ok(frameLoader !== null, "frameLoader looks okay"); browser.messageManager.loadFrameScript("data:,(" + frameScript.toString() + ")()", false); browser.messageManager.addMessageListener("Test:Fail", (msg) => { ok(false, msg.data); }, true); let index = 0; browser.messageManager.addMessageListener("Test:Event", (msg) => { ok(msg.target === browser, " is correct"); ok(msg.targetFrameLoader === frameLoader, "frameLoader is correct"); ok(browser.frameLoader === null, "browser frameloader null during teardown"); info(JSON.stringify(msg.data)); is(JSON.stringify(msg.data), JSON.stringify(EXPECTED[index]), "results match"); index++; if (index == EXPECTED.length) { finish(); } }, true); browser.messageManager.addMessageListener("Test:Ready", () => { info("Got ready message"); gBrowser.removeCurrentTab(); }); }