зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1703607 - Exempt about:*pages from new bfcache, with the exception of about:blank, r=peterv
This also fixes test browser/base/content/test/tabs/browser_navigate_through_urls_origin_attributes.js which was failing for fission + bfcacheInParent, because about:privatebrowsing was getting bfcached, and an extra XULFrameLoaderCreated event was firing, when we were not expecting it. Differential Revision: https://phabricator.services.mozilla.com/D112441
This commit is contained in:
Родитель
1a72ada683
Коммит
c5100b9329
|
@ -6,6 +6,7 @@ support-files =
|
|||
file_mediaPlayback.html
|
||||
test_process_flags_chrome.html
|
||||
helper_origin_attrs_testing.js
|
||||
file_about_srcdoc.html
|
||||
|
||||
[browser_accessibility_indicator.js]
|
||||
skip-if = (verify && debug && (os == 'linux')) || (os == 'win' && processor == 'aarch64')
|
||||
|
@ -128,3 +129,5 @@ support-files = file_rel_opener_noopener.html
|
|||
skip-if = (verify && os == 'mac' && webrender)
|
||||
[browser_removeTabsToTheStart.js]
|
||||
[browser_removeTabsToTheEnd.js]
|
||||
[browser_bfcache_exemption_about_pages.js]
|
||||
skip-if = !fission
|
||||
|
|
|
@ -0,0 +1,176 @@
|
|||
requestLongerTimeout(2);
|
||||
|
||||
const BASE = getRootDirectory(gTestPath).replace(
|
||||
"chrome://mochitests/content",
|
||||
"http://example.com"
|
||||
);
|
||||
|
||||
async function navigateTo(browser, urls, expectedPersist) {
|
||||
// Navigate to a bunch of urls
|
||||
for (let url of urls) {
|
||||
let loaded = BrowserTestUtils.browserLoaded(browser, false, url);
|
||||
BrowserTestUtils.loadURI(browser, url);
|
||||
await loaded;
|
||||
}
|
||||
// When we track pageshow event, save the evt.persisted on a doc element,
|
||||
// so it can be checked from the test directly.
|
||||
let pageShowCheck = evt => {
|
||||
evt.target.ownerGlobal.document.documentElement.setAttribute(
|
||||
"persisted",
|
||||
evt.persisted
|
||||
);
|
||||
return true;
|
||||
};
|
||||
is(
|
||||
browser.canGoBack,
|
||||
true,
|
||||
`After navigating to urls=${urls}, we can go back from uri=${browser.currentURI.spec}`
|
||||
);
|
||||
if (expectedPersist) {
|
||||
// If we expect the page to persist, then the uri we are testing is about:blank.
|
||||
// Currently we are only testing cases when we go forward to about:blank page,
|
||||
// because it gets removed from history if it is sandwiched between two
|
||||
// regular history entries. This means we can't test a scenario such as:
|
||||
// page X, about:blank, page Y, go back -- about:blank page will be removed, and
|
||||
// going back from page Y will take us to page X.
|
||||
|
||||
// Go back from about:blank (it will be the last uri in 'urls')
|
||||
let pageShowPromise = BrowserTestUtils.waitForContentEvent(
|
||||
browser,
|
||||
"pageshow"
|
||||
);
|
||||
info(`Navigating back from uri=${browser.currentURI.spec}`);
|
||||
browser.goBack();
|
||||
await pageShowPromise;
|
||||
info(`Got pageshow event`);
|
||||
// Now go forward
|
||||
let forwardPageShow = BrowserTestUtils.waitForContentEvent(
|
||||
browser,
|
||||
"pageshow",
|
||||
false,
|
||||
pageShowCheck
|
||||
);
|
||||
info(`Navigating forward from uri=${browser.currentURI.spec}`);
|
||||
browser.goForward();
|
||||
await forwardPageShow;
|
||||
// Check that the page got persisted
|
||||
let persisted = await SpecialPowers.spawn(browser, [], async function() {
|
||||
return content.document.documentElement.getAttribute("persisted");
|
||||
});
|
||||
is(
|
||||
persisted,
|
||||
expectedPersist.toString(),
|
||||
`uri ${browser.currentURI.spec} should have persisted`
|
||||
);
|
||||
} else {
|
||||
// Go back
|
||||
let pageShowPromise = BrowserTestUtils.waitForContentEvent(
|
||||
browser,
|
||||
"pageshow",
|
||||
false,
|
||||
pageShowCheck
|
||||
);
|
||||
info(`Navigating back from uri=${browser.currentURI.spec}`);
|
||||
browser.goBack();
|
||||
await pageShowPromise;
|
||||
info(`Got pageshow event`);
|
||||
// Check that the page did not get persisted
|
||||
let persisted = await SpecialPowers.spawn(browser, [], async function() {
|
||||
return content.document.documentElement.getAttribute("persisted");
|
||||
});
|
||||
is(
|
||||
persisted,
|
||||
expectedPersist.toString(),
|
||||
`uri ${browser.currentURI.spec} shouldn't have persisted`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
add_task(async function testAboutPagesExemptFromBfcache() {
|
||||
// If Fission is disabled, the pref is no-op.
|
||||
await SpecialPowers.pushPrefEnv({ set: [["fission.bfcacheInParent", true]] });
|
||||
|
||||
// Navigate to a bunch of urls, then go back once, check that the penultimate page did not go into BFbache
|
||||
var browser;
|
||||
// First page is about:privatebrowsing
|
||||
const private_test_cases = [
|
||||
["about:blank"],
|
||||
["about:blank", "about:privatebrowsing", "about:blank"],
|
||||
];
|
||||
for (const urls of private_test_cases) {
|
||||
info(`Private tab - navigate to ${urls} urls`);
|
||||
let win = await BrowserTestUtils.openNewBrowserWindow({
|
||||
private: true,
|
||||
waitForTabURL: "about:privatebrowsing",
|
||||
});
|
||||
browser = win.gBrowser.selectedTab.linkedBrowser;
|
||||
await navigateTo(browser, urls, false);
|
||||
await BrowserTestUtils.closeWindow(win);
|
||||
}
|
||||
|
||||
// First page is about:blank
|
||||
const regular_test_cases = [
|
||||
["about:home"],
|
||||
["about:home", "about:blank"],
|
||||
["about:blank", "about:newtab"],
|
||||
];
|
||||
for (const urls of regular_test_cases) {
|
||||
info(`Regular tab - navigate to ${urls} urls`);
|
||||
let win = await BrowserTestUtils.openNewBrowserWindow();
|
||||
let tab = await BrowserTestUtils.openNewForegroundTab({
|
||||
gBrowser: win.gBrowser,
|
||||
opening: "about:newtab",
|
||||
});
|
||||
browser = tab.linkedBrowser;
|
||||
await navigateTo(browser, urls, false);
|
||||
BrowserTestUtils.removeTab(tab);
|
||||
await BrowserTestUtils.closeWindow(win);
|
||||
}
|
||||
});
|
||||
|
||||
// Test that about:blank or pages that have about:* subframes get bfcached.
|
||||
// TODO bug 1705789: add about:reader tests when we make them bfcache compatible.
|
||||
add_task(async function testAboutPagesBfcacheAllowed() {
|
||||
// If Fission is disabled, the pref is no-op.
|
||||
await SpecialPowers.pushPrefEnv({ set: [["fission.bfcacheInParent", true]] });
|
||||
|
||||
var browser;
|
||||
// First page is about:privatebrowsing
|
||||
// about:privatebrowsing -> about:blank, go back, go forward, - about:blank is bfcached
|
||||
// about:privatebrowsing -> about:home -> about:blank, go back, go forward, - about:blank is bfcached
|
||||
// about:privatebrowsing -> file_about_srcdoc.html, go back, go forward - file_about_srcdoc.html is bfcached
|
||||
const private_test_cases = [
|
||||
["about:blank"],
|
||||
["about:home", "about:blank"],
|
||||
[BASE + "file_about_srcdoc.html"],
|
||||
];
|
||||
for (const urls of private_test_cases) {
|
||||
info(`Private tab - navigate to ${urls} urls`);
|
||||
let win = await BrowserTestUtils.openNewBrowserWindow({
|
||||
private: true,
|
||||
waitForTabURL: "about:privatebrowsing",
|
||||
});
|
||||
browser = win.gBrowser.selectedTab.linkedBrowser;
|
||||
await navigateTo(browser, urls, true);
|
||||
await BrowserTestUtils.closeWindow(win);
|
||||
}
|
||||
|
||||
// First page is about:blank
|
||||
// about:blank -> about:home -> about:blank, go back, go forward, - about:blank is bfcached
|
||||
// about:blank -> about:home -> file_about_srcdoc.html, go back, go forward - file_about_srcdoc.html is bfcached
|
||||
const regular_test_cases = [
|
||||
["about:home", "about:blank"],
|
||||
["about:home", BASE + "file_about_srcdoc.html"],
|
||||
];
|
||||
for (const urls of regular_test_cases) {
|
||||
info(`Regular tab - navigate to ${urls} urls`);
|
||||
let win = await BrowserTestUtils.openNewBrowserWindow();
|
||||
let tab = await BrowserTestUtils.openNewForegroundTab({
|
||||
gBrowser: win.gBrowser,
|
||||
});
|
||||
browser = tab.linkedBrowser;
|
||||
await navigateTo(browser, urls, true);
|
||||
BrowserTestUtils.removeTab(tab);
|
||||
await BrowserTestUtils.closeWindow(win);
|
||||
}
|
||||
});
|
|
@ -79,7 +79,7 @@ function setupRemoteTypes() {
|
|||
async function testNavigate() {
|
||||
setupRemoteTypes();
|
||||
/**
|
||||
* Open a regular tab, 3 container tabs and a private window, load about:blank
|
||||
* Open a regular tab, 3 container tabs and a private window, load about:blank or about:privatebrowsing
|
||||
* For each test case
|
||||
* load the uri
|
||||
* verify correct remote type
|
||||
|
@ -104,7 +104,7 @@ async function testNavigate() {
|
|||
containerPages.push(containerPage);
|
||||
}
|
||||
|
||||
let privatePage = await openURIInPrivateTab("about:blank");
|
||||
let privatePage = await openURIInPrivateTab();
|
||||
gPrevRemoteTypePrivateTab = privatePage.tab.linkedBrowser.remoteType;
|
||||
|
||||
for (const testCase of TEST_CASES) {
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
</head>
|
||||
<body>
|
||||
<iframe srcdoc="hello world!"></iframe>
|
||||
</body>
|
||||
</html>
|
|
@ -78,28 +78,51 @@ async function openURIInContainer(uri, win, userContextId) {
|
|||
}
|
||||
|
||||
async function openURIInPrivateTab(uri) {
|
||||
info(`Opening url ${uri} in a private browsing tab`);
|
||||
info(
|
||||
`Opening url ${
|
||||
uri ? uri : "about:privatebrowsing"
|
||||
} in a private browsing tab`
|
||||
);
|
||||
let win = await BrowserTestUtils.openNewBrowserWindow({
|
||||
private: true,
|
||||
waitForTabURL: "about:privatebrowsing",
|
||||
});
|
||||
if (!uri) {
|
||||
return { tab: win.gBrowser.selectedTab, uri: "about:privatebrowsing" };
|
||||
}
|
||||
initXulFrameLoaderListenerInfo();
|
||||
win.gBrowser.addEventListener("XULFrameLoaderCreated", handleEvent);
|
||||
|
||||
const browser = win.gBrowser.selectedTab.linkedBrowser;
|
||||
let prevRemoteType = browser.remoteType;
|
||||
let loaded = BrowserTestUtils.browserLoaded(browser, false, uri);
|
||||
BrowserTestUtils.loadURI(browser, uri);
|
||||
await BrowserTestUtils.browserLoaded(browser, false, uri);
|
||||
await loaded;
|
||||
let currRemoteType = browser.remoteType;
|
||||
|
||||
info(
|
||||
`XULFrameLoaderCreated was fired ${xulFrameLoaderCreatedListenerInfo.numCalledSoFar} time(s) for ${uri} in private tab`
|
||||
);
|
||||
|
||||
is(
|
||||
xulFrameLoaderCreatedListenerInfo.numCalledSoFar,
|
||||
currRemoteType == prevRemoteType ? 0 : 1,
|
||||
"XULFrameLoaderCreated fired correct number of times"
|
||||
);
|
||||
if (
|
||||
SpecialPowers.Services.prefs.getBoolPref("fission.bfcacheInParent") &&
|
||||
currRemoteType == prevRemoteType &&
|
||||
uri == "about:blank"
|
||||
) {
|
||||
// about:blank page gets flagged for being eligible to go into bfcache
|
||||
// and thus we create a new XULFrameLoader for these pages
|
||||
is(
|
||||
xulFrameLoaderCreatedListenerInfo.numCalledSoFar,
|
||||
1,
|
||||
"XULFrameLoaderCreated fired correct number of times"
|
||||
);
|
||||
} else {
|
||||
is(
|
||||
xulFrameLoaderCreatedListenerInfo.numCalledSoFar,
|
||||
currRemoteType == prevRemoteType ? 0 : 1,
|
||||
"XULFrameLoaderCreated fired correct number of times"
|
||||
);
|
||||
}
|
||||
|
||||
win.gBrowser.removeEventListener("XULFrameLoaderCreated", handleEvent);
|
||||
return { tab: win.gBrowser.selectedTab, uri };
|
||||
|
|
|
@ -2123,6 +2123,18 @@ bool CanonicalBrowsingContext::AllowedInBFCache(
|
|||
(" * auxiliary BrowsingContexts"));
|
||||
}
|
||||
|
||||
// There are not a lot of about:* pages that are allowed to load in
|
||||
// subframes, so it's OK to allow those few about:* pages enter BFCache.
|
||||
MOZ_ASSERT(IsTop(), "Trying to put a non top level BC into BFCache");
|
||||
|
||||
nsCOMPtr<nsIURI> currentURI = GetCurrentURI();
|
||||
// Exempt about:* pages from bfcache, with the exception of about:blank
|
||||
if (currentURI && currentURI->SchemeIs("about") &&
|
||||
!currentURI->GetSpecOrDefault().EqualsLiteral("about:blank")) {
|
||||
bfcacheCombo |= BFCacheStatus::ABOUT_PAGE;
|
||||
MOZ_LOG(gSHIPBFCacheLog, LogLevel::Debug, (" * about:* page"));
|
||||
}
|
||||
|
||||
// For telemetry we're collecting all the flags for all the BCs hanging
|
||||
// from this top-level BC.
|
||||
PreOrderWalk([&](BrowsingContext* aBrowsingContext) {
|
||||
|
|
|
@ -302,7 +302,8 @@ enum BFCacheStatus {
|
|||
HAS_ACTIVE_SPEECH_SYNTHESIS = 1 << 9, // Status 9
|
||||
HAS_USED_VR = 1 << 10, // Status 10
|
||||
CONTAINS_REMOTE_SUBFRAMES = 1 << 11, // Status 11
|
||||
NOT_ONLY_TOPLEVEL_IN_BCG = 1 << 12 // Status 12
|
||||
NOT_ONLY_TOPLEVEL_IN_BCG = 1 << 12, // Status 12
|
||||
ABOUT_PAGE = 1 << 13, // Status 13
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
|
Загрузка…
Ссылка в новой задаче