diff --git a/docshell/base/nsDocShell.cpp b/docshell/base/nsDocShell.cpp index 90db48b4ce40..31e2a5b6738f 100644 --- a/docshell/base/nsDocShell.cpp +++ b/docshell/base/nsDocShell.cpp @@ -8508,11 +8508,18 @@ nsresult nsDocShell::HandleSameDocumentNavigation( // Link our new SHEntry to the old SHEntry's back/forward // cache data, since the two SHEntries correspond to the // same document. + if (mLoadingEntry && !mLoadingEntry->mIsLoadFromSessionHistory) { + // If we're not doing a history load, scroll restoration + // should be inherited from the previous session history entry. + SetScrollRestorationIsManualOnHistoryEntry( + nullptr, &mLoadingEntry->mInfo, scrollRestorationIsManual); + } if (mLSHE) { if (!aLoadState->SHEntry()) { // If we're not doing a history load, scroll restoration // should be inherited from the previous session history entry. - mLSHE->SetScrollRestorationIsManual(scrollRestorationIsManual); + SetScrollRestorationIsManualOnHistoryEntry(mLSHE, nullptr, + scrollRestorationIsManual); } mLSHE->AdoptBFCacheEntry(mOSHE); } @@ -10787,13 +10794,35 @@ nsDocShell::GetCurrentScrollRestorationIsManual(bool* aIsManual) { NS_IMETHODIMP nsDocShell::SetCurrentScrollRestorationIsManual(bool aIsManual) { - if (mOSHE) { - mOSHE->SetScrollRestorationIsManual(aIsManual); - } + SetScrollRestorationIsManualOnHistoryEntry(mOSHE, mActiveEntry.get(), + aIsManual); return NS_OK; } +void nsDocShell::SetScrollRestorationIsManualOnHistoryEntry( + nsISHEntry* aSHEntry, mozilla::dom::SessionHistoryInfo* aInfo, + bool aIsManual) { + if (aSHEntry) { + aSHEntry->SetScrollRestorationIsManual(aIsManual); + } + + if (aInfo) { + aInfo->SetScrollRestorationIsManual(aIsManual); + if (XRE_IsParentProcess()) { + SessionHistoryEntry* entry = + SessionHistoryEntry::GetByInfoId(aInfo->Id()); + if (entry) { + entry->SetScrollRestorationIsManual(aIsManual); + } + } else { + mozilla::Unused << ContentChild::GetSingleton() + ->SendSessionHistoryEntryScrollRestorationIsManual( + aInfo->Id(), aIsManual); + } + } +} + bool nsDocShell::ShouldAddToSessionHistory(nsIURI* aURI, nsIChannel* aChannel) { // I believe none of the about: urls should go in the history. But then // that could just be me... If the intent is only deny about:blank then we diff --git a/docshell/base/nsDocShell.h b/docshell/base/nsDocShell.h index 1feb2c734af7..5c852dd02a35 100644 --- a/docshell/base/nsDocShell.h +++ b/docshell/base/nsDocShell.h @@ -1050,6 +1050,10 @@ class nsDocShell final : public nsDocLoader, void SetTitleOnHistoryEntry(); + void SetScrollRestorationIsManualOnHistoryEntry( + nsISHEntry* aSHEntry, mozilla::dom::SessionHistoryInfo* aInfo, + bool aIsManual); + private: // data members nsID mHistoryID; nsString mTitle; diff --git a/docshell/shistory/SessionHistoryEntry.h b/docshell/shistory/SessionHistoryEntry.h index f815ef2b4043..bfed1fc6e4e0 100644 --- a/docshell/shistory/SessionHistoryEntry.h +++ b/docshell/shistory/SessionHistoryEntry.h @@ -49,6 +49,10 @@ class SessionHistoryInfo { const nsAString& GetTitle() { return mTitle; } void SetTitle(const nsAString& aTitle) { mTitle = aTitle; } + void SetScrollRestorationIsManual(bool aIsManual) { + mScrollRestorationIsManual = aIsManual; + } + nsIURI* GetURI() const { return mURI; } bool GetURIWasModified() const { return mURIWasModified; } diff --git a/dom/ipc/ContentParent.cpp b/dom/ipc/ContentParent.cpp index ef958b019942..131eb5d027c5 100644 --- a/dom/ipc/ContentParent.cpp +++ b/dom/ipc/ContentParent.cpp @@ -6977,6 +6977,17 @@ mozilla::ipc::IPCResult ContentParent::RecvSessionHistoryEntryTitle( return IPC_OK(); } +mozilla::ipc::IPCResult +ContentParent::RecvSessionHistoryEntryScrollRestorationIsManual( + const uint64_t& aSessionHistoryEntryID, const bool& aIsManual) { + SessionHistoryEntry* entry = + SessionHistoryEntry::GetByInfoId(aSessionHistoryEntryID); + if (entry) { + entry->SetScrollRestorationIsManual(aIsManual); + } + return IPC_OK(); +} + mozilla::ipc::IPCResult ContentParent::RecvCommitWindowContextTransaction( const MaybeDiscarded& aContext, WindowContext::BaseTransaction&& aTransaction, uint64_t aEpoch) { diff --git a/dom/ipc/ContentParent.h b/dom/ipc/ContentParent.h index 130bbf892895..3be4e4944105 100644 --- a/dom/ipc/ContentParent.h +++ b/dom/ipc/ContentParent.h @@ -1343,6 +1343,9 @@ class ContentParent final mozilla::ipc::IPCResult RecvSessionHistoryEntryTitle( const uint64_t& aSessionHistoryEntryID, const nsString& aTitle); + mozilla::ipc::IPCResult RecvSessionHistoryEntryScrollRestorationIsManual( + const uint64_t& aSessionHistoryEntryID, const bool& aIsManual); + // Notify the ContentChild to enable the input event prioritization when // initializing. void MaybeEnableRemoteInputEventQueue(); diff --git a/dom/ipc/PContent.ipdl b/dom/ipc/PContent.ipdl index 5ca2603f2561..7bc795094ffc 100644 --- a/dom/ipc/PContent.ipdl +++ b/dom/ipc/PContent.ipdl @@ -928,6 +928,9 @@ parent: async SessionHistoryEntryTitle(uint64_t aSessionHistoryEntryID, nsString aTitle); + async SessionHistoryEntryScrollRestorationIsManual(uint64_t aSessionHistoryEntryID, + bool aIsManual); + async InitBackground(Endpoint aEndpoint); async CreateGMPService();