<!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>[183906] 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/183906">183906</a></dd>
<dt>Author</dt> <dd>bfulgham@apple.com</dd>
<dt>Date</dt> <dd>2015-05-06 19:53:00 -0700 (Wed, 06 May 2015)</dd>
</dl>

<h3>Log Message</h3>
<pre>Scroll-snap points do not handle margins and padding propertly
https://bugs.webkit.org/show_bug.cgi?id=144647
&lt;rdar://problem/20829473&gt;

Reviewed by Simon Fraser.

Source/WebCore:

The calculation of scroll snap points was incorrect because it did not account for margins or padding.
This was fixed by using the &quot;paddingBoxRect&quot; to represent the overall size of the view area, and
subtracting the relevant padding when computing the size of the scroll snap offsets.

Extend testing internals with accessor methods to retrieve string representations of the scroll snap
offsets and scroll snap coordinates computed during layout. These values are used in the new
'css3/scroll-snap/scroll-snap-offsets-and-coordinates.html' test.

New tests:
* css3/scroll-snap/scroll-snap-offsets-and-coordinates.html: Added.
* platform/mac-wk2/tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-borders.html: Added.
* platform/mac-wk2/tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-padding.html: Added.
* platform/mac-wk2/tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-rotated.html: Added.

* css/LengthFunctions.h: Expose the 'valueForLength' method so we can use it in WebCoreTestSupport.
* dom/Node.h: Expose the 'renderBox' method so we can use it in WebCoreTestSupport.
* page/scrolling/AxisScrollSnapOffsets.cpp:
(WebCore::appendChildSnapOffsets): Use 'contentBoxRect' for overall size, so that we don't use padding
as part of our offset calculations.
(WebCore::updateSnapOffsetsForScrollableArea): Ditto.
* rendering/RenderBox.h: Expose 'canBeScrolledAndHasScrollableArea' for use in WebCoreTestSupport.
* rendering/style/RenderStyle.h: Expose 'scrollSnapCoordinates' for use in WebCoreTestSupport.
* testing/Internals.cpp:
(WebCore::appendOffsets): Helper function.
(WebCore::Internals::scrollSnapOffsets): Added.
* testing/Internals.h:
* testing/Internals.idl:

LayoutTests:

Add new scroll-snap tests that cover elements with borders, padding, and rotation. Also correct the
cause of the 'scroll-snap-mandatory-overflow.html' test flakiness by making sure the mouse is always
inside the element when starting new wheel gestures.

Also add a new 'generic' test that confirms that we have expected results for scroll-snap coordinates
and calculated scroll-snap-offset values.
 
* css3/scroll-snap/scroll-snap-offsets.html: Added.
* platform/mac-wk2/TestExpectations: Remove flakiness annotation for scroll-snap-mandatory-overflow.
* platform/mac-wk2/tiled-drawing/scrolling/scroll-snap/scroll-snap-iframe.html:
* platform/mac-wk2/tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-borders-expected.txt: Added.
* platform/mac-wk2/tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-borders.html: Added.
* platform/mac-wk2/tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-overflow.html:
* platform/mac-wk2/tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-padding-expected.txt: Added.
* platform/mac-wk2/tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-padding.html: Added.
* platform/mac-wk2/tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-rotated-expected.txt: Added.
* platform/mac-wk2/tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-rotated.html: Added.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkLayoutTestsplatformmacwk2TestExpectations">trunk/LayoutTests/platform/mac-wk2/TestExpectations</a></li>
<li><a href="#trunkLayoutTestsplatformmacwk2tileddrawingscrollingscrollsnapscrollsnapiframehtml">trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/scroll-snap/scroll-snap-iframe.html</a></li>
<li><a href="#trunkLayoutTestsplatformmacwk2tileddrawingscrollingscrollsnapscrollsnapmandatoryoverflowhtml">trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-overflow.html</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCorecssLengthFunctionsh">trunk/Source/WebCore/css/LengthFunctions.h</a></li>
<li><a href="#trunkSourceWebCoredomNodeh">trunk/Source/WebCore/dom/Node.h</a></li>
<li><a href="#trunkSourceWebCorepagescrollingAxisScrollSnapOffsetscpp">trunk/Source/WebCore/page/scrolling/AxisScrollSnapOffsets.cpp</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderBoxh">trunk/Source/WebCore/rendering/RenderBox.h</a></li>
<li><a href="#trunkSourceWebCorerenderingstyleRenderStyleh">trunk/Source/WebCore/rendering/style/RenderStyle.h</a></li>
<li><a href="#trunkSourceWebCoretestingInternalscpp">trunk/Source/WebCore/testing/Internals.cpp</a></li>
<li><a href="#trunkSourceWebCoretestingInternalsh">trunk/Source/WebCore/testing/Internals.h</a></li>
<li><a href="#trunkSourceWebCoretestingInternalsidl">trunk/Source/WebCore/testing/Internals.idl</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestscss3scrollsnapscrollsnapoffsetsexpectedtxt">trunk/LayoutTests/css3/scroll-snap/scroll-snap-offsets-expected.txt</a></li>
<li><a href="#trunkLayoutTestscss3scrollsnapscrollsnapoffsetshtml">trunk/LayoutTests/css3/scroll-snap/scroll-snap-offsets.html</a></li>
<li><a href="#trunkLayoutTestsplatformmacwk2tileddrawingscrollingscrollsnapscrollsnapmandatorybordersexpectedtxt">trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-borders-expected.txt</a></li>
<li><a href="#trunkLayoutTestsplatformmacwk2tileddrawingscrollingscrollsnapscrollsnapmandatorybordershtml">trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-borders.html</a></li>
<li><a href="#trunkLayoutTestsplatformmacwk2tileddrawingscrollingscrollsnapscrollsnapmandatorypaddingexpectedtxt">trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-padding-expected.txt</a></li>
<li><a href="#trunkLayoutTestsplatformmacwk2tileddrawingscrollingscrollsnapscrollsnapmandatorypaddinghtml">trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-padding.html</a></li>
<li><a href="#trunkLayoutTestsplatformmacwk2tileddrawingscrollingscrollsnapscrollsnapmandatoryrotatedexpectedtxt">trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-rotated-expected.txt</a></li>
<li><a href="#trunkLayoutTestsplatformmacwk2tileddrawingscrollingscrollsnapscrollsnapmandatoryrotatedhtml">trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-rotated.html</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (183905 => 183906)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2015-05-07 02:32:57 UTC (rev 183905)
+++ trunk/LayoutTests/ChangeLog        2015-05-07 02:53:00 UTC (rev 183906)
</span><span class="lines">@@ -1,3 +1,29 @@
</span><ins>+2015-05-06  Brent Fulgham  &lt;bfulgham@apple.com&gt;
+
+        Scroll-snap points do not handle margins and padding propertly
+        https://bugs.webkit.org/show_bug.cgi?id=144647
+        &lt;rdar://problem/20829473&gt;
+
+        Reviewed by Simon Fraser.
+
+        Add new scroll-snap tests that cover elements with borders, padding, and rotation. Also correct the
+        cause of the 'scroll-snap-mandatory-overflow.html' test flakiness by making sure the mouse is always
+        inside the element when starting new wheel gestures.
+
+        Also add a new 'generic' test that confirms that we have expected results for scroll-snap coordinates
+        and calculated scroll-snap-offset values.

