tor-browser

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

commit 40ec99472948a07e16fbfde9ddae0b1a5016215d
parent 0891ca9a7afd063426b2177f44409305a3252e28
Author: Andreas Farre <farre@mozilla.com>
Date:   Mon, 24 Nov 2025 16:04:50 +0000

Bug 2001975 - More closely follow spec for waiting on commit handlers. r=dom-core,smaug

Introduce an internal method tracker, only used when not performing
Navigation API initiated navigations and no method tracker is created.
By doing this we can make sure that we won't run success steps until
the navigation has committed in a way that is consistent with how it is
performed for Navigation API methods.

This also aligns Navigation API methods to have the same timing also
non-Navigation API navigations, and removing the unspecced behavior of
forcing Navigation API to take an extra turn on the microtask queue.

Differential Revision: https://phabricator.services.mozilla.com/D273811

Diffstat:
Mdom/navigation/Navigation.cpp | 24+++++++++++++++++++++++-
Mmodules/libpref/init/StaticPrefList.yaml | 7+++++++
2 files changed, 30 insertions(+), 1 deletion(-)

diff --git a/dom/navigation/Navigation.cpp b/dom/navigation/Navigation.cpp @@ -1363,6 +1363,11 @@ struct NavigationWaitForAllScope final : public nsISupports, if (endResultIsSameDocument) { // 10.1 Let promisesList be an empty list. AutoTArray<RefPtr<Promise>, 16> promiseList; + + if (StaticPrefs::dom_navigation_api_internal_method_tracker()) { + promiseList.AppendElement(mAPIMethodTracker->CommittedPromise()); + } + // 10.2 For each handler of event's navigation handler list: for (auto& handler : mEvent->NavigationHandlerList().Clone()) { // 10.2.1 Append the result of invoking handler with an empty @@ -1408,7 +1413,8 @@ struct NavigationWaitForAllScope final : public nsISupports, scope->CommitNavigateEventSuccessSteps(); } }; - if (mAPIMethodTracker) { + if (mAPIMethodTracker && + !StaticPrefs::dom_navigation_api_internal_method_tracker()) { LOG_FMTD("Waiting for committed"); mAPIMethodTracker->CommittedPromise() ->AddCallbacksWithCycleCollectedArgs( @@ -1505,6 +1511,19 @@ NS_INTERFACE_MAP_END NS_IMPL_CYCLE_COLLECTING_ADDREF(NavigationWaitForAllScope) NS_IMPL_CYCLE_COLLECTING_RELEASE(NavigationWaitForAllScope) +already_AddRefed<NavigationAPIMethodTracker> CreateInternalTracker( + Navigation* aNavigation) { + RefPtr committedPromise = + Promise::CreateInfallible(aNavigation->GetOwnerGlobal()); + (void)committedPromise->SetAnyPromiseIsHandled(); + RefPtr finishedPromise = Promise::CreateResolvedWithUndefined( + aNavigation->GetOwnerGlobal(), IgnoreErrors()); + return MakeAndAddRef<NavigationAPIMethodTracker>( + aNavigation, Nothing(), JS::UndefinedHandleValue, + /* aSerializedState */ nullptr, + /* aCommittedToEntry */ nullptr, committedPromise, finishedPromise); +} + // https://html.spec.whatwg.org/#inner-navigate-event-firing-algorithm bool Navigation::InnerFireNavigateEvent( JSContext* aCx, NavigationType aNavigationType, @@ -1552,7 +1571,10 @@ bool Navigation::InnerFireNavigateEvent( // Step 4 if (apiMethodTracker) { apiMethodTracker->MarkAsNotPending(); + } else if (StaticPrefs::dom_navigation_api_internal_method_tracker()) { + apiMethodTracker = CreateInternalTracker(this); } + // This step is currently missing in the spec. See // https://github.com/whatwg/html/issues/11816 mOngoingAPIMethodTracker = apiMethodTracker; diff --git a/modules/libpref/init/StaticPrefList.yaml b/modules/libpref/init/StaticPrefList.yaml @@ -3697,6 +3697,13 @@ value: false mirror: always +# For non-Navigation API navigations, create an internal method tracker +# so that it's possible to await navigations being committed. +- name: dom.navigation.api.internal_method_tracker + type: bool + value: false + mirror: always + # Network Information API # This feature is not available on Firefox desktop. It exposes too much # user information. Let's be consistent and disable it on Android.