From fdd79b0fba9d131d4d2a21db2f54185b51fd148f Mon Sep 17 00:00:00 2001 From: Andreas Farre Date: Thu, 12 Sep 2024 06:02:24 +0000 Subject: [PATCH] Bug 1916559 - Only store pending uninvoked directives for same document navigation. r=peterv Differential Revision: https://phabricator.services.mozilla.com/D221637 --- docshell/base/nsDocShell.cpp | 29 ++++++++++++++++++++--------- docshell/base/nsDocShell.h | 12 ++---------- 2 files changed, 22 insertions(+), 19 deletions(-) diff --git a/docshell/base/nsDocShell.cpp b/docshell/base/nsDocShell.cpp index a85e779b3dac..3a5787b6b817 100644 --- a/docshell/base/nsDocShell.cpp +++ b/docshell/base/nsDocShell.cpp @@ -8431,6 +8431,17 @@ uint32_t nsDocShell::GetSameDocumentNavigationFlags(nsIURI* aNewURI) { return flags; } +struct SameDocumentNavigationState { + nsAutoCString mCurrentHash; + nsAutoCString mNewHash; + nsTArray mTextDirectives; + bool mCurrentURIHasRef = false; + bool mNewURIHasRef = false; + bool mSameExceptHashes = false; + bool mSecureUpgradeURI = false; + bool mHistoryNavBetweenSameDoc = false; +}; + bool nsDocShell::IsSameDocumentNavigation(nsDocShellLoadState* aLoadState, SameDocumentNavigationState& aState) { MOZ_ASSERT(aLoadState); @@ -8451,15 +8462,9 @@ bool nsDocShell::IsSameDocumentNavigation(nsDocShellLoadState* aLoadState, } // A Fragment Directive must be removed from the new hash in order to allow - // fallback element id scroll. Additionally, the extracted parsed text - // directives need to be stored for further use. - nsTArray textDirectives; - if (FragmentDirective::ParseAndRemoveFragmentDirectiveFromFragmentString( - aState.mNewHash, &textDirectives, aLoadState->URI())) { - if (Document* doc = GetDocument()) { - doc->FragmentDirective()->SetTextDirectives(std::move(textDirectives)); - } - } + // fallback element id scroll. + FragmentDirective::ParseAndRemoveFragmentDirectiveFromFragmentString( + aState.mNewHash, &aState.mTextDirectives, aLoadState->URI()); if (currentURI && NS_SUCCEEDED(rvURINew)) { nsresult rvURIOld = currentURI->GetRef(aState.mCurrentHash); @@ -8596,6 +8601,12 @@ nsresult nsDocShell::HandleSameDocumentNavigation( NS_ENSURE_TRUE(doc, NS_ERROR_FAILURE); doc->DoNotifyPossibleTitleChange(); + // Store the pending uninvoked directives if it is a same document navigation. + // We need to set it here, in case the navigation happens before the document + // has actually finished loading. + doc->FragmentDirective()->SetTextDirectives( + std::move(aState.mTextDirectives)); + nsCOMPtr currentURI = mCurrentURI; // We need to upgrade the new URI from http: to https: diff --git a/docshell/base/nsDocShell.h b/docshell/base/nsDocShell.h index efc85bf17dc6..0cf72f8fffb4 100644 --- a/docshell/base/nsDocShell.h +++ b/docshell/base/nsDocShell.h @@ -90,6 +90,8 @@ enum eCharsetReloadState { eCharsetReloadStopOrigional }; +struct SameDocumentNavigationState; + class nsDocShell final : public nsDocLoader, public nsIDocShell, public nsIWebNavigation, @@ -1032,16 +1034,6 @@ class nsDocShell final : public nsDocLoader, // embedder element, for both in-process and OOP embedders. void UnblockEmbedderLoadEventForFailure(bool aFireFrameErrorEvent = false); - struct SameDocumentNavigationState { - nsAutoCString mCurrentHash; - nsAutoCString mNewHash; - bool mCurrentURIHasRef = false; - bool mNewURIHasRef = false; - bool mSameExceptHashes = false; - bool mSecureUpgradeURI = false; - bool mHistoryNavBetweenSameDoc = false; - }; - // Check to see if we're loading a prior history entry or doing a fragment // navigation in the same document. // NOTE: In case we are doing a fragment navigation, and HTTPS-Only/ -First