commit 39869215be1cbecb1964724f675fae08942f555a
parent 1eced8664b90328443b6232de76c861511f53c64
Author: Adam Vandolder <avandolder@mozilla.com>
Date: Thu, 11 Dec 2025 19:23:20 +0000
Bug 1998761 - Copy the Navigation API Key from the old to the new entry for same-origin cross-document replace navigations. r=farre,dom-core
Differential Revision: https://phabricator.services.mozilla.com/D275908
Diffstat:
4 files changed, 43 insertions(+), 6 deletions(-)
diff --git a/docshell/base/CanonicalBrowsingContext.cpp b/docshell/base/CanonicalBrowsingContext.cpp
@@ -634,6 +634,25 @@ CanonicalBrowsingContext::CreateLoadingSessionHistoryEntryForLoad(
}
MOZ_DIAGNOSTIC_ASSERT(entry);
+ // https://html.spec.whatwg.org/#finalize-a-cross-document-navigation
+ // 9. If entryToReplace is null, then: ...
+ // Otherwise: ...
+ // 4. If historyEntry's document state's origin is same origin with
+ // entryToReplace's document state's origin, then set
+ // historyEntry's navigation API key to entryToReplace's
+ // navigation API key.
+ if (mActiveEntry &&
+ aLoadState->GetNavigationType() == NavigationType::Replace) {
+ nsCOMPtr<nsIURI> uri = mActiveEntry->GetURIOrInheritedForAboutBlank();
+ nsCOMPtr<nsIURI> targetURI = entry->GetURIOrInheritedForAboutBlank();
+ bool sameOrigin =
+ NS_SUCCEEDED(nsContentUtils::GetSecurityManager()->CheckSameOriginURI(
+ targetURI, uri, false, false));
+ if (sameOrigin) {
+ entry->SetNavigationKey(mActiveEntry->Info().NavigationKey());
+ }
+ }
+
UniquePtr<LoadingSessionHistoryInfo> loadingInfo;
if (existingLoadingInfo) {
loadingInfo = MakeUnique<LoadingSessionHistoryInfo>(*existingLoadingInfo);
diff --git a/docshell/base/nsDocShell.cpp b/docshell/base/nsDocShell.cpp
@@ -7896,6 +7896,30 @@ nsresult nsDocShell::CreateDocumentViewer(const nsACString& aContentType,
nsCOMPtr<nsIChannel> failedChannel = mFailedChannel;
nsCOMPtr<nsIURI> failedURI;
+ // https://html.spec.whatwg.org/#finalize-a-cross-document-navigation
+ // 9. If entryToReplace is null, then: ...
+ // Otherwise: ...
+ // 4. If historyEntry's document state's origin is same origin with
+ // entryToReplace's document state's origin, then set
+ // historyEntry's navigation API key to entryToReplace's
+ // navigation API key.
+ bool isReplace =
+ mActiveEntry && mLoadingEntry && IsValidLoadType(mLoadType) &&
+ NavigationUtils::NavigationTypeFromLoadType(mLoadType)
+ .map([](auto type) { return type == NavigationType::Replace; })
+ .valueOr(false);
+ if (isReplace) {
+ nsCOMPtr<nsIURI> uri = mActiveEntry->GetURIOrInheritedForAboutBlank();
+ nsCOMPtr<nsIURI> targetURI =
+ mLoadingEntry->mInfo.GetURIOrInheritedForAboutBlank();
+ bool sameOrigin =
+ NS_SUCCEEDED(nsContentUtils::GetSecurityManager()->CheckSameOriginURI(
+ targetURI, uri, false, false));
+ if (sameOrigin) {
+ mLoadingEntry->mInfo.NavigationKey() = mActiveEntry->NavigationKey();
+ }
+ }
+
if (mLoadType == LOAD_ERROR_PAGE) {
// We need to set the SH entry and our current URI here and not
// at the moment we load the page. We want the same behavior
diff --git a/testing/web-platform/meta/navigation-api/navigation-history-entry/key-id-location-replace.html.ini b/testing/web-platform/meta/navigation-api/navigation-history-entry/key-id-location-replace.html.ini
@@ -1,3 +0,0 @@
-[key-id-location-replace.html]
- [NavigationHistoryEntry's key and id after location.replace()]
- expected: FAIL
diff --git a/testing/web-platform/meta/navigation-api/navigation-methods/navigate-replace-cross-document.html.ini b/testing/web-platform/meta/navigation-api/navigation-methods/navigate-replace-cross-document.html.ini
@@ -1,3 +0,0 @@
-[navigate-replace-cross-document.html]
- [navigate() with history: 'replace' option]
- expected: FAIL