diff --git a/dom/base/Element.cpp b/dom/base/Element.cpp index ecd47243ea3a..466911d20bbd 100644 --- a/dom/base/Element.cpp +++ b/dom/base/Element.cpp @@ -797,6 +797,15 @@ Element::ScrollByNoFlush(int32_t aDx, int32_t aDy) return (before != after); } +void +Element::MozScrollSnap() +{ + nsIScrollableFrame* sf = GetScrollFrame(nullptr, false); + if (sf) { + sf->ScrollSnap(); + } +} + static nsSize GetScrollRectSizeForOverflowVisibleFrame(nsIFrame* aFrame) { if (!aFrame) { diff --git a/dom/base/Element.h b/dom/base/Element.h index 929f566cadca..ca627fdaa85c 100644 --- a/dom/base/Element.h +++ b/dom/base/Element.h @@ -762,6 +762,7 @@ public: void SetScrollLeft(int32_t aScrollLeft); int32_t ScrollWidth(); int32_t ScrollHeight(); + void MozScrollSnap(); int32_t ClientTop() { return nsPresContext::AppUnitsToIntCSSPixels(GetClientAreaRect().y); diff --git a/dom/base/nsGlobalWindow.cpp b/dom/base/nsGlobalWindow.cpp index 2dab9f09b6fa..501f7d258815 100644 --- a/dom/base/nsGlobalWindow.cpp +++ b/dom/base/nsGlobalWindow.cpp @@ -7355,6 +7355,16 @@ nsGlobalWindow::ScrollByPages(int32_t numPages, } } +void +nsGlobalWindow::MozScrollSnap() +{ + FlushPendingNotifications(Flush_Layout); + nsIScrollableFrame *sf = GetScrollFrame(); + if (sf) { + sf->ScrollSnap(); + } +} + void nsGlobalWindow::MozRequestOverfill(OverfillCallback& aCallback, mozilla::ErrorResult& aError) diff --git a/dom/base/nsGlobalWindow.h b/dom/base/nsGlobalWindow.h index 8e48f059ec71..0b11b87be83f 100644 --- a/dom/base/nsGlobalWindow.h +++ b/dom/base/nsGlobalWindow.h @@ -946,6 +946,7 @@ public: const mozilla::dom::ScrollOptions& aOptions); void ScrollByPages(int32_t numPages, const mozilla::dom::ScrollOptions& aOptions); + void MozScrollSnap(); int32_t GetInnerWidth(mozilla::ErrorResult& aError); void SetInnerWidth(int32_t aInnerWidth, mozilla::ErrorResult& aError); int32_t GetInnerHeight(mozilla::ErrorResult& aError); diff --git a/dom/webidl/Element.webidl b/dom/webidl/Element.webidl index 2c95d91314d6..c8218bd6ab58 100644 --- a/dom/webidl/Element.webidl +++ b/dom/webidl/Element.webidl @@ -185,6 +185,11 @@ partial interface Element { void scrollTo(optional ScrollToOptions options); void scrollBy(unrestricted double x, unrestricted double y); void scrollBy(optional ScrollToOptions options); + // mozScrollSnap is used by chrome to perform scroll snapping after the + // user performs actions that may affect scroll position + // mozScrollSnap is deprecated, to be replaced by a web accessible API, such + // as an extension to the ScrollOptions dictionary. See bug 1137937. + [ChromeOnly] void mozScrollSnap(); readonly attribute long clientTop; readonly attribute long clientLeft; diff --git a/dom/webidl/Window.webidl b/dom/webidl/Window.webidl index a32af1ee69fd..415357e51cf0 100644 --- a/dom/webidl/Window.webidl +++ b/dom/webidl/Window.webidl @@ -190,6 +190,11 @@ partial interface Window { void scrollTo(optional ScrollToOptions options); void scrollBy(unrestricted double x, unrestricted double y); void scrollBy(optional ScrollToOptions options); + // mozScrollSnap is used by chrome to perform scroll snapping after the + // user performs actions that may affect scroll position + // mozScrollSnap is deprecated, to be replaced by a web accessible API, such + // as an extension to the ScrollOptions dictionary. See bug 1137937. + [ChromeOnly] void mozScrollSnap(); [Replaceable, Throws] readonly attribute long scrollX; [Throws] readonly attribute long pageXOffset; [Replaceable, Throws] readonly attribute long scrollY; diff --git a/toolkit/content/browser-content.js b/toolkit/content/browser-content.js index 7b45363e365f..b61e7d427ec7 100644 --- a/toolkit/content/browser-content.js +++ b/toolkit/content/browser-content.js @@ -146,6 +146,7 @@ let ClickEventHandler = { stopScroll: function() { if (this._scrollable) { + this._scrollable.mozScrollSnap(); this._scrollable = null; Cc["@mozilla.org/eventlistenerservice;1"]