Bug 1544428 - Do not dispatch popstate or hashchange when hasRef changes. r=jjaschke,dom-core,sessionstore-reviewers,dao,farre

This behavior was already agreed upon in
<https://github.com/whatwg/html/issues/7386>, but bug 1544428 was an
implementation edge case needing to be fixed.

An exception is when the fragment contains a directive, in which case a
difference in `hasRef` is sufficient, to retain existing behavior WRT
directives.

Although bug 1544428 is about popstate, hashchange was erroneously being
dispatched, as well, which this patch fixes.

Some tests that depended on the old behavior are updated.

Differential Revision: https://phabricator.services.mozilla.com/D225567
This commit is contained in:
Zach Hoffman
2024-10-23 14:59:04 +00:00
parent f53e8d314d
commit 14134ce9b2
6 changed files with 44 additions and 6 deletions

View File

@@ -8981,6 +8981,11 @@ nsresult nsDocShell::HandleSameDocumentNavigation(
nsCOMPtr<nsPIDOMWindowInner> win =
scriptGlobal ? scriptGlobal->GetCurrentInnerWindow() : nullptr;
// The check for uninvoked directives must come before ScrollToAnchor() is
// called.
const bool hasTextDirectives =
doc->FragmentDirective()->HasUninvokedDirectives();
// ScrollToAnchor doesn't necessarily cause us to scroll the window;
// the function decides whether a scroll is appropriate based on the
// arguments it receives. But even if we don't end up scrolling,
@@ -9015,9 +9020,11 @@ nsresult nsDocShell::HandleSameDocumentNavigation(
// reference to avoid null derefs. See bug 914521.
if (win) {
// Fire a hashchange event URIs differ, and only in their hashes.
// If the fragment contains a directive, compare hasRef.
bool doHashchange = aState.mSameExceptHashes &&
(aState.mCurrentURIHasRef != aState.mNewURIHasRef ||
!aState.mCurrentHash.Equals(aState.mNewHash));
(!aState.mCurrentHash.Equals(aState.mNewHash) ||
(hasTextDirectives &&
aState.mCurrentURIHasRef != aState.mNewURIHasRef));
if (aState.mHistoryNavBetweenSameDoc || doHashchange) {
win->DispatchSyncPopState();