From c16c8b5937d7f639a24245254497751646aa08a8 Mon Sep 17 00:00:00 2001 From: Olli Pettay Date: Sat, 14 Apr 2018 15:13:23 +0300 Subject: [PATCH] Bug 1452825, use smooth scrolling also for history navigations, r=bz --HG-- extra : rebase_source : 562e0123597484851db6241912b7cd7e275078d9 --- docshell/base/nsDocShell.cpp | 9 ++- .../cssom-view/scroll-behavior-smooth.html | 80 +++++++++++++++++++ 2 files changed, 87 insertions(+), 2 deletions(-) diff --git a/docshell/base/nsDocShell.cpp b/docshell/base/nsDocShell.cpp index 6f7b56004cd6..7126171f0545 100644 --- a/docshell/base/nsDocShell.cpp +++ b/docshell/base/nsDocShell.cpp @@ -6159,8 +6159,13 @@ nsDocShell::SetCurScrollPosEx(int32_t aCurHorizontalPos, nsIScrollableFrame* sf = GetRootScrollFrame(); NS_ENSURE_TRUE(sf, NS_ERROR_FAILURE); - sf->ScrollTo(nsPoint(aCurHorizontalPos, aCurVerticalPos), - nsIScrollableFrame::INSTANT); + nsIScrollableFrame::ScrollMode scrollMode = nsIScrollableFrame::INSTANT; + if (sf->GetScrollbarStyles().mScrollBehavior == + NS_STYLE_SCROLL_BEHAVIOR_SMOOTH) { + scrollMode = nsIScrollableFrame::SMOOTH_MSD; + } + + sf->ScrollTo(nsPoint(aCurHorizontalPos, aCurVerticalPos), scrollMode); return NS_OK; } diff --git a/testing/web-platform/tests/css/cssom-view/scroll-behavior-smooth.html b/testing/web-platform/tests/css/cssom-view/scroll-behavior-smooth.html index f144a5f61cdd..e1a7a6a16803 100644 --- a/testing/web-platform/tests/css/cssom-view/scroll-behavior-smooth.html +++ b/testing/web-platform/tests/css/cssom-view/scroll-behavior-smooth.html @@ -56,5 +56,85 @@ window.scrollTo(0, 0); }, "BODY element scroll-behavior should not propagate to viewport"); + var instantHistoryNavigationTest = + async_test("Instant scrolling while doing history navigation."); + var smoothHistoryNavigationTest = + async_test("Smooth scrolling while doing history navigation."); + + function instant() { + document.documentElement.className = ""; + document.body.className = ""; + window.scrollTo(0, 0); + var p = document.createElement("pre"); + p.textContent = new Array(1000).join("newline\n"); + var a = document.createElement("a"); + a.href = "#"; + a.name = "foo"; + a.textContent = "foo"; + p.appendChild(a); + document.body.appendChild(p); + window.onhashchange = function() { + window.onhashchange = function() { + instantHistoryNavigationTest.step(function() { + assert_equals(location.hash, "", "Shouldn't be scrolled to a fragment."); + assert_equals(window.scrollY, 0, "Shouldn't be scrolled back to top yet."); + }); + p.remove(); + instantHistoryNavigationTest.done(); + smooth(); + } + + instantHistoryNavigationTest.step(function() { + assert_equals(location.hash, "#foo", "Should be scrolled to a fragment."); + assert_not_equals(window.scrollY, 0, "Shouldn't be scrolled to top anymore."); + }); + history.back(); + } + + instantHistoryNavigationTest.step(function() { + assert_equals(window.scrollY, 0, "Should be scrolled to top."); + assert_equals(location.hash, "", "Shouldn't be scrolled to a fragment."); + }); + location.hash = "foo"; + }; + instant(); + + function smooth() { + document.documentElement.className = ""; + document.body.className = ""; + window.scrollTo(0, 0); + var p = document.createElement("pre"); + p.textContent = new Array(1000).join("newline\n"); + var a = document.createElement("a"); + a.href = "#"; + a.name = "bar"; + a.textContent = "bar"; + p.appendChild(a); + document.body.appendChild(p); + window.onhashchange = function() { + window.onhashchange = function() { + smoothHistoryNavigationTest.step(function() { + assert_equals(location.hash, "", "Shouldn't be scrolled to a fragment."); + assert_not_equals(window.scrollY, 0, "Shouldn't be scrolled back to top yet."); + }); + p.remove(); + smoothHistoryNavigationTest.done(); + } + + smoothHistoryNavigationTest.step(function() { + assert_equals(location.hash, "#bar", "Should be scrolled to a fragment."); + assert_not_equals(window.scrollY, 0, "Shouldn't be scrolled to top anymore."); + }); + history.back(); + } + + smoothHistoryNavigationTest.step(function() { + assert_equals(window.scrollY, 0, "Should be scrolled to top."); + assert_equals(location.hash, "", "Shouldn't be scrolled to a fragment."); + }); + location.hash = "bar"; + document.documentElement.className = "smooth"; + }; + testContainer.style.display = "none";