<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[269506] trunk</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/269506">269506</a></dd>
<dt>Author</dt> <dd>commit-queue@webkit.org</dd>
<dt>Date</dt> <dd>2020-11-06 01:44:54 -0800 (Fri, 06 Nov 2020)</dd>
</dl>

<h3>Log Message</h3>
<pre>Scroll snap specified on :root doesn't work
https://bugs.webkit.org/show_bug.cgi?id=210469
<rdar://problem/61746676>

Source/WebCore:

Properly handle scroll-snap-type on the root element.

This change is originally based on a patch by Simon Fraser.

Patch by Martin Robinson <mrobinson@igalia.com> on 2020-11-06
Reviewed by Simon Fraser.

Tests: tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-mainframe-horizontal-legacy.html
       tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-mainframe-vertical-legacy.html
       tiled-drawing/scrolling/scroll-snap/scroll-snap-proximity-mainframe-legacy.html

* page/FrameView.cpp:
(WebCore::FrameView::updateSnapOffsets): Send the body or root element style depending
on where the scroll-snap properties are set, but always use the FrameView viewport
when calculating geometry for scroll snap.
* page/scrolling/AxisScrollSnapOffsets.cpp:
(WebCore::updateSnapOffsetsForScrollableArea): Accept a viewport rectangle from the
caller and also eliminate redundant argument that was causing a bit of confusion.
* page/scrolling/AxisScrollSnapOffsets.h: Update the function declaration.
* platform/ScrollableArea.cpp:
(WebCore::ScrollableArea::clearSnapOffsets):  Added a helper to clear both vertical and horizontal snap info.
* platform/ScrollableArea.h:
* rendering/RenderBox.cpp:
(WebCore::RenderBox::findEnclosingScrollableContainerForSnapping const): Renamed findEnclosingScrollableContainer
to this because now it is only useful for scroll snapping. The only preexisting caller was
the scroll snap code.
(WebCore::RenderBox::findEnclosingScrollableContainer const): Deleted.
* rendering/RenderBox.h: Updated method name.
* rendering/RenderLayer.cpp:
(WebCore::RenderLayer::updateSnapOffsets): Update to reflect changes to updateSnapOffsetsForScrollableArea.
* rendering/RenderObject.cpp:
(WebCore::RenderObject::enclosingScrollableContainerForSnapping const): Always return the
document root as the container instead of the body. The body never captures scroll
snap points.

LayoutTests:

Patch by Martin Robinson <mrobinson@igalia.com> on 2020-11-06
Reviewed by Simon Fraser.

Modified main frame scroll snap tests to reflect the specification and add a
few more tests to test the legacy behavior which this change maintains for
backwards compatibility.

