Title: [210117] trunk
Revision
210117
Author
[email protected]
Date
2016-12-22 14:55:31 -0800 (Thu, 22 Dec 2016)

Log Message

CSS Scroll Snap does not work if scrollbar is hidden
https://bugs.webkit.org/show_bug.cgi?id=160442
<rdar://problem/23317034>

Reviewed by Simon Fraser.

Source/WebCore:

Currently, the only reason scroll snapping works in overflow scrolling containers without forcing layout is
because we would initialize the scrolling container's ScrollAnimator in the process of updating scrollbars. If
there are no scrollbars to render, we won't bother creating a ScrollAnimator. Without an existing
ScrollAnimator, ScrollableArea::updateScrollSnapState will simply bail instead of setting up the scroll snap
state. Instead, we should take setting a non-empty vector of scroll offsets on the ScrollableArea as a cue that
the ScrollableArea also needs a ScrollAnimator, and initialize it there if necessary.

Test: tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-hidden-scrollbars.html

* platform/ScrollableArea.cpp:
(WebCore::ScrollableArea::setHorizontalSnapOffsets):
(WebCore::ScrollableArea::setVerticalSnapOffsets):

LayoutTests:

Adds a new layout test verifying that scroll snapping still works when scrollbars are hidden via CSS.

* tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-hidden-scrollbars-expected.txt: Added.
* tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-hidden-scrollbars.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (210116 => 210117)


--- trunk/LayoutTests/ChangeLog	2016-12-22 22:48:32 UTC (rev 210116)
+++ trunk/LayoutTests/ChangeLog	2016-12-22 22:55:31 UTC (rev 210117)
@@ -1,3 +1,16 @@
+2016-12-22  Wenson Hsieh  <[email protected]>
+
+        CSS Scroll Snap does not work if scrollbar is hidden
+        https://bugs.webkit.org/show_bug.cgi?id=160442
+        <rdar://problem/23317034>
+
+        Reviewed by Simon Fraser.
+
+        Adds a new layout test verifying that scroll snapping still works when scrollbars are hidden via CSS.
+
+        * tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-hidden-scrollbars-expected.txt: Added.
+        * tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-hidden-scrollbars.html: Added.
+
 2016-12-22  Daniel Bates  <[email protected]>
 
         Make http/tests/security/popup-blocked-from-{fake-event, window-open}.html actually test popup

Added: trunk/LayoutTests/tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-hidden-scrollbars-expected.txt (0 => 210117)


--- trunk/LayoutTests/tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-hidden-scrollbars-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-hidden-scrollbars-expected.txt	2016-12-22 22:55:31 UTC (rev 210117)
@@ -0,0 +1,2 @@
+After swiping, the container's scrollTop is now: 500
+

Added: trunk/LayoutTests/tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-hidden-scrollbars.html (0 => 210117)


--- trunk/LayoutTests/tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-hidden-scrollbars.html	                        (rev 0)
+++ trunk/LayoutTests/tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-hidden-scrollbars.html	2016-12-22 22:55:31 UTC (rev 210117)
@@ -0,0 +1,74 @@
+<!DOCTYPE HTML>
+<html>
+    <head>
+        <style>
+            body {
+                margin: 0;
+                overflow: hidden;
+            }
+
+            ::-webkit-scrollbar {
+                display: none;
+            }
+
+            #port {
+                width: 500px;
+                height: 500px;
+                position: absolute;
+                top: 0;
+                left: 0;
+                overflow-x: none;
+                overflow-y: scroll;
+                scroll-snap-type: y mandatory;
+                opacity: 0.5;
+            }
+
+            .area {
+                height: 500px;
+                width: 500px;
+                float: left;
+                scroll-snap-align: center;
+            }
+        </style>
+        <script>
+        let write = s => output.innerHTML += s + "<br>";
+
+        if (window.testRunner) {
+            testRunner.dumpAsText();
+            testRunner.waitUntilDone();
+        }
+
+        function run() {
+            if (!window.testRunner || !window.eventSender) {
+                write("To manually test, verify that scrolling in the overflow container snaps to each of the children.");
+                return;
+            }
+
+            eventSender.monitorWheelEvents();
+            eventSender.mouseMoveTo(250, 250);
+            eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, "began", "none");
+            eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, "changed", "none");
+            eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, "changed", "none");
+            eventSender.mouseScrollByWithWheelAndMomentumPhases(0, 0, "ended", "none");
+            eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, "none", "begin");
+            eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, "none", "continue");
+            eventSender.mouseScrollByWithWheelAndMomentumPhases(0, 0, "none", "end");
+            eventSender.callAfterScrollingCompletes(() => {
+                write(`After swiping, the container's scrollTop is now: ${port.scrollTop}`);
+                testRunner.notifyDone();
+            });
+        }
+        </script>
+    </head>
+    <body _onload_=run()>
+        <div id="port">
+            <div class="area" style="background-color: red;"></div>
+            <div class="area" style="background-color: green;"></div>
+            <div class="area" style="background-color: blue;"></div>
+            <div class="area" style="background-color: aqua;"></div>
+            <div class="area" style="background-color: yellow;"></div>
+            <div class="area" style="background-color: fuchsia;"></div>
+        </div>
+        <div id="output"></div>
+    </body>
+</html>

