Other browsers and iframes already keep non-initial about:blank documents in session history. This change extends that to top-level about:blank loads. In addition, nsDocShell::ShouldAddToSessionHistory is removed. When browser.newtabpage.enabled=false, newly opened tabs continue to have their initial about:newtab session history entry marked as transient. The logic is moved from nsDocShell to AboutNewTabParent. Differential Revision: https://phabricator.services.mozilla.com/D284624
131 lines
3.7 KiB
JavaScript
131 lines
3.7 KiB
JavaScript
"use strict";
|
|
|
|
const TOPIC = "browsing-context-discarded";
|
|
|
|
async function observeDiscarded(browsingContexts, callback) {
|
|
let discarded = new Map();
|
|
|
|
let promise = BrowserUtils.promiseObserved(TOPIC, (subject, why) => {
|
|
ok(BrowsingContext.isInstance(subject), "subject to be a BrowsingContext");
|
|
discarded.set(subject, why);
|
|
|
|
return browsingContexts.every(item => discarded.has(item));
|
|
});
|
|
await callback();
|
|
await promise;
|
|
|
|
return discarded;
|
|
}
|
|
|
|
function check_reason(discardedContexts, expected) {
|
|
discardedContexts.forEach((why, browsingContext) => {
|
|
if (expected.has(browsingContext)) {
|
|
is(why, expected.get(browsingContext));
|
|
}
|
|
});
|
|
}
|
|
|
|
add_task(async function toplevelForNewWindow() {
|
|
const win = await BrowserTestUtils.openNewBrowserWindow();
|
|
const browsingContext = win.gBrowser.selectedBrowser.browsingContext;
|
|
|
|
const expected = new Map([
|
|
[win.browsingContext, "discard"],
|
|
[browsingContext, "discard"],
|
|
]);
|
|
|
|
const discarded = await observeDiscarded([...expected.keys()], async () => {
|
|
await BrowserTestUtils.closeWindow(win);
|
|
});
|
|
|
|
check_reason(discarded, expected);
|
|
});
|
|
|
|
add_task(async function toplevelForNewTab() {
|
|
const tab = await BrowserTestUtils.openNewForegroundTab(gBrowser);
|
|
const browsingContext = tab.linkedBrowser.browsingContext;
|
|
|
|
const expected = new Map([[browsingContext, "discard"]]);
|
|
|
|
const discarded = await observeDiscarded([...expected.keys()], () => {
|
|
BrowserTestUtils.removeTab(tab);
|
|
});
|
|
|
|
ok(
|
|
!discarded.has(window.browsingContext),
|
|
"no notification for the current window's chrome browsing context"
|
|
);
|
|
|
|
check_reason(discarded, expected);
|
|
});
|
|
|
|
add_task(async function subframe() {
|
|
const tab = await BrowserTestUtils.openNewForegroundTab(gBrowser);
|
|
const frameBrowsingContext = await SpecialPowers.spawn(
|
|
tab.linkedBrowser,
|
|
[],
|
|
() => {
|
|
const iframe = content.document.createElement("iframe");
|
|
iframe.src = "https://example.com/";
|
|
content.document.body.appendChild(iframe);
|
|
return iframe.browsingContext;
|
|
}
|
|
);
|
|
|
|
const expected = new Map([[frameBrowsingContext, "discard"]]);
|
|
|
|
const discarded = await observeDiscarded([...expected.keys()], async () => {
|
|
await SpecialPowers.spawn(tab.linkedBrowser, [], () => {
|
|
let iframe = content.document.querySelector("iframe");
|
|
iframe.remove();
|
|
});
|
|
});
|
|
|
|
ok(
|
|
!discarded.has(tab.linkedBrowser.browsingContext),
|
|
"no notification for toplevel browsing context"
|
|
);
|
|
ok(
|
|
!discarded.has(window.browsingContext),
|
|
"no notification for the current window's chrome browsing context"
|
|
);
|
|
|
|
check_reason(discarded, expected);
|
|
|
|
BrowserTestUtils.removeTab(tab);
|
|
});
|
|
|
|
add_task(async function replaceToplevel() {
|
|
const tab = await BrowserTestUtils.openNewForegroundTab(gBrowser);
|
|
|
|
// Force load about:blank such that BC::HasLoadedNonInitialDocument is true
|
|
// which means it's BFCache eligible and will be replaced
|
|
BrowserTestUtils.startLoadingURIString(tab.linkedBrowser, "about:blank");
|
|
await BrowserTestUtils.browserLoaded(tab.linkedBrowser, {
|
|
wantLoad: "about:blank",
|
|
});
|
|
// Make it transient so that it doesn't stay in SH and the BC is discarded
|
|
tab.linkedBrowser.browsingContext.sessionHistory
|
|
.getEntryAtIndex(0)
|
|
.setTransient();
|
|
|
|
const browsingContext = tab.linkedBrowser.browsingContext;
|
|
|
|
const expected = new Map([[browsingContext, "replace"]]);
|
|
|
|
const discarded = await observeDiscarded([...expected.keys()], async () => {
|
|
await SpecialPowers.spawn(tab.linkedBrowser, [], () => {
|
|
content.location = "about:newtab";
|
|
});
|
|
});
|
|
|
|
ok(
|
|
!discarded.has(window.browsingContext),
|
|
"no notification for the current window's chrome browsing context"
|
|
);
|
|
|
|
check_reason(discarded, expected);
|
|
|
|
BrowserTestUtils.removeTab(tab);
|
|
});
|