tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit 15dba1db03c812191a3fcd04d0542e12b3c3b85f
parent 4552a2f867a8074cfdd2c69fdde2aab0e33f129a
Author: Cristina Horotan <chorotan@mozilla.com>
Date:   Fri, 21 Nov 2025 12:55:44 +0200

Revert "Bug 1948948 - Removed browser.tabs.documentchannel.parent-controlled. r=farre,tabbrowser-reviewers,sthompson" for causing build bustages on CanonicalBrowsingContext.cpp

This reverts commit 66d18cee690a1df212878254c24f1730fee6af63.

Diffstat:
Mbrowser/components/tabbrowser/content/tabbrowser.js | 7++++---
Mdocshell/base/BrowsingContext.cpp | 4++++
Mdocshell/base/CanonicalBrowsingContext.cpp | 43++++++++++++++++++++++++++++++++++++++++++-
Mdocshell/base/CanonicalBrowsingContext.h | 6++++++
Mdocshell/test/browser/browser_backforward_userinteraction_systemprincipal.js | 13++++++++++++-
Mmodules/libpref/init/StaticPrefList.yaml | 7+++++++
Mxpcom/base/ErrorList.py | 3++-
7 files changed, 77 insertions(+), 6 deletions(-)

diff --git a/browser/components/tabbrowser/content/tabbrowser.js b/browser/components/tabbrowser/content/tabbrowser.js @@ -8718,15 +8718,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/BrowsingContext.cpp b/docshell/base/BrowsingContext.cpp @@ -2182,6 +2182,10 @@ nsresult BrowsingContext::LoadURI(nsDocShellLoadState* aLoadState, wgc->SendLoadURI(this, mozilla::WrapNotNull(aLoadState), aSetNavigating); } } else if (XRE_IsParentProcess()) { + if (Canonical()->LoadInParent(aLoadState, aSetNavigating)) { + return NS_OK; + } + if (ContentParent* cp = Canonical()->GetContentParent()) { // Attempt to initiate this load immediately in the parent, if it succeeds // it'll return a unique identifier so that we can find it later. 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/base/CanonicalBrowsingContext.h b/docshell/base/CanonicalBrowsingContext.h @@ -286,6 +286,12 @@ class CanonicalBrowsingContext final : public BrowsingContext { bool HasCreatedMediaController() const; // Attempts to start loading the given load state in this BrowsingContext, + // without requiring any communication from a docshell. This will handle + // computing the right process to load in, and organising handoff to + // the right docshell when we get a response. + bool LoadInParent(nsDocShellLoadState* aLoadState, bool aSetNavigating); + + // Attempts to start loading the given load state in this BrowsingContext, // in parallel with a DocumentChannelChild being created in the docshell. // Requires the DocumentChannel to connect with this load for it to // complete successfully. 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 @@ -1952,6 +1952,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)