Modified: trunk/Source/WebCore/ChangeLog (210116 => 210117)


--- trunk/Source/WebCore/ChangeLog	2016-12-22 22:48:32 UTC (rev 210116)
+++ trunk/Source/WebCore/ChangeLog	2016-12-22 22:55:31 UTC (rev 210117)
@@ -1,3 +1,24 @@
+2016-12-22  Wenson Hsieh  <[email protected]>
+
+        CSS Scroll Snap does not work if scrollbar is hidden
+        https://bugs.webkit.org/show_bug.cgi?id=160442
+        <rdar://problem/23317034>
+
+        Reviewed by Simon Fraser.
+
+        Currently, the only reason scroll snapping works in overflow scrolling containers without forcing layout is
+        because we would initialize the scrolling container's ScrollAnimator in the process of updating scrollbars. If
+        there are no scrollbars to render, we won't bother creating a ScrollAnimator. Without an existing
+        ScrollAnimator, ScrollableArea::updateScrollSnapState will simply bail instead of setting up the scroll snap
+        state. Instead, we should take setting a non-empty vector of scroll offsets on the ScrollableArea as a cue that
+        the ScrollableArea also needs a ScrollAnimator, and initialize it there if necessary.
+
+        Test: tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-hidden-scrollbars.html
+
+        * platform/ScrollableArea.cpp:
+        (WebCore::ScrollableArea::setHorizontalSnapOffsets):
+        (WebCore::ScrollableArea::setVerticalSnapOffsets):
+
 2016-12-22  Daniel Bates  <[email protected]>
 
         Bypass pop-up blocker from cross-origin or sandboxed frame

Modified: trunk/Source/WebCore/platform/ScrollableArea.cpp (210116 => 210117)


--- trunk/Source/WebCore/platform/ScrollableArea.cpp	2016-12-22 22:48:32 UTC (rev 210116)
+++ trunk/Source/WebCore/platform/ScrollableArea.cpp	2016-12-22 22:55:31 UTC (rev 210117)
@@ -427,11 +427,21 @@
 #if ENABLE(CSS_SCROLL_SNAP)
 void ScrollableArea::setHorizontalSnapOffsets(std::unique_ptr<Vector<LayoutUnit>> horizontalSnapOffsets)
 {
+    ASSERT(horizontalSnapOffsets);
+    // Consider having a non-empty set of snap offsets as a cue to initialize the ScrollAnimator.
+    if (horizontalSnapOffsets->size())
+        scrollAnimator();
+
     m_horizontalSnapOffsets = WTFMove(horizontalSnapOffsets);
 }
 
 void ScrollableArea::setVerticalSnapOffsets(std::unique_ptr<Vector<LayoutUnit>> verticalSnapOffsets)
 {
+    ASSERT(verticalSnapOffsets);
+    // Consider having a non-empty set of snap offsets as a cue to initialize the ScrollAnimator.
+    if (verticalSnapOffsets->size())
+        scrollAnimator();
+
     m_verticalSnapOffsets = WTFMove(verticalSnapOffsets);
 }
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to