commit a31b1bf340928b62ff2fb753f79396ea67231ffc
parent 569ef287466f189b92605efa761d6524a24037ff
Author: Narcis Beleuzu <nbeleuzu@mozilla.com>
Date: Sat, 15 Nov 2025 04:56:16 +0200
Revert "Bug 1948948 - Removed browser.tabs.documentchannel.parent-controlled. r=farre,tabbrowser-reviewers,sthompson" for bustages on CanonicalBrowsingContext.cpp
This reverts commit 5baca4aca49ea5d2a017725bbd12f8018c82d03d.
Diffstat:
5 files changed, 67 insertions(+), 6 deletions(-)
diff --git a/browser/components/tabbrowser/content/tabbrowser.js b/browser/components/tabbrowser/content/tabbrowser.js
@@ -8663,15 +8663,16 @@
// before the location changed.
this.mBrowser.userTypedValue = null;
- // When SHIP is enabled and a load gets cancelled due to another one
+ // When browser.tabs.documentchannel.parent-controlled pref and SHIP
+ // are enabled and a load gets cancelled due to another one
// starting, the error is NS_BINDING_CANCELLED_OLD_LOAD.
// When these prefs are not enabled, the error is different and
// that's why we still want to look at the isNavigating flag.
// We could add a workaround and make sure that in the alternative
// codepaths we would also omit the same error, but considering
// how we will be enabling fission by default soon, we can keep
- // using isNavigating for now, and remove it when SHIP is enabled
- // by default.
+ // using isNavigating for now, and remove it when the
+ // parent-controlled pref and SHIP are enabled by default.
// Bug 1725716 has been filed to consider removing isNavigating
// field alltogether.
let isNavigating = this.mBrowser.isNavigating;
diff --git a/docshell/base/CanonicalBrowsingContext.cpp b/docshell/base/CanonicalBrowsingContext.cpp
@@ -2713,13 +2713,42 @@ bool CanonicalBrowsingContext::SupportsLoadingInParent(
return true;
}
+bool CanonicalBrowsingContext::LoadInParent(nsDocShellLoadState* aLoadState,
+ bool aSetNavigating) {
+ // We currently only support starting loads directly from the
+ // CanonicalBrowsingContext for top-level BCs.
+ // We currently only support starting loads directly from the
+ // CanonicalBrowsingContext for top-level BCs.
+ if (!IsTopContent() || !GetContentParent() ||
+ !StaticPrefs::browser_tabs_documentchannel_parent_controlled()) {
+ return false;
+ }
+
+ uint64_t outerWindowId = 0;
+ if (!SupportsLoadingInParent(aLoadState, &outerWindowId)) {
+ return false;
+ }
+
+ MOZ_ASSERT(!aLoadState->URI()->SchemeIs("javascript"));
+
+ MOZ_ALWAYS_SUCCEEDS(
+ SetParentInitiatedNavigationEpoch(++gParentInitiatedNavigationEpoch));
+ // Note: If successful, this will recurse into StartDocumentLoad and
+ // set mCurrentLoad to the DocumentLoadListener instance created.
+ // Ideally in the future we will only start loads from here, and we can
+ // just set this directly instead.
+ return net::DocumentLoadListener::LoadInParent(this, aLoadState,
+ aSetNavigating);
+}
+
bool CanonicalBrowsingContext::AttemptSpeculativeLoadInParent(
nsDocShellLoadState* aLoadState) {
// We currently only support starting loads directly from the
// CanonicalBrowsingContext for top-level BCs.
// We currently only support starting loads directly from the
// CanonicalBrowsingContext for top-level BCs.
- if (!IsTopContent() || !GetContentParent()) {
+ if (!IsTopContent() || !GetContentParent() ||
+ (StaticPrefs::browser_tabs_documentchannel_parent_controlled())) {
return false;
}
@@ -2736,6 +2765,18 @@ bool CanonicalBrowsingContext::AttemptSpeculativeLoadInParent(
bool CanonicalBrowsingContext::StartDocumentLoad(
net::DocumentLoadListener* aLoad) {
+ // If we're controlling loads from the parent, then starting a new load means
+ // that we need to cancel any existing ones.
+ if (StaticPrefs::browser_tabs_documentchannel_parent_controlled() &&
+ mCurrentLoad) {
+ // Make sure we are not loading a javascript URI.
+ MOZ_ASSERT(!aLoad->IsLoadingJSURI());
+
+ // If we want to do a download, don't cancel the current navigation.
+ if (!aLoad->IsDownload()) {
+ mCurrentLoad->Cancel(NS_BINDING_CANCELLED_OLD_LOAD, ""_ns);
+ }
+ }
mCurrentLoad = aLoad;
if (NS_FAILED(SetCurrentLoadIdentifier(Some(aLoad->GetLoadIdentifier())))) {
diff --git a/docshell/test/browser/browser_backforward_userinteraction_systemprincipal.js b/docshell/test/browser/browser_backforward_userinteraction_systemprincipal.js
@@ -10,7 +10,18 @@ const TEST_PAGE =
) + "dummy_page.html";
async function runTest(privilegedLoad) {
- for (let requireUserInteraction of [true, false]) {
+ let prefVals;
+ // Test with both pref on and off, unless parent-controlled pref is enabled.
+ // This distinction can be removed once SHIP is enabled by default.
+ if (
+ Services.prefs.getBoolPref("browser.tabs.documentchannel.parent-controlled")
+ ) {
+ prefVals = [false];
+ } else {
+ prefVals = [true, false];
+ }
+
+ for (let requireUserInteraction of prefVals) {
Services.prefs.setBoolPref(
"browser.navigation.requireUserInteraction",
requireUserInteraction
diff --git a/modules/libpref/init/StaticPrefList.yaml b/modules/libpref/init/StaticPrefList.yaml
@@ -1939,6 +1939,13 @@
value: 2
mirror: always
+# If set, use DocumentChannel to directly initiate loads entirely
+# from parent-process BrowsingContexts
+- name: browser.tabs.documentchannel.parent-controlled
+ type: bool
+ value: false
+ mirror: always
+
# If set, middle clicking on a link opens the link in a new tab.
- name: browser.tabs.opentabfor.middleclick
type: bool
diff --git a/xpcom/base/ErrorList.py b/xpcom/base/ErrorList.py
@@ -963,7 +963,8 @@ with modules["URILOADER"]:
# doesn't need to be reparsed from the original source.
errors["NS_ERROR_PARSED_DATA_CACHED"] = FAILURE(33)
- # When SHIP is enabled and a load gets cancelled due to another one
+ # When browser.tabs.documentchannel.parent-controlled pref and SHIP
+ # are enabled and a load gets cancelled due to another one
# starting, the error is NS_BINDING_CANCELLED_OLD_LOAD.
errors["NS_BINDING_CANCELLED_OLD_LOAD"] = FAILURE(39)