commit de898334fb149c80173e50d37615c532d84decf6
parent 35b02b2cfa2c7d07e687316d2291507a02a349b4
Author: Adam Vandolder <avandolder@mozilla.com>
Date: Fri, 31 Oct 2025 09:17:10 +0000
Bug 1996573 - Part 3: Reconstruct the active entry list when restoring to a different entry than the active one. r=dom-core,core-sessionstore-reviewers,farre
Differential Revision: https://phabricator.services.mozilla.com/D270288
Diffstat:
5 files changed, 37 insertions(+), 0 deletions(-)
diff --git a/docshell/base/CanonicalBrowsingContext.cpp b/docshell/base/CanonicalBrowsingContext.cpp
@@ -3704,6 +3704,19 @@ bool CanonicalBrowsingContext::ShouldEnforceParentalControls() {
return false;
}
+void CanonicalBrowsingContext::MaybeReconstructActiveEntryList() {
+ MOZ_ASSERT(IsTop());
+ if (!Navigation::IsAPIEnabled()) {
+ return;
+ }
+
+ auto* shistory = static_cast<nsSHistory*>(GetSessionHistory());
+ if (mActiveEntry && !shistory->ContainsEntry(mActiveEntry)) {
+ mActiveEntryList.clear();
+ mActiveEntryList = shistory->ConstructContiguousEntryList();
+ }
+}
+
NS_IMPL_CYCLE_COLLECTION_CLASS(CanonicalBrowsingContext)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(CanonicalBrowsingContext,
diff --git a/docshell/base/CanonicalBrowsingContext.h b/docshell/base/CanonicalBrowsingContext.h
@@ -455,6 +455,8 @@ class CanonicalBrowsingContext final : public BrowsingContext {
static bool ShouldEnforceParentalControls();
+ void MaybeReconstructActiveEntryList();
+
protected:
// Called when the browsing context is being discarded.
void CanonicalDiscard();
diff --git a/docshell/shistory/nsSHistory.cpp b/docshell/shistory/nsSHistory.cpp
@@ -2515,6 +2515,13 @@ LinkedList<SessionHistoryEntry> nsSHistory::ConstructContiguousEntryListFrom(
return entryList;
}
+LinkedList<SessionHistoryEntry> nsSHistory::ConstructContiguousEntryList() {
+ MOZ_ASSERT(mIndex >= 0 && mIndex < Length());
+ nsCOMPtr currentEntry = mEntries[mIndex];
+ return ConstructContiguousEntryListFrom(
+ static_cast<SessionHistoryEntry*>(currentEntry.get()));
+}
+
bool nsSHistory::ForEachDifferingEntry(
nsISHEntry* aPrevEntry, nsISHEntry* aNextEntry, BrowsingContext* aParent,
const std::function<void(nsISHEntry*, BrowsingContext*)>& aCallback) {
@@ -2721,3 +2728,12 @@ void nsSHistory::UpdateEntryLength(nsISHEntry* aOldEntry, nsISHEntry* aNewEntry,
::UpdateEntryLength(docshellIDToEntry, newSHE, aMove);
}
+
+bool nsSHistory::ContainsEntry(nsISHEntry* aEntry) {
+ if (!aEntry) {
+ return false;
+ }
+
+ nsCOMPtr rootEntry = GetRootSHEntry(aEntry);
+ return GetIndexOfEntry(rootEntry) != -1;
+}
diff --git a/docshell/shistory/nsSHistory.h b/docshell/shistory/nsSHistory.h
@@ -221,6 +221,10 @@ class nsSHistory : public mozilla::LinkedListElement<nsSHistory>,
mozilla::dom::SessionHistoryEntry* aEntry, int32_t aSearchDirection);
mozilla::LinkedList<mozilla::dom::SessionHistoryEntry>
ConstructContiguousEntryListFrom(mozilla::dom::SessionHistoryEntry* aEntry);
+ mozilla::LinkedList<mozilla::dom::SessionHistoryEntry>
+ ConstructContiguousEntryList();
+
+ bool ContainsEntry(nsISHEntry* aEntry);
protected:
virtual ~nsSHistory();
diff --git a/toolkit/components/sessionstore/SessionStoreUtils.cpp b/toolkit/components/sessionstore/SessionStoreUtils.cpp
@@ -1661,6 +1661,8 @@ already_AddRefed<Promise> SessionStoreUtils::InitializeRestore(
return nullptr;
}
+ aContext.MaybeReconstructActiveEntryList();
+
nsCOMPtr<nsISHistory> shistory = aContext.GetSessionHistory();
MOZ_DIAGNOSTIC_ASSERT(shistory);
shistory->ReloadCurrentEntry();