Bug 1964955 - Make sure NavigateEvent.intercept can execute. r=smaug
Intercept was prevented by four things: 1) the return value of FirePushReplaceReloadNavigateEvent for pushState was used inverted. 2) the event was created untrusted 3) the wrong flag was being checked to see if the event was in the process of being dispatched. 4) wrong uri equality method was used. Differential Revision: https://phabricator.services.mozilla.com/D248222
This commit is contained in:
committed by
afarre@mozilla.com
parent
74378bf229
commit
6ab0d18691
@@ -11405,19 +11405,23 @@ nsDocShell::AddState(JS::Handle<JS::Value> aData, const nsAString& aTitle,
|
||||
// https://html.spec.whatwg.org/#shared-history-push/replace-state-steps
|
||||
// Step 8
|
||||
if (nsCOMPtr<nsPIDOMWindowInner> window = document->GetInnerWindow()) {
|
||||
if (RefPtr<Navigation> navigation = window->Navigation();
|
||||
navigation &&
|
||||
navigation->FirePushReplaceReloadNavigateEvent(
|
||||
aCx, aReplace ? NavigationType::Replace : NavigationType::Push,
|
||||
newURI,
|
||||
/* aIsSameDocument */ true, /* aUserInvolvement */ Nothing(),
|
||||
/* aSourceElement */ nullptr, /* aFormDataEntryList */ Nothing(),
|
||||
/* aNavigationAPIState */ nullptr, scContainer)) {
|
||||
return NS_OK;
|
||||
if (RefPtr<Navigation> navigation = window->Navigation()) {
|
||||
bool shouldContinue = navigation->FirePushReplaceReloadNavigateEvent(
|
||||
aCx, aReplace ? NavigationType::Replace : NavigationType::Push,
|
||||
newURI,
|
||||
/* aIsSameDocument */ true, /* aUserInvolvement */ Nothing(),
|
||||
/* aSourceElement */ nullptr, /* aFormDataEntryList */ Nothing(),
|
||||
/* aNavigationAPIState */ nullptr, scContainer);
|
||||
|
||||
// Step 9
|
||||
if (!shouldContinue) {
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Step 8: call "URL and history update steps"
|
||||
// Step 10
|
||||
// Run #url-and-history-update-steps
|
||||
rv = UpdateURLAndHistory(document, newURI, scContainer,
|
||||
aReplace ? NavigationHistoryBehavior::Replace
|
||||
: NavigationHistoryBehavior::Push,
|
||||
|
||||
@@ -127,6 +127,7 @@ static void MaybeReportWarningToConsole(Document* aDocument,
|
||||
"PreviousInterceptCallOptionOverriddenWarning", params);
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/#dom-navigateevent-intercept
|
||||
void NavigateEvent::Intercept(const NavigationInterceptOptions& aOptions,
|
||||
ErrorResult& aRv) {
|
||||
// Step 1
|
||||
@@ -141,7 +142,7 @@ void NavigateEvent::Intercept(const NavigationInterceptOptions& aOptions,
|
||||
}
|
||||
|
||||
// Step 3
|
||||
if (!HasBeenDispatched()) {
|
||||
if (!IsBeingDispatched()) {
|
||||
aRv.ThrowInvalidStateError("Event has never been dispatched");
|
||||
return;
|
||||
}
|
||||
@@ -252,8 +253,8 @@ AbortController* NavigateEvent::AbortController() const {
|
||||
return mAbortController;
|
||||
}
|
||||
|
||||
bool NavigateEvent::HasBeenDispatched() const {
|
||||
return mEvent->mFlags.mDispatchedAtLeastOnce;
|
||||
bool NavigateEvent::IsBeingDispatched() const {
|
||||
return mEvent->mFlags.mIsBeingDispatched;
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/#navigateevent-finish
|
||||
|
||||
@@ -99,7 +99,7 @@ class NavigateEvent final : public Event {
|
||||
|
||||
dom::AbortController* AbortController() const;
|
||||
|
||||
bool HasBeenDispatched() const;
|
||||
bool IsBeingDispatched() const;
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
void Finish(bool aDidFulfill);
|
||||
|
||||
@@ -604,7 +604,14 @@ static bool HasUAVisualTransition(Maybe<Document&>) { return false; }
|
||||
static bool EqualsExceptRef(nsIURI* aURI, nsIURI* aOtherURI) {
|
||||
bool equalsExceptRef = false;
|
||||
return aURI && aOtherURI &&
|
||||
NS_SUCCEEDED(aURI->EqualsExceptRef(aOtherURI, &equalsExceptRef));
|
||||
NS_SUCCEEDED(aURI->EqualsExceptRef(aOtherURI, &equalsExceptRef)) &&
|
||||
equalsExceptRef;
|
||||
}
|
||||
|
||||
static bool Equals(nsIURI* aURI, nsIURI* aOtherURI) {
|
||||
bool equals = false;
|
||||
return aURI && aOtherURI && NS_SUCCEEDED(aURI->Equals(aOtherURI, &equals)) &&
|
||||
equals;
|
||||
}
|
||||
|
||||
static bool HasIdenticalFragment(nsIURI* aURI, nsIURI* aOtherURI) {
|
||||
@@ -764,6 +771,9 @@ bool Navigation::InnerFireNavigateEvent(
|
||||
// delay it until here.
|
||||
RefPtr<NavigateEvent> event = NavigateEvent::Constructor(
|
||||
this, u"navigate"_ns, init, aClassicHistoryAPIState, abortController);
|
||||
// Here we're running #concept-event-create from https://dom.spec.whatwg.org/
|
||||
// which explicitly sets event's isTrusted attribute to true.
|
||||
event->SetTrusted(true);
|
||||
|
||||
// Step 26
|
||||
mOngoingNavigateEvent = event;
|
||||
@@ -829,7 +839,8 @@ bool Navigation::InnerFireNavigateEvent(
|
||||
docShell->UpdateURLAndHistory(
|
||||
document, aDestination->GetURI(), event->ClassicHistoryAPIState(),
|
||||
*NavigationUtils::NavigationHistoryBehavior(aNavigationType),
|
||||
document->GetDocumentURI(), aDestination->SameDocument());
|
||||
document->GetDocumentURI(),
|
||||
Equals(aDestination->GetURI(), document->GetDocumentURI()));
|
||||
}
|
||||
break;
|
||||
case NavigationType::Reload:
|
||||
@@ -1045,7 +1056,7 @@ void Navigation::AbortOngoingNavigation(JSContext* aCx,
|
||||
}
|
||||
|
||||
// Step 6
|
||||
if (event->HasBeenDispatched()) {
|
||||
if (event->IsBeingDispatched()) {
|
||||
event->PreventDefault();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
[intercept-history-pushState.html]
|
||||
prefs: [dom.navigation.webidl.enabled: true]
|
||||
expected:
|
||||
if (os == "android") and fission: [OK, TIMEOUT]
|
||||
[event.intercept() should proceed if the given promise resolves]
|
||||
expected: FAIL
|
||||
|
||||
Reference in New Issue
Block a user