<!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>[183702] 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/183702">183702</a></dd>
<dt>Author</dt> <dd>bfulgham@apple.com</dd>
<dt>Date</dt> <dd>2015-05-01 17:39:37 -0700 (Fri, 01 May 2015)</dd>
</dl>

<h3>Log Message</h3>
<pre>Expand test infrastructure to support scrolling tests (Part 4): Scroll Snap Support
https://bugs.webkit.org/show_bug.cgi?id=144482

Reviewed by Simon Fraser.

New tests will be landed in a second patch.

The new WheelEventTestTriggers do not work properly with scroll snap points, because some test deferral notifications
need to be triggered for state changes on the scrolling thread. This required the following changes:
1. A flag indicating that we want to know about WheelEvent state changes needed to be propagated to the scrolling thread,
   so that tests could be deferred until Scrolling thread rubberband or scroll-snap animations had completed.
2. The ScrollingNodeID needed to be used for registering and clearing deferrals.
3. The scrolling thread needed a way to dispatch messages to the main thread indicating that we should (or should not)
   defer tests due to scrolling actions.

Note that a future patch will extend this support to include the RemoteScrollingTree.

* page/WheelEventTestTrigger.cpp:
(WebCore::WheelEventTestTrigger::deferTestsForReason): Added some logging features.
(WebCore::WheelEventTestTrigger::removeTestDeferralForReason): Ditto.
(WebCore::dumpState): Helper function for logging test deferral state.
(WebCore::WheelEventTestTrigger::triggerTestTimerFired): Added some logging features.
* page/scrolling/AsyncScrollingCoordinator.cpp:
(WebCore::AsyncScrollingCoordinator::frameViewLayoutUpdated): Make sure that the scrolling thread is
told that it needs to send scrolling state back to the main thread. Only do this if we are in testing mode.
(WebCore::AsyncScrollingCoordinator::updateScrollPositionAfterAsyncScroll): The scrollingNodeID should be
used as the identifier for this operation, not the page address.
(WebCore::AsyncScrollingCoordinator::deferTestsForReason): Added. receives messages from the scrolling thread
and notifies the testing infrastructure.
(WebCore::AsyncScrollingCoordinator::removeTestDeferralForReason): Ditto.
* page/scrolling/AsyncScrollingCoordinator.h:
* page/scrolling/ScrollingStateScrollingNode.cpp:
(WebCore::ScrollingStateScrollingNode::ScrollingStateScrollingNode): When cloning the ScrollingStateScrollingNode,
include the testing mode state.
(WebCore::ScrollingStateScrollingNode::setExpectsWheelEventTestTrigger): Added.
* page/scrolling/ScrollingStateScrollingNode.h:
(WebCore::ScrollingStateScrollingNode::expectsWheelEventTestTrigger): Added.
* page/scrolling/ScrollingTree.h:
(WebCore::ScrollingTree::deferTestsForReason): Added stub.
(WebCore::ScrollingTree::removeTestDeferralForReason): Ditto.
* page/scrolling/ThreadedScrollingTree.cpp:
(WebCore::ThreadedScrollingTree::deferTestsForReason): Added. Dispatches messages from the scrolling thread to the
main thread.
(WebCore::ThreadedScrollingTree::removeTestDeferralForReason): Ditto.
* page/scrolling/ThreadedScrollingTree.h:
* page/scrolling/mac/ScrollingTreeFrameScrollingNodeMac.h:
* page/scrolling/mac/ScrollingTreeFrameScrollingNodeMac.mm:
(WebCore::ScrollingTreeFrameScrollingNodeMac::ScrollingTreeFrameScrollingNodeMac): Initialize testing state flag.
(WebCore::ScrollingTreeFrameScrollingNodeMac::updateBeforeChildren): If the 'ExpectsWheelEventTestTrigger' flag is
set, update local state.
(WebCore::ScrollingTreeFrameScrollingNodeMac::handleWheelEvent): If we are testing, and the wheel event should be handled
asynchronously, tell the testing infrastructure we need to wait for the thread state to sync.
(WebCore::ScrollingTreeFrameScrollingNodeMac::deferTestsForReason): Added. Notifies test system we need to defer tests
until we notify them. Also used by the ScrollController during animations.
(WebCore::ScrollingTreeFrameScrollingNodeMac::removeTestDeferralForReason): Ditto.
* platform/Logging.h:
* platform/ScrollAnimator.cpp:
(WebCore::ScrollAnimator::deferTestsForReason): Added. Used by ScrollController during animation. This updates the
testing infrastructure directly, since it is running in the same process and main thread.
(WebCore::ScrollAnimator::removeTestDeferralForReason): Ditto.
* platform/ScrollAnimator.h:
* platform/cocoa/ScrollController.h:
(WebCore::ScrollControllerClient::deferTestsForReason): Change client API.
(WebCore::ScrollControllerClient::removeTestDeferralForReason): Ditto.
(WebCore::ScrollControllerClient::testTrigger): Deleted.
* platform/cocoa/ScrollController.mm:
(WebCore::ScrollController::startSnapRubberbandTimer): Use new client API.
(WebCore::ScrollController::stopSnapRubberbandTimer): Ditto.
(WebCore::ScrollController::startScrollSnapTimer): Ditto.
(WebCore::ScrollController::stopScrollSnapTimer): Ditto.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCorepageWheelEventTestTriggercpp">trunk/Source/WebCore/page/WheelEventTestTrigger.cpp</a></li>
<li><a href="#trunkSourceWebCorepagescrollingAsyncScrollingCoordinatorcpp">trunk/Source/WebCore/page/scrolling/AsyncScrollingCoordinator.cpp</a></li>
<li><a href="#trunkSourceWebCorepagescrollingAsyncScrollingCoordinatorh">trunk/Source/WebCore/page/scrolling/AsyncScrollingCoordinator.h</a></li>
<li><a href="#trunkSourceWebCorepagescrollingScrollingStateScrollingNodecpp">trunk/Source/WebCore/page/scrolling/ScrollingStateScrollingNode.cpp</a></li>
<li><a href="#trunkSourceWebCorepagescrollingScrollingStateScrollingNodeh">trunk/Source/WebCore/page/scrolling/ScrollingStateScrollingNode.h</a></li>
<li><a href="#trunkSourceWebCorepagescrollingScrollingTreeh">trunk/Source/WebCore/page/scrolling/ScrollingTree.h</a></li>
<li><a href="#trunkSourceWebCorepagescrollingThreadedScrollingTreecpp">trunk/Source/WebCore/page/scrolling/ThreadedScrollingTree.cpp</a></li>
<li><a href="#trunkSourceWebCorepagescrollingThreadedScrollingTreeh">trunk/Source/WebCore/page/scrolling/ThreadedScrollingTree.h</a></li>
<li><a href="#trunkSourceWebCorepagescrollingmacScrollingTreeFrameScrollingNodeMach">trunk/Source/WebCore/page/scrolling/mac/ScrollingTreeFrameScrollingNodeMac.h</a></li>
<li><a href="#trunkSourceWebCorepagescrollingmacScrollingTreeFrameScrollingNodeMacmm">trunk/Source/WebCore/page/scrolling/mac/ScrollingTreeFrameScrollingNodeMac.mm</a></li>
<li><a href="#trunkSourceWebCoreplatformLoggingh">trunk/Source/WebCore/platform/Logging.h</a></li>
<li><a href="#trunkSourceWebCoreplatformScrollAnimatorcpp">trunk/Source/WebCore/platform/ScrollAnimator.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformScrollAnimatorh">trunk/Source/WebCore/platform/ScrollAnimator.h</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>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (183701 => 183702)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2015-05-02 00:23:58 UTC (rev 183701)
+++ trunk/Source/WebCore/ChangeLog        2015-05-02 00:39:37 UTC (rev 183702)
</span><span class="lines">@@ -1,3 +1,76 @@
</span><ins>+2015-05-01  Brent Fulgham  &lt;bfulgham@apple.com&gt;
+
+        Expand test infrastructure to support scrolling tests (Part 4): Scroll Snap Support
+        https://bugs.webkit.org/show_bug.cgi?id=144482
+
+        Reviewed by Simon Fraser.
+
+        New tests will be landed in a second patch.
+
+        The new WheelEventTestTriggers do not work properly with scroll snap points, because some test deferral notifications
+        need to be triggered for state changes on the scrolling thread. This required the following changes:
+        1. A flag indicating that we want to know about WheelEvent state changes needed to be propagated to the scrolling thread,
+           so that tests could be deferred until Scrolling thread rubberband or scroll-snap animations had completed.
+        2. The ScrollingNodeID needed to be used for registering and clearing deferrals.
+        3. The scrolling thread needed a way to dispatch messages to the main thread indicating that we should (or should not)
+           defer tests due to scrolling actions.
+
+        Note that a future patch will extend this support to include the RemoteScrollingTree.
+
+        * page/WheelEventTestTrigger.cpp:
+        (WebCore::WheelEventTestTrigger::deferTestsForReason): Added some logging features.
+        (WebCore::WheelEventTestTrigger::removeTestDeferralForReason): Ditto.
+        (WebCore::dumpState): Helper function for logging test deferral state.
+        (WebCore::WheelEventTestTrigger::triggerTestTimerFired): Added some logging features.
+        * page/scrolling/AsyncScrollingCoordinator.cpp:
+        (WebCore::AsyncScrollingCoordinator::frameViewLayoutUpdated): Make sure that the scrolling thread is
+        told that it needs to send scrolling state back to the main thread. Only do this if we are in testing mode.
+        (WebCore::AsyncScrollingCoordinator::updateScrollPositionAfterAsyncScroll): The scrollingNodeID should be
+        used as the identifier for this operation, not the page address.
+        (WebCore::AsyncScrollingCoordinator::deferTestsForReason): Added. receives messages from the scrolling thread
+        and notifies the testing infrastructure.
+        (WebCore::AsyncScrollingCoordinator::removeTestDeferralForReason): Ditto.
+        * page/scrolling/AsyncScrollingCoordinator.h:
+        * page/scrolling/ScrollingStateScrollingNode.cpp:
+        (WebCore::ScrollingStateScrollingNode::ScrollingStateScrollingNode): When cloning the ScrollingStateScrollingNode,
+        include the testing mode state.
+        (WebCore::ScrollingStateScrollingNode::setExpectsWheelEventTestTrigger): Added.
+        * page/scrolling/ScrollingStateScrollingNode.h:
+        (WebCore::ScrollingStateScrollingNode::expectsWheelEventTestTrigger): Added.
+        * page/scrolling/ScrollingTree.h:
+        (WebCore::ScrollingTree::deferTestsForReason): Added stub.
+        (WebCore::ScrollingTree::removeTestDeferralForReason): Ditto.
+        * page/scrolling/ThreadedScrollingTree.cpp:
+        (WebCore::ThreadedScrollingTree::deferTestsForReason): Added. Dispatches messages from the scrolling thread to the
+        main thread.
+        (WebCore::ThreadedScrollingTree::removeTestDeferralForReason): Ditto.
+        * page/scrolling/ThreadedScrollingTree.h:
+        * page/scrolling/mac/ScrollingTreeFrameScrollingNodeMac.h:
+        * page/scrolling/mac/ScrollingTreeFrameScrollingNodeMac.mm:
+        (WebCore::ScrollingTreeFrameScrollingNodeMac::ScrollingTreeFrameScrollingNodeMac): Initialize testing state flag.
+        (WebCore::ScrollingTreeFrameScrollingNodeMac::updateBeforeChildren): If the 'ExpectsWheelEventTestTrigger' flag is
+        set, update local state.
+        (WebCore::ScrollingTreeFrameScrollingNodeMac::handleWheelEvent): If we are testing, and the wheel event should be handled
+        asynchronously, tell the testing infrastructure we need to wait for the thread state to sync.
+        (WebCore::ScrollingTreeFrameScrollingNodeMac::deferTestsForReason): Added. Notifies test system we need to defer tests
+        until we notify them. Also used by the ScrollController during animations.
+        (WebCore::ScrollingTreeFrameScrollingNodeMac::removeTestDeferralForReason): Ditto.
+        * platform/Logging.h:
+        * platform/ScrollAnimator.cpp:
+        (WebCore::ScrollAnimator::deferTestsForReason): Added. Used by ScrollController during animation. This updates the
+        testing infrastructure directly, since it is running in the same process and main thread.
+        (WebCore::ScrollAnimator::removeTestDeferralForReason): Ditto.
+        * platform/ScrollAnimator.h:
+        * platform/cocoa/ScrollController.h:
+        (WebCore::ScrollControllerClient::deferTestsForReason): Change client API.
+        (WebCore::ScrollControllerClient::removeTestDeferralForReason): Ditto.
+        (WebCore::ScrollControllerClient::testTrigger): Deleted.
+        * platform/cocoa/ScrollController.mm:
+        (WebCore::ScrollController::startSnapRubberbandTimer): Use new client API.
+        (WebCore::ScrollController::stopSnapRubberbandTimer): Ditto.
+        (WebCore::ScrollController::startScrollSnapTimer): Ditto.
+        (WebCore::ScrollController::stopScrollSnapTimer): Ditto.
+
</ins><span class="cx"> 2015-05-01  Joseph Pecoraro  &lt;pecoraro@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Inline some small methods instead of them being EXPORT'd and out of line
</span></span></pre></div>
<a id="trunkSourceWebCorepageWheelEventTestTriggercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/page/WheelEventTestTrigger.cpp (183701 => 183702)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/page/WheelEventTestTrigger.cpp        2015-05-02 00:23:58 UTC (rev 183701)
+++ trunk/Source/WebCore/page/WheelEventTestTrigger.cpp        2015-05-02 00:39:37 UTC (rev 183702)
</span><span class="lines">@@ -29,6 +29,13 @@
</span><span class="cx"> #include &quot;config.h&quot;
</span><span class="cx"> #include &quot;WheelEventTestTrigger.h&quot;
</span><span class="cx"> 
</span><ins>+#include &quot;Logging.h&quot;
+
+#if !LOG_DISABLED
+#include &lt;wtf/text/CString.h&gt;
+#include &lt;wtf/text/StringBuilder.h&gt;
+#endif
+
</ins><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><span class="cx"> WheelEventTestTrigger::WheelEventTestTrigger()
</span><span class="lines">@@ -42,6 +49,7 @@
</span><span class="cx">     m_deferTestTriggerReasons.clear();
</span><span class="cx">     m_testNotificationCallback = std::function&lt;void()&gt;();
</span><span class="cx">     m_testTriggerTimer.stop();
</span><ins>+    LOG(WheelEventTestTriggers, &quot;      (=) WheelEventTestTrigger::clearAllTestDeferrals: cleared all test state.&quot;);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void WheelEventTestTrigger::setTestCallbackAndStartNotificationTimer(std::function&lt;void()&gt; functionCallback)
</span><span class="lines">@@ -62,6 +70,7 @@
</span><span class="cx">     if (it == m_deferTestTriggerReasons.end())
</span><span class="cx">         it = m_deferTestTriggerReasons.add(identifier, std::set&lt;DeferTestTriggerReason&gt;()).iterator;
</span><span class="cx">     
</span><ins>+    LOG(WheelEventTestTriggers, &quot;      (=) WheelEventTestTrigger::deferTestsForReason: id=%p, reason=%d&quot;, identifier, reason);
</ins><span class="cx">     it-&gt;value.insert(reason);
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -72,20 +81,43 @@
</span><span class="cx">     if (it == m_deferTestTriggerReasons.end())
</span><span class="cx">         return;
</span><span class="cx"> 
</span><ins>+    LOG(WheelEventTestTriggers, &quot;      (=) WheelEventTestTrigger::removeTestDeferralForReason: id=%p, reason=%d&quot;, identifier, reason);
</ins><span class="cx">     it-&gt;value.erase(reason);
</span><span class="cx">     
</span><span class="cx">     if (it-&gt;value.empty())
</span><span class="cx">         m_deferTestTriggerReasons.remove(it);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+#if !LOG_DISABLED
+static void dumpState(WTF::HashMap&lt;WheelEventTestTrigger::ScrollableAreaIdentifier, std::set&lt;WheelEventTestTrigger::DeferTestTriggerReason&gt;&gt; reasons)
+{
+    LOG(WheelEventTestTriggers, &quot;   WheelEventTestTrigger::dumpState:&quot;);
+    for (const auto&amp; scrollRegion : reasons) {
+        LOG(WheelEventTestTriggers, &quot;   For scroll region %p&quot;, scrollRegion.key);
+        StringBuilder reasons;
+        for (const auto&amp; reason : scrollRegion.value) {
+            if (!reasons.isEmpty())
+                reasons.append(&quot;, &quot;);
+            reasons.append(String::number(reason));
+        }
+        LOG(WheelEventTestTriggers, &quot;     Reasons: %s&quot;, reasons.toString().utf8().data());
+    }
+}
+#endif
+    
</ins><span class="cx"> void WheelEventTestTrigger::triggerTestTimerFired()
</span><span class="cx"> {
</span><span class="cx">     std::function&lt;void()&gt; functionCallback;
</span><span class="cx"> 
</span><span class="cx">     {
</span><span class="cx">         std::lock_guard&lt;std::mutex&gt; lock(m_testTriggerMutex);
</span><del>-        if (!m_deferTestTriggerReasons.isEmpty())
</del><ins>+        if (!m_deferTestTriggerReasons.isEmpty()) {
+#if !LOG_DISABLED
+            if (isLogChannelEnabled(&quot;WheelEventTestTrigger&quot;))
+                dumpState(m_deferTestTriggerReasons);
+#endif
</ins><span class="cx">             return;
</span><ins>+        }
</ins><span class="cx"> 
</span><span class="cx">         functionCallback = WTF::move(m_testNotificationCallback);
</span><span class="cx">         m_testNotificationCallback = std::function&lt;void()&gt;();
</span><span class="lines">@@ -93,6 +125,7 @@
</span><span class="cx"> 
</span><span class="cx">     m_testTriggerTimer.stop();
</span><span class="cx"> 
</span><ins>+    LOG(WheelEventTestTriggers, &quot;  WheelEventTestTrigger::triggerTestTimerFired: FIRING TEST&quot;);
</ins><span class="cx">     if (functionCallback)
</span><span class="cx">         functionCallback();
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebCorepagescrollingAsyncScrollingCoordinatorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/page/scrolling/AsyncScrollingCoordinator.cpp (183701 => 183702)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/page/scrolling/AsyncScrollingCoordinator.cpp        2015-05-02 00:23:58 UTC (rev 183701)
+++ trunk/Source/WebCore/page/scrolling/AsyncScrollingCoordinator.cpp        2015-05-02 00:39:37 UTC (rev 183702)
</span><span class="lines">@@ -32,6 +32,7 @@
</span><span class="cx"> #include &quot;Frame.h&quot;
</span><span class="cx"> #include &quot;FrameView.h&quot;
</span><span class="cx"> #include &quot;GraphicsLayer.h&quot;
</span><ins>+#include &quot;Logging.h&quot;
</ins><span class="cx"> #include &quot;MainFrame.h&quot;
</span><span class="cx"> #include &quot;Page.h&quot;
</span><span class="cx"> #include &quot;ScrollAnimator.h&quot;
</span><span class="lines">@@ -147,6 +148,14 @@
</span><span class="cx">         setStateScrollingNodeSnapOffsetsAsFloat(*node, ScrollEventAxis::Vertical, *verticalSnapOffsets, m_page-&gt;deviceScaleFactor());
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><ins>+#if PLATFORM(COCOA)
+    Page* page = frameView.frame().page();
+    if (page &amp;&amp; page-&gt;expectsWheelEventTriggers()) {
+        LOG(WheelEventTestTriggers, &quot;    AsyncScrollingCoordinator::frameViewLayoutUpdated: Expects wheel event test trigger=%d&quot;, page-&gt;expectsWheelEventTriggers());
+        node-&gt;setExpectsWheelEventTestTrigger(page-&gt;expectsWheelEventTriggers());
+    }
+#endif
+
</ins><span class="cx">     ScrollableAreaParameters scrollParameters;
</span><span class="cx">     scrollParameters.horizontalScrollElasticity = frameView.horizontalScrollElasticity();
</span><span class="cx">     scrollParameters.verticalScrollElasticity = frameView.verticalScrollElasticity();
</span><span class="lines">@@ -361,7 +370,7 @@
</span><span class="cx">         if (m_page-&gt;expectsWheelEventTriggers()) {
</span><span class="cx">             frameView.scrollAnimator().setWheelEventTestTrigger(m_page-&gt;testTrigger());
</span><span class="cx">             if (const auto&amp; trigger = m_page-&gt;testTrigger())
</span><del>-                trigger-&gt;removeTestDeferralForReason(reinterpret_cast&lt;WheelEventTestTrigger::ScrollableAreaIdentifier&gt;(m_page), WheelEventTestTrigger::ScrollingThreadSyncNeeded);
</del><ins>+                trigger-&gt;removeTestDeferralForReason(reinterpret_cast&lt;WheelEventTestTrigger::ScrollableAreaIdentifier&gt;(scrollingNodeID), WheelEventTestTrigger::ScrollingThreadSyncNeeded);
</ins><span class="cx">         }
</span><span class="cx"> #endif
</span><span class="cx">         
</span><span class="lines">@@ -380,7 +389,7 @@
</span><span class="cx">         if (m_page-&gt;expectsWheelEventTriggers()) {
</span><span class="cx">             frameView.scrollAnimator().setWheelEventTestTrigger(m_page-&gt;testTrigger());
</span><span class="cx">             if (const auto&amp; trigger = m_page-&gt;testTrigger())
</span><del>-                trigger-&gt;removeTestDeferralForReason(reinterpret_cast&lt;WheelEventTestTrigger::ScrollableAreaIdentifier&gt;(m_page), WheelEventTestTrigger::ScrollingThreadSyncNeeded);
</del><ins>+                trigger-&gt;removeTestDeferralForReason(reinterpret_cast&lt;WheelEventTestTrigger::ScrollableAreaIdentifier&gt;(scrollingNodeID), WheelEventTestTrigger::ScrollingThreadSyncNeeded);
</ins><span class="cx">         }
</span><span class="cx"> #endif
</span><span class="cx">     }
</span><span class="lines">@@ -552,6 +561,30 @@
</span><span class="cx">     return String();
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+#if PLATFORM(COCOA)
+void AsyncScrollingCoordinator::deferTestsForReason(WheelEventTestTrigger::ScrollableAreaIdentifier identifier, WheelEventTestTrigger::DeferTestTriggerReason reason) const
+{
+    if (!m_page || !m_page-&gt;expectsWheelEventTriggers())
+        return;
+
+    if (const auto&amp; trigger = m_page-&gt;testTrigger()) {
+        LOG(WheelEventTestTriggers, &quot;    (!) AsyncScrollingCoordinator::deferTestsForReason: Deferring %p for reason %d.&quot;, identifier, reason);
+        trigger-&gt;deferTestsForReason(identifier, reason);
+    }
+}
+
+void AsyncScrollingCoordinator::removeTestDeferralForReason(WheelEventTestTrigger::ScrollableAreaIdentifier identifier, WheelEventTestTrigger::DeferTestTriggerReason reason) const
+{
+    if (!m_page || !m_page-&gt;expectsWheelEventTriggers())
+        return;
+
+    if (const auto&amp; trigger = m_page-&gt;testTrigger()) {
+        LOG(WheelEventTestTriggers, &quot;    (!) AsyncScrollingCoordinator::removeTestDeferralForReason: Deferring %p for reason %d.&quot;, identifier, reason);
+        trigger-&gt;removeTestDeferralForReason(identifier, reason);
+    }
+}
+#endif
+
</ins><span class="cx"> } // namespace WebCore
</span><span class="cx"> 
</span><span class="cx"> #endif // ENABLE(ASYNC_SCROLLING)
</span></span></pre></div>
<a id="trunkSourceWebCorepagescrollingAsyncScrollingCoordinatorh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/page/scrolling/AsyncScrollingCoordinator.h (183701 => 183702)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/page/scrolling/AsyncScrollingCoordinator.h        2015-05-02 00:23:58 UTC (rev 183701)
+++ trunk/Source/WebCore/page/scrolling/AsyncScrollingCoordinator.h        2015-05-02 00:39:37 UTC (rev 183702)
</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">@@ -56,6 +56,11 @@
</span><span class="cx"> 
</span><span class="cx">     WEBCORE_EXPORT void scheduleUpdateScrollPositionAfterAsyncScroll(ScrollingNodeID, const FloatPoint&amp;, bool programmaticScroll, SetOrSyncScrollingLayerPosition);
</span><span class="cx"> 
</span><ins>+#if PLATFORM(COCOA)
+    void deferTestsForReason(WheelEventTestTrigger::ScrollableAreaIdentifier, WheelEventTestTrigger::DeferTestTriggerReason) const;
+    void removeTestDeferralForReason(WheelEventTestTrigger::ScrollableAreaIdentifier, WheelEventTestTrigger::DeferTestTriggerReason) const;
+#endif
+
</ins><span class="cx"> protected:
</span><span class="cx">     WEBCORE_EXPORT AsyncScrollingCoordinator(Page*);
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCorepagescrollingScrollingStateScrollingNodecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/page/scrolling/ScrollingStateScrollingNode.cpp (183701 => 183702)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/page/scrolling/ScrollingStateScrollingNode.cpp        2015-05-02 00:23:58 UTC (rev 183701)
+++ trunk/Source/WebCore/page/scrolling/ScrollingStateScrollingNode.cpp        2015-05-02 00:39:37 UTC (rev 183702)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2012 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2012, 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">@@ -35,7 +35,6 @@
</span><span class="cx"> 
</span><span class="cx"> ScrollingStateScrollingNode::ScrollingStateScrollingNode(ScrollingStateTree&amp; stateTree, ScrollingNodeType nodeType, ScrollingNodeID nodeID)
</span><span class="cx">     : ScrollingStateNode(nodeType, stateTree, nodeID)
</span><del>-    , m_requestedScrollPositionRepresentsProgrammaticScroll(false)
</del><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -53,6 +52,7 @@
</span><span class="cx"> #endif
</span><span class="cx">     , m_scrollableAreaParameters(stateNode.scrollableAreaParameters())
</span><span class="cx">     , m_requestedScrollPositionRepresentsProgrammaticScroll(stateNode.requestedScrollPositionRepresentsProgrammaticScroll())
</span><ins>+    , m_expectsWheelEventTestTrigger(stateNode.expectsWheelEventTestTrigger())
</ins><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -141,6 +141,15 @@
</span><span class="cx">     setPropertyChanged(RequestedScrollPosition);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void ScrollingStateScrollingNode::setExpectsWheelEventTestTrigger(bool expectsTestTrigger)
+{
+    if (expectsTestTrigger == m_expectsWheelEventTestTrigger)
+        return;
+
+    m_expectsWheelEventTestTrigger = expectsTestTrigger;
+    setPropertyChanged(ExpectsWheelEventTestTrigger);
+}
+
</ins><span class="cx"> void ScrollingStateScrollingNode::dumpProperties(TextStream&amp; ts, int indent) const
</span><span class="cx"> {
</span><span class="cx">     if (m_scrollPosition != FloatPoint()) {
</span></span></pre></div>
<a id="trunkSourceWebCorepagescrollingScrollingStateScrollingNodeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/page/scrolling/ScrollingStateScrollingNode.h (183701 => 183702)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/page/scrolling/ScrollingStateScrollingNode.h        2015-05-02 00:23:58 UTC (rev 183701)
+++ trunk/Source/WebCore/page/scrolling/ScrollingStateScrollingNode.h        2015-05-02 00:39:37 UTC (rev 183702)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2012 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2012, 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">@@ -51,6 +51,7 @@
</span><span class="cx">         HorizontalSnapOffsets,
</span><span class="cx">         VerticalSnapOffsets,
</span><span class="cx"> #endif
</span><ins>+        ExpectsWheelEventTestTrigger,
</ins><span class="cx">     };
</span><span class="cx"> 
</span><span class="cx">     const FloatSize&amp; scrollableAreaSize() const { return m_scrollableAreaSize; }
</span><span class="lines">@@ -82,7 +83,10 @@
</span><span class="cx">     const FloatPoint&amp; requestedScrollPosition() const { return m_requestedScrollPosition; }
</span><span class="cx">     bool requestedScrollPositionRepresentsProgrammaticScroll() const { return m_requestedScrollPositionRepresentsProgrammaticScroll; }
</span><span class="cx">     WEBCORE_EXPORT void setRequestedScrollPosition(const FloatPoint&amp;, bool representsProgrammaticScroll);
</span><del>-    
</del><ins>+
+    bool expectsWheelEventTestTrigger() const { return m_expectsWheelEventTestTrigger; }
+    WEBCORE_EXPORT void setExpectsWheelEventTestTrigger(bool);
+
</ins><span class="cx">     virtual void dumpProperties(TextStream&amp;, int indent) const override;
</span><span class="cx">     
</span><span class="cx"> protected:
</span><span class="lines">@@ -101,7 +105,8 @@
</span><span class="cx">     Vector&lt;float&gt; m_verticalSnapOffsets;
</span><span class="cx"> #endif
</span><span class="cx">     ScrollableAreaParameters m_scrollableAreaParameters;
</span><del>-    bool m_requestedScrollPositionRepresentsProgrammaticScroll;
</del><ins>+    bool m_requestedScrollPositionRepresentsProgrammaticScroll { false };
+    bool m_expectsWheelEventTestTrigger { false };
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkSourceWebCorepagescrollingScrollingTreeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/page/scrolling/ScrollingTree.h (183701 => 183702)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/page/scrolling/ScrollingTree.h        2015-05-02 00:23:58 UTC (rev 183701)
+++ trunk/Source/WebCore/page/scrolling/ScrollingTree.h        2015-05-02 00:39:37 UTC (rev 183702)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2012, 2013, 2014 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2012-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">@@ -31,6 +31,7 @@
</span><span class="cx"> #include &quot;PlatformWheelEvent.h&quot;
</span><span class="cx"> #include &quot;Region.h&quot;
</span><span class="cx"> #include &quot;ScrollingCoordinator.h&quot;
</span><ins>+#include &quot;WheelEventTestTrigger.h&quot;
</ins><span class="cx"> #include &lt;wtf/Functional.h&gt;
</span><span class="cx"> #include &lt;wtf/HashMap.h&gt;
</span><span class="cx"> #include &lt;wtf/ThreadSafeRefCounted.h&gt;
</span><span class="lines">@@ -100,6 +101,8 @@
</span><span class="cx">     
</span><span class="cx"> #if PLATFORM(MAC)
</span><span class="cx">     virtual void handleWheelEventPhase(PlatformWheelEventPhase) = 0;
</span><ins>+    virtual void deferTestsForReason(WheelEventTestTrigger::ScrollableAreaIdentifier, WheelEventTestTrigger::DeferTestTriggerReason) { }
+    virtual void removeTestDeferralForReason(WheelEventTestTrigger::ScrollableAreaIdentifier, WheelEventTestTrigger::DeferTestTriggerReason) { }
</ins><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx">     // Can be called from any thread. Will update what edges allow rubber-banding.
</span></span></pre></div>
<a id="trunkSourceWebCorepagescrollingThreadedScrollingTreecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/page/scrolling/ThreadedScrollingTree.cpp (183701 => 183702)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/page/scrolling/ThreadedScrollingTree.cpp        2015-05-02 00:23:58 UTC (rev 183701)
+++ trunk/Source/WebCore/page/scrolling/ThreadedScrollingTree.cpp        2015-05-02 00:39:37 UTC (rev 183702)
</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">@@ -122,6 +122,29 @@
</span><span class="cx">         scrollingCoordinator-&gt;handleWheelEventPhase(phase);
</span><span class="cx">     });
</span><span class="cx"> }
</span><ins>+
+void ThreadedScrollingTree::deferTestsForReason(WheelEventTestTrigger::ScrollableAreaIdentifier identifier, WheelEventTestTrigger::DeferTestTriggerReason reason)
+{
+    if (!m_scrollingCoordinator)
+        return;
+
+    RefPtr&lt;AsyncScrollingCoordinator&gt; scrollingCoordinator = m_scrollingCoordinator;
+    RunLoop::main().dispatch([scrollingCoordinator, identifier, reason] {
+        scrollingCoordinator-&gt;deferTestsForReason(identifier, reason);
+    });
+}
+
+void ThreadedScrollingTree::removeTestDeferralForReason(WheelEventTestTrigger::ScrollableAreaIdentifier identifier, WheelEventTestTrigger::DeferTestTriggerReason reason)
+{
+    if (!m_scrollingCoordinator)
+        return;
+    
+    RefPtr&lt;AsyncScrollingCoordinator&gt; scrollingCoordinator = m_scrollingCoordinator;
+    RunLoop::main().dispatch([scrollingCoordinator, identifier, reason] {
+        scrollingCoordinator-&gt;removeTestDeferralForReason(identifier, reason);
+    });
+}
+
</ins><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkSourceWebCorepagescrollingThreadedScrollingTreeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/page/scrolling/ThreadedScrollingTree.h (183701 => 183702)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/page/scrolling/ThreadedScrollingTree.h        2015-05-02 00:23:58 UTC (rev 183701)
+++ trunk/Source/WebCore/page/scrolling/ThreadedScrollingTree.h        2015-05-02 00:39:37 UTC (rev 183702)
</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">@@ -61,7 +61,9 @@
</span><span class="cx"> 
</span><span class="cx">     virtual void scrollingTreeNodeDidScroll(ScrollingNodeID, const FloatPoint&amp; scrollPosition, SetOrSyncScrollingLayerPosition = SyncScrollingLayerPosition) override;
</span><span class="cx"> #if PLATFORM(MAC)
</span><del>-    virtual void handleWheelEventPhase(PlatformWheelEventPhase) override;
</del><ins>+    void handleWheelEventPhase(PlatformWheelEventPhase) override;
+    void deferTestsForReason(WheelEventTestTrigger::ScrollableAreaIdentifier, WheelEventTestTrigger::DeferTestTriggerReason) override;
+    void removeTestDeferralForReason(WheelEventTestTrigger::ScrollableAreaIdentifier, WheelEventTestTrigger::DeferTestTriggerReason) override;
</ins><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx"> private:
</span></span></pre></div>
<a id="trunkSourceWebCorepagescrollingmacScrollingTreeFrameScrollingNodeMach"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/page/scrolling/mac/ScrollingTreeFrameScrollingNodeMac.h (183701 => 183702)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/page/scrolling/mac/ScrollingTreeFrameScrollingNodeMac.h        2015-05-02 00:23:58 UTC (rev 183701)
+++ trunk/Source/WebCore/page/scrolling/mac/ScrollingTreeFrameScrollingNodeMac.h        2015-05-02 00:39:37 UTC (rev 183702)
</span><span class="lines">@@ -79,6 +79,9 @@
</span><span class="cx"> 
</span><span class="cx">     bool isAlreadyPinnedInDirectionOfGesture(const PlatformWheelEvent&amp;, ScrollEventAxis);
</span><span class="cx"> 
</span><ins>+    void deferTestsForReason(WheelEventTestTrigger::ScrollableAreaIdentifier, WheelEventTestTrigger::DeferTestTriggerReason) const override;
+    void removeTestDeferralForReason(WheelEventTestTrigger::ScrollableAreaIdentifier, WheelEventTestTrigger::DeferTestTriggerReason) const override;
+
</ins><span class="cx"> #if ENABLE(CSS_SCROLL_SNAP) &amp;&amp; PLATFORM(MAC)
</span><span class="cx">     LayoutUnit scrollOffsetOnAxis(ScrollEventAxis) const override;
</span><span class="cx">     void immediateScrollOnAxis(ScrollEventAxis, float delta) override;
</span><span class="lines">@@ -99,8 +102,9 @@
</span><span class="cx">     RetainPtr&lt;ScrollbarPainter&gt; m_verticalScrollbarPainter;
</span><span class="cx">     RetainPtr&lt;ScrollbarPainter&gt; m_horizontalScrollbarPainter;
</span><span class="cx">     FloatPoint m_probableMainThreadScrollPosition;
</span><del>-    bool m_lastScrollHadUnfilledPixels;
-    bool m_hadFirstUpdate;
</del><ins>+    bool m_lastScrollHadUnfilledPixels { false };
+    bool m_hadFirstUpdate { false };
+    bool m_expectsWheelEventTestTrigger { false };
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkSourceWebCorepagescrollingmacScrollingTreeFrameScrollingNodeMacmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/page/scrolling/mac/ScrollingTreeFrameScrollingNodeMac.mm (183701 => 183702)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/page/scrolling/mac/ScrollingTreeFrameScrollingNodeMac.mm        2015-05-02 00:23:58 UTC (rev 183701)
+++ trunk/Source/WebCore/page/scrolling/mac/ScrollingTreeFrameScrollingNodeMac.mm        2015-05-02 00:39:37 UTC (rev 183702)
</span><span class="lines">@@ -29,6 +29,7 @@
</span><span class="cx"> #if ENABLE(ASYNC_SCROLLING) &amp;&amp; PLATFORM(MAC)
</span><span class="cx"> 
</span><span class="cx"> #import &quot;FrameView.h&quot;
</span><ins>+#import &quot;Logging.h&quot;
</ins><span class="cx"> #import &quot;NSScrollerImpDetails.h&quot;
</span><span class="cx"> #import &quot;PlatformWheelEvent.h&quot;
</span><span class="cx"> #import &quot;ScrollingCoordinator.h&quot;
</span><span class="lines">@@ -56,10 +57,8 @@
</span><span class="cx"> ScrollingTreeFrameScrollingNodeMac::ScrollingTreeFrameScrollingNodeMac(ScrollingTree&amp; scrollingTree, ScrollingNodeID nodeID)
</span><span class="cx">     : ScrollingTreeFrameScrollingNode(scrollingTree, nodeID)
</span><span class="cx">     , m_scrollController(*this)
</span><del>-    , m_verticalScrollbarPainter(0)
-    , m_horizontalScrollbarPainter(0)
-    , m_lastScrollHadUnfilledPixels(false)
-    , m_hadFirstUpdate(false)
</del><ins>+    , m_verticalScrollbarPainter(nullptr)
+    , m_horizontalScrollbarPainter(nullptr)
</ins><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -139,6 +138,9 @@
</span><span class="cx">         m_scrollController.updateScrollSnapPoints(ScrollEventAxis::Vertical, convertToLayoutUnits(scrollingStateNode.verticalSnapOffsets()));
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><ins>+    if (scrollingStateNode.hasChangedProperty(ScrollingStateScrollingNode::ExpectsWheelEventTestTrigger))
+        m_expectsWheelEventTestTrigger = scrollingStateNode.expectsWheelEventTestTrigger();
+
</ins><span class="cx">     m_hadFirstUpdate = true;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -172,6 +174,15 @@
</span><span class="cx">         [m_horizontalScrollbarPainter setUsePresentationValue:NO];
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+#if ENABLE(CSS_SCROLL_SNAP) || ENABLE(RUBBER_BANDING)
+    if (m_expectsWheelEventTestTrigger) {
+        if (scrollingTree().shouldHandleWheelEventSynchronously(wheelEvent))
+            removeTestDeferralForReason(reinterpret_cast&lt;WheelEventTestTrigger::ScrollableAreaIdentifier&gt;(scrollingNodeID()), WheelEventTestTrigger::ScrollingThreadSyncNeeded);
+        else
+            deferTestsForReason(reinterpret_cast&lt;WheelEventTestTrigger::ScrollableAreaIdentifier&gt;(scrollingNodeID()), WheelEventTestTrigger::ScrollingThreadSyncNeeded);
+    }
+#endif
+
</ins><span class="cx">     m_scrollController.handleWheelEvent(wheelEvent);
</span><span class="cx">     scrollingTree().setOrClearLatchedNode(wheelEvent, scrollingNodeID());
</span><span class="cx">     scrollingTree().handleWheelEventPhase(wheelEvent.phase());
</span><span class="lines">@@ -561,6 +572,24 @@
</span><span class="cx"> }
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><ins>+void ScrollingTreeFrameScrollingNodeMac::deferTestsForReason(WheelEventTestTrigger::ScrollableAreaIdentifier identifier, WheelEventTestTrigger::DeferTestTriggerReason reason) const
+{
+    if (!m_expectsWheelEventTestTrigger)
+        return;
+
+    LOG(WheelEventTestTriggers, &quot;  ScrollingTreeFrameScrollingNodeMac::deferTestsForReason: STARTING deferral for %p because of %d&quot;, identifier, reason);
+    scrollingTree().deferTestsForReason(identifier, reason);
+}
+    
+void ScrollingTreeFrameScrollingNodeMac::removeTestDeferralForReason(WheelEventTestTrigger::ScrollableAreaIdentifier identifier, WheelEventTestTrigger::DeferTestTriggerReason reason) const
+{
+    if (!m_expectsWheelEventTestTrigger)
+        return;
+    
+    LOG(WheelEventTestTriggers, &quot;   ScrollingTreeFrameScrollingNodeMac::deferTestsForReason: ENDING deferral for %p because of %d&quot;, identifier, reason);
+    scrollingTree().removeTestDeferralForReason(identifier, reason);
+}
+
</ins><span class="cx"> } // namespace WebCore
</span><span class="cx"> 
</span><span class="cx"> #endif // ENABLE(ASYNC_SCROLLING) &amp;&amp; PLATFORM(MAC)
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformLoggingh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/Logging.h (183701 => 183702)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/Logging.h        2015-05-02 00:23:58 UTC (rev 183701)
+++ trunk/Source/WebCore/platform/Logging.h        2015-05-02 00:39:37 UTC (rev 183702)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2003, 2006, 2013 Apple Inc.  All rights reserved.
</del><ins>+ * Copyright (C) 2003, 2006, 2013, 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">@@ -76,6 +76,7 @@
</span><span class="cx">     M(WebAudio) \
</span><span class="cx">     M(WebGL) \
</span><span class="cx">     M(WebReplay) \
</span><ins>+    M(WheelEventTestTriggers) \
</ins><span class="cx"> 
</span><span class="cx"> #define DECLARE_LOG_CHANNEL(name) \
</span><span class="cx">     WEBCORE_EXPORT extern WTFLogChannel JOIN_LOG_CHANNEL_WITH_PREFIX(LOG_CHANNEL_PREFIX, name);
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformScrollAnimatorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/ScrollAnimator.cpp (183701 => 183702)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/ScrollAnimator.cpp        2015-05-02 00:23:58 UTC (rev 183701)
+++ trunk/Source/WebCore/platform/ScrollAnimator.cpp        2015-05-02 00:39:37 UTC (rev 183702)
</span><span class="lines">@@ -192,4 +192,22 @@
</span><span class="cx"> }
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><ins>+#if (ENABLE(CSS_SCROLL_SNAP) || ENABLE(RUBBER_BANDING)) &amp;&amp; PLATFORM(MAC)
+void ScrollAnimator::deferTestsForReason(WheelEventTestTrigger::ScrollableAreaIdentifier identifier, WheelEventTestTrigger::DeferTestTriggerReason reason) const
+{
+    if (!m_wheelEventTestTrigger)
+        return;
+
+    m_wheelEventTestTrigger-&gt;deferTestsForReason(identifier, reason);
+}
+
+void ScrollAnimator::removeTestDeferralForReason(WheelEventTestTrigger::ScrollableAreaIdentifier identifier, WheelEventTestTrigger::DeferTestTriggerReason reason) const
+{
+    if (!m_wheelEventTestTrigger)
+        return;
+    
+    m_wheelEventTestTrigger-&gt;removeTestDeferralForReason(identifier, reason);
+}
+#endif
+
</ins><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformScrollAnimatorh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/ScrollAnimator.h (183701 => 183702)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/ScrollAnimator.h        2015-05-02 00:23:58 UTC (rev 183701)
+++ trunk/Source/WebCore/platform/ScrollAnimator.h        2015-05-02 00:39:37 UTC (rev 183702)
</span><span class="lines">@@ -121,7 +121,8 @@
</span><span class="cx"> 
</span><span class="cx">     void setWheelEventTestTrigger(RefPtr&lt;WheelEventTestTrigger&gt;&amp;&amp; testTrigger) { m_wheelEventTestTrigger = testTrigger; }
</span><span class="cx"> #if (ENABLE(CSS_SCROLL_SNAP) || ENABLE(RUBBER_BANDING)) &amp;&amp; PLATFORM(MAC)
</span><del>-    WheelEventTestTrigger* testTrigger() const override { return m_wheelEventTestTrigger.get(); }
</del><ins>+    void deferTestsForReason(WheelEventTestTrigger::ScrollableAreaIdentifier, WheelEventTestTrigger::DeferTestTriggerReason) const override;
+    void removeTestDeferralForReason(WheelEventTestTrigger::ScrollableAreaIdentifier, WheelEventTestTrigger::DeferTestTriggerReason) const override;
</ins><span class="cx"> #endif
</span><span class="cx">     
</span><span class="cx"> #if ENABLE(CSS_SCROLL_SNAP) &amp;&amp; PLATFORM(MAC)
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformcocoaScrollControllerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/cocoa/ScrollController.h (183701 => 183702)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/cocoa/ScrollController.h        2015-05-02 00:23:58 UTC (rev 183701)
+++ trunk/Source/WebCore/platform/cocoa/ScrollController.h        2015-05-02 00:39:37 UTC (rev 183702)
</span><span class="lines">@@ -31,6 +31,7 @@
</span><span class="cx"> #include &quot;FloatPoint.h&quot;
</span><span class="cx"> #include &quot;FloatSize.h&quot;
</span><span class="cx"> #include &quot;ScrollTypes.h&quot;
</span><ins>+#include &quot;WheelEventTestTrigger.h&quot;
</ins><span class="cx"> #include &lt;wtf/Noncopyable.h&gt;
</span><span class="cx"> #include &lt;wtf/RunLoop.h&gt;
</span><span class="cx"> 
</span><span class="lines">@@ -76,7 +77,8 @@
</span><span class="cx">     // the page to scroll to the nearest boundary point.
</span><span class="cx">     virtual void adjustScrollPositionToBoundsIfNecessary() = 0;
</span><span class="cx"> 
</span><del>-    virtual WheelEventTestTrigger* testTrigger() const { return nullptr; }
</del><ins>+    virtual void deferTestsForReason(WheelEventTestTrigger::ScrollableAreaIdentifier, WheelEventTestTrigger::DeferTestTriggerReason) const { /* Do nothing */ }
+    virtual void removeTestDeferralForReason(WheelEventTestTrigger::ScrollableAreaIdentifier, WheelEventTestTrigger::DeferTestTriggerReason) const { /* Do nothing */ }
</ins><span class="cx"> 
</span><span class="cx"> #if ENABLE(CSS_SCROLL_SNAP) &amp;&amp; PLATFORM(MAC)
</span><span class="cx">     virtual LayoutUnit scrollOffsetOnAxis(ScrollEventAxis) const = 0;
</span><span class="lines">@@ -166,12 +168,12 @@
</span><span class="cx">     RunLoop::Timer&lt;ScrollController&gt; m_verticalScrollSnapTimer;
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><del>-    bool m_inScrollGesture;
-    bool m_momentumScrollInProgress;
-    bool m_ignoreMomentumScrolls;
-    bool m_snapRubberbandTimerIsActive;
</del><ins>+    bool m_inScrollGesture { false };
+    bool m_momentumScrollInProgress { false };
+    bool m_ignoreMomentumScrolls { false };
+    bool m_snapRubberbandTimerIsActive { false };
</ins><span class="cx"> };
</span><del>-
</del><ins>+    
</ins><span class="cx"> } // namespace WebCore
</span><span class="cx"> 
</span><span class="cx"> #endif // ENABLE(RUBBER_BANDING)
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformcocoaScrollControllermm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/cocoa/ScrollController.mm (183701 => 183702)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/cocoa/ScrollController.mm        2015-05-02 00:23:58 UTC (rev 183701)
+++ trunk/Source/WebCore/platform/cocoa/ScrollController.mm        2015-05-02 00:39:37 UTC (rev 183702)
</span><span class="lines">@@ -130,10 +130,6 @@
</span><span class="cx">     , m_horizontalScrollSnapTimer(RunLoop::current(), this, &amp;ScrollController::horizontalScrollSnapTimerFired)
</span><span class="cx">     , m_verticalScrollSnapTimer(RunLoop::current(), this, &amp;ScrollController::verticalScrollSnapTimerFired)
</span><span class="cx"> #endif
</span><del>-    , m_inScrollGesture(false)
-    , m_momentumScrollInProgress(false)
-    , m_ignoreMomentumScrolls(false)
-    , m_snapRubberbandTimerIsActive(false)
</del><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -413,8 +409,7 @@
</span><span class="cx">     m_client.startSnapRubberbandTimer();
</span><span class="cx">     m_snapRubberbandTimer.startRepeating(1.0 / 60.0);
</span><span class="cx"> 
</span><del>-    if (auto* trigger = m_client.testTrigger())
-        trigger-&gt;deferTestsForReason(reinterpret_cast&lt;WheelEventTestTrigger::ScrollableAreaIdentifier&gt;(this), WheelEventTestTrigger::RubberbandInProgress);
</del><ins>+    m_client.deferTestsForReason(reinterpret_cast&lt;WheelEventTestTrigger::ScrollableAreaIdentifier&gt;(this), WheelEventTestTrigger::RubberbandInProgress);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void ScrollController::stopSnapRubberbandTimer()
</span><span class="lines">@@ -423,8 +418,7 @@
</span><span class="cx">     m_snapRubberbandTimer.stop();
</span><span class="cx">     m_snapRubberbandTimerIsActive = false;
</span><span class="cx">     
</span><del>-    if (auto* trigger = m_client.testTrigger())
-        trigger-&gt;removeTestDeferralForReason(reinterpret_cast&lt;WheelEventTestTrigger::ScrollableAreaIdentifier&gt;(this), WheelEventTestTrigger::RubberbandInProgress);
</del><ins>+    m_client.removeTestDeferralForReason(reinterpret_cast&lt;WheelEventTestTrigger::ScrollableAreaIdentifier&gt;(this), WheelEventTestTrigger::RubberbandInProgress);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void ScrollController::snapRubberBand()
</span><span class="lines">@@ -624,8 +618,7 @@
</span><span class="cx">     if (!m_horizontalScrollSnapTimer.isActive() &amp;&amp; !m_verticalScrollSnapTimer.isActive())
</span><span class="cx">         return;
</span><span class="cx"> 
</span><del>-    if (auto* trigger = m_client.testTrigger())
-        trigger-&gt;deferTestsForReason(reinterpret_cast&lt;WheelEventTestTrigger::ScrollableAreaIdentifier&gt;(this), WheelEventTestTrigger::ScrollSnapInProgress);
</del><ins>+    m_client.deferTestsForReason(reinterpret_cast&lt;WheelEventTestTrigger::ScrollableAreaIdentifier&gt;(this), WheelEventTestTrigger::ScrollSnapInProgress);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void ScrollController::stopScrollSnapTimer(ScrollEventAxis axis)
</span><span class="lines">@@ -637,8 +630,7 @@
</span><span class="cx">     if (m_horizontalScrollSnapTimer.isActive() || m_verticalScrollSnapTimer.isActive())
</span><span class="cx">         return;
</span><span class="cx"> 
</span><del>-    if (auto* trigger = m_client.testTrigger())
-        trigger-&gt;removeTestDeferralForReason(reinterpret_cast&lt;WheelEventTestTrigger::ScrollableAreaIdentifier&gt;(this), WheelEventTestTrigger::ScrollSnapInProgress);
</del><ins>+    m_client.removeTestDeferralForReason(reinterpret_cast&lt;WheelEventTestTrigger::ScrollableAreaIdentifier&gt;(this), WheelEventTestTrigger::ScrollSnapInProgress);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void ScrollController::horizontalScrollSnapTimerFired()
</span></span></pre>
</div>
</div>

</body>
</html>