commit 451168ca30b263a89521faec1d0df4bd17c92aad parent 25cebeac46f86fae49437fda3a206a67630f287e Author: Keith Cirkel <keithamus@users.noreply.github.com> Date: Fri, 3 Oct 2025 12:25:53 +0000 Bug 1955947 - Part 2: Implement RestoreScrollPositionData r=farre,dom-core This implements the basics of RestoreScrollPositionData. It introduces the new method nsDocShell::RestoreScrollPosFromActiveSHE which will set the scroll position to the position stored by the active session history entry. One could say this deviates slightly from the stated spec because the spec suggests "HasBeenScrolledByUser" should be true/false if the "user" has scrolled the document. This however, is a little ambiguous and doesn't seem to correlate with behaviour from other browsers. Instead we simply check if the scroll generation has changed since the navigation event was fired. It does not pass all scroll-behavior tests, as some rely on an unspecced behaviour whereby the scroll restoration is deferred until the active navigation interception promise has settled. We can resolve this in another bug because this behaviour is not detailed in the spec. Differential Revision: https://phabricator.services.mozilla.com/D266431 Diffstat:
11 files changed, 26 insertions(+), 26 deletions(-)
diff --git a/docshell/base/nsDocShell.cpp b/docshell/base/nsDocShell.cpp @@ -5050,6 +5050,19 @@ nsresult nsDocShell::SetCurScrollPosEx(int32_t aCurHorizontalPos, return NS_OK; } +void nsDocShell::RestoreScrollPosFromActiveSHE() { + nscoord bx = 0; + nscoord by = 0; + if ((mozilla::SessionHistoryInParent() ? !!mActiveEntry : !!mOSHE)) { + if (mozilla::SessionHistoryInParent()) { + mActiveEntry->GetScrollPosition(&bx, &by); + } else { + mOSHE->GetScrollPosition(&bx, &by); + } + SetCurScrollPosEx(bx, by); + } +} + void nsDocShell::SetScrollbarPreference(mozilla::ScrollbarPreference aPref) { if (mScrollbarPref == aPref) { return; diff --git a/docshell/base/nsDocShell.h b/docshell/base/nsDocShell.h @@ -1045,6 +1045,8 @@ class nsDocShell final : public nsDocLoader, int32_t aCurVerticalPos); nsPoint GetCurScrollPos(); + void RestoreScrollPosFromActiveSHE(); + already_AddRefed<mozilla::dom::ChildSHistory> GetRootSessionHistory(); bool CSSErrorReportingEnabled() const { return mCSSErrorReportingEnabled; } diff --git a/dom/events/NavigateEvent.cpp b/dom/events/NavigateEvent.cpp @@ -9,6 +9,7 @@ #include "mozilla/HoldDropJSObjects.h" #include "mozilla/PresShell.h" #include "mozilla/dom/AbortController.h" +#include "mozilla/dom/Document.h" #include "mozilla/dom/ElementBinding.h" #include "mozilla/dom/NavigateEventBinding.h" #include "mozilla/dom/Navigation.h" @@ -424,8 +425,16 @@ static void RestoreScrollPositionData(Document* aDocument, return; } - // This will be implemented in Bug 1955947. Make sure to move this to - // `SessionHistoryEntry`/`SessionHistoryInfo`. + RefPtr<nsDocShell> docShell = nsDocShell::Cast(aDocument->GetDocShell()); + if (!docShell) { + return; + } + + // 3. The user agent should attempt to use entry's scroll position data to + // restore the scroll positions of entry's document's restorable scrollable + // regions. The user agent may continue to attempt to do so periodically, + // until document's has been scrolled by the user becomes true. + docShell->RestoreScrollPosFromActiveSHE(); } // https://html.spec.whatwg.org/#process-scroll-behavior diff --git a/testing/web-platform/meta/navigation-api/scroll-behavior/after-transition-basic.html.ini b/testing/web-platform/meta/navigation-api/scroll-behavior/after-transition-basic.html.ini @@ -1,3 +0,0 @@ -[after-transition-basic.html] - [scroll: after-transition should scroll when back completes] - expected: FAIL diff --git a/testing/web-platform/meta/navigation-api/scroll-behavior/after-transition-change-history-scroll-restoration-during-promise.html.ini b/testing/web-platform/meta/navigation-api/scroll-behavior/after-transition-change-history-scroll-restoration-during-promise.html.ini @@ -1,3 +0,0 @@ -[after-transition-change-history-scroll-restoration-during-promise.html] - [scroll: after-transition should ignore history.scrollRestoration even if it changes in the middle of the navigation] - expected: FAIL diff --git a/testing/web-platform/meta/navigation-api/scroll-behavior/after-transition-explicit-scroll.html.ini b/testing/web-platform/meta/navigation-api/scroll-behavior/after-transition-explicit-scroll.html.ini @@ -1,3 +0,0 @@ -[after-transition-explicit-scroll.html] - [scroll: scroll() should preempt after-transition] - expected: FAIL diff --git a/testing/web-platform/meta/navigation-api/scroll-behavior/after-transition-intercept-handler-modifies.html.ini b/testing/web-platform/meta/navigation-api/scroll-behavior/after-transition-intercept-handler-modifies.html.ini @@ -1,3 +0,0 @@ -[after-transition-intercept-handler-modifies.html] - [scroll: state should be saved before intercept handlers run] - expected: [FAIL, PASS] diff --git a/testing/web-platform/meta/navigation-api/scroll-behavior/after-transition-timing.html.ini b/testing/web-platform/meta/navigation-api/scroll-behavior/after-transition-timing.html.ini @@ -1,3 +0,0 @@ -[after-transition-timing.html] - [scroll: after-transition should scroll when back completes, just before navigatesuccess] - expected: FAIL diff --git a/testing/web-platform/meta/navigation-api/scroll-behavior/manual-scroll-after-dispatch.html.ini b/testing/web-platform/meta/navigation-api/scroll-behavior/manual-scroll-after-dispatch.html.ini @@ -1,3 +0,0 @@ -[manual-scroll-after-dispatch.html] - [scroll: scroll() should work after a navigate event dispatch] - expected: FAIL diff --git a/testing/web-platform/meta/navigation-api/scroll-behavior/manual-scroll-in-precommit-handler.html.ini b/testing/web-platform/meta/navigation-api/scroll-behavior/manual-scroll-in-precommit-handler.html.ini @@ -1,3 +0,0 @@ -[manual-scroll-in-precommit-handler.html] - [scroll: scroll() in precommitHandler throws] - expected: FAIL diff --git a/testing/web-platform/meta/navigation-api/scroll-behavior/manual-scroll-repeated.html.ini b/testing/web-platform/meta/navigation-api/scroll-behavior/manual-scroll-repeated.html.ini @@ -1,3 +0,0 @@ -[manual-scroll-repeated.html] - [scroll: scroll() should throw if called a second time] - expected: FAIL