* css3/scroll-snap/scroll-snap-positions-mainframe.html:
* tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-mainframe-horizontal-legacy-expected.txt: Added.
* tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-mainframe-horizontal-legacy.html: Copied from LayoutTests/tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-mainframe-horizontal.html.
* tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-mainframe-horizontal.html:
* tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-mainframe-slow-horizontal.html:
* tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-mainframe-slow-vertical.html:
* tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-mainframe-vertical-legacy-expected.txt: Added.
* tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-mainframe-vertical-legacy.html: Copied from LayoutTests/tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-mainframe-vertical.html.
* tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-mainframe-vertical-then-horizontal.html:
* tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-mainframe-vertical.html:
* tiled-drawing/scrolling/scroll-snap/scroll-snap-proximity-mainframe-legacy-expected.txt: Added.
* tiled-drawing/scrolling/scroll-snap/scroll-snap-proximity-mainframe-legacy.html: Copied from LayoutTests/tiled-drawing/scrolling/scroll-snap/scroll-snap-proximity-mainframe.html.
* tiled-drawing/scrolling/scroll-snap/scroll-snap-proximity-mainframe.html:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkLayoutTestscss3scrollsnapscrollsnappositionsmainframehtml">trunk/LayoutTests/css3/scroll-snap/scroll-snap-positions-mainframe.html</a></li>
<li><a href="#trunkLayoutTeststileddrawingscrollingscrollsnapscrollsnapmandatorymainframehorizontalhtml">trunk/LayoutTests/tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-mainframe-horizontal.html</a></li>
<li><a href="#trunkLayoutTeststileddrawingscrollingscrollsnapscrollsnapmandatorymainframeslowhorizontalhtml">trunk/LayoutTests/tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-mainframe-slow-horizontal.html</a></li>
<li><a href="#trunkLayoutTeststileddrawingscrollingscrollsnapscrollsnapmandatorymainframeslowverticalhtml">trunk/LayoutTests/tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-mainframe-slow-vertical.html</a></li>
<li><a href="#trunkLayoutTeststileddrawingscrollingscrollsnapscrollsnapmandatorymainframeverticalthenhorizontalhtml">trunk/LayoutTests/tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-mainframe-vertical-then-horizontal.html</a></li>
<li><a href="#trunkLayoutTeststileddrawingscrollingscrollsnapscrollsnapmandatorymainframeverticalhtml">trunk/LayoutTests/tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-mainframe-vertical.html</a></li>
<li><a href="#trunkLayoutTeststileddrawingscrollingscrollsnapscrollsnapproximitymainframehtml">trunk/LayoutTests/tiled-drawing/scrolling/scroll-snap/scroll-snap-proximity-mainframe.html</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCorepageFrameViewcpp">trunk/Source/WebCore/page/FrameView.cpp</a></li>
<li><a href="#trunkSourceWebCorepagescrollingAxisScrollSnapOffsetscpp">trunk/Source/WebCore/page/scrolling/AxisScrollSnapOffsets.cpp</a></li>
<li><a href="#trunkSourceWebCorepagescrollingAxisScrollSnapOffsetsh">trunk/Source/WebCore/page/scrolling/AxisScrollSnapOffsets.h</a></li>
<li><a href="#trunkSourceWebCoreplatformScrollableAreacpp">trunk/Source/WebCore/platform/ScrollableArea.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformScrollableAreah">trunk/Source/WebCore/platform/ScrollableArea.h</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderBoxcpp">trunk/Source/WebCore/rendering/RenderBox.cpp</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderBoxh">trunk/Source/WebCore/rendering/RenderBox.h</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderLayercpp">trunk/Source/WebCore/rendering/RenderLayer.cpp</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderObjectcpp">trunk/Source/WebCore/rendering/RenderObject.cpp</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTeststileddrawingscrollingscrollsnapscrollsnapmandatorymainframehorizontallegacyexpectedtxt">trunk/LayoutTests/tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-mainframe-horizontal-legacy-expected.txt</a></li>
<li><a href="#trunkLayoutTeststileddrawingscrollingscrollsnapscrollsnapmandatorymainframehorizontallegacyhtml">trunk/LayoutTests/tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-mainframe-horizontal-legacy.html</a></li>
<li><a href="#trunkLayoutTeststileddrawingscrollingscrollsnapscrollsnapmandatorymainframeverticallegacyexpectedtxt">trunk/LayoutTests/tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-mainframe-vertical-legacy-expected.txt</a></li>
<li><a href="#trunkLayoutTeststileddrawingscrollingscrollsnapscrollsnapmandatorymainframeverticallegacyhtml">trunk/LayoutTests/tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-mainframe-vertical-legacy.html</a></li>
<li><a href="#trunkLayoutTeststileddrawingscrollingscrollsnapscrollsnapproximitymainframelegacyexpectedtxt">trunk/LayoutTests/tiled-drawing/scrolling/scroll-snap/scroll-snap-proximity-mainframe-legacy-expected.txt</a></li>
<li><a href="#trunkLayoutTeststileddrawingscrollingscrollsnapscrollsnapproximitymainframelegacyhtml">trunk/LayoutTests/tiled-drawing/scrolling/scroll-snap/scroll-snap-proximity-mainframe-legacy.html</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (269505 => 269506)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog      2020-11-06 09:09:31 UTC (rev 269505)
+++ trunk/LayoutTests/ChangeLog 2020-11-06 09:44:54 UTC (rev 269506)
</span><span class="lines">@@ -1,3 +1,29 @@
</span><ins>+2020-11-06  Martin Robinson  <mrobinson@igalia.com>
+
+        Scroll snap specified on :root doesn't work
+        https://bugs.webkit.org/show_bug.cgi?id=210469
+        <rdar://problem/61746676>
+
+        Reviewed by Simon Fraser.
+
+        Modified main frame scroll snap tests to reflect the specification and add a
+        few more tests to test the legacy behavior which this change maintains for
+        backwards compatibility.
+
+        * css3/scroll-snap/scroll-snap-positions-mainframe.html:
+        * tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-mainframe-horizontal-legacy-expected.txt: Added.
+        * tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-mainframe-horizontal-legacy.html: Copied from LayoutTests/tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-mainframe-horizontal.html.
+        * tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-mainframe-horizontal.html:
+        * tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-mainframe-slow-horizontal.html:
+        * tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-mainframe-slow-vertical.html:
+        * tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-mainframe-vertical-legacy-expected.txt: Added.
+        * tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-mainframe-vertical-legacy.html: Copied from LayoutTests/tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-mainframe-vertical.html.
+        * tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-mainframe-vertical-then-horizontal.html:
+        * tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-mainframe-vertical.html:
+        * tiled-drawing/scrolling/scroll-snap/scroll-snap-proximity-mainframe-legacy-expected.txt: Added.
+        * tiled-drawing/scrolling/scroll-snap/scroll-snap-proximity-mainframe-legacy.html: Copied from LayoutTests/tiled-drawing/scrolling/scroll-snap/scroll-snap-proximity-mainframe.html.
+        * tiled-drawing/scrolling/scroll-snap/scroll-snap-proximity-mainframe.html:
+
</ins><span class="cx"> 2020-11-05  Alex Christensen  <achristensen@webkit.org>
</span><span class="cx"> 
</span><span class="cx">         Align GBK and gb18030 encoder and decoder with specification and other browsers
</span></span></pre></div>
<a id="trunkLayoutTestscss3scrollsnapscrollsnappositionsmainframehtml"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/css3/scroll-snap/scroll-snap-positions-mainframe.html (269505 => 269506)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/css3/scroll-snap/scroll-snap-positions-mainframe.html  2020-11-06 09:09:31 UTC (rev 269505)
+++ trunk/LayoutTests/css3/scroll-snap/scroll-snap-positions-mainframe.html     2020-11-06 09:44:54 UTC (rev 269506)
</span><span class="lines">@@ -1,11 +1,13 @@
</span><span class="cx"> <html>
</span><span class="cx"> <head>
</span><span class="cx">     <style>
</span><del>-        body {
</del><ins>+        html {
</ins><span class="cx">             margin: 0;
</span><span class="cx">             scroll-snap-type: y mandatory;
</span><span class="cx">         }
</span><del>-
</del><ins>+        body {
+            margin: 0;
+        }
</ins><span class="cx">         .vertical {
</span><span class="cx">             width: 100%;
</span><span class="cx">             height: 600px;
</span></span></pre></div>
<a id="trunkLayoutTeststileddrawingscrollingscrollsnapscrollsnapmandatorymainframehorizontallegacyexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-mainframe-horizontal-legacy-expected.txt (0 => 269506)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-mainframe-horizontal-legacy-expected.txt                             (rev 0)
+++ trunk/LayoutTests/tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-mainframe-horizontal-legacy-expected.txt        2020-11-06 09:44:54 UTC (rev 269506)
</span><span class="lines">@@ -0,0 +1,6 @@
</span><ins>+PASS div scrolled to next window.
+PASS div honored snap points.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTeststileddrawingscrollingscrollsnapscrollsnapmandatorymainframehorizontallegacyhtmlfromrev269505trunkLayoutTeststileddrawingscrollingscrollsnapscrollsnapmandatorymainframehorizontalhtml"></a>
<div class="copfile"><h4>Copied: trunk/LayoutTests/tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-mainframe-horizontal-legacy.html (from rev 269505, trunk/LayoutTests/tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-mainframe-horizontal.html) (0 => 269506)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-mainframe-horizontal-legacy.html                             (rev 0)
+++ trunk/LayoutTests/tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-mainframe-horizontal-legacy.html        2020-11-06 09:44:54 UTC (rev 269506)
</span><span class="lines">@@ -0,0 +1,119 @@
</span><ins>+<!DOCTYPE HTML>
+<html>
+    <head>
+        <style>
+            .horizontalGallery {
+                width: 600vw;
+                height: 100vh;
+                margin: 0;
+                padding: 0;
+                scroll-snap-type: x mandatory;
+            }
+            .colorBox {
+                height: 100vh;
+                width: 100vw;
+                float: left;
+                scroll-snap-align: start;
+            }
+            #item0 { background-color: red; }
+            #item1 { background-color: green; }
+            #item2 { background-color: blue; }
+            #item3 { background-color: aqua; }
+            #item4 { background-color: yellow; }
+            #item5 { background-color: fuchsia; }
+        </style>
+        <script src="../../../resources/js-test.js"></script>
+        <script>
+        window.jsTestIsAsync = true;
+
+        var targetScroller;
+        var scrollPositionBeforeGlide;
+        var scrollPositionBeforeSnap;
+
+        function checkForScrollSnap()
+        {
+            // The div should have snapped back to the previous position
+            if (targetScroller.scrollLeft != scrollPositionBeforeSnap)
+                testFailed("div did not snap back to proper location. Expected " + scrollPositionBeforeSnap + ", but got " + targetScroller.scrollLeft);
+            else
+                testPassed("div honored snap points.");
+
+            finishJSTest();
+        }
+
+        function scrollSnapTest()
+        {
+            scrollPositionBeforeSnap = targetScroller.scrollLeft;
+
+            var startPosX = targetScroller.offsetLeft + 20;
+            var startPosY = targetScroller.offsetTop + 20;
+            eventSender.monitorWheelEvents();
+            eventSender.mouseMoveTo(startPosX, startPosY); // Make sure we are just outside the iFrame
+            eventSender.mouseScrollByWithWheelAndMomentumPhases(-1, 0, 'began', 'none');
+            eventSender.mouseScrollByWithWheelAndMomentumPhases(-1, 0, 'changed', 'none');
+            eventSender.mouseScrollByWithWheelAndMomentumPhases(-1, 0, 'changed', 'none');
+            eventSender.mouseScrollByWithWheelAndMomentumPhases(0, 0, 'ended', 'none');
+            eventSender.callAfterScrollingCompletes(checkForScrollSnap);
+        }
+
+        function checkForScrollGlide()
+        {
+            // The div should have scrolled (glided) to the next snap point.
+            if (targetScroller.scrollLeft == window.innerWidth)
+                testPassed("div scrolled to next window.");
+            else
+                testFailed("div did not honor snap points. Expected " + window.innerWidth + ", but got " + targetScroller.scrollLeft);
+
+            setTimeout(scrollSnapTest, 0);
+        }
+
+        function scrollGlideTest()
+        {
+            scrollPositionBeforeGlide = targetScroller.scrollLeft;
+
+            var startPosX = targetScroller.offsetLeft + 20;
+            var startPosY = targetScroller.offsetTop + 20;
+            eventSender.monitorWheelEvents();
+            eventSender.mouseMoveTo(startPosX, startPosY); // Make sure we are just outside the iFrame
+            eventSender.mouseScrollByWithWheelAndMomentumPhases(-1, 0, 'began', 'none');
+            eventSender.mouseScrollByWithWheelAndMomentumPhases(-1, 0, 'changed', 'none');
+            eventSender.mouseScrollByWithWheelAndMomentumPhases(-1, 0, 'changed', 'none');
+            eventSender.mouseScrollByWithWheelAndMomentumPhases(-1, 0, 'changed', 'none');
+            eventSender.mouseScrollByWithWheelAndMomentumPhases(0, 0, 'ended', 'none');
+            eventSender.mouseScrollByWithWheelAndMomentumPhases(-1, 0, 'none', 'begin');
+            eventSender.mouseScrollByWithWheelAndMomentumPhases(-1, 0, 'none', 'continue');
+            eventSender.mouseScrollByWithWheelAndMomentumPhases(0, 0, 'none', 'end');
+            eventSender.callAfterScrollingCompletes(checkForScrollGlide);
+        }
+
+        function onLoad()
+        {
+            targetScroller = document.scrollingElement;
+            if (window.eventSender) {
+                internals.setPlatformMomentumScrollingPredictionEnabled(false);
+                setTimeout(scrollGlideTest, 0);
+            } else {
+                var messageLocation = document.getElementById('item0');
+                var message = document.createElement('div');
+                message.innerHTML = "<p>This test is better run under DumpRenderTree. To manually test it, place the mouse pointer<br/>"
+                    + "inside the red region at the top of the page, and then use the mouse wheel or a two-finger swipe to make a<br/>"
+                    + "small swipe gesture with some momentum.<br/><br/>"
+                    + "The region should scroll to show a green region.<br/><br/>"
+                    + "Next, perform a small scroll gesture that does not involve momentum. You should begin to see one of the colors<br/>"
+                    + "to the left (or right) of the current green box. When you release the wheel, the region should scroll back so<br/>"
+                    + "that the region is a single color.<br/><br/>"
+                    + "You should also be able to repeat these test steps for the vertical region below.</p>";
+                messageLocation.appendChild(message);
+            }
+        }
+        </script>
+    </head>
+    <body onload="onLoad();" class="horizontalGallery">
+        <div id="item0" class="colorBox"><div id="console"></div></div>
+        <div id="item1" class="colorBox"></div>
+        <div id="item2" class="colorBox"></div>
+        <div id="item3" class="colorBox"></div>
+        <div id="item4" class="colorBox"></div>
+        <div id="item5" class="colorBox"></div>
+    </body>
+</html>
</ins></span></pre></div>
<a id="trunkLayoutTeststileddrawingscrollingscrollsnapscrollsnapmandatorymainframehorizontalhtml"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-mainframe-horizontal.html (269505 => 269506)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-mainframe-horizontal.html    2020-11-06 09:09:31 UTC (rev 269505)
+++ trunk/LayoutTests/tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-mainframe-horizontal.html       2020-11-06 09:44:54 UTC (rev 269506)
</span><span class="lines">@@ -2,12 +2,14 @@
</span><span class="cx"> <html>
</span><span class="cx">     <head>
</span><span class="cx">         <style>
</span><ins>+            html {
+                scroll-snap-type: x mandatory;
+            }
</ins><span class="cx">             .horizontalGallery {
</span><span class="cx">                 width: 600vw;
</span><span class="cx">                 height: 100vh;
</span><span class="cx">                 margin: 0;
</span><span class="cx">                 padding: 0;
</span><del>-                scroll-snap-type: x mandatory;
</del><span class="cx">             }
</span><span class="cx">             .colorBox {
</span><span class="cx">                 height: 100vh;
</span></span></pre></div>
<a id="trunkLayoutTeststileddrawingscrollingscrollsnapscrollsnapmandatorymainframeslowhorizontalhtml"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-mainframe-slow-horizontal.html (269505 => 269506)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-mainframe-slow-horizontal.html       2020-11-06 09:09:31 UTC (rev 269505)
+++ trunk/LayoutTests/tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-mainframe-slow-horizontal.html  2020-11-06 09:44:54 UTC (rev 269506)
</span><span class="lines">@@ -2,12 +2,14 @@
</span><span class="cx"> <html>
</span><span class="cx">     <head>
</span><span class="cx">         <style>
</span><ins>+            html {
+                scroll-snap-type: x mandatory;
+            }
</ins><span class="cx">             .horizontalGallery {
</span><span class="cx">                 width: 600vw;
</span><span class="cx">                 height: 100vh;
</span><span class="cx">                 margin: 0;
</span><span class="cx">                 padding: 0;
</span><del>-                scroll-snap-type: x mandatory;
</del><span class="cx">             }
</span><span class="cx">             .colorBox {
</span><span class="cx">                 height: 100vh;
</span></span></pre></div>
<a id="trunkLayoutTeststileddrawingscrollingscrollsnapscrollsnapmandatorymainframeslowverticalhtml"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-mainframe-slow-vertical.html (269505 => 269506)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-mainframe-slow-vertical.html 2020-11-06 09:09:31 UTC (rev 269505)
+++ trunk/LayoutTests/tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-mainframe-slow-vertical.html    2020-11-06 09:44:54 UTC (rev 269506)
</span><span class="lines">@@ -2,12 +2,14 @@
</span><span class="cx"> <html>
</span><span class="cx">     <head>
</span><span class="cx">         <style>
</span><ins>+            html {
+                scroll-snap-type: y mandatory;
+            }
</ins><span class="cx">             .verticalGallery {
</span><span class="cx">                 width: 100vw;
</span><span class="cx">                 height: 600vh;
</span><span class="cx">                 margin: 0;
</span><span class="cx">                 padding: 0;
</span><del>-                scroll-snap-type: y mandatory;
</del><span class="cx">             }
</span><span class="cx">             .colorBox {
</span><span class="cx">                 height: 100vh;
</span></span></pre></div>
<a id="trunkLayoutTeststileddrawingscrollingscrollsnapscrollsnapmandatorymainframeverticallegacyexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-mainframe-vertical-legacy-expected.txt (0 => 269506)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-mainframe-vertical-legacy-expected.txt                               (rev 0)
+++ trunk/LayoutTests/tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-mainframe-vertical-legacy-expected.txt  2020-11-06 09:44:54 UTC (rev 269506)
</span><span class="lines">@@ -0,0 +1,6 @@
</span><ins>+PASS div scrolled to next window.
+PASS div honored snap points.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTeststileddrawingscrollingscrollsnapscrollsnapmandatorymainframeverticallegacyhtmlfromrev269505trunkLayoutTeststileddrawingscrollingscrollsnapscrollsnapmandatorymainframeverticalhtml"></a>
<div class="copfile"><h4>Copied: trunk/LayoutTests/tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-mainframe-vertical-legacy.html (from rev 269505, trunk/LayoutTests/tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-mainframe-vertical.html) (0 => 269506)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-mainframe-vertical-legacy.html                               (rev 0)
+++ trunk/LayoutTests/tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-mainframe-vertical-legacy.html  2020-11-06 09:44:54 UTC (rev 269506)
</span><span class="lines">@@ -0,0 +1,119 @@
</span><ins>+<!DOCTYPE HTML>
+<html>
+    <head>
+        <style>
+            .verticalGallery {
+                width: 100vw;
+                height: 600vh;
+                margin: 0;
+                padding: 0;
+                scroll-snap-type: y mandatory;
+            }
+            .colorBox {
+                height: 100vh;
+                width: 100vw;
+                float: left;
+                scroll-snap-align: start;
+            }
+            #item0 { background-color: red; }
+            #item1 { background-color: green; }
+            #item2 { background-color: blue; }
+            #item3 { background-color: aqua; }
+            #item4 { background-color: yellow; }
+            #item5 { background-color: fuchsia; }
+        </style>
+        <script src="../../../resources/js-test.js"></script>
+        <script>
+        window.jsTestIsAsync = true;
+
+        var scrollingTarget;
+        var scrollPositionBeforeGlide;
+        var scrollPositionBeforeSnap;
+
+        function checkForScrollSnap()
+        {
+            // The div should have snapped back to the previous position
+            if (scrollingTarget.scrollTop != scrollPositionBeforeSnap)
+                testFailed(`div did not snap back to proper location. (${scrollingTarget.scrollTop} vs. ${scrollPositionBeforeSnap})`);
+            else
+                testPassed("div honored snap points.");
+
+            finishJSTest();
+        }
+
+        function scrollSnapTest()
+        {
+            scrollPositionBeforeSnap = scrollingTarget.scrollTop;
+
+            var startPosX = scrollingTarget.offsetLeft + 20;
+            var startPosY = scrollingTarget.offsetTop + 20;
+            eventSender.monitorWheelEvents();
+            eventSender.mouseMoveTo(startPosX, startPosY); // Make sure we are just outside the iFrame
+            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.callAfterScrollingCompletes(checkForScrollSnap);
+        }
+
+        function checkForScrollGlide()
+        {
+            // The div should have scrolled (glided) to the next snap point.
+            if (scrollingTarget.scrollTop == window.innerHeight)
+                testPassed("div scrolled to next window.");
+            else
+                testFailed(`div did not honor snap points. (${scrollingTarget.scrollTop} vs. ${window.innerHeight})`);
+
+            setTimeout(scrollSnapTest, 0);
+        }
+
+        function scrollGlideTest()
+        {
+            scrollPositionBeforeGlide = scrollingTarget.scrollTop;
+
+            var startPosX = scrollingTarget.offsetLeft + 20;
+            var startPosY = scrollingTarget.offsetTop + 20;
+            eventSender.monitorWheelEvents();
+            eventSender.mouseMoveTo(startPosX, startPosY); // Make sure we are just outside the iFrame
+            eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'began', 'none');
+            eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'changed', '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, -4, 'none', 'continue');
+            eventSender.mouseScrollByWithWheelAndMomentumPhases(0, 0, 'none', 'end');
+            eventSender.callAfterScrollingCompletes(checkForScrollGlide);
+        }
+
+        function onLoad()
+        {
+            scrollingTarget = document.scrollingElement;
+            if (window.eventSender) {
+                internals.setPlatformMomentumScrollingPredictionEnabled(false);
+                setTimeout(scrollGlideTest, 0);
+            } else {
+                var messageLocation = document.getElementById('item0');
+                var message = document.createElement('div');
+                message.innerHTML = "<p>This test is better run under DumpRenderTree. To manually test it, place the mouse pointer<br/>"
+                    + "inside the red region at the top of the page, and then use the mouse wheel or a two-finger swipe to make a<br/>"
+                    + "small swipe gesture with some momentum.<br/><br/>"
+                    + "The region should scroll to show a green region.<br/><br/>"
+                    + "Next, perform a small scroll gesture that does not involve momentum. You should begin to see one of the colors<br/>"
+                    + "to the left (or right) of the current green box. When you release the wheel, the region should scroll back so<br/>"
+                    + "that the region is a single color.<br/><br/>"
+                    + "You should also be able to repeat these test steps for the vertical region below.</p>";
+                messageLocation.appendChild(message);
+            }
+        }
+        </script>
+    </head>
+    <body onload="onLoad();" class="verticalGallery">
+        <div id="item0" class="colorBox"><div id="console"></div></div>
+        <div id="item1" class="colorBox"></div>
+        <div id="item2" class="colorBox"></div>
+        <div id="item3" class="colorBox"></div>
+        <div id="item4" class="colorBox"></div>
+        <div id="item5" class="colorBox"></div>
+    </body>
+</html>
</ins></span></pre></div>
<a id="trunkLayoutTeststileddrawingscrollingscrollsnapscrollsnapmandatorymainframeverticalthenhorizontalhtml"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-mainframe-vertical-then-horizontal.html (269505 => 269506)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-mainframe-vertical-then-horizontal.html      2020-11-06 09:09:31 UTC (rev 269505)
+++ trunk/LayoutTests/tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-mainframe-vertical-then-horizontal.html 2020-11-06 09:44:54 UTC (rev 269506)
</span><span class="lines">@@ -2,12 +2,14 @@
</span><span class="cx"> <html>
</span><span class="cx">     <head>
</span><span class="cx">         <style>
</span><ins>+            html {
+                scroll-snap-type: y mandatory;
+            }
</ins><span class="cx">             .verticalGallery {
</span><span class="cx">                 width: 100vw;
</span><span class="cx">                 height: 600vh;
</span><span class="cx">                 margin: 0;
</span><span class="cx">                 padding: 0;
</span><del>-                scroll-snap-type: y mandatory;
</del><span class="cx">             }
</span><span class="cx">             .colorBox {
</span><span class="cx">                 height: 100vh;
</span></span></pre></div>
<a id="trunkLayoutTeststileddrawingscrollingscrollsnapscrollsnapmandatorymainframeverticalhtml"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-mainframe-vertical.html (269505 => 269506)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-mainframe-vertical.html      2020-11-06 09:09:31 UTC (rev 269505)
+++ trunk/LayoutTests/tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-mainframe-vertical.html 2020-11-06 09:44:54 UTC (rev 269506)
</span><span class="lines">@@ -2,12 +2,14 @@
</span><span class="cx"> <html>
</span><span class="cx">     <head>
</span><span class="cx">         <style>
</span><ins>+            html {
+                scroll-snap-type: y mandatory;
+            }
</ins><span class="cx">             .verticalGallery {
</span><span class="cx">                 width: 100vw;
</span><span class="cx">                 height: 600vh;
</span><span class="cx">                 margin: 0;
</span><span class="cx">                 padding: 0;
</span><del>-                scroll-snap-type: y mandatory;
</del><span class="cx">             }
</span><span class="cx">             .colorBox {
</span><span class="cx">                 height: 100vh;
</span></span></pre></div>
<a id="trunkLayoutTeststileddrawingscrollingscrollsnapscrollsnapproximitymainframelegacyexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/tiled-drawing/scrolling/scroll-snap/scroll-snap-proximity-mainframe-legacy-expected.txt (0 => 269506)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/tiled-drawing/scrolling/scroll-snap/scroll-snap-proximity-mainframe-legacy-expected.txt                                (rev 0)
+++ trunk/LayoutTests/tiled-drawing/scrolling/scroll-snap/scroll-snap-proximity-mainframe-legacy-expected.txt   2020-11-06 09:44:54 UTC (rev 269506)
</span><span class="lines">@@ -0,0 +1,10 @@
</span><ins>+Scrolling body with 2 drag ticks
+- Did the scrolling snap to the top? YES
+- Did scrolling snap to the second box? NO
+Scrolling body with 30 drag ticks
+- Did the scrolling snap to the top? NO
+- Did scrolling snap to the second box? NO
+Scrolling body with 60 drag ticks
+- Did the scrolling snap to the top? NO
+- Did scrolling snap to the second box? YES
+
</ins></span></pre></div>
<a id="trunkLayoutTeststileddrawingscrollingscrollsnapscrollsnapproximitymainframelegacyhtmlfromrev269505trunkLayoutTeststileddrawingscrollingscrollsnapscrollsnapproximitymainframehtml"></a>
<div class="copfile"><h4>Copied: trunk/LayoutTests/tiled-drawing/scrolling/scroll-snap/scroll-snap-proximity-mainframe-legacy.html (from rev 269505, trunk/LayoutTests/tiled-drawing/scrolling/scroll-snap/scroll-snap-proximity-mainframe.html) (0 => 269506)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/tiled-drawing/scrolling/scroll-snap/scroll-snap-proximity-mainframe-legacy.html                                (rev 0)
+++ trunk/LayoutTests/tiled-drawing/scrolling/scroll-snap/scroll-snap-proximity-mainframe-legacy.html   2020-11-06 09:44:54 UTC (rev 269506)
</span><span class="lines">@@ -0,0 +1,78 @@
</span><ins>+<!DOCTYPE HTML>
+<html>
+    <head>
+        <style>
+            body {
+                margin: 0;
+                width: 100%;
+                height: 100%;
+                overflow-x: none;
+                overflow-y: scroll;
+                position: absolute;
+                scroll-snap-type: y proximity;
+            }
+
+            .area {
+                width: 100%;
+                height: 100%;
+                float: left;
+                opacity: 0.5;
+                scroll-snap-align: start;
+            }
+
+            #output {
+                position: fixed;
+            }
+        </style>
+        <script>
+        let write = s => output.innerHTML += s + "<br>";
+        if (window.testRunner) {
+            testRunner.dumpAsText();
+            testRunner.waitUntilDone();
+        }
+
+        function verticalScrollInBody(dragDeltas)
+        {
+            return new Promise(resolve => {
+                write(`Scrolling body with ${dragDeltas.length} drag ticks`);
+                eventSender.monitorWheelEvents();
+                internals.setPlatformMomentumScrollingPredictionEnabled(false);
+                eventSender.mouseMoveTo(window.innerWidth / 2, window.innerHeight / 2);
+                dragDeltas.forEach((delta, i) => eventSender.mouseScrollByWithWheelAndMomentumPhases(0, delta, i == 0 ? "began" : "changed", "none"));
+                eventSender.mouseScrollByWithWheelAndMomentumPhases(0, 0, "ended", "none");
+                eventSender.callAfterScrollingCompletes(() => {
+                    let areaHeight = document.querySelector(".area").clientHeight;
+                    write(`- Did the scrolling snap to the top? ${document.scrollingElement.scrollTop == 0 ? "YES" : "NO"}`);
+                    write(`- Did scrolling snap to the second box? ${document.scrollingElement.scrollTop == areaHeight ? "YES" : "NO"}`);
+                    document.scrollingElement.scrollTop = 0;
+                    setTimeout(resolve, 0);
+                });
+            });
+        }
+
+        function run() {
+            if (!window.testRunner || !window.eventSender) {
+                write("To manually test, verify that scrolling near one of the boundaries between the colored boxes");
+                write("snaps to the edge of the nearest colored box, but scrolling somewhere near the middle of two");
+                write("boxes does not cause the scroll offset to snap.");
+                return;
+            }
+
+            let areaHeight = document.querySelector(".area").clientHeight;
+            verticalScrollInBody(new Array(2).fill(-1))
+                .then(() => verticalScrollInBody(new Array(Math.round(areaHeight / 20)).fill(-1)))
+                .then(() => verticalScrollInBody(new Array(Math.round(areaHeight / 10)).fill(-1)))
+                .then(() => testRunner.notifyDone());
+        }
+        </script>
+    </head>
+    <body onload=run()>
+        <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>
+    </body>
+    <div id="output"></div>
+</html>
</ins></span></pre></div>
<a id="trunkLayoutTeststileddrawingscrollingscrollsnapscrollsnapproximitymainframehtml"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/tiled-drawing/scrolling/scroll-snap/scroll-snap-proximity-mainframe.html (269505 => 269506)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/tiled-drawing/scrolling/scroll-snap/scroll-snap-proximity-mainframe.html       2020-11-06 09:09:31 UTC (rev 269505)
+++ trunk/LayoutTests/tiled-drawing/scrolling/scroll-snap/scroll-snap-proximity-mainframe.html  2020-11-06 09:44:54 UTC (rev 269506)
</span><span class="lines">@@ -2,6 +2,9 @@
</span><span class="cx"> <html>
</span><span class="cx">     <head>
</span><span class="cx">         <style>
</span><ins>+            html {
+                scroll-snap-type: y proximity;
+            }
</ins><span class="cx">             body {
</span><span class="cx">                 margin: 0;
</span><span class="cx">                 width: 100%;
</span><span class="lines">@@ -9,9 +12,6 @@
</span><span class="cx">                 overflow-x: none;
</span><span class="cx">                 overflow-y: scroll;
</span><span class="cx">                 position: absolute;
</span><del>-                scroll-snap-type: y proximity;
-                -webkit-scroll-snap-type: proximity;
-                scroll-snap-type: proximity;
</del><span class="cx">             }
</span><span class="cx"> 
</span><span class="cx">             .area {
</span><span class="lines">@@ -20,8 +20,6 @@
</span><span class="cx">                 float: left;
</span><span class="cx">                 opacity: 0.5;
</span><span class="cx">                 scroll-snap-align: start;
</span><del>-                -webkit-scroll-snap-coordinate: 0 0;
-                scroll-snap-coordinate: 0 0;
</del><span class="cx">             }
</span><span class="cx"> 
</span><span class="cx">             #output {
</span></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (269505 => 269506)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog   2020-11-06 09:09:31 UTC (rev 269505)
+++ trunk/Source/WebCore/ChangeLog      2020-11-06 09:44:54 UTC (rev 269506)
</span><span class="lines">@@ -1,3 +1,43 @@
</span><ins>+2020-11-06  Martin Robinson  <mrobinson@igalia.com>
+
+        Scroll snap specified on :root doesn't work
+        https://bugs.webkit.org/show_bug.cgi?id=210469
+        <rdar://problem/61746676>
+
+        Properly handle scroll-snap-type on the root element.
+
+        This change is originally based on a patch by Simon Fraser.
+
+        Reviewed by Simon Fraser.
+
+        Tests: tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-mainframe-horizontal-legacy.html
+               tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-mainframe-vertical-legacy.html
+               tiled-drawing/scrolling/scroll-snap/scroll-snap-proximity-mainframe-legacy.html
+
+        * page/FrameView.cpp:
+        (WebCore::FrameView::updateSnapOffsets): Send the body or root element style depending
+        on where the scroll-snap properties are set, but always use the FrameView viewport
+        when calculating geometry for scroll snap.
+        * page/scrolling/AxisScrollSnapOffsets.cpp:
+        (WebCore::updateSnapOffsetsForScrollableArea): Accept a viewport rectangle from the
+        caller and also eliminate redundant argument that was causing a bit of confusion.
+        * page/scrolling/AxisScrollSnapOffsets.h: Update the function declaration.
+        * platform/ScrollableArea.cpp:
+        (WebCore::ScrollableArea::clearSnapOffsets):  Added a helper to clear both vertical and horizontal snap info.
+        * platform/ScrollableArea.h:
+        * rendering/RenderBox.cpp:
+        (WebCore::RenderBox::findEnclosingScrollableContainerForSnapping const): Renamed findEnclosingScrollableContainer
+        to this because now it is only useful for scroll snapping. The only preexisting caller was
+        the scroll snap code.
+        (WebCore::RenderBox::findEnclosingScrollableContainer const): Deleted.
+        * rendering/RenderBox.h: Updated method name.
+        * rendering/RenderLayer.cpp:
+        (WebCore::RenderLayer::updateSnapOffsets): Update to reflect changes to updateSnapOffsetsForScrollableArea.
+        * rendering/RenderObject.cpp:
+        (WebCore::RenderObject::enclosingScrollableContainerForSnapping const): Always return the
+        document root as the container instead of the body. The body never captures scroll
+        snap points.
+
</ins><span class="cx"> 2020-11-05  Said Abou-Hallawa  <said@apple.com>
</span><span class="cx"> 
</span><span class="cx">         [GPU Process] Use the Ref counting of ImageBuffer to control its life cycle in Web Process and GPU Process
</span></span></pre></div>
<a id="trunkSourceWebCorepageFrameViewcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/page/FrameView.cpp (269505 => 269506)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/page/FrameView.cpp  2020-11-06 09:09:31 UTC (rev 269505)
+++ trunk/Source/WebCore/page/FrameView.cpp     2020-11-06 09:44:54 UTC (rev 269506)
</span><span class="lines">@@ -919,12 +919,30 @@
</span><span class="cx">     if (!frame().document())
</span><span class="cx">         return;
</span><span class="cx"> 
</span><del>-    // FIXME: Should we allow specifying snap points through <html> tags too?
-    HTMLElement* body = frame().document()->bodyOrFrameset();
-    if (!renderView() || !body || !body->renderer())
</del><ins>+    auto& document = *frame().document();
+    auto* documentElement = document.documentElement();
+    RenderBox* bodyRenderer = document.bodyOrFrameset() ? document.bodyOrFrameset()->renderBox() : nullptr;
+    RenderBox* rootRenderer = documentElement ? documentElement->renderBox() : nullptr;
+    auto rendererSyleHasScrollSnap = [](const RenderObject* renderer) {
+        return renderer && renderer->style().scrollSnapType().strictness != ScrollSnapStrictness::None;
+    };
+
+    const RenderStyle* styleToUse = nullptr;
+    if (rendererSyleHasScrollSnap(bodyRenderer)) {
+        //  The specification doesn't allow setting scroll-snap-type on the body, but
+        //  we do this to ensure backwards compatibility with an earlier version of the
+        //  specification: See webkit.org/b/200643.
+        styleToUse = &bodyRenderer->style();
+    } else if (rendererSyleHasScrollSnap(rootRenderer))
+        styleToUse = &rootRenderer->style();
+
+    if (!styleToUse || !documentElement) {
+        clearSnapOffsets();
</ins><span class="cx">         return;
</span><del>-    
-    updateSnapOffsetsForScrollableArea(*this, *body, *renderView(), body->renderer()->style());
</del><ins>+    }
+
+    LayoutRect viewport = LayoutRect(IntPoint(), baseLayoutViewportSize());
+    updateSnapOffsetsForScrollableArea(*this, *rootRenderer, *styleToUse, viewport);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> bool FrameView::isScrollSnapInProgress() const
</span></span></pre></div>
<a id="trunkSourceWebCorepagescrollingAxisScrollSnapOffsetscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/page/scrolling/AxisScrollSnapOffsets.cpp (269505 => 269506)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/page/scrolling/AxisScrollSnapOffsets.cpp    2020-11-06 09:09:31 UTC (rev 269505)
+++ trunk/Source/WebCore/page/scrolling/AxisScrollSnapOffsets.cpp       2020-11-06 09:44:54 UTC (rev 269506)
</span><span class="lines">@@ -160,13 +160,12 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void updateSnapOffsetsForScrollableArea(ScrollableArea& scrollableArea, HTMLElement& scrollingElement, const RenderBox& scrollingElementBox, const RenderStyle& scrollingElementStyle)
</del><ins>+void updateSnapOffsetsForScrollableArea(ScrollableArea& scrollableArea, const RenderBox& scrollingElementBox, const RenderStyle& scrollingElementStyle, LayoutRect viewportRectInBorderBoxCoordinates)
</ins><span class="cx"> {
</span><del>-    auto* scrollContainer = scrollingElement.renderer();
</del><span class="cx">     auto scrollSnapType = scrollingElementStyle.scrollSnapType();
</span><del>-    if (!scrollContainer || scrollSnapType.strictness == ScrollSnapStrictness::None || scrollContainer->view().boxesWithScrollSnapPositions().isEmpty()) {
-        scrollableArea.clearHorizontalSnapOffsets();
-        scrollableArea.clearVerticalSnapOffsets();
</del><ins>+    const auto& boxesWithScrollSnapPositions = scrollingElementBox.view().boxesWithScrollSnapPositions();
+    if (scrollSnapType.strictness == ScrollSnapStrictness::None || boxesWithScrollSnapPositions.isEmpty()) {
+        scrollableArea.clearSnapOffsets();
</ins><span class="cx">         return;
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="lines">@@ -184,16 +183,16 @@
</span><span class="cx">     bool scrollerIsRTL = !scrollingElementBox.style().isLeftToRightDirection();
</span><span class="cx"> 
</span><span class="cx">     // The bounds of the scrolling container's snap port, where the top left of the scrolling container's border box is the origin.
</span><del>-    auto scrollSnapPort = computeScrollSnapPortOrAreaRect(scrollingElementBox.paddingBoxRect(), scrollingElementStyle.scrollPadding(), InsetOrOutset::Inset);
</del><ins>+    auto scrollSnapPort = computeScrollSnapPortOrAreaRect(viewportRectInBorderBoxCoordinates, scrollingElementStyle.scrollPadding(), InsetOrOutset::Inset);
</ins><span class="cx">     LOG_WITH_STREAM(ScrollSnap, stream << "Computing scroll snap offsets for " << scrollableArea << " in snap port " << scrollSnapPort);
</span><del>-    for (auto* child : scrollContainer->view().boxesWithScrollSnapPositions()) {
-        if (child->enclosingScrollableContainerForSnapping() != scrollContainer)
</del><ins>+    for (auto* child : boxesWithScrollSnapPositions) {
+        if (child->enclosingScrollableContainerForSnapping() != &scrollingElementBox)
</ins><span class="cx">             continue;
</span><span class="cx"> 
</span><span class="cx">         // The bounds of the child element's snap area, where the top left of the scrolling container's border box is the origin.
</span><span class="cx">         // The snap area is the bounding box of the child element's border box, after applying transformations.
</span><span class="cx">         // FIXME: For now, just consider whether the scroller is RTL. The behavior of LTR boxes inside a RTL scroller is poorly defined: https://github.com/w3c/csswg-drafts/issues/5361.
</span><del>-        auto scrollSnapArea = LayoutRect(child->localToContainerQuad(FloatQuad(child->borderBoundingBox()), scrollingElement.renderBox()).boundingBox());
</del><ins>+        auto scrollSnapArea = LayoutRect(child->localToContainerQuad(FloatQuad(child->borderBoundingBox()), &scrollingElementBox).boundingBox());
</ins><span class="cx"> 
</span><span class="cx">         // localToContainerQuad will transform the scroll snap area by the scroll position, except in the case that this position is
</span><span class="cx">         // coming from a ScrollView. We want the transformed area, but without scroll position taken into account.
</span></span></pre></div>
<a id="trunkSourceWebCorepagescrollingAxisScrollSnapOffsetsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/page/scrolling/AxisScrollSnapOffsets.h (269505 => 269506)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/page/scrolling/AxisScrollSnapOffsets.h      2020-11-06 09:09:31 UTC (rev 269505)
+++ trunk/Source/WebCore/page/scrolling/AxisScrollSnapOffsets.h 2020-11-06 09:44:54 UTC (rev 269506)
</span><span class="lines">@@ -27,6 +27,7 @@
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(CSS_SCROLL_SNAP)
</span><span class="cx"> 
</span><ins>+#include "LayoutRect.h"
</ins><span class="cx"> #include "LayoutUnit.h"
</span><span class="cx"> #include "ScrollSnapOffsetsInfo.h"
</span><span class="cx"> #include "ScrollTypes.h"
</span><span class="lines">@@ -39,7 +40,10 @@
</span><span class="cx"> class RenderStyle;
</span><span class="cx"> class ScrollableArea;
</span><span class="cx"> 
</span><del>-void updateSnapOffsetsForScrollableArea(ScrollableArea&, HTMLElement& scrollingElement, const RenderBox& scrollingElementBox, const RenderStyle& scrollingElementStyle);
</del><ins>+// Update the snap offsets for this scrollable area, given the RenderBox of the scroll container, the RenderStyle
+// which defines the scroll-snap properties, and the viewport rectangle with the origin at the top left of
+// the scrolling container's border box.
+void updateSnapOffsetsForScrollableArea(ScrollableArea&, const RenderBox& scrollingElementBox, const RenderStyle& scrollingElementStyle, LayoutRect viewportRectInBorderBoxCoordinates);
</ins><span class="cx"> 
</span><span class="cx"> const unsigned invalidSnapOffsetIndex = UINT_MAX;
</span><span class="cx"> WEBCORE_EXPORT LayoutUnit closestSnapOffset(const Vector<LayoutUnit>& snapOffsets, const Vector<ScrollOffsetRange<LayoutUnit>>& snapOffsetRanges, LayoutUnit scrollDestination, float velocity, unsigned& activeSnapIndex);
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformScrollableAreacpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/ScrollableArea.cpp (269505 => 269506)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/ScrollableArea.cpp 2020-11-06 09:09:31 UTC (rev 269505)
+++ trunk/Source/WebCore/platform/ScrollableArea.cpp    2020-11-06 09:44:54 UTC (rev 269506)
</span><span class="lines">@@ -530,6 +530,12 @@
</span><span class="cx">     ensureSnapOffsetsInfo().verticalSnapOffsetRanges = verticalRanges;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void ScrollableArea::clearSnapOffsets()
+{
+    clearHorizontalSnapOffsets();
+    clearVerticalSnapOffsets();
+}
+
</ins><span class="cx"> void ScrollableArea::clearHorizontalSnapOffsets()
</span><span class="cx"> {
</span><span class="cx">     if (!m_snapOffsetsInfo)
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformScrollableAreah"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/ScrollableArea.h (269505 => 269506)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/ScrollableArea.h   2020-11-06 09:09:31 UTC (rev 269505)
+++ trunk/Source/WebCore/platform/ScrollableArea.h      2020-11-06 09:44:54 UTC (rev 269506)
</span><span class="lines">@@ -96,6 +96,7 @@
</span><span class="cx">     void setVerticalSnapOffsets(const Vector<LayoutUnit>&);
</span><span class="cx">     void setHorizontalSnapOffsetRanges(const Vector<ScrollOffsetRange<LayoutUnit>>&);
</span><span class="cx">     void setVerticalSnapOffsetRanges(const Vector<ScrollOffsetRange<LayoutUnit>>&);
</span><ins>+    void clearSnapOffsets();
</ins><span class="cx">     void clearHorizontalSnapOffsets();
</span><span class="cx">     void clearVerticalSnapOffsets();
</span><span class="cx">     unsigned currentHorizontalSnapPointIndex() const { return m_currentHorizontalSnapPointIndex; }
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderBoxcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderBox.cpp (269505 => 269506)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderBox.cpp     2020-11-06 09:09:31 UTC (rev 269505)
+++ trunk/Source/WebCore/rendering/RenderBox.cpp        2020-11-06 09:44:54 UTC (rev 269506)
</span><span class="lines">@@ -5033,17 +5033,18 @@
</span><span class="cx">     return containerBlock->offsetFromLogicalTopOfFirstPage() + logicalTop();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-const RenderBox* RenderBox::findEnclosingScrollableContainer() const
</del><ins>+const RenderBox* RenderBox::findEnclosingScrollableContainerForSnapping() const
</ins><span class="cx"> {
</span><span class="cx">     for (auto& candidate : lineageOfType<RenderBox>(*this)) {
</span><span class="cx">         if (candidate.hasOverflowClip())
</span><span class="cx">             return &candidate;
</span><span class="cx">     }
</span><del>-    // If all parent elements are not overflow scrollable, check the body.
-    // FIXME: We should not treat the body as the scrollable element (see webkit.org/b/210469).
-    if (document().body() && frame().view() && frame().view()->isScrollable())
-        return document().body()->renderBox();
-    
</del><ins>+
+    // If all parent elements are not overflow scrollable and the frame is, then return
+    // the root element.
+    if (document().documentElement() && frame().view() && frame().view()->isScrollable())
+        return document().documentElement()->renderBox();
+
</ins><span class="cx">     return nullptr;
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderBoxh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderBox.h (269505 => 269506)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderBox.h       2020-11-06 09:09:31 UTC (rev 269505)
+++ trunk/Source/WebCore/rendering/RenderBox.h  2020-11-06 09:44:54 UTC (rev 269506)
</span><span class="lines">@@ -637,7 +637,7 @@
</span><span class="cx">     bool canHaveOutsideFragmentRange() const { return !isInFlowRenderFragmentedFlow(); }
</span><span class="cx">     virtual bool needsLayoutAfterFragmentRangeChange() const { return false; }
</span><span class="cx"> 
</span><del>-    const RenderBox* findEnclosingScrollableContainer() const;
</del><ins>+    const RenderBox* findEnclosingScrollableContainerForSnapping() const;
</ins><span class="cx">     
</span><span class="cx">     bool isGridItem() const { return parent() && parent()->isRenderGrid() && !isExcludedFromNormalLayout(); }
</span><span class="cx">     bool isFlexItem() const { return parent() && parent()->isFlexibleBox() && !isExcludedFromNormalLayout(); }
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderLayercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderLayer.cpp (269505 => 269506)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderLayer.cpp   2020-11-06 09:09:31 UTC (rev 269505)
+++ trunk/Source/WebCore/rendering/RenderLayer.cpp      2020-11-06 09:44:54 UTC (rev 269506)
</span><span class="lines">@@ -3592,7 +3592,7 @@
</span><span class="cx">         return;
</span><span class="cx"> 
</span><span class="cx">     RenderBox* box = enclosingElement()->renderBox();
</span><del>-    updateSnapOffsetsForScrollableArea(*this, *downcast<HTMLElement>(enclosingElement()), *box, box->style());
</del><ins>+    updateSnapOffsetsForScrollableArea(*this, *box, box->style(), box->paddingBoxRect());
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> bool RenderLayer::isScrollSnapInProgress() const
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderObjectcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderObject.cpp (269505 => 269506)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderObject.cpp  2020-11-06 09:09:31 UTC (rev 269505)
+++ trunk/Source/WebCore/rendering/RenderObject.cpp     2020-11-06 09:44:54 UTC (rev 269506)
</span><span class="lines">@@ -455,12 +455,12 @@
</span><span class="cx"> const RenderBox* RenderObject::enclosingScrollableContainerForSnapping() const
</span><span class="cx"> {
</span><span class="cx">     auto& renderBox = enclosingBox();
</span><del>-    if (auto* scrollableContainer = renderBox.findEnclosingScrollableContainer()) {
</del><ins>+    if (auto* scrollableContainer = renderBox.findEnclosingScrollableContainerForSnapping()) {
</ins><span class="cx">         // The scrollable container for snapping cannot be the node itself.
</span><span class="cx">         if (scrollableContainer != this)
</span><span class="cx">             return scrollableContainer;
</span><span class="cx">         if (renderBox.parentBox())
</span><del>-            return renderBox.parentBox()->findEnclosingScrollableContainer();
</del><ins>+            return renderBox.parentBox()->findEnclosingScrollableContainerForSnapping();
</ins><span class="cx">     }
</span><span class="cx">     return nullptr;
</span><span class="cx"> }
</span></span></pre>
</div>
</div>

</body>
</html>