commit 8c29484ca9cd1072ce8b4bca539ea4c75d9f3b09
parent 8b732c4b790bfb729475ddba1dc36a4fd235a5ba
Author: Jan-Niklas Jaeschke <jjaschke@mozilla.com>
Date: Tue, 28 Oct 2025 17:18:26 +0000
Bug 1970123, part 9 - Navigation API: Only run `AbortController()->Abort()` in certain conditions. r=dom-core,smaug
The spec runs currently this step unconditionally (step 2 in #abort-a-navigateevent).
However, according to tests and Chromium's implementation,
this step must only be run if
- #abort-a-navigateevent is not called from #process-navigate-event-handler-failure
- or the event's interception state is `Intercepted`.
Spec issue: https://github.com/whatwg/html/issues/11831
Differential Revision: https://phabricator.services.mozilla.com/D270186
Diffstat:
2 files changed, 16 insertions(+), 6 deletions(-)
diff --git a/dom/navigation/Navigation.cpp b/dom/navigation/Navigation.cpp
@@ -1225,7 +1225,9 @@ struct NavigationWaitForAllScope final : public nsISupports,
// 5. Abort event given reason.
if (AutoJSAPI jsapi; !NS_WARN_IF(!jsapi.Init(mEvent->GetParentObject()))) {
RefPtr navigation = mNavigation;
- navigation->AbortNavigateEvent(jsapi.cx(), event, aRejectionReason);
+ navigation->AbortNavigateEvent(
+ jsapi.cx(), event, aRejectionReason,
+ /*aIsCalledFromNavigateFiringFailureSteps=*/true);
}
}
// https://html.spec.whatwg.org/#commit-a-navigate-event
@@ -1807,17 +1809,24 @@ void Navigation::AbortOngoingNavigation(JSContext* aCx,
}
// Step 7
- AbortNavigateEvent(aCx, event, error);
+ AbortNavigateEvent(aCx, event, error,
+ /*aIsCalledFromNavigateFiringFailureSteps=*/false);
}
// https://html.spec.whatwg.org/#abort-a-navigateevent
-void Navigation::AbortNavigateEvent(JSContext* aCx, NavigateEvent* aEvent,
- JS::Handle<JS::Value> aReason) {
+void Navigation::AbortNavigateEvent(
+ JSContext* aCx, NavigateEvent* aEvent, JS::Handle<JS::Value> aReason,
+ bool aIsCalledFromNavigateFiringFailureSteps) {
// 1. Let navigation be event's relevant global object's navigation API.
// Omitted since this is called from a Navigation object.
// 2. Signal abort on event's abort controller given reason.
- aEvent->AbortController()->Abort(aCx, aReason);
+ if (!aIsCalledFromNavigateFiringFailureSteps ||
+ aEvent->InterceptionState() ==
+ NavigateEvent::InterceptionState::Intercepted) {
+ // https://github.com/whatwg/html/issues/11831
+ aEvent->AbortController()->Abort(aCx, aReason);
+ }
// 3. Let errorInfo be the result of extracting error information from reason.
RootedDictionary<ErrorEventInit> init(aCx);
diff --git a/dom/navigation/Navigation.h b/dom/navigation/Navigation.h
@@ -186,7 +186,8 @@ class Navigation final : public DOMEventTargetHelper {
MOZ_CAN_RUN_SCRIPT
void AbortNavigateEvent(JSContext* aCx, NavigateEvent* aEvent,
- JS::Handle<JS::Value> aReason);
+ JS::Handle<JS::Value> aReason,
+ bool aIsCalledFromNavigateFiringFailureSteps);
MOZ_CAN_RUN_SCRIPT
void InformAboutChildNavigableDestruction(JSContext* aCx);