+        * css3/scroll-snap/scroll-snap-offsets.html: Added.
+        * platform/mac-wk2/TestExpectations: Remove flakiness annotation for scroll-snap-mandatory-overflow.
+        * platform/mac-wk2/tiled-drawing/scrolling/scroll-snap/scroll-snap-iframe.html:
+        * platform/mac-wk2/tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-borders-expected.txt: Added.
+        * platform/mac-wk2/tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-borders.html: Added.
+        * platform/mac-wk2/tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-overflow.html:
+        * platform/mac-wk2/tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-padding-expected.txt: Added.
+        * platform/mac-wk2/tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-padding.html: Added.
+        * platform/mac-wk2/tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-rotated-expected.txt: Added.
+        * platform/mac-wk2/tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-rotated.html: Added.
+
</ins><span class="cx"> 2015-05-06  Commit Queue  &lt;commit-queue@webkit.org&gt;
</span><span class="cx"> 
</span><span class="cx">         Unreviewed, rolling out r183894.
</span></span></pre></div>
<a id="trunkLayoutTestscss3scrollsnapscrollsnapoffsetsexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/css3/scroll-snap/scroll-snap-offsets-expected.txt (0 => 183906)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/css3/scroll-snap/scroll-snap-offsets-expected.txt                                (rev 0)
+++ trunk/LayoutTests/css3/scroll-snap/scroll-snap-offsets-expected.txt        2015-05-07 02:53:00 UTC (rev 183906)
</span><span class="lines">@@ -0,0 +1,18 @@
</span><ins>+Tests that the scroll-snap feature works properly in overflow regions.
+ PASS successfullyParsed is true
+
+TEST COMPLETE
+Scroll-snap offsets for horizontalTarget: horizontal = { 0, 30, 60, 90, 120, 150 }, vertical = { 0, 15 }
+Scroll-snap offsets for verticalTarget: horizontal = { 0, 15 }, vertical = { 0, 30, 60, 90, 120, 150 }
+Scroll-snap offsets for horizontalBorderedTarget: horizontal = { 0, 30, 60, 90, 120, 150 }, vertical = { 0, 15 }
+Scroll-snap offsets for verticalBorderedTarget: horizontal = { 0, 15 }, vertical = { 0, 30, 60, 90, 120, 150 }
+Scroll-snap offsets for horizontalPaddedTarget: horizontal = { 0, 30, 60, 90, 120, 150, 170 }, vertical = { 0, 39 }
+Scroll-snap offsets for verticalPaddedTarget: horizontal = { 0, 35 }, vertical = { 0, 30, 60, 90, 120, 150, 174 }
+Scroll-snap offsets for horizontalBorderedPaddedTarget: horizontal = { 0, 30, 60, 90, 120, 150, 170 }, vertical = { 0, 39 }
+Scroll-snap offsets for verticalBorderedPaddedTarget: horizontal = { 0, 35 }, vertical = { 0, 30, 60, 90, 120, 150, 174 }
+Scroll-snap offsets for horizontalRotatedTarget: horizontal = { 0, 30, 60, 90, 120, 150, 170 }, vertical = { 0, 39 }
+Scroll-snap offsets for verticalRotatedTarget: horizontal = { 0, 35 }, vertical = { 0, 30, 60, 90, 120, 150, 174 }
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestscss3scrollsnapscrollsnapoffsetshtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/css3/scroll-snap/scroll-snap-offsets.html (0 => 183906)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/css3/scroll-snap/scroll-snap-offsets.html                                (rev 0)
+++ trunk/LayoutTests/css3/scroll-snap/scroll-snap-offsets.html        2015-05-07 02:53:00 UTC (rev 183906)
</span><span class="lines">@@ -0,0 +1,201 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+    &lt;head&gt;
+        &lt;style&gt;
+            .bordered {
+                border-top: 20px solid black;
+                border-bottom: 10px solid black;
+                border-left: 15px solid black;
+                border-right: 9px solid black;
+            }
+            .padded {
+                padding-left: 20px;
+                padding-right: 10px;
+                padding-top: 15px;
+                padding-bottom: 9px;
+            }
+            .horizontalGallery {
+                width: 30px;
+                height: 30px;
+                overflow-y: hidden;
+                overflow-x: auto;
+                margin: 2px;
+                -webkit-overflow-scrolling: touch;
+                -webkit-scroll-snap-points-x: repeat(100%);
+                -webkit-scroll-snap-type: mandatory;
+                -webkit-scroll-snap-coordinate: 50% 50%;
+            }
+            .horizontalGalleryDrawer {
+                width: 180px;
+                height: 30px;
+            }
+            .verticalGallery {
+                width: 30px;
+                height: 30px;
+                display: inline-block;
+                overflow-x: hidden;
+                overflow-y: auto;
+                margin: 2px;
+                -webkit-overflow-scrolling: touch;
+                -webkit-scroll-snap-points-y: repeat(100%);
+                -webkit-scroll-snap-type: mandatory;
+                -webkit-scroll-snap-coordinate: 50% 50%;
+            }
+            .verticalGalleryDrawer {
+                width: 30px;
+                height: 180px;
+            }
+            .colorBox {
+                height: 30px;
+                width: 30px;
+                float: left;
+            }
+            #itemH0, #itemV0 { background-color: red; }
+            #itemH1, #itemV1 { background-color: green; }
+            #itemH2, #itemV2 { background-color: blue; }
+            #itemH3, #itemV3 { background-color: aqua; }
+            #itemH4, #itemV4 { background-color: yellow; }
+            #itemH5, #itemV5 { background-color: fuchsia; }
+        &lt;/style&gt;
+        &lt;script src=&quot;../../resources/js-test-pre.js&quot;&gt;&lt;/script&gt;
+        &lt;script&gt;
+        function reportResult(horizontalTargetID, verticalTargetID)
+        {
+            var horizontalTarget = document.getElementById(horizontalTargetID);
+            var verticalTarget = document.getElementById(verticalTargetID);
+
+            debug(&quot;Scroll-snap offsets for &quot; + horizontalTargetID + &quot;: &quot; + window.internals.scrollSnapOffsets(horizontalTarget));
+            debug(&quot;Scroll-snap offsets for &quot; + verticalTargetID + &quot;: &quot; + window.internals.scrollSnapOffsets(verticalTarget));
+        }
+
+        function runTest()
+        {
+            reportResult('horizontalTarget', 'verticalTarget');
+            reportResult('horizontalBorderedTarget', 'verticalBorderedTarget');
+            reportResult('horizontalPaddedTarget', 'verticalPaddedTarget');
+            reportResult('horizontalBorderedPaddedTarget', 'verticalBorderedPaddedTarget');
+            reportResult('horizontalRotatedTarget', 'verticalRotatedTarget')
+
+            finishJSTest();
+            testRunner.notifyDone();
+        }
+
+        function onLoad()
+        {
+            if (window.testRunner) {
+                window.jsTestIsAsync = true;
+                testRunner.dumpAsText();
+                testRunner.waitUntilDone();
+                setTimeout(runTest, 0);
+            }
+        }
+        &lt;/script&gt;
+    &lt;/head&gt;
+    &lt;body onload=&quot;onLoad();&quot;&gt;
+        &lt;div style=&quot;position: relative; width: 300px&quot;&gt;
+            &lt;div&gt;Tests that the scroll-snap feature works properly in overflow regions.&lt;/div&gt;
+            &lt;div class=&quot;horizontalGallery&quot; id=&quot;horizontalTarget&quot;&gt;
+                &lt;div class=&quot;horizontalGalleryDrawer&quot;&gt;
+                    &lt;div id=&quot;itemH0&quot; class=&quot;colorBox&quot;&gt;&lt;/div&gt;
+                    &lt;div id=&quot;itemH1&quot; class=&quot;colorBox&quot;&gt;&lt;/div&gt;
+                    &lt;div id=&quot;itemH2&quot; class=&quot;colorBox&quot;&gt;&lt;/div&gt;
+                    &lt;div id=&quot;itemH3&quot; class=&quot;colorBox&quot;&gt;&lt;/div&gt;
+                    &lt;div id=&quot;itemH4&quot; class=&quot;colorBox&quot;&gt;&lt;/div&gt;
+                    &lt;div id=&quot;itemH5&quot; class=&quot;colorBox&quot;&gt;&lt;/div&gt;
+                &lt;/div&gt;
+            &lt;/div&gt;
+            &lt;div class=&quot;verticalGallery&quot; id=&quot;verticalTarget&quot;&gt;
+                &lt;div class=&quot;verticalGalleryDrawer&quot;&gt;
+                    &lt;div id=&quot;itemV0&quot; class=&quot;colorBox&quot;&gt;&lt;/div&gt;
+                    &lt;div id=&quot;itemV1&quot; class=&quot;colorBox&quot;&gt;&lt;/div&gt;
+                    &lt;div id=&quot;itemV2&quot; class=&quot;colorBox&quot;&gt;&lt;/div&gt;
+                    &lt;div id=&quot;itemV3&quot; class=&quot;colorBox&quot;&gt;&lt;/div&gt;
+                    &lt;div id=&quot;itemV4&quot; class=&quot;colorBox&quot;&gt;&lt;/div&gt;
+                    &lt;div id=&quot;itemV5&quot; class=&quot;colorBox&quot;&gt;&lt;/div&gt;
+                &lt;/div&gt;
+            &lt;/div&gt;
+            &lt;div class=&quot;horizontalGallery bordered&quot; id=&quot;horizontalBorderedTarget&quot;&gt;
+                &lt;div class=&quot;horizontalGalleryDrawer&quot;&gt;
+                    &lt;div id=&quot;itemH0&quot; class=&quot;colorBox&quot;&gt;&lt;/div&gt;
+                    &lt;div id=&quot;itemH1&quot; class=&quot;colorBox&quot;&gt;&lt;/div&gt;
+                    &lt;div id=&quot;itemH2&quot; class=&quot;colorBox&quot;&gt;&lt;/div&gt;
+                    &lt;div id=&quot;itemH3&quot; class=&quot;colorBox&quot;&gt;&lt;/div&gt;
+                    &lt;div id=&quot;itemH4&quot; class=&quot;colorBox&quot;&gt;&lt;/div&gt;
+                    &lt;div id=&quot;itemH5&quot; class=&quot;colorBox&quot;&gt;&lt;/div&gt;
+                &lt;/div&gt;
+            &lt;/div&gt;
+            &lt;div class=&quot;verticalGallery bordered&quot; id=&quot;verticalBorderedTarget&quot;&gt;
+                &lt;div class=&quot;verticalGalleryDrawer&quot;&gt;
+                    &lt;div id=&quot;itemV0&quot; class=&quot;colorBox&quot;&gt;&lt;/div&gt;
+                    &lt;div id=&quot;itemV1&quot; class=&quot;colorBox&quot;&gt;&lt;/div&gt;
+                    &lt;div id=&quot;itemV2&quot; class=&quot;colorBox&quot;&gt;&lt;/div&gt;
+                    &lt;div id=&quot;itemV3&quot; class=&quot;colorBox&quot;&gt;&lt;/div&gt;
+                    &lt;div id=&quot;itemV4&quot; class=&quot;colorBox&quot;&gt;&lt;/div&gt;
+                    &lt;div id=&quot;itemV5&quot; class=&quot;colorBox&quot;&gt;&lt;/div&gt;
+                &lt;/div&gt;
+            &lt;/div&gt;
+            &lt;div class=&quot;horizontalGallery padded&quot; id=&quot;horizontalPaddedTarget&quot;&gt;
+                &lt;div class=&quot;horizontalGalleryDrawer&quot;&gt;
+                    &lt;div id=&quot;itemH0&quot; class=&quot;colorBox&quot;&gt;&lt;/div&gt;
+                    &lt;div id=&quot;itemH1&quot; class=&quot;colorBox&quot;&gt;&lt;/div&gt;
+                    &lt;div id=&quot;itemH2&quot; class=&quot;colorBox&quot;&gt;&lt;/div&gt;
+                    &lt;div id=&quot;itemH3&quot; class=&quot;colorBox&quot;&gt;&lt;/div&gt;
+                    &lt;div id=&quot;itemH4&quot; class=&quot;colorBox&quot;&gt;&lt;/div&gt;
+                    &lt;div id=&quot;itemH5&quot; class=&quot;colorBox&quot;&gt;&lt;/div&gt;
+                &lt;/div&gt;
+            &lt;/div&gt;
+            &lt;div class=&quot;verticalGallery padded&quot; id=&quot;verticalPaddedTarget&quot;&gt;
+                &lt;div class=&quot;verticalGalleryDrawer&quot;&gt;
+                    &lt;div id=&quot;itemV0&quot; class=&quot;colorBox&quot;&gt;&lt;/div&gt;
+                    &lt;div id=&quot;itemV1&quot; class=&quot;colorBox&quot;&gt;&lt;/div&gt;
+                    &lt;div id=&quot;itemV2&quot; class=&quot;colorBox&quot;&gt;&lt;/div&gt;
+                    &lt;div id=&quot;itemV3&quot; class=&quot;colorBox&quot;&gt;&lt;/div&gt;
+                    &lt;div id=&quot;itemV4&quot; class=&quot;colorBox&quot;&gt;&lt;/div&gt;
+                    &lt;div id=&quot;itemV5&quot; class=&quot;colorBox&quot;&gt;&lt;/div&gt;
+                &lt;/div&gt;
+            &lt;/div&gt;
+            &lt;div class=&quot;horizontalGallery bordered padded&quot; id=&quot;horizontalBorderedPaddedTarget&quot;&gt;
+                &lt;div class=&quot;horizontalGalleryDrawer&quot;&gt;
+                    &lt;div id=&quot;itemH0&quot; class=&quot;colorBox&quot;&gt;&lt;/div&gt;
+                    &lt;div id=&quot;itemH1&quot; class=&quot;colorBox&quot;&gt;&lt;/div&gt;
+                    &lt;div id=&quot;itemH2&quot; class=&quot;colorBox&quot;&gt;&lt;/div&gt;
+                    &lt;div id=&quot;itemH3&quot; class=&quot;colorBox&quot;&gt;&lt;/div&gt;
+                    &lt;div id=&quot;itemH4&quot; class=&quot;colorBox&quot;&gt;&lt;/div&gt;
+                    &lt;div id=&quot;itemH5&quot; class=&quot;colorBox&quot;&gt;&lt;/div&gt;
+                &lt;/div&gt;
+            &lt;/div&gt;
+            &lt;div class=&quot;verticalGallery bordered padded&quot; id=&quot;verticalBorderedPaddedTarget&quot;&gt;
+                &lt;div class=&quot;verticalGalleryDrawer&quot;&gt;
+                    &lt;div id=&quot;itemV0&quot; class=&quot;colorBox&quot;&gt;&lt;/div&gt;
+                    &lt;div id=&quot;itemV1&quot; class=&quot;colorBox&quot;&gt;&lt;/div&gt;
+                    &lt;div id=&quot;itemV2&quot; class=&quot;colorBox&quot;&gt;&lt;/div&gt;
+                    &lt;div id=&quot;itemV3&quot; class=&quot;colorBox&quot;&gt;&lt;/div&gt;
+                    &lt;div id=&quot;itemV4&quot; class=&quot;colorBox&quot;&gt;&lt;/div&gt;
+                    &lt;div id=&quot;itemV5&quot; class=&quot;colorBox&quot;&gt;&lt;/div&gt;
+                &lt;/div&gt;
+            &lt;/div&gt;
+            &lt;div class=&quot;horizontalGallery bordered padded&quot; id=&quot;horizontalRotatedTarget&quot; style=&quot;-webkit-transform: rotate(20deg)&quot;&gt;
+                &lt;div class=&quot;horizontalGalleryDrawer&quot;&gt;
+                    &lt;div id=&quot;itemH0&quot; class=&quot;colorBox&quot;&gt;&lt;/div&gt;
+                    &lt;div id=&quot;itemH1&quot; class=&quot;colorBox&quot;&gt;&lt;/div&gt;
+                    &lt;div id=&quot;itemH2&quot; class=&quot;colorBox&quot;&gt;&lt;/div&gt;
+                    &lt;div id=&quot;itemH3&quot; class=&quot;colorBox&quot;&gt;&lt;/div&gt;
+                    &lt;div id=&quot;itemH4&quot; class=&quot;colorBox&quot;&gt;&lt;/div&gt;
+                    &lt;div id=&quot;itemH5&quot; class=&quot;colorBox&quot;&gt;&lt;/div&gt;
+                &lt;/div&gt;
+            &lt;/div&gt;
+            &lt;div class=&quot;verticalGallery bordered padded&quot; id=&quot;verticalRotatedTarget&quot; style=&quot;-webkit-transform: rotate(-20deg)&quot;&gt;
+                &lt;div class=&quot;verticalGalleryDrawer&quot;&gt;
+                    &lt;div id=&quot;itemV0&quot; class=&quot;colorBox&quot;&gt;&lt;/div&gt;
+                    &lt;div id=&quot;itemV1&quot; class=&quot;colorBox&quot;&gt;&lt;/div&gt;
+                    &lt;div id=&quot;itemV2&quot; class=&quot;colorBox&quot;&gt;&lt;/div&gt;
+                    &lt;div id=&quot;itemV3&quot; class=&quot;colorBox&quot;&gt;&lt;/div&gt;
+                    &lt;div id=&quot;itemV4&quot; class=&quot;colorBox&quot;&gt;&lt;/div&gt;
+                    &lt;div id=&quot;itemV5&quot; class=&quot;colorBox&quot;&gt;&lt;/div&gt;
+                &lt;/div&gt;
+            &lt;/div&gt;
+            &lt;div id=&quot;console&quot;&gt;&lt;/div&gt;
+        &lt;/div&gt;
+        &lt;script src=&quot;../../resources/js-test-post.js&quot;&gt;&lt;/script&gt;
+    &lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestsplatformmacwk2TestExpectations"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/platform/mac-wk2/TestExpectations (183905 => 183906)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/platform/mac-wk2/TestExpectations        2015-05-07 02:32:57 UTC (rev 183905)
+++ trunk/LayoutTests/platform/mac-wk2/TestExpectations        2015-05-07 02:53:00 UTC (rev 183906)
</span><span class="lines">@@ -523,10 +523,3 @@
</span><span class="cx"> ########################################
</span><span class="cx"> 
</span><span class="cx"> http/tests/contentextensions [ Pass ]
</span><del>-
-########################################
-### START OF (1) New scroll-snap flake
-platform/mac-wk2/tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-overflow.html [ Timeout Pass ]
-
-### END OF (1) scroll-snap flake
-########################################
</del></span></pre></div>
<a id="trunkLayoutTestsplatformmacwk2tileddrawingscrollingscrollsnapscrollsnapiframehtml"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/scroll-snap/scroll-snap-iframe.html (183905 => 183906)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/scroll-snap/scroll-snap-iframe.html        2015-05-07 02:32:57 UTC (rev 183905)
+++ trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/scroll-snap/scroll-snap-iframe.html        2015-05-07 02:53:00 UTC (rev 183906)
</span><span class="lines">@@ -82,8 +82,10 @@
</span><span class="cx">                 dy = -1;
</span><span class="cx">             }
</span><span class="cx"> 
</span><del>-            var startPosX = iframeTarget.offsetLeft + 20;
-            var startPosY = iframeTarget.offsetTop + 20;
</del><ins>+            var windowPosition = locationInWindowCoordinates(iframeTarget);
+
+            var startPosX = windowPosition.x + 0.5 * iframeTarget.clientWidth;
+            var startPosY = windowPosition.y + 0.5 * iframeTarget.clientHeight;
</ins><span class="cx">             eventSender.mouseMoveTo(startPosX, startPosY); // Make sure we are just outside the iFrame
</span><span class="cx">             eventSender.mouseScrollByWithWheelAndMomentumPhases(dx, dy, 'began', 'none', false);
</span><span class="cx">             eventSender.mouseScrollByWithWheelAndMomentumPhases(dx, dy, 'changed', 'none', false);
</span><span class="lines">@@ -131,8 +133,8 @@
</span><span class="cx"> 
</span><span class="cx">             var windowPosition = locationInWindowCoordinates(iframeTarget);
</span><span class="cx"> 
</span><del>-            var startPosX = windowPosition.x + iframeTarget.clientWidth - 10;
-            var startPosY = windowPosition.y + 50;
</del><ins>+            var startPosX = windowPosition.x + 0.5 * iframeTarget.clientWidth;
+            var startPosY = windowPosition.y + 0.5 * iframeTarget.clientHeight;
</ins><span class="cx">             eventSender.mouseMoveTo(startPosX, startPosY);
</span><span class="cx">             eventSender.mouseScrollByWithWheelAndMomentumPhases(dx, dy, 'began', 'none', false);
</span><span class="cx">             eventSender.mouseScrollByWithWheelAndMomentumPhases(dx, dy, 'changed', 'none', false);
</span></span></pre></div>
<a id="trunkLayoutTestsplatformmacwk2tileddrawingscrollingscrollsnapscrollsnapmandatorybordersexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-borders-expected.txt (0 => 183906)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-borders-expected.txt                                (rev 0)
+++ trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-borders-expected.txt        2015-05-07 02:53:00 UTC (rev 183906)
</span><span class="lines">@@ -0,0 +1,16 @@
</span><ins>+Tests that the scroll-snap feature works properly in overflow regions.
+ PASS successfullyParsed is true
+
+TEST COMPLETE
+Testing scroll-snap glide for horizontalTarget:
+PASS div scrolled to next window.
+Testing scroll-snap snap for horizontalTarget:
+PASS div honored snap points.
+Testing scroll-snap glide for verticalTarget:
+PASS div scrolled to next window.
+Testing scroll-snap snap for verticalTarget:
+PASS div honored snap points.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestsplatformmacwk2tileddrawingscrollingscrollsnapscrollsnapmandatorybordershtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-borders.html (0 => 183906)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-borders.html                                (rev 0)
+++ trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-borders.html        2015-05-07 02:53:00 UTC (rev 183906)
</span><span class="lines">@@ -0,0 +1,239 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+    &lt;head&gt;
+        &lt;style&gt;
+            .horizontalGallery {
+                width: 300px;
+                height: 300px;
+                overflow-y: hidden;
+                overflow-x: auto;
+                border-top: 20px solid black;
+                border-bottom: 10px solid black;
+                border-left: 15px solid black;
+                border-right: 9px solid black;
+                margin-bottom: 2px;
+                -webkit-overflow-scrolling: touch;
+                -webkit-scroll-snap-points-x: repeat(100%);
+                -webkit-scroll-snap-type: mandatory;
+            }
+            .horizontalGalleryDrawer {
+                width: 1800px;
+                height: 300px;
+            }
+            .verticalGallery {
+                width: 300px;
+                height: 300px;
+                display: inline-block;
+                overflow-x: hidden;
+                overflow-y: auto;
+                border-top: 20px solid black;
+                border-bottom: 10px solid black;
+                border-left: 15px solid black;
+                border-right: 9px solid black;
+                margin-top: 2px;
+                -webkit-overflow-scrolling: touch;
+                -webkit-scroll-snap-points-y: repeat(100%);
+                -webkit-scroll-snap-type: mandatory;
+            }
+            .verticalGalleryDrawer {
+                width: 300px;
+                height: 1800px;
+            }
+            .colorBox {
+                height: 300px;
+                width: 300px;
+                float: left;
+            }
+            #itemH0, #itemV0 { background-color: red; }
+            #itemH1, #itemV1 { background-color: green; }
+            #itemH2, #itemV2 { background-color: blue; }
+            #itemH3, #itemV3 { background-color: aqua; }
+            #itemH4, #itemV4 { background-color: yellow; }
+            #itemH5, #itemV5 { background-color: fuchsia; }
+        &lt;/style&gt;
+        &lt;script src=&quot;../../../../../resources/js-test-pre.js&quot;&gt;&lt;/script&gt;
+        &lt;script&gt;
+        var divScrollPositionBeforeGlide;
+        var divScrollPositionBeforeSnap;
+
+        function locationInWindowCoordinates(element)
+        {
+            var position = {};
+            position.x = element.offsetLeft;
+            position.y = element.offsetTop;
+
+            while (element.offsetParent) {
+                position.x = position.x + element.offsetParent.offsetLeft;
+                position.y = position.y + element.offsetParent.offsetTop;
+                if (element == document.getElementsByTagName(&quot;body&quot;)[0])
+                    break;
+
+                element = element.offsetParent;
+            }
+
+            return position;
+        }
+
+        function finishTest()
+        {
+            finishJSTest();
+            testRunner.notifyDone();            
+        }
+
+        function checkForScrollSnap(targetLabel)
+        {
+            var divTarget = document.getElementById(targetLabel);
+
+            var actualPosition = divTarget.scrollTop;
+            if (targetLabel == 'horizontalTarget')
+                actualPosition = divTarget.scrollLeft;
+
+            // The div should have snapped back to the previous position
+            if (actualPosition != divScrollPositionBeforeSnap)
+                testFailed(&quot;div did not snap back to proper location for &quot; + targetLabel +&quot;. Expected &quot; + divScrollPositionBeforeSnap + &quot;, but got &quot; + actualPosition);
+            else
+                testPassed(&quot;div honored snap points.&quot;);
+
+            if (targetLabel == 'horizontalTarget')
+                setTimeout(scrollGlideTest('verticalTarget'), 0);
+            else   
+                finishTest();
+        }
+
+        function scrollSnapTest(targetLabel)
+        {
+            debug(&quot;Testing scroll-snap snap for &quot; + targetLabel + &quot;:&quot;);
+            var divTarget = document.getElementById(targetLabel);

+            var dx = 0;
+            var dy = 0;
+            if (targetLabel == 'horizontalTarget') {
+                divScrollPositionBeforeSnap = divTarget.scrollLeft;
+                dx = -1;
+            } else {
+                divScrollPositionBeforeSnap = divTarget.scrollTop;
+                dy = -1;
+            }
+
+            var windowPosition = locationInWindowCoordinates(divTarget);
+
+            var startPosX = windowPosition.x + 0.5 * divTarget.clientWidth;
+            var startPosY = windowPosition.y + 0.5 * divTarget.clientHeight;
+            eventSender.mouseMoveTo(startPosX, startPosY); // Make sure we are just outside the iFrame
+            eventSender.mouseScrollByWithWheelAndMomentumPhases(dx, dy, 'began', 'none', false);
+            eventSender.mouseScrollByWithWheelAndMomentumPhases(dx, dy, 'changed', 'none', false);
+            eventSender.mouseScrollByWithWheelAndMomentumPhases(dx, dy, 'changed', 'none', false);
+            eventSender.mouseScrollByWithWheelAndMomentumPhases(0, 0, 'ended', 'none', false);
+            eventSender.callAfterScrollingCompletes(function() { return checkForScrollSnap(targetLabel); });
+        }
+
+        function checkForScrollGlide(targetLabel)
+        {
+            var divTarget = document.getElementById(targetLabel);
+
+            var actualPosition = divTarget.scrollTop;
+            var expectedPosition = divTarget.clientHeight;
+            if (targetLabel == 'horizontalTarget') {
+                actualPosition = divTarget.scrollLeft;
+                expectedPosition = divTarget.clientWidth;
+            }
+
+            // The div should have scrolled (glided) to the next snap point.
+            if (actualPosition == expectedPosition)
+                testPassed(&quot;div scrolled to next window.&quot;);
+            else
+                testFailed(&quot;div did not honor snap points. Expected &quot; + expectedPosition + &quot;, but got &quot; + actualPosition);
+
+            setTimeout(scrollSnapTest(targetLabel), 0);
+        }
+
+        function scrollGlideTest(targetLabel)
+        {
+            debug(&quot;Testing scroll-snap glide for &quot; + targetLabel + &quot;:&quot;);
+            var divTarget = document.getElementById(targetLabel);

+            var dx = 0;
+            var dy = 0;
+            if (targetLabel == 'horizontalTarget') {
+                divScrollPositionBeforeGlide = divTarget.scrollLeft;
+                dx = -1;
+            } else {
+                divScrollPositionBeforeGlide = divTarget.scrollTop;
+                dy = -1;
+            }
+
+            var windowPosition = locationInWindowCoordinates(divTarget);
+
+            var startPosX = windowPosition.x + divTarget.clientWidth - 10;
+            var startPosY = windowPosition.y + 50;
+            eventSender.mouseMoveTo(startPosX, startPosY);
+            eventSender.mouseScrollByWithWheelAndMomentumPhases(dx, dy, 'began', 'none', false);
+            eventSender.mouseScrollByWithWheelAndMomentumPhases(dx, dy, 'changed', 'none', false);
+            eventSender.mouseScrollByWithWheelAndMomentumPhases(dx, dy, 'changed', 'none', false);
+            eventSender.mouseScrollByWithWheelAndMomentumPhases(dx, dy, 'changed', 'none', false);
+            eventSender.mouseScrollByWithWheelAndMomentumPhases(0, 0, 'ended', 'none', false);
+            eventSender.mouseScrollByWithWheelAndMomentumPhases(dx, dy, 'none', 'begin', false);
+            eventSender.mouseScrollByWithWheelAndMomentumPhases(dx, dy, 'none', 'continue', false);
+            eventSender.mouseScrollByWithWheelAndMomentumPhases(dx, dy, 'none', 'continue', false);
+            eventSender.mouseScrollByWithWheelAndMomentumPhases(dx, dy, 'none', 'continue', false);
+            eventSender.mouseScrollByWithWheelAndMomentumPhases(dx, dy, 'none', 'continue', false);
+            eventSender.mouseScrollByWithWheelAndMomentumPhases(0, 0, 'none', 'end', false);
+            eventSender.callAfterScrollingCompletes(function() { return checkForScrollGlide(targetLabel); });
+        }
+
+        function onLoad()
+        {
+            if (window.eventSender) {
+                window.jsTestIsAsync = true;
+                testRunner.dumpAsText();
+                testRunner.waitUntilDone();
+
+                eventSender.monitorWheelEvents();
+                setTimeout(scrollGlideTest('horizontalTarget'), 0);
+            } else {
+                var messageLocationH = document.getElementById('itemH0');
+                var message = document.createElement('div');
+                message.innerHTML = &quot;&lt;p&gt;This test is better run under DumpRenderTree.&lt;br/&gt;To manually test it, place the mouse pointer&lt;br/&gt;&quot;
+                    + &quot;inside the red region at the top of the page,&lt;br/&gt;and then use the mouse wheel or a two-finger&lt;br/&gt;swipe to make a&quot;
+                    + &quot;small swipe gesture with&lt;br/&gt;some momentum.&lt;br/&gt;&lt;br/&gt;&quot;
+                    + &quot;The region should scroll to show a green region.&lt;br/&gt;&lt;br/&gt;&quot;
+                    + &quot;Next, perform a small scroll gesture that does&lt;br/&gt;not involve momentum. You should begin to&lt;br/&gt;see one of the colors &quot;
+                    + &quot;to the side of the current&lt;br/&gt;green box. When you release the wheel, the&lt;br/&gt;region should scroll back to a single color.&quot;;
+                messageLocationH.appendChild(message);
+
+                var messageLocationV = document.getElementById('itemV0');
+                var message = document.createElement('div');
+                message.innerHTML = &quot;&lt;p&gt;You should also be able to repeat these tests steps for this vertical region.&lt;br/&gt;&quot;
+                messageLocationV.appendChild(message);
+            }
+        }
+        &lt;/script&gt;
+    &lt;/head&gt;
+    &lt;body onload=&quot;onLoad();&quot;&gt;
+        &lt;div style=&quot;position: relative; width: 300px&quot;&gt;
+            &lt;div&gt;Tests that the scroll-snap feature works properly in overflow regions.&lt;/div&gt;
+            &lt;div class=&quot;horizontalGallery&quot; id=&quot;horizontalTarget&quot;&gt;
+                &lt;div class=&quot;horizontalGalleryDrawer&quot;&gt;
+                    &lt;div id=&quot;itemH0&quot; class=&quot;colorBox&quot;&gt;&lt;/div&gt;
+                    &lt;div id=&quot;itemH1&quot; class=&quot;colorBox&quot;&gt;&lt;/div&gt;
+                    &lt;div id=&quot;itemH2&quot; class=&quot;colorBox&quot;&gt;&lt;/div&gt;
+                    &lt;div id=&quot;itemH3&quot; class=&quot;colorBox&quot;&gt;&lt;/div&gt;
+                    &lt;div id=&quot;itemH4&quot; class=&quot;colorBox&quot;&gt;&lt;/div&gt;
+                    &lt;div id=&quot;itemH5&quot; class=&quot;colorBox&quot;&gt;&lt;/div&gt;
+                &lt;/div&gt;
+            &lt;/div&gt;
+            &lt;div class=&quot;verticalGallery&quot; id=&quot;verticalTarget&quot;&gt;
+                &lt;div class=&quot;verticalGalleryDrawer&quot;&gt;
+                    &lt;div id=&quot;itemV0&quot; class=&quot;colorBox&quot;&gt;&lt;/div&gt;
+                    &lt;div id=&quot;itemV1&quot; class=&quot;colorBox&quot;&gt;&lt;/div&gt;
+                    &lt;div id=&quot;itemV2&quot; class=&quot;colorBox&quot;&gt;&lt;/div&gt;
+                    &lt;div id=&quot;itemV3&quot; class=&quot;colorBox&quot;&gt;&lt;/div&gt;
+                    &lt;div id=&quot;itemV4&quot; class=&quot;colorBox&quot;&gt;&lt;/div&gt;
+                    &lt;div id=&quot;itemV5&quot; class=&quot;colorBox&quot;&gt;&lt;/div&gt;
+                &lt;/div&gt;
+            &lt;/div&gt;
+            &lt;div id=&quot;console&quot;&gt;&lt;/div&gt;
+        &lt;/div&gt;
+        &lt;script src=&quot;../../../../../resources/js-test-post.js&quot;&gt;&lt;/script&gt;
+    &lt;/body&gt;
+&lt;/html&gt;
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="trunkLayoutTestsplatformmacwk2tileddrawingscrollingscrollsnapscrollsnapmandatoryoverflowhtml"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-overflow.html (183905 => 183906)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-overflow.html        2015-05-07 02:32:57 UTC (rev 183905)
+++ trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-overflow.html        2015-05-07 02:53:00 UTC (rev 183906)
</span><span class="lines">@@ -105,8 +105,10 @@
</span><span class="cx">                 dy = -1;
</span><span class="cx">             }
</span><span class="cx"> 
</span><del>-            var startPosX = divTarget.offsetLeft + 20;
-            var startPosY = divTarget.offsetTop + 20;
</del><ins>+            var windowPosition = locationInWindowCoordinates(divTarget);
+
+            var startPosX = windowPosition.x + 0.5 * divTarget.clientWidth;
+            var startPosY = windowPosition.y + 0.5 * divTarget.clientHeight;
</ins><span class="cx">             eventSender.mouseMoveTo(startPosX, startPosY); // Make sure we are just outside the iFrame
</span><span class="cx">             eventSender.mouseScrollByWithWheelAndMomentumPhases(dx, dy, 'began', 'none', false);
</span><span class="cx">             eventSender.mouseScrollByWithWheelAndMomentumPhases(dx, dy, 'changed', 'none', false);
</span><span class="lines">@@ -152,8 +154,8 @@
</span><span class="cx"> 
</span><span class="cx">             var windowPosition = locationInWindowCoordinates(divTarget);
</span><span class="cx"> 
</span><del>-            var startPosX = windowPosition.x + divTarget.clientWidth - 10;
-            var startPosY = windowPosition.y + 50;
</del><ins>+            var startPosX = windowPosition.x + 0.5 * divTarget.clientWidth;
+            var startPosY = windowPosition.y + 0.5 * divTarget.clientHeight;
</ins><span class="cx">             eventSender.mouseMoveTo(startPosX, startPosY);
</span><span class="cx">             eventSender.mouseScrollByWithWheelAndMomentumPhases(dx, dy, 'began', 'none', false);
</span><span class="cx">             eventSender.mouseScrollByWithWheelAndMomentumPhases(dx, dy, 'changed', 'none', false);
</span></span></pre></div>
<a id="trunkLayoutTestsplatformmacwk2tileddrawingscrollingscrollsnapscrollsnapmandatorypaddingexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-padding-expected.txt (0 => 183906)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-padding-expected.txt                                (rev 0)
+++ trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-padding-expected.txt        2015-05-07 02:53:00 UTC (rev 183906)
</span><span class="lines">@@ -0,0 +1,16 @@
</span><ins>+Tests that the scroll-snap feature works properly in overflow regions.
+ PASS successfullyParsed is true
+
+TEST COMPLETE
+Testing scroll-snap glide for horizontalTarget:
+PASS div scrolled to next window.
+Testing scroll-snap snap for horizontalTarget:
+PASS div honored snap points.
+Testing scroll-snap glide for verticalTarget:
+PASS div scrolled to next window.
+Testing scroll-snap snap for verticalTarget:
+PASS div honored snap points.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestsplatformmacwk2tileddrawingscrollingscrollsnapscrollsnapmandatorypaddinghtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-padding.html (0 => 183906)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-padding.html                                (rev 0)
+++ trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-padding.html        2015-05-07 02:53:00 UTC (rev 183906)
</span><span class="lines">@@ -0,0 +1,239 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+    &lt;head&gt;
+        &lt;style&gt;
+            .horizontalGallery {
+                width: 300px;
+                height: 300px;
+                overflow-y: hidden;
+                overflow-x: auto;
+                padding-left: 20px;
+                padding-right: 10px;
+                padding-top: 15px;
+                padding-bottom: 9px;
+                margin-bottom: 2px;
+                -webkit-scroll-snap-points-x: repeat(100%);
+                -webkit-scroll-snap-type: mandatory;
+            }
+            .horizontalGalleryDrawer {
+                width: 1800px;
+                height: 300px;
+            }
+            .verticalGallery {
+                width: 300px;
+                height: 300px;
+                display: inline-block;
+                overflow-x: hidden;
+                overflow-y: auto;
+                padding-left: 20px;
+                padding-right: 10px;
+                padding-top: 15px;
+                padding-bottom: 9px;
+                margin-top: 2px;
+                -webkit-scroll-snap-points-y: repeat(100%);
+                -webkit-scroll-snap-type: mandatory;
+            }
+            .verticalGalleryDrawer {
+                width: 300px;
+                height: 1800px;
+            }
+            .colorBox {
+                height: 300px;
+                width: 300px;
+                float: left;
+            }
+            #itemH0, #itemV0 { background-color: red; }
+            #itemH1, #itemV1 { background-color: green; }
+            #itemH2, #itemV2 { background-color: blue; }
+            #itemH3, #itemV3 { background-color: aqua; }
+            #itemH4, #itemV4 { background-color: yellow; }
+            #itemH5, #itemV5 { background-color: fuchsia; }
+        &lt;/style&gt;
+        &lt;script src=&quot;../../../../../resources/js-test-pre.js&quot;&gt;&lt;/script&gt;
+        &lt;script&gt;
+        var divScrollPositionBeforeGlide;
+        var divScrollPositionBeforeSnap;
+
+        function locationInWindowCoordinates(element)
+        {
+            var position = {};
+            position.x = element.offsetLeft;
+            position.y = element.offsetTop;
+
+            while (element.offsetParent) {
+                position.x = position.x + element.offsetParent.offsetLeft;
+                position.y = position.y + element.offsetParent.offsetTop;
+                if (element == document.getElementsByTagName(&quot;body&quot;)[0])
+                    break;
+
+                element = element.offsetParent;
+            }
+
+            return position;
+        }
+
+        function finishTest()
+        {
+            finishJSTest();
+            testRunner.notifyDone();            
+        }
+
+        function checkForScrollSnap(targetLabel)
+        {
+            var divTarget = document.getElementById(targetLabel);
+
+            var actualPosition = divTarget.scrollTop;
+            if (targetLabel == 'horizontalTarget')
+                actualPosition = divTarget.scrollLeft;
+
+            // The div should have snapped back to the previous position
+            if (actualPosition != divScrollPositionBeforeSnap)
+                testFailed(&quot;div did not snap back to proper location for &quot; + targetLabel +&quot;. Expected &quot; + divScrollPositionBeforeSnap + &quot;, but got &quot; + actualPosition);
+            else
+                testPassed(&quot;div honored snap points.&quot;);
+
+            if (targetLabel == 'horizontalTarget')
+                setTimeout(scrollGlideTest('verticalTarget'), 0);
+            else   
+                finishTest();
+        }
+
+        function scrollSnapTest(targetLabel)
+        {
+            debug(&quot;Testing scroll-snap snap for &quot; + targetLabel + &quot;:&quot;);
+            var divTarget = document.getElementById(targetLabel);

+            var dx = 0;
+            var dy = 0;
+            if (targetLabel == 'horizontalTarget') {
+                divScrollPositionBeforeSnap = divTarget.scrollLeft;
+                dx = -1;
+            } else {
+                divScrollPositionBeforeSnap = divTarget.scrollTop;
+                dy = -1;
+            }
+
+            var windowPosition = locationInWindowCoordinates(divTarget);
+
+            var startPosX = windowPosition.x + 0.5 * divTarget.clientWidth;
+            var startPosY = windowPosition.y + 0.5 * divTarget.clientHeight;
+            eventSender.mouseMoveTo(startPosX, startPosY); // Make sure we are just outside the iFrame
+            eventSender.mouseScrollByWithWheelAndMomentumPhases(dx, dy, 'began', 'none', false);
+            eventSender.mouseScrollByWithWheelAndMomentumPhases(dx, dy, 'changed', 'none', false);
+            eventSender.mouseScrollByWithWheelAndMomentumPhases(dx, dy, 'changed', 'none', false);
+            eventSender.mouseScrollByWithWheelAndMomentumPhases(0, 0, 'ended', 'none', false);
+            eventSender.callAfterScrollingCompletes(function() { return checkForScrollSnap(targetLabel); });
+        }
+
+        function checkForScrollGlide(targetLabel)
+        {
+            var divTarget = document.getElementById(targetLabel);
+
+            var style = window.getComputedStyle(divTarget, null);
+
+            var actualPosition = divTarget.scrollTop;
+            var expectedPosition = divTarget.clientHeight - style.getPropertyValue('padding-top').replace(&quot;px&quot;, &quot;&quot;) - style.getPropertyValue('padding-bottom').replace(&quot;px&quot;, &quot;&quot;);
+            if (targetLabel == 'horizontalTarget') {
+                actualPosition = divTarget.scrollLeft;
+                expectedPosition = divTarget.clientWidth - style.getPropertyValue('padding-right').replace(&quot;px&quot;, &quot;&quot;) - style.getPropertyValue('padding-left').replace(&quot;px&quot;, &quot;&quot;);
+            }
+
+            // The div should have scrolled (glided) to the next snap point.
+            if (actualPosition == expectedPosition)
+                testPassed(&quot;div scrolled to next window.&quot;);
+            else
+                testFailed(&quot;div did not honor snap points. Expected &quot; + expectedPosition + &quot;, but got &quot; + actualPosition);
+
+            setTimeout(scrollSnapTest(targetLabel), 0);
+        }
+
+        function scrollGlideTest(targetLabel)
+        {
+            debug(&quot;Testing scroll-snap glide for &quot; + targetLabel + &quot;:&quot;);
+            var divTarget = document.getElementById(targetLabel);

+            var dx = 0;
+            var dy = 0;
+            if (targetLabel == 'horizontalTarget') {
+                divScrollPositionBeforeGlide = divTarget.scrollLeft;
+                dx = -1;
+            } else {
+                divScrollPositionBeforeGlide = divTarget.scrollTop;
+                dy = -1;
+            }
+
+            var windowPosition = locationInWindowCoordinates(divTarget);
+
+            var startPosX = windowPosition.x + divTarget.clientWidth - 10;
+            var startPosY = windowPosition.y + 50;
+            eventSender.mouseMoveTo(startPosX, startPosY);
+            eventSender.mouseScrollByWithWheelAndMomentumPhases(dx, dy, 'began', 'none', false);
+            eventSender.mouseScrollByWithWheelAndMomentumPhases(dx, dy, 'changed', 'none', false);
+            eventSender.mouseScrollByWithWheelAndMomentumPhases(dx, dy, 'changed', 'none', false);
+            eventSender.mouseScrollByWithWheelAndMomentumPhases(dx, dy, 'changed', 'none', false);
+            eventSender.mouseScrollByWithWheelAndMomentumPhases(0, 0, 'ended', 'none', false);
+            eventSender.mouseScrollByWithWheelAndMomentumPhases(dx, dy, 'none', 'begin', false);
+            eventSender.mouseScrollByWithWheelAndMomentumPhases(dx, dy, 'none', 'continue', false);
+            eventSender.mouseScrollByWithWheelAndMomentumPhases(dx, dy, 'none', 'continue', false);
+            eventSender.mouseScrollByWithWheelAndMomentumPhases(dx, dy, 'none', 'continue', false);
+            eventSender.mouseScrollByWithWheelAndMomentumPhases(dx, dy, 'none', 'continue', false);
+            eventSender.mouseScrollByWithWheelAndMomentumPhases(0, 0, 'none', 'end', false);
+            eventSender.callAfterScrollingCompletes(function() { return checkForScrollGlide(targetLabel); });
+        }
+
+        function onLoad()
+        {
+            if (window.eventSender) {
+                window.jsTestIsAsync = true;
+                testRunner.dumpAsText();
+                testRunner.waitUntilDone();
+
+                eventSender.monitorWheelEvents();
+                setTimeout(scrollGlideTest('horizontalTarget'), 0);
+            } else {
+                var messageLocationH = document.getElementById('itemH0');
+                var message = document.createElement('div');
+                message.innerHTML = &quot;&lt;p&gt;This test is better run under DumpRenderTree.&lt;br/&gt;To manually test it, place the mouse pointer&lt;br/&gt;&quot;
+                    + &quot;inside the red region at the top of the page,&lt;br/&gt;and then use the mouse wheel or a two-finger&lt;br/&gt;swipe to make a&quot;
+                    + &quot;small swipe gesture with&lt;br/&gt;some momentum.&lt;br/&gt;&lt;br/&gt;&quot;
+                    + &quot;The region should scroll to show a green region.&lt;br/&gt;&lt;br/&gt;&quot;
+                    + &quot;Next, perform a small scroll gesture that does&lt;br/&gt;not involve momentum. You should begin to&lt;br/&gt;see one of the colors &quot;
+                    + &quot;to the side of the current&lt;br/&gt;green box. When you release the wheel, the&lt;br/&gt;region should scroll back to a single color.&quot;;
+                messageLocationH.appendChild(message);
+
+                var messageLocationV = document.getElementById('itemV0');
+                var message = document.createElement('div');
+                message.innerHTML = &quot;&lt;p&gt;You should also be able to repeat these tests steps for this vertical region.&lt;br/&gt;&quot;
+                messageLocationV.appendChild(message);
+            }
+        }
+        &lt;/script&gt;
+    &lt;/head&gt;
+    &lt;body onload=&quot;onLoad();&quot;&gt;
+        &lt;div style=&quot;position: relative; width: 300px&quot;&gt;
+            &lt;div&gt;Tests that the scroll-snap feature works properly in overflow regions.&lt;/div&gt;
+            &lt;div class=&quot;horizontalGallery&quot; id=&quot;horizontalTarget&quot;&gt;
+                &lt;div class=&quot;horizontalGalleryDrawer&quot;&gt;
+                    &lt;div id=&quot;itemH0&quot; class=&quot;colorBox&quot;&gt;&lt;/div&gt;
+                    &lt;div id=&quot;itemH1&quot; class=&quot;colorBox&quot;&gt;&lt;/div&gt;
+                    &lt;div id=&quot;itemH2&quot; class=&quot;colorBox&quot;&gt;&lt;/div&gt;
+                    &lt;div id=&quot;itemH3&quot; class=&quot;colorBox&quot;&gt;&lt;/div&gt;
+                    &lt;div id=&quot;itemH4&quot; class=&quot;colorBox&quot;&gt;&lt;/div&gt;
+                    &lt;div id=&quot;itemH5&quot; class=&quot;colorBox&quot;&gt;&lt;/div&gt;
+                &lt;/div&gt;
+            &lt;/div&gt;
+            &lt;div class=&quot;verticalGallery&quot; id=&quot;verticalTarget&quot;&gt;
+                &lt;div class=&quot;verticalGalleryDrawer&quot;&gt;
+                    &lt;div id=&quot;itemV0&quot; class=&quot;colorBox&quot;&gt;&lt;/div&gt;
+                    &lt;div id=&quot;itemV1&quot; class=&quot;colorBox&quot;&gt;&lt;/div&gt;
+                    &lt;div id=&quot;itemV2&quot; class=&quot;colorBox&quot;&gt;&lt;/div&gt;
+                    &lt;div id=&quot;itemV3&quot; class=&quot;colorBox&quot;&gt;&lt;/div&gt;
+                    &lt;div id=&quot;itemV4&quot; class=&quot;colorBox&quot;&gt;&lt;/div&gt;
+                    &lt;div id=&quot;itemV5&quot; class=&quot;colorBox&quot;&gt;&lt;/div&gt;
+                &lt;/div&gt;
+            &lt;/div&gt;
+            &lt;div id=&quot;console&quot;&gt;&lt;/div&gt;
+        &lt;/div&gt;
+        &lt;script src=&quot;../../../../../resources/js-test-post.js&quot;&gt;&lt;/script&gt;
+    &lt;/body&gt;
+&lt;/html&gt;
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="trunkLayoutTestsplatformmacwk2tileddrawingscrollingscrollsnapscrollsnapmandatoryrotatedexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-rotated-expected.txt (0 => 183906)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-rotated-expected.txt                                (rev 0)
+++ trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-rotated-expected.txt        2015-05-07 02:53:00 UTC (rev 183906)
</span><span class="lines">@@ -0,0 +1,16 @@
</span><ins>+Tests that the scroll-snap feature works properly in overflow regions.
+ PASS successfullyParsed is true
+
+TEST COMPLETE
+Testing scroll-snap glide for horizontalTarget:
+PASS div scrolled to next window.
+Testing scroll-snap snap for horizontalTarget:
+PASS div honored snap points.
+Testing scroll-snap glide for verticalTarget:
+PASS div scrolled to next window.
+Testing scroll-snap snap for verticalTarget:
+PASS div honored snap points.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestsplatformmacwk2tileddrawingscrollingscrollsnapscrollsnapmandatoryrotatedhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-rotated.html (0 => 183906)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-rotated.html                                (rev 0)
+++ trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-rotated.html        2015-05-07 02:53:00 UTC (rev 183906)
</span><span class="lines">@@ -0,0 +1,231 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+    &lt;head&gt;
+        &lt;style&gt;
+            .horizontalGallery {
+                width: 300px;
+                height: 300px;
+                overflow-y: hidden;
+                overflow-x: auto;
+                border: 2px solid black;
+                margin-bottom: 15px;
+                -webkit-scroll-snap-points-x: repeat(100%);
+                -webkit-scroll-snap-type: mandatory;
+            }
+            .horizontalGalleryDrawer {
+                width: 1800px;
+                height: 300px;
+            }
+            .verticalGallery {
+                width: 300px;
+                height: 300px;
+                display: inline-block;
+                overflow-x: hidden;
+                overflow-y: auto;
+                border: 2px solid black;
+                margin-top: 15px;
+                -webkit-scroll-snap-points-y: repeat(100%);
+                -webkit-scroll-snap-type: mandatory;
+            }
+            .verticalGalleryDrawer {
+                width: 300px;
+                height: 1800px;
+            }
+            .colorBox {
+                height: 300px;
+                width: 300px;
+                float: left;
+            }
+            #itemH0, #itemV0 { background-color: red; }
+            #itemH1, #itemV1 { background-color: green; }
+            #itemH2, #itemV2 { background-color: blue; }
+            #itemH3, #itemV3 { background-color: aqua; }
+            #itemH4, #itemV4 { background-color: yellow; }
+            #itemH5, #itemV5 { background-color: fuchsia; }
+        &lt;/style&gt;
+        &lt;script src=&quot;../../../../../resources/js-test-pre.js&quot;&gt;&lt;/script&gt;
+        &lt;script&gt;
+        var divScrollPositionBeforeGlide;
+        var divScrollPositionBeforeSnap;
+
+        function locationInWindowCoordinates(element)
+        {
+            var position = {};
+            position.x = element.offsetLeft;
+            position.y = element.offsetTop;
+
+            while (element.offsetParent) {
+                position.x = position.x + element.offsetParent.offsetLeft;
+                position.y = position.y + element.offsetParent.offsetTop;
+                if (element == document.getElementsByTagName(&quot;body&quot;)[0])
+                    break;
+
+                element = element.offsetParent;
+            }
+
+            return position;
+        }
+
+        function finishTest()
+        {
+            finishJSTest();
+            testRunner.notifyDone();            
+        }
+
+        function checkForScrollSnap(targetLabel)
+        {
+            var divTarget = document.getElementById(targetLabel);
+
+            var actualPosition = divTarget.scrollTop;
+            if (targetLabel == 'horizontalTarget')
+                actualPosition = divTarget.scrollLeft;
+
+            // The div should have snapped back to the previous position
+            if (actualPosition != divScrollPositionBeforeSnap)
+                testFailed(&quot;div did not snap back to proper location for &quot; + targetLabel +&quot;. Expected &quot; + divScrollPositionBeforeSnap + &quot;, but got &quot; + actualPosition);
+            else
+                testPassed(&quot;div honored snap points.&quot;);
+
+            if (targetLabel == 'horizontalTarget')
+                setTimeout(scrollGlideTest('verticalTarget'), 0);
+            else   
+                finishTest();
+        }
+
+        function scrollSnapTest(targetLabel)
+        {
+            debug(&quot;Testing scroll-snap snap for &quot; + targetLabel + &quot;:&quot;);
+            var divTarget = document.getElementById(targetLabel);

+            var dx = 0;
+            var dy = 0;
+            if (targetLabel == 'horizontalTarget') {
+                divScrollPositionBeforeSnap = divTarget.scrollLeft;
+                dx = -1;
+            } else {
+                divScrollPositionBeforeSnap = divTarget.scrollTop;
+                dy = -1;
+            }
+
+            var windowPosition = locationInWindowCoordinates(divTarget);
+
+            var startPosX = windowPosition.x + 0.5 * divTarget.clientWidth;
+            var startPosY = windowPosition.y + 0.5 * divTarget.clientHeight;
+            eventSender.mouseMoveTo(startPosX, startPosY); // Make sure we are just outside the iFrame
+            eventSender.mouseScrollByWithWheelAndMomentumPhases(dx, dy, 'began', 'none', false);
+            eventSender.mouseScrollByWithWheelAndMomentumPhases(dx, dy, 'changed', 'none', false);
+            eventSender.mouseScrollByWithWheelAndMomentumPhases(dx, dy, 'changed', 'none', false);
+            eventSender.mouseScrollByWithWheelAndMomentumPhases(0, 0, 'ended', 'none', false);
+            eventSender.callAfterScrollingCompletes(function() { return checkForScrollSnap(targetLabel); });
+        }
+
+        function checkForScrollGlide(targetLabel)
+        {
+            var divTarget = document.getElementById(targetLabel);
+
+            var actualPosition = divTarget.scrollTop;
+            var expectedPosition = divTarget.clientHeight;
+            if (targetLabel == 'horizontalTarget') {
+                actualPosition = divTarget.scrollLeft;
+                expectedPosition = divTarget.clientWidth;
+            }
+
+            // The div should have scrolled (glided) to the next snap point.
+            if (actualPosition == expectedPosition)
+                testPassed(&quot;div scrolled to next window.&quot;);
+            else
+                testFailed(&quot;div did not honor snap points. Expected &quot; + expectedPosition + &quot;, but got &quot; + actualPosition);
+
+            setTimeout(scrollSnapTest(targetLabel), 0);
+        }
+
+        function scrollGlideTest(targetLabel)
+        {
+            debug(&quot;Testing scroll-snap glide for &quot; + targetLabel + &quot;:&quot;);
+            var divTarget = document.getElementById(targetLabel);

+            var dx = 0;
+            var dy = 0;
+            if (targetLabel == 'horizontalTarget') {
+                divScrollPositionBeforeGlide = divTarget.scrollLeft;
+                dx = -1;
+            } else {
+                divScrollPositionBeforeGlide = divTarget.scrollTop;
+                dy = -1;
+            }
+
+            var windowPosition = locationInWindowCoordinates(divTarget);
+
+            var startPosX = windowPosition.x + 0.5 * divTarget.clientWidth;
+            var startPosY = windowPosition.y + 0.5 * divTarget.clientHeight;
+            eventSender.mouseMoveTo(startPosX, startPosY);
+            eventSender.mouseScrollByWithWheelAndMomentumPhases(dx, dy, 'began', 'none', false);
+            eventSender.mouseScrollByWithWheelAndMomentumPhases(dx, dy, 'changed', 'none', false);
+            eventSender.mouseScrollByWithWheelAndMomentumPhases(dx, dy, 'changed', 'none', false);
+            eventSender.mouseScrollByWithWheelAndMomentumPhases(dx, dy, 'changed', 'none', false);
+            eventSender.mouseScrollByWithWheelAndMomentumPhases(0, 0, 'ended', 'none', false);
+            eventSender.mouseScrollByWithWheelAndMomentumPhases(dx, dy, 'none', 'begin', false);
+            eventSender.mouseScrollByWithWheelAndMomentumPhases(dx, dy, 'none', 'continue', false);
+            eventSender.mouseScrollByWithWheelAndMomentumPhases(dx, dy, 'none', 'continue', false);
+            eventSender.mouseScrollByWithWheelAndMomentumPhases(dx, dy, 'none', 'continue', false);
+            eventSender.mouseScrollByWithWheelAndMomentumPhases(dx, dy, 'none', 'continue', false);
+            eventSender.mouseScrollByWithWheelAndMomentumPhases(0, 0, 'none', 'end', false);
+            eventSender.callAfterScrollingCompletes(function() { return checkForScrollGlide(targetLabel); });
+        }
+
+        function onLoad()
+        {
+            if (window.eventSender) {
+                window.jsTestIsAsync = true;
+                testRunner.dumpAsText();
+                testRunner.waitUntilDone();
+
+                eventSender.monitorWheelEvents();
+                setTimeout(scrollGlideTest('horizontalTarget'), 0);
+            } else {
+                var messageLocationH = document.getElementById('itemH0');
+                var message = document.createElement('div');
+                message.innerHTML = &quot;&lt;p&gt;This test is better run under DumpRenderTree.&lt;br/&gt;To manually test it, place the mouse pointer&lt;br/&gt;&quot;
+                    + &quot;inside the red region at the top of the page,&lt;br/&gt;and then use the mouse wheel or a two-finger&lt;br/&gt;swipe to make a&quot;
+                    + &quot;small swipe gesture with&lt;br/&gt;some momentum.&lt;br/&gt;&lt;br/&gt;&quot;
+                    + &quot;The region should scroll to show a green region.&lt;br/&gt;&lt;br/&gt;&quot;
+                    + &quot;Next, perform a small scroll gesture that does&lt;br/&gt;not involve momentum. You should begin to&lt;br/&gt;see one of the colors &quot;
+                    + &quot;to the side of the current&lt;br/&gt;green box. When you release the wheel, the&lt;br/&gt;region should scroll back to a single color.&quot;;
+                messageLocationH.appendChild(message);
+
+                var messageLocationV = document.getElementById('itemV0');
+                var message = document.createElement('div');
+                message.innerHTML = &quot;&lt;p&gt;You should also be able to repeat these tests steps for this vertical region.&lt;br/&gt;&quot;
+                messageLocationV.appendChild(message);
+            }
+        }
+        &lt;/script&gt;
+    &lt;/head&gt;
+    &lt;body onload=&quot;onLoad();&quot;&gt;
+        &lt;div style=&quot;position: relative; width: 300px&quot;&gt;
+            &lt;div&gt;Tests that the scroll-snap feature works properly in overflow regions.&lt;/div&gt;
+            &lt;div class=&quot;horizontalGallery&quot; id=&quot;horizontalTarget&quot; style=&quot;-webkit-transform: rotate(20deg)&quot;&gt;
+                &lt;div class=&quot;horizontalGalleryDrawer&quot;&gt;
+                    &lt;div id=&quot;itemH0&quot; class=&quot;colorBox&quot;&gt;&lt;/div&gt;
+                    &lt;div id=&quot;itemH1&quot; class=&quot;colorBox&quot;&gt;&lt;/div&gt;
+                    &lt;div id=&quot;itemH2&quot; class=&quot;colorBox&quot;&gt;&lt;/div&gt;
+                    &lt;div id=&quot;itemH3&quot; class=&quot;colorBox&quot;&gt;&lt;/div&gt;
+                    &lt;div id=&quot;itemH4&quot; class=&quot;colorBox&quot;&gt;&lt;/div&gt;
+                    &lt;div id=&quot;itemH5&quot; class=&quot;colorBox&quot;&gt;&lt;/div&gt;
+                &lt;/div&gt;
+            &lt;/div&gt;
+            &lt;div class=&quot;verticalGallery&quot; id=&quot;verticalTarget&quot; style=&quot;-webkit-transform: rotate(-20deg)&quot;&gt;
+                &lt;div class=&quot;verticalGalleryDrawer&quot;&gt;
+                    &lt;div id=&quot;itemV0&quot; class=&quot;colorBox&quot;&gt;&lt;/div&gt;
+                    &lt;div id=&quot;itemV1&quot; class=&quot;colorBox&quot;&gt;&lt;/div&gt;
+                    &lt;div id=&quot;itemV2&quot; class=&quot;colorBox&quot;&gt;&lt;/div&gt;
+                    &lt;div id=&quot;itemV3&quot; class=&quot;colorBox&quot;&gt;&lt;/div&gt;
+                    &lt;div id=&quot;itemV4&quot; class=&quot;colorBox&quot;&gt;&lt;/div&gt;
+                    &lt;div id=&quot;itemV5&quot; class=&quot;colorBox&quot;&gt;&lt;/div&gt;
+                &lt;/div&gt;
+            &lt;/div&gt;
+            &lt;div id=&quot;console&quot;&gt;&lt;/div&gt;
+        &lt;/div&gt;
+        &lt;script src=&quot;../../../../../resources/js-test-post.js&quot;&gt;&lt;/script&gt;
+    &lt;/body&gt;
+&lt;/html&gt;
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (183905 => 183906)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2015-05-07 02:32:57 UTC (rev 183905)
+++ trunk/Source/WebCore/ChangeLog        2015-05-07 02:53:00 UTC (rev 183906)
</span><span class="lines">@@ -1,3 +1,39 @@
</span><ins>+2015-05-06  Brent Fulgham  &lt;bfulgham@apple.com&gt;
+
+        Scroll-snap points do not handle margins and padding propertly
+        https://bugs.webkit.org/show_bug.cgi?id=144647
+        &lt;rdar://problem/20829473&gt;
+
+        Reviewed by Simon Fraser.
+
+        The calculation of scroll snap points was incorrect because it did not account for margins or padding.
+        This was fixed by using the &quot;paddingBoxRect&quot; to represent the overall size of the view area, and
+        subtracting the relevant padding when computing the size of the scroll snap offsets.
+
+        Extend testing internals with accessor methods to retrieve string representations of the scroll snap
+        offsets and scroll snap coordinates computed during layout. These values are used in the new
+        'css3/scroll-snap/scroll-snap-offsets-and-coordinates.html' test.
+
+        New tests:
+        * css3/scroll-snap/scroll-snap-offsets-and-coordinates.html: Added.
+        * platform/mac-wk2/tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-borders.html: Added.
+        * platform/mac-wk2/tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-padding.html: Added.
+        * platform/mac-wk2/tiled-drawing/scrolling/scroll-snap/scroll-snap-mandatory-rotated.html: Added.
+
+        * css/LengthFunctions.h: Expose the 'valueForLength' method so we can use it in WebCoreTestSupport.
+        * dom/Node.h: Expose the 'renderBox' method so we can use it in WebCoreTestSupport.
+        * page/scrolling/AxisScrollSnapOffsets.cpp:
+        (WebCore::appendChildSnapOffsets): Use 'contentBoxRect' for overall size, so that we don't use padding
+        as part of our offset calculations.
+        (WebCore::updateSnapOffsetsForScrollableArea): Ditto.
+        * rendering/RenderBox.h: Expose 'canBeScrolledAndHasScrollableArea' for use in WebCoreTestSupport.
+        * rendering/style/RenderStyle.h: Expose 'scrollSnapCoordinates' for use in WebCoreTestSupport.
+        * testing/Internals.cpp:
+        (WebCore::appendOffsets): Helper function.
+        (WebCore::Internals::scrollSnapOffsets): Added.
+        * testing/Internals.h:
+        * testing/Internals.idl:
+
</ins><span class="cx"> 2015-05-06  Myles C. Maxfield  &lt;mmaxfield@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Clean up TextRun constructors
</span></span></pre></div>
<a id="trunkSourceWebCorecssLengthFunctionsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/LengthFunctions.h (183905 => 183906)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/LengthFunctions.h        2015-05-07 02:32:57 UTC (rev 183905)
+++ trunk/Source/WebCore/css/LengthFunctions.h        2015-05-07 02:53:00 UTC (rev 183906)
</span><span class="lines">@@ -35,7 +35,7 @@
</span><span class="cx"> int minimumIntValueForLength(const Length&amp;, LayoutUnit maximumValue, bool roundPercentages = false);
</span><span class="cx"> int intValueForLength(const Length&amp;, LayoutUnit maximumValue);
</span><span class="cx"> LayoutUnit minimumValueForLength(const Length&amp;, LayoutUnit maximumValue, bool roundPercentages = false);
</span><del>-LayoutUnit valueForLength(const Length&amp;, LayoutUnit maximumValue);
</del><ins>+WEBCORE_EXPORT LayoutUnit valueForLength(const Length&amp;, LayoutUnit maximumValue);
</ins><span class="cx"> float floatValueForLength(const Length&amp;, LayoutUnit maximumValue);
</span><span class="cx"> WEBCORE_EXPORT float floatValueForLength(const Length&amp;, float maximumValue);
</span><span class="cx"> FloatSize floatSizeForLengthSize(const LengthSize&amp;, const FloatSize&amp;);
</span></span></pre></div>
<a id="trunkSourceWebCoredomNodeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/dom/Node.h (183905 => 183906)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/dom/Node.h        2015-05-07 02:32:57 UTC (rev 183905)
+++ trunk/Source/WebCore/dom/Node.h        2015-05-07 02:53:00 UTC (rev 183906)
</span><span class="lines">@@ -444,7 +444,7 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     // Use these two methods with caution.
</span><del>-    RenderBox* renderBox() const;
</del><ins>+    WEBCORE_EXPORT RenderBox* renderBox() const;
</ins><span class="cx">     RenderBoxModelObject* renderBoxModelObject() const;
</span><span class="cx">     
</span><span class="cx">     // Wrapper for nodes that don't have a renderer, but still cache the style (like HTMLOptionElement).
</span></span></pre></div>
<a id="trunkSourceWebCorepagescrollingAxisScrollSnapOffsetscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/page/scrolling/AxisScrollSnapOffsets.cpp (183905 => 183906)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/page/scrolling/AxisScrollSnapOffsets.cpp        2015-05-07 02:32:57 UTC (rev 183905)
+++ trunk/Source/WebCore/page/scrolling/AxisScrollSnapOffsets.cpp        2015-05-07 02:53:00 UTC (rev 183906)
</span><span class="lines">@@ -43,12 +43,17 @@
</span><span class="cx">     // FIXME: Instead of traversing all children, register children with snap coordinates before appending to snapOffsetSubsequence.
</span><span class="cx">     for (auto&amp; child : childrenOfType&lt;Element&gt;(parent)) {
</span><span class="cx">         if (RenderBox* box = child.renderBox()) {
</span><del>-            LayoutUnit viewWidth = box-&gt;width();
-            LayoutUnit viewHeight = box-&gt;height();
</del><ins>+            const auto&amp; scrollSnapCoordinates = box-&gt;style().scrollSnapCoordinates();
+            if (scrollSnapCoordinates.isEmpty())
+                continue;
+
+            LayoutRect viewSize = box-&gt;contentBoxRect();
+            LayoutUnit viewWidth = viewSize.width();
+            LayoutUnit viewHeight = viewSize.height();
</ins><span class="cx">             FloatPoint position = box-&gt;localToContainerPoint(FloatPoint(), parent.renderBox());
</span><span class="cx">             LayoutUnit left = position.x();
</span><span class="cx">             LayoutUnit top = position.y();
</span><del>-            for (auto&amp; coordinate : box-&gt;style().scrollSnapCoordinates()) {
</del><ins>+            for (auto&amp; coordinate : scrollSnapCoordinates) {
</ins><span class="cx">                 LayoutUnit lastPotentialSnapPositionX = left + valueForLength(coordinate.width(), viewWidth);
</span><span class="cx">                 if (shouldAddHorizontalChildOffsets &amp;&amp; lastPotentialSnapPositionX &gt; 0)
</span><span class="cx">                     horizontalSnapOffsetSubsequence.append(lastPotentialSnapPositionX);
</span><span class="lines">@@ -126,8 +131,9 @@
</span><span class="cx">         return;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    LayoutUnit viewWidth = scrollingElementBox.width();
-    LayoutUnit viewHeight = scrollingElementBox.height();
</del><ins>+    LayoutRect viewSize = scrollingElementBox.contentBoxRect();
+    LayoutUnit viewWidth = viewSize.width();
+    LayoutUnit viewHeight = viewSize.height();
</ins><span class="cx">     LayoutUnit scrollWidth = scrollingElementBox.scrollWidth();
</span><span class="cx">     LayoutUnit scrollHeight = scrollingElementBox.scrollHeight();
</span><span class="cx">     bool canComputeHorizontalOffsets = scrollWidth &gt; 0 &amp;&amp; viewWidth &gt; 0 &amp;&amp; viewWidth &lt; scrollWidth;
</span><span class="lines">@@ -145,7 +151,7 @@
</span><span class="cx">     Vector&lt;LayoutUnit&gt; verticalSnapOffsetSubsequence;
</span><span class="cx"> 
</span><span class="cx">     bool scrollSnapPointsXUsesElements = styleUsesElements(ScrollEventAxis::Horizontal, scrollingElementStyle);
</span><del>-    bool scrollSnapPointsYUsesElements = styleUsesElements(ScrollEventAxis::Vertical , scrollingElementStyle);
</del><ins>+    bool scrollSnapPointsYUsesElements = styleUsesElements(ScrollEventAxis::Vertical, scrollingElementStyle);
</ins><span class="cx"> 
</span><span class="cx">     if (scrollSnapPointsXUsesElements || scrollSnapPointsYUsesElements) {
</span><span class="cx">         bool shouldAddHorizontalChildOffsets = scrollSnapPointsXUsesElements &amp;&amp; canComputeHorizontalOffsets;
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderBoxh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderBox.h (183905 => 183906)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderBox.h        2015-05-07 02:32:57 UTC (rev 183905)
+++ trunk/Source/WebCore/rendering/RenderBox.h        2015-05-07 02:53:00 UTC (rev 183906)
</span><span class="lines">@@ -463,7 +463,7 @@
</span><span class="cx">     int scrollbarLogicalHeight() const { return style().isHorizontalWritingMode() ? horizontalScrollbarHeight() : verticalScrollbarWidth(); }
</span><span class="cx">     virtual bool scroll(ScrollDirection, ScrollGranularity, float multiplier = 1, Element** stopElement = nullptr, RenderBox* startBox = nullptr, const IntPoint&amp; wheelEventAbsolutePoint = IntPoint());
</span><span class="cx">     virtual bool logicalScroll(ScrollLogicalDirection, ScrollGranularity, float multiplier = 1, Element** stopElement = nullptr);
</span><del>-    bool canBeScrolledAndHasScrollableArea() const;
</del><ins>+    WEBCORE_EXPORT bool canBeScrolledAndHasScrollableArea() const;
</ins><span class="cx">     virtual bool canBeProgramaticallyScrolled() const;
</span><span class="cx">     virtual void autoscroll(const IntPoint&amp;);
</span><span class="cx">     bool canAutoscroll() const;
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingstyleRenderStyleh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/style/RenderStyle.h (183905 => 183906)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/style/RenderStyle.h        2015-05-07 02:32:57 UTC (rev 183905)
+++ trunk/Source/WebCore/rendering/style/RenderStyle.h        2015-05-07 02:53:00 UTC (rev 183906)
</span><span class="lines">@@ -1112,7 +1112,7 @@
</span><span class="cx">     const ScrollSnapPoints* scrollSnapPointsX() const;
</span><span class="cx">     const ScrollSnapPoints* scrollSnapPointsY() const;
</span><span class="cx">     const LengthSize&amp; scrollSnapDestination() const;
</span><del>-    const Vector&lt;LengthSize&gt;&amp; scrollSnapCoordinates() const;
</del><ins>+    WEBCORE_EXPORT const Vector&lt;LengthSize&gt;&amp; scrollSnapCoordinates() const;
</ins><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(TOUCH_EVENTS)
</span></span></pre></div>
<a id="trunkSourceWebCoretestingInternalscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/testing/Internals.cpp (183905 => 183906)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/testing/Internals.cpp        2015-05-07 02:32:57 UTC (rev 183905)
+++ trunk/Source/WebCore/testing/Internals.cpp        2015-05-07 02:53:00 UTC (rev 183906)
</span><span class="lines">@@ -2777,4 +2777,61 @@
</span><span class="cx"> }
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><ins>+#if ENABLE(CSS_SCROLL_SNAP)
+static void appendOffsets(StringBuilder&amp; builder, const Vector&lt;LayoutUnit&gt;&amp; snapOffsets)
+{
+    bool justStarting = true;
+
+    builder.append(&quot;{ &quot;);
+    for (auto&amp; coordinate : snapOffsets) {
+        if (!justStarting)
+            builder.append(&quot;, &quot;);
+        else
+            justStarting = false;
+        
+        builder.append(String::number(coordinate.toUnsigned()));
+    }
+    builder.append(&quot; }&quot;);
</ins><span class="cx"> }
</span><ins>+    
+String Internals::scrollSnapOffsets(Element* element, ExceptionCode&amp; ec)
+{
+    if (!element) {
+        ec = INVALID_ACCESS_ERR;
+        return String();
+    }
+
+    if (!element-&gt;renderBox())
+        return String();
+
+    RenderBox&amp; box = *element-&gt;renderBox();
+    if (!box.canBeScrolledAndHasScrollableArea()) {
+        ec = INVALID_ACCESS_ERR;
+        return String();
+    }
+
+    if (!box.layer())
+        return String();
+    
+    ScrollableArea&amp; scrollableArea = *box.layer();
+    
+    StringBuilder result;
+
+    if (scrollableArea.horizontalSnapOffsets()) {
+        result.append(&quot;horizontal = &quot;);
+        appendOffsets(result, *scrollableArea.horizontalSnapOffsets());
+    }
+
+    if (scrollableArea.verticalSnapOffsets()) {
+        if (result.length())
+            result.append(&quot;, &quot;);
+
+        result.append(&quot;vertical = &quot;);
+        appendOffsets(result, *scrollableArea.verticalSnapOffsets());
+    }
+
+    return result.toString();
+}
+#endif
+
+}
</ins></span></pre></div>
<a id="trunkSourceWebCoretestingInternalsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/testing/Internals.h (183905 => 183906)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/testing/Internals.h        2015-05-07 02:32:57 UTC (rev 183905)
+++ trunk/Source/WebCore/testing/Internals.h        2015-05-07 02:53:00 UTC (rev 183906)
</span><span class="lines">@@ -400,6 +400,10 @@
</span><span class="cx">     MockContentFilterSettings&amp; mockContentFilterSettings();
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><ins>+#if ENABLE(CSS_SCROLL_SNAP)
+    String scrollSnapOffsets(Element*, ExceptionCode&amp;);
+#endif
+
</ins><span class="cx"> private:
</span><span class="cx">     explicit Internals(Document*);
</span><span class="cx">     Document* contextDocument() const;
</span></span></pre></div>
<a id="trunkSourceWebCoretestingInternalsidl"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/testing/Internals.idl (183905 => 183906)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/testing/Internals.idl        2015-05-07 02:32:57 UTC (rev 183905)
+++ trunk/Source/WebCore/testing/Internals.idl        2015-05-07 02:53:00 UTC (rev 183906)
</span><span class="lines">@@ -359,4 +359,8 @@
</span><span class="cx">     void queueMicroTask(long testNumber);
</span><span class="cx"> 
</span><span class="cx">     [Conditional=CONTENT_FILTERING] readonly attribute MockContentFilterSettings mockContentFilterSettings;
</span><ins>+
+#if defined(ENABLE_CSS_SCROLL_SNAP) &amp;&amp; ENABLE_CSS_SCROLL_SNAP
+    [RaisesException] DOMString scrollSnapOffsets(Element element);
+#endif
</ins><span class="cx"> };
</span></span></pre>
</div>
</div>

</body>
</html>