commit e4338fcdcb24e288142eab0703bed60243d9ed1a
parent a10da7a0320d634a50e797a4b6b1330709d8fde6
Author: Hiroyuki Ikezoe <hikezoe.birchill@mozilla.com>
Date: Tue, 4 Nov 2025 20:19:04 +0000
Bug 1997214 - Explicitely `InActive` for the replacing browsing context in CanonicalBrowsingContext::ReplacedBy. r=dom-core,smaug
The change in CanonicalBrowsingContext.cpp was provided by Nika.
Differential Revision: https://phabricator.services.mozilla.com/D270799
Diffstat:
2 files changed, 71 insertions(+), 14 deletions(-)
diff --git a/docshell/base/CanonicalBrowsingContext.cpp b/docshell/base/CanonicalBrowsingContext.cpp
@@ -323,7 +323,10 @@ void CanonicalBrowsingContext::ReplacedBy(
}
aNewContext->mRestoreState = mRestoreState.forget();
- MOZ_ALWAYS_SUCCEEDS(SetHasRestoreData(false));
+ Transaction selfTxn;
+ selfTxn.SetHasRestoreData(false);
+ selfTxn.SetExplicitActive(ExplicitActiveStatus::Inactive);
+ MOZ_ALWAYS_SUCCEEDS(selfTxn.Commit(this));
// XXXBFCache name handling is still a bit broken in Fission in general,
// at least in case name should be cleared.
diff --git a/docshell/test/browser/browser_browsing_context_active_change.js b/docshell/test/browser/browser_browsing_context_active_change.js
@@ -3,31 +3,30 @@
// Test browsing-context-active-change notification which is fired on the parent process
// to know when a BrowsingContext becomes visible/hidden.
-const TEST_PATH =
- getRootDirectory(gTestPath).replace(
- "chrome://mochitests/content",
- // eslint-disable-next-line @microsoft/sdl/no-insecure-url
- "http://example.com"
- ) + "dummy_page.html";
-
-const TOPIC = "browsing-context-active-change";
-
-async function waitForActiveChange() {
+function observeTopic(aTopic) {
return new Promise(resolve => {
function observer(subject, topic) {
- is(topic, TOPIC, "observing correct topic");
+ is(topic, aTopic, "observing correct topic");
ok(
BrowsingContext.isInstance(subject),
"subject to be a BrowsingContext"
);
- Services.obs.removeObserver(observer, TOPIC);
+ Services.obs.removeObserver(observer, aTopic);
resolve();
}
- Services.obs.addObserver(observer, TOPIC);
+ Services.obs.addObserver(observer, aTopic);
});
}
+function waitForActiveChange() {
+ return observeTopic("browsing-context-active-change");
+}
+
+function waitForAttached() {
+ return observeTopic("browsing-context-attached");
+}
+
add_task(async function () {
const tab = await BrowserTestUtils.openNewForegroundTab(gBrowser);
const browser = tab.linkedBrowser;
@@ -52,3 +51,58 @@ add_task(async function () {
BrowserTestUtils.removeTab(tab);
});
+
+// Tests that BrowsingContext.isActive becomes false in BF cache.
+add_task(async function () {
+ const TEST_PATH1 =
+ getRootDirectory(gTestPath).replace(
+ "chrome://mochitests/content",
+ // eslint-disable-next-line @microsoft/sdl/no-insecure-url
+ "http://example.com"
+ ) + "dummy_page.html";
+ const TEST_PATH2 =
+ getRootDirectory(gTestPath).replace(
+ "chrome://mochitests/content",
+ // eslint-disable-next-line @microsoft/sdl/no-insecure-url
+ "http://example.com"
+ ) + "dummy_iframe_page.html";
+
+ let attached = waitForActiveChange();
+ const tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_PATH1);
+ await attached;
+
+ const firstBC = tab.linkedBrowser.browsingContext;
+ is(firstBC.isActive, true, "The first browsing context is now active");
+ is(firstBC.currentURI.spec, TEST_PATH1);
+
+ // Load a new page now.
+ attached = waitForActiveChange();
+ await loadURI(TEST_PATH2);
+ await attached;
+
+ const secondBC = tab.linkedBrowser.browsingContext;
+ isnot(firstBC, secondBC);
+
+ is(secondBC.isActive, true, "The second browsing context is now active");
+ is(secondBC.currentURI.spec, TEST_PATH2);
+ is(firstBC.isActive, false, "The first browsing context is no longer active");
+ is(firstBC.currentURI.spec, TEST_PATH1);
+
+ // Now try to back to the previous page, unlike above cases we don't wait
+ // "browsing-context-active-change" since it's not notified on this history back.
+ const stoppedLoadingPromise = BrowserTestUtils.browserStopped(
+ tab.linkedBrowser,
+ TEST_PATH1
+ );
+ gBrowser.goBack();
+ await stoppedLoadingPromise;
+
+ is(
+ secondBC.isActive,
+ false,
+ "The second browsing context is no longer active"
+ );
+ is(firstBC.isActive, true, "The first browsing context is active again");
+
+ BrowserTestUtils.removeTab(tab);
+});