<!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>[180987] trunk/Source/WebCore</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/180987">180987</a></dd>
<dt>Author</dt> <dd>bfulgham@apple.com</dd>
<dt>Date</dt> <dd>2015-03-03 20:56:44 -0800 (Tue, 03 Mar 2015)</dd>
</dl>

<h3>Log Message</h3>
<pre>Scroll snap points are not supported on the main frame
https://bugs.webkit.org/show_bug.cgi?id=141973
&lt;rdar://problem/19938393&gt;

Reviewed by Simon Fraser.

No new tests. Tests will be added when the animation behavior is finalized. Manual tests are attached to the bug.

Update the ScrollingTreeFrameScrollingNodeMac class to implement the delegate interface needed by the
ScrollController. This involves the following:
1. Implement scrollOffsetOnAxis: Used by the AxisScrollAnimator to determine the current position of the ScrollableArea.
2. Implement immediateScrollOnAxis: Used by the AxisScrollAnimator to scroll the ScrollableArea

We also need to hold a copy of the snap points vector to send to the scrolling thread.

* page/scrolling/mac/ScrollingTreeFrameScrollingNodeMac.mm:
(WebCore::convertToLayoutUnits): Added helper function to match Scroll Snap Points API.
(WebCore::ScrollingTreeFrameScrollingNodeMac::updateBeforeChildren): Recognize and react to changes to
Scroll Snap Points on top-level frames.
(WebCore::ScrollingTreeFrameScrollingNodeMac::scrollOffsetOnAxis): Implement delegate method needed by the ScrollController.
(WebCore::ScrollingTreeFrameScrollingNodeMac::immediateScrollOnAxis): Ditto.
* platform/cocoa/ScrollController.h:
* platform/cocoa/ScrollController.mm:
(WebCore::ScrollController::updateScrollAnimatorsAndTimers): Pass snap offsets to AxisScrollSnapAnimator constructor as references.
(WebCore::ScrollController::updateScrollSnapPoints): Added. Used by ScrollingTreeFrameScrollingNodeMac to update scroll snap point
settings in the scrolling thread.
* platform/mac/AxisScrollSnapAnimator.h:
* platform/mac/AxisScrollSnapAnimator.mm:
(WebCore::toWheelEventStatus): Don't ignore the &quot;MayBegin&quot; or &quot;Cancelled&quot; event phases.
(WebCore::AxisScrollSnapAnimator::AxisScrollSnapAnimator): Revise signature to take a reference to the layout units.
(WebCore::AxisScrollSnapAnimator::scrollSnapAnimationUpdate): Handle the case where this method gets called from a thread
when the scrollable area has already reached its final destination.
(WebCore::AxisScrollSnapAnimator::beginScrollSnapAnimation): Handle the possibility that the snap offset point vector might be
empty. Update method to account for m_snapOffsets being a value, instead of a pointer.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCorepagescrollingmacScrollingTreeFrameScrollingNodeMacmm">trunk/Source/WebCore/page/scrolling/mac/ScrollingTreeFrameScrollingNodeMac.mm</a></li>
<li><a href="#trunkSourceWebCoreplatformcocoaScrollControllerh">trunk/Source/WebCore/platform/cocoa/ScrollController.h</a></li>
<li><a href="#trunkSourceWebCoreplatformcocoaScrollControllermm">trunk/Source/WebCore/platform/cocoa/ScrollController.mm</a></li>
<li><a href="#trunkSourceWebCoreplatformmacAxisScrollSnapAnimatorh">trunk/Source/WebCore/platform/mac/AxisScrollSnapAnimator.h</a></li>
<li><a href="#trunkSourceWebCoreplatformmacAxisScrollSnapAnimatormm">trunk/Source/WebCore/platform/mac/AxisScrollSnapAnimator.mm</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (180986 => 180987)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2015-03-04 04:47:05 UTC (rev 180986)
+++ trunk/Source/WebCore/ChangeLog        2015-03-04 04:56:44 UTC (rev 180987)
</span><span class="lines">@@ -1,3 +1,40 @@
</span><ins>+2015-03-03  Brent Fulgham  &lt;bfulgham@apple.com&gt;
+
+        Scroll snap points are not supported on the main frame
+        https://bugs.webkit.org/show_bug.cgi?id=141973
+        &lt;rdar://problem/19938393&gt;
+
+        Reviewed by Simon Fraser.
+
+        No new tests. Tests will be added when the animation behavior is finalized. Manual tests are attached to the bug.
+
+        Update the ScrollingTreeFrameScrollingNodeMac class to implement the delegate interface needed by the
+        ScrollController. This involves the following:
+        1. Implement scrollOffsetOnAxis: Used by the AxisScrollAnimator to determine the current position of the ScrollableArea.
+        2. Implement immediateScrollOnAxis: Used by the AxisScrollAnimator to scroll the ScrollableArea
+
+        We also need to hold a copy of the snap points vector to send to the scrolling thread.
+
+        * page/scrolling/mac/ScrollingTreeFrameScrollingNodeMac.mm:
+        (WebCore::convertToLayoutUnits): Added helper function to match Scroll Snap Points API.
+        (WebCore::ScrollingTreeFrameScrollingNodeMac::updateBeforeChildren): Recognize and react to changes to
+        Scroll Snap Points on top-level frames.
+        (WebCore::ScrollingTreeFrameScrollingNodeMac::scrollOffsetOnAxis): Implement delegate method needed by the ScrollController.
+        (WebCore::ScrollingTreeFrameScrollingNodeMac::immediateScrollOnAxis): Ditto.
+        * platform/cocoa/ScrollController.h:
+        * platform/cocoa/ScrollController.mm:
+        (WebCore::ScrollController::updateScrollAnimatorsAndTimers): Pass snap offsets to AxisScrollSnapAnimator constructor as references.
+        (WebCore::ScrollController::updateScrollSnapPoints): Added. Used by ScrollingTreeFrameScrollingNodeMac to update scroll snap point
+        settings in the scrolling thread.
+        * platform/mac/AxisScrollSnapAnimator.h:
+        * platform/mac/AxisScrollSnapAnimator.mm:
+        (WebCore::toWheelEventStatus): Don't ignore the &quot;MayBegin&quot; or &quot;Cancelled&quot; event phases.
+        (WebCore::AxisScrollSnapAnimator::AxisScrollSnapAnimator): Revise signature to take a reference to the layout units.
+        (WebCore::AxisScrollSnapAnimator::scrollSnapAnimationUpdate): Handle the case where this method gets called from a thread
+        when the scrollable area has already reached its final destination.
+        (WebCore::AxisScrollSnapAnimator::beginScrollSnapAnimation): Handle the possibility that the snap offset point vector might be
+        empty. Update method to account for m_snapOffsets being a value, instead of a pointer.
+
</ins><span class="cx"> 2015-03-03  Andy Estes  &lt;aestes@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         [Content Filtering] Separate unblock handling into its own class
</span></span></pre></div>
<a id="trunkSourceWebCorepagescrollingmacScrollingTreeFrameScrollingNodeMacmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/page/scrolling/mac/ScrollingTreeFrameScrollingNodeMac.mm (180986 => 180987)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/page/scrolling/mac/ScrollingTreeFrameScrollingNodeMac.mm        2015-03-04 04:47:05 UTC (rev 180986)
+++ trunk/Source/WebCore/page/scrolling/mac/ScrollingTreeFrameScrollingNodeMac.mm        2015-03-04 04:56:44 UTC (rev 180987)
</span><span class="lines">@@ -68,6 +68,18 @@
</span><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+#if ENABLE(CSS_SCROLL_SNAP)
+static inline Vector&lt;LayoutUnit&gt; convertToLayoutUnits(const Vector&lt;float&gt;&amp; snapOffsetsAsFloat)
+{
+    Vector&lt;LayoutUnit&gt; snapOffsets;
+    snapOffsets.reserveInitialCapacity(snapOffsetsAsFloat.size());
+    for (auto offset : snapOffsetsAsFloat)
+        snapOffsets.append(offset);
+
+    return snapOffsets;
+}
+#endif
+
</ins><span class="cx"> void ScrollingTreeFrameScrollingNodeMac::updateBeforeChildren(const ScrollingStateNode&amp; stateNode)
</span><span class="cx"> {
</span><span class="cx">     ScrollingTreeFrameScrollingNode::updateBeforeChildren(stateNode);
</span><span class="lines">@@ -119,6 +131,14 @@
</span><span class="cx">         if (scrollingTree().scrollingPerformanceLoggingEnabled())
</span><span class="cx">             logWheelEventHandlerCountChanged(scrollingStateNode.wheelEventHandlerCount());
</span><span class="cx">     }
</span><ins>+
+#if ENABLE(CSS_SCROLL_SNAP)
+    if (scrollingStateNode.hasChangedProperty(ScrollingStateFrameScrollingNode::HorizontalSnapOffsets))
+        m_scrollController.updateScrollSnapPoints(ScrollEventAxis::Horizontal, convertToLayoutUnits(scrollingStateNode.horizontalSnapOffsets()));
+
+    if (scrollingStateNode.hasChangedProperty(ScrollingStateFrameScrollingNode::VerticalSnapOffsets))
+        m_scrollController.updateScrollSnapPoints(ScrollEventAxis::Vertical, convertToLayoutUnits(scrollingStateNode.verticalSnapOffsets()));
+#endif
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void ScrollingTreeFrameScrollingNodeMac::updateAfterChildren(const ScrollingStateNode&amp; stateNode)
</span><span class="lines">@@ -521,15 +541,22 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(CSS_SCROLL_SNAP) &amp;&amp; PLATFORM(MAC)
</span><del>-LayoutUnit ScrollingTreeFrameScrollingNodeMac::scrollOffsetOnAxis(ScrollEventAxis)
</del><ins>+LayoutUnit ScrollingTreeFrameScrollingNodeMac::scrollOffsetOnAxis(ScrollEventAxis axis)
</ins><span class="cx"> {
</span><del>-    // Temporary stub until http://webkit.org/b/141973.
-    return 0;
</del><ins>+    const FloatPoint&amp; currentPosition = scrollPosition();
+    return axis == ScrollEventAxis::Horizontal ? currentPosition.x() : currentPosition.y();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-void ScrollingTreeFrameScrollingNodeMac::immediateScrollOnAxis(ScrollEventAxis, float)
</del><ins>+void ScrollingTreeFrameScrollingNodeMac::immediateScrollOnAxis(ScrollEventAxis axis, float delta)
</ins><span class="cx"> {
</span><del>-    // Temporary stub until http://webkit.org/b/141973.
</del><ins>+    const FloatPoint&amp; currentPosition = scrollPosition();
+    FloatPoint change;
+    if (axis == ScrollEventAxis::Horizontal)
+        change = FloatPoint(currentPosition.x() + delta, currentPosition.y());
+    else
+        change = FloatPoint(currentPosition.x(), currentPosition.y() + delta);
+
+    immediateScrollBy(change - currentPosition);
</ins><span class="cx"> }
</span><span class="cx"> #endif
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformcocoaScrollControllerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/cocoa/ScrollController.h (180986 => 180987)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/cocoa/ScrollController.h        2015-03-04 04:47:05 UTC (rev 180986)
+++ trunk/Source/WebCore/platform/cocoa/ScrollController.h        2015-03-04 04:56:44 UTC (rev 180987)
</span><span class="lines">@@ -108,6 +108,7 @@
</span><span class="cx"> #if ENABLE(CSS_SCROLL_SNAP) &amp;&amp; PLATFORM(MAC)
</span><span class="cx">     bool processWheelEventForScrollSnap(const PlatformWheelEvent&amp;);
</span><span class="cx">     void updateScrollAnimatorsAndTimers(const ScrollableArea&amp;);
</span><ins>+    void updateScrollSnapPoints(ScrollEventAxis, const Vector&lt;LayoutUnit&gt;&amp;);
</ins><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx"> private:
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformcocoaScrollControllermm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/cocoa/ScrollController.mm (180986 => 180987)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/cocoa/ScrollController.mm        2015-03-04 04:47:05 UTC (rev 180986)
+++ trunk/Source/WebCore/platform/cocoa/ScrollController.mm        2015-03-04 04:56:44 UTC (rev 180987)
</span><span class="lines">@@ -443,16 +443,26 @@
</span><span class="cx"> {
</span><span class="cx">     // FIXME: Currently, scroll snap animators are recreated even though the snap offsets alone can be updated.
</span><span class="cx">     if (scrollableArea.horizontalSnapOffsets())
</span><del>-        m_horizontalScrollSnapAnimator = std::make_unique&lt;AxisScrollSnapAnimator&gt;(this, scrollableArea.horizontalSnapOffsets(), ScrollEventAxis::Horizontal);
</del><ins>+        m_horizontalScrollSnapAnimator = std::make_unique&lt;AxisScrollSnapAnimator&gt;(this, *scrollableArea.horizontalSnapOffsets(), ScrollEventAxis::Horizontal);
</ins><span class="cx">     else if (m_horizontalScrollSnapAnimator)
</span><span class="cx">         m_horizontalScrollSnapAnimator = nullptr;
</span><span class="cx"> 
</span><span class="cx">     if (scrollableArea.verticalSnapOffsets())
</span><del>-        m_verticalScrollSnapAnimator = std::make_unique&lt;AxisScrollSnapAnimator&gt;(this, scrollableArea.verticalSnapOffsets(), ScrollEventAxis::Vertical);
</del><ins>+        m_verticalScrollSnapAnimator = std::make_unique&lt;AxisScrollSnapAnimator&gt;(this, *scrollableArea.verticalSnapOffsets(), ScrollEventAxis::Vertical);
</ins><span class="cx">     else if (m_verticalScrollSnapAnimator)
</span><span class="cx">         m_verticalScrollSnapAnimator = nullptr;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void ScrollController::updateScrollSnapPoints(ScrollEventAxis axis, const Vector&lt;LayoutUnit&gt;&amp; snapPoints)
+{
+    // FIXME: Currently, scroll snap animators are recreated even though the snap offsets alone can be updated.
+    if (axis == ScrollEventAxis::Horizontal)
+        m_horizontalScrollSnapAnimator = std::make_unique&lt;AxisScrollSnapAnimator&gt;(this, snapPoints, ScrollEventAxis::Horizontal);
+
+    if (axis == ScrollEventAxis::Vertical)
+        m_verticalScrollSnapAnimator = std::make_unique&lt;AxisScrollSnapAnimator&gt;(this, snapPoints, ScrollEventAxis::Vertical);
+}
+
</ins><span class="cx"> void ScrollController::startScrollSnapTimer(ScrollEventAxis axis)
</span><span class="cx"> {
</span><span class="cx">     RunLoop::Timer&lt;ScrollController&gt;&amp; scrollSnapTimer = axis == ScrollEventAxis::Horizontal ? m_horizontalScrollSnapTimer : m_verticalScrollSnapTimer;
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformmacAxisScrollSnapAnimatorh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/mac/AxisScrollSnapAnimator.h (180986 => 180987)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/mac/AxisScrollSnapAnimator.h        2015-03-04 04:47:05 UTC (rev 180986)
+++ trunk/Source/WebCore/platform/mac/AxisScrollSnapAnimator.h        2015-03-04 04:56:44 UTC (rev 180987)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2014 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2014-2015 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -65,7 +65,7 @@
</span><span class="cx"> 
</span><span class="cx"> class AxisScrollSnapAnimator {
</span><span class="cx"> public:
</span><del>-    AxisScrollSnapAnimator(AxisScrollSnapAnimatorClient*, const Vector&lt;LayoutUnit&gt;* snapOffsets, ScrollEventAxis);
</del><ins>+    AxisScrollSnapAnimator(AxisScrollSnapAnimatorClient*, const Vector&lt;LayoutUnit&gt;&amp;, ScrollEventAxis);
</ins><span class="cx">     void handleWheelEvent(const PlatformWheelEvent&amp;);
</span><span class="cx">     bool shouldOverrideWheelEvent(const PlatformWheelEvent&amp;) const;
</span><span class="cx">     void scrollSnapAnimationUpdate();
</span><span class="lines">@@ -85,7 +85,7 @@
</span><span class="cx">     static const int wheelDeltaWindowSize = 3;
</span><span class="cx"> 
</span><span class="cx">     AxisScrollSnapAnimatorClient* m_client;
</span><del>-    const Vector&lt;LayoutUnit&gt;* m_snapOffsets;
</del><ins>+    Vector&lt;LayoutUnit&gt; m_snapOffsets;
</ins><span class="cx">     ScrollEventAxis m_axis;
</span><span class="cx">     // Used to track both snapping and gliding behaviors.
</span><span class="cx">     ScrollSnapState m_currentState;
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformmacAxisScrollSnapAnimatormm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/mac/AxisScrollSnapAnimator.mm (180986 => 180987)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/mac/AxisScrollSnapAnimator.mm        2015-03-04 04:47:05 UTC (rev 180986)
+++ trunk/Source/WebCore/platform/mac/AxisScrollSnapAnimator.mm        2015-03-04 04:56:44 UTC (rev 180987)
</span><span class="lines">@@ -60,12 +60,14 @@
</span><span class="cx">     if (momentumPhase == PlatformWheelEventPhaseNone) {
</span><span class="cx">         switch (phase) {
</span><span class="cx">         case PlatformWheelEventPhaseBegan:
</span><ins>+        case PlatformWheelEventPhaseMayBegin:
</ins><span class="cx">             return WheelEventStatus::UserScrollBegin;
</span><span class="cx"> 
</span><span class="cx">         case PlatformWheelEventPhaseChanged:
</span><span class="cx">             return WheelEventStatus::UserScrolling;
</span><span class="cx"> 
</span><span class="cx">         case PlatformWheelEventPhaseEnded:
</span><ins>+        case PlatformWheelEventPhaseCancelled:
</ins><span class="cx">             return WheelEventStatus::UserScrollEnd;
</span><span class="cx"> 
</span><span class="cx">         default:
</span><span class="lines">@@ -82,7 +84,7 @@
</span><span class="cx">     return inertialScrollPredictionFactor * initialWheelDelta;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-AxisScrollSnapAnimator::AxisScrollSnapAnimator(AxisScrollSnapAnimatorClient* client, const Vector&lt;LayoutUnit&gt;* snapOffsets, ScrollEventAxis axis)
</del><ins>+AxisScrollSnapAnimator::AxisScrollSnapAnimator(AxisScrollSnapAnimatorClient* client, const Vector&lt;LayoutUnit&gt;&amp; snapOffsets, ScrollEventAxis axis)
</ins><span class="cx">     : m_client(client)
</span><span class="cx">     , m_snapOffsets(snapOffsets)
</span><span class="cx">     , m_axis(axis)
</span><span class="lines">@@ -150,6 +152,9 @@
</span><span class="cx"> 
</span><span class="cx"> void AxisScrollSnapAnimator::scrollSnapAnimationUpdate()
</span><span class="cx"> {
</span><ins>+    if (m_currentState == ScrollSnapState::DestinationReached)
+        return;
+
</ins><span class="cx">     ASSERT(m_currentState == ScrollSnapState::Gliding || m_currentState == ScrollSnapState::Snapping);
</span><span class="cx">     float delta = m_currentState == ScrollSnapState::Snapping ? computeSnapDelta() : computeGlideDelta();
</span><span class="cx">     if (delta)
</span><span class="lines">@@ -164,9 +169,12 @@
</span><span class="cx">     LayoutUnit offset = m_client-&gt;scrollOffsetOnAxis(m_axis);
</span><span class="cx">     float initialWheelDelta = newState == ScrollSnapState::Gliding ? averageInitialWheelDelta() : 0;
</span><span class="cx">     LayoutUnit projectedScrollDestination = newState == ScrollSnapState::Gliding ? m_beginTrackingWheelDeltaOffset + LayoutUnit(projectedInertialScrollDistance(initialWheelDelta)) : offset;
</span><del>-    projectedScrollDestination = std::min(std::max(projectedScrollDestination, m_snapOffsets-&gt;first()), m_snapOffsets-&gt;last());
</del><ins>+    if (m_snapOffsets.isEmpty())
+        return;
+
+    projectedScrollDestination = std::min(std::max(projectedScrollDestination, m_snapOffsets.first()), m_snapOffsets.last());
</ins><span class="cx">     m_initialOffset = offset;
</span><del>-    m_targetOffset = closestSnapOffset&lt;LayoutUnit, float&gt;(*m_snapOffsets, projectedScrollDestination, initialWheelDelta);
</del><ins>+    m_targetOffset = closestSnapOffset&lt;LayoutUnit, float&gt;(m_snapOffsets, projectedScrollDestination, initialWheelDelta);
</ins><span class="cx">     if (m_initialOffset == m_targetOffset)
</span><span class="cx">         return;
</span><span class="cx"> 
</span></span></pre>
</div>
</div>

</body>
</html>