<!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>[182768] 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/182768">182768</a></dd>
<dt>Author</dt> <dd>bfulgham@apple.com</dd>
<dt>Date</dt> <dd>2015-04-13 17:05:17 -0700 (Mon, 13 Apr 2015)</dd>
</dl>

<h3>Log Message</h3>
<pre>Expand test infrastructure to support scrolling tests
https://bugs.webkit.org/show_bug.cgi?id=143286
&lt;rdar://problem/20375516&gt;

Reviewed by Simon Fraser.

Source/WebCore:

No new functionality.

This series of changes adds a new singleton class, 'WheelEventTestTrigger', which encapsulates a
function object to be fired when scroll events are finished. The object also keeps track of reasons
why the test should not yet fire (e.g., 'rubberbanding' is active) so that tests do not incorrectly
check rendering state in the middle of an animation.

This code is not yet hooked up to the rendering system, and so does not have any effect on behavior.

* CMakeLists.txt: Add new WheelEventTestTrigger files.
* WebCore.vcxproj/WebCore.vcxproj: Ditto.
* WebCore.vcxproj/WebCore.vcxproj.filters: Ditto.
* WebCore.xcodeproj/project.pbxproj: Ditto.
* page/MainFrame.cpp:
(WebCore::MainFrame::MainFrame): Add new member to constructor.
(WebCore::MainFrame::testTrigger): Added.
(WebCore::MainFrame::ensureTestTrigger): Added.
(WebCore::MainFrame::clearTrigger): Added.
* page/MainFrame.h:
* page/WheelEventTestTrigger.cpp: Added.
(WebCore::WheelEventTestTrigger::WheelEventTestTrigger):
(WebCore::WheelEventTestTrigger::createWeakPtr):
(WebCore::WheelEventTestTrigger::clearAllTestDeferrals):
(WebCore::WheelEventTestTrigger::setTestNotificationCallback):
(WebCore::WheelEventTestTrigger::deferTestsForReason):
(WebCore::WheelEventTestTrigger::removeTestDeferralForReason):
(WebCore::WheelEventTestTrigger::triggerTestTimerFired):
* page/WheelEventTestTrigger.h: Added.

Source/WebKit2:

Extend the WK2 testing API to include a method for setting a JSC callback function to be triggered
by the new WebCore::WheelEventTestTrigger singleton.

* WebProcess/InjectedBundle/API/c/WKBundlePage.cpp:
(WKBundlePageStartMonitoringScrollOperations): WK2 method that causes the testing system to begin tracking wheel events.
(WKBundlePageRegisterScrollOperationCompletionCallback): WK2 method to set the callback function for testing.
* WebProcess/InjectedBundle/API/c/WKBundlePage.h:

Tools:

Extend the WK1 and WK2 test programs to support two new EventSender commands:
(1) monitorWheelEvents: Tells DRT and WKTR to track the wheel event and animation state, so that we can
block executing tests until WebKit has completed any rubberband, scroll, or scroll-snap animations.
(2) callAfterScrollingCompletes: Provide a callback method to be executed when WebKit determines that
relevant rubberband, scroll, and scroll-snap animations are finished.

* DumpRenderTree/mac/EventSendingController.mm:
(+[EventSendingController isSelectorExcludedFromWebScript:]): Update to recognize 'callAfterScrollingCompletes:'
and 'monitorWheelEvents'.
(+[EventSendingController webScriptNameForSelector:]): Ditto.
(-[EventSendingController mouseScrollByX:andY:continuously:]): Add some stderr logging to help when
debugging test failures.
(-[EventSendingController mouseScrollByX:andY:withWheel:andMomentumPhases:]): Ditto.
(-[EventSendingController callAfterScrollingCompletes:]): Added. Protects the JSObject representing the callback
function, then passes it to WebCore to be called once the test deferrals have been cleared.
(-[EventSendingController monitorWheelEvents:]): Added. Activates the wheel event tracking used by the
'callAfterScrollingCompletes' method.
* WebKitTestRunner/InjectedBundle/Bindings/EventSendingController.idl: Added signatures for 'callAfterScrollingCompletes'
and 'monitorWheelEvents'.
* WebKitTestRunner/InjectedBundle/EventSendingController.cpp:
(WTR::EventSendingController::callAfterScrollingCompletes): Added. Protects the JSObject representing the
callback function, then passes it to WebCore to be called once the test deferrals have been cleared
(WTR::EventSendingController::monitorWheelEvents): Added. Activates the wheel event tracking used by the
'callAfterScrollingComplates' method.
* WebKitTestRunner/InjectedBundle/EventSendingController.h:

LayoutTests:

Correct a scrolling test that had not been issuing wheel events to a valid
view. This was found by some new logging in this patch.

* platform/mac/fast/scrolling/scroll-div-latched-div-expected.txt:
* platform/mac/fast/scrolling/scroll-div-latched-div.html:
* platform/mac-wk1/scrollbars/scrollevent-iframe-no-scrolling-wheel-expected.txt: Added.*</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkLayoutTestsplatformmacfastscrollingscrolldivlatcheddivexpectedtxt">trunk/LayoutTests/platform/mac/fast/scrolling/scroll-div-latched-div-expected.txt</a></li>
<li><a href="#trunkLayoutTestsplatformmacfastscrollingscrolldivlatcheddivhtml">trunk/LayoutTests/platform/mac/fast/scrolling/scroll-div-latched-div.html</a></li>
<li><a href="#trunkSourceWebCoreCMakeListstxt">trunk/Source/WebCore/CMakeLists.txt</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreWebCorevcxprojWebCorevcxproj">trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj</a></li>
<li><a href="#trunkSourceWebCoreWebCorevcxprojWebCorevcxprojfilters">trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj.filters</a></li>
<li><a href="#trunkSourceWebCoreWebCorexcodeprojprojectpbxproj">trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkSourceWebCorepageMainFramecpp">trunk/Source/WebCore/page/MainFrame.cpp</a></li>
<li><a href="#trunkSourceWebCorepageMainFrameh">trunk/Source/WebCore/page/MainFrame.h</a></li>
<li><a href="#trunkSourceWebCoreplatformPlatformExportMacrosh">trunk/Source/WebCore/platform/PlatformExportMacros.h</a></li>
<li><a href="#trunkSourceWebCoreplatformspimacNSSharingServicePickerSPIh">trunk/Source/WebCore/platform/spi/mac/NSSharingServicePickerSPI.h</a></li>
<li><a href="#trunkSourceWebKit2ChangeLog">trunk/Source/WebKit2/ChangeLog</a></li>
<li><a href="#trunkSourceWebKit2WebProcessInjectedBundleAPIcWKBundlePagecpp">trunk/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundlePage.cpp</a></li>
<li><a href="#trunkSourceWebKit2WebProcessInjectedBundleAPIcWKBundlePageh">trunk/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundlePage.h</a></li>
<li><a href="#trunkToolsChangeLog">trunk/Tools/ChangeLog</a></li>
<li><a href="#trunkToolsDumpRenderTreeDumpRenderTreexcodeprojprojectpbxproj">trunk/Tools/DumpRenderTree/DumpRenderTree.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkToolsDumpRenderTreemacEventSendingControllermm">trunk/Tools/DumpRenderTree/mac/EventSendingController.mm</a></li>
<li><a href="#trunkToolsWebKitTestRunnerInjectedBundleBindingsEventSendingControlleridl">trunk/Tools/WebKitTestRunner/InjectedBundle/Bindings/EventSendingController.idl</a></li>
<li><a href="#trunkToolsWebKitTestRunnerInjectedBundleEventSendingControllercpp">trunk/Tools/WebKitTestRunner/InjectedBundle/EventSendingController.cpp</a></li>
<li><a href="#trunkToolsWebKitTestRunnerInjectedBundleEventSendingControllerh">trunk/Tools/WebKitTestRunner/InjectedBundle/EventSendingController.h</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li>trunk/LayoutTests/platform/mac-wk1/scrollbars/</li>
<li><a href="#trunkLayoutTestsplatformmacwk1scrollbarsscrolleventiframenoscrollingwheelexpectedtxt">trunk/LayoutTests/platform/mac-wk1/scrollbars/scrollevent-iframe-no-scrolling-wheel-expected.txt</a></li>
<li><a href="#trunkSourceWebCorepageWheelEventTestTriggercpp">trunk/Source/WebCore/page/WheelEventTestTrigger.cpp</a></li>
<li><a href="#trunkSourceWebCorepageWheelEventTestTriggerh">trunk/Source/WebCore/page/WheelEventTestTrigger.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (182767 => 182768)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2015-04-13 23:51:36 UTC (rev 182767)
+++ trunk/LayoutTests/ChangeLog        2015-04-14 00:05:17 UTC (rev 182768)
</span><span class="lines">@@ -1,3 +1,18 @@
</span><ins>+2015-04-10  Brent Fulgham  &lt;bfulgham@apple.com&gt;
+
+        Expand test infrastructure to support scrolling tests
+        https://bugs.webkit.org/show_bug.cgi?id=143286
+        &lt;rdar://problem/20375516&gt;
+
+        Reviewed by Simon Fraser.
+
+        Correct a scrolling test that had not been issuing wheel events to a valid
+        view. This was found by some new logging in this patch.
+
+        * platform/mac/fast/scrolling/scroll-div-latched-div-expected.txt:
+        * platform/mac/fast/scrolling/scroll-div-latched-div.html:
+        * platform/mac-wk1/scrollbars/scrollevent-iframe-no-scrolling-wheel-expected.txt: Added.*
+
</ins><span class="cx"> 2015-04-13  Said Abou-Hallawa  &lt;sabouhallawa@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Fix LayoutTests/http/tests/canvas/canvas-tainted-after-draw-image.html on all bots
</span></span></pre></div>
<a id="trunkLayoutTestsplatformmacfastscrollingscrolldivlatcheddivexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/platform/mac/fast/scrolling/scroll-div-latched-div-expected.txt (182767 => 182768)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/platform/mac/fast/scrolling/scroll-div-latched-div-expected.txt        2015-04-13 23:51:36 UTC (rev 182767)
+++ trunk/LayoutTests/platform/mac/fast/scrolling/scroll-div-latched-div-expected.txt        2015-04-14 00:05:17 UTC (rev 182768)
</span><span class="lines">@@ -52,7 +52,5 @@
</span><span class="cx"> PASS successfullyParsed is true
</span><span class="cx"> 
</span><span class="cx"> TEST COMPLETE
</span><del>-div display height = 485
-Mouse moved to (28, 610)
</del><span class="cx"> PASS Page did not receive wheel events.
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkLayoutTestsplatformmacfastscrollingscrolldivlatcheddivhtml"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/platform/mac/fast/scrolling/scroll-div-latched-div.html (182767 => 182768)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/platform/mac/fast/scrolling/scroll-div-latched-div.html        2015-04-13 23:51:36 UTC (rev 182767)
+++ trunk/LayoutTests/platform/mac/fast/scrolling/scroll-div-latched-div.html        2015-04-14 00:05:17 UTC (rev 182768)
</span><span class="lines">@@ -40,15 +40,12 @@
</span><span class="cx"> var divScrollPositionBefore;
</span><span class="cx"> var continueCount = 5;
</span><span class="cx"> 
</span><del>-function checkForScroll() {
-
</del><ins>+function checkForScroll()
+{
</ins><span class="cx">     // The div should not have scrolled at all.
</span><span class="cx">     var pageScrollPositionAfter = document.body.scrollTop;
</span><span class="cx">     var divScrollPositionAfter = divTarget.scrollTop;
</span><span class="cx"> 
</span><del>-    //debug(&quot;Page before: &quot; + pageScrollPositionBefore + &quot;, div before: &quot; + divScrollPositionBefore);
-    //debug(&quot;Page after:  &quot; + pageScrollPositionAfter + &quot;, div after: &quot; + divScrollPositionAfter);
-
</del><span class="cx">     if (pageScrollPositionBefore != pageScrollPositionAfter)
</span><span class="cx">         testFailed(&quot;Page received wheel events.&quot;);
</span><span class="cx">     else
</span><span class="lines">@@ -57,8 +54,8 @@
</span><span class="cx">     testRunner.notifyDone();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-function scrollTest() {
-    // See where our IFrame lives:
</del><ins>+function scrollTest()
+{
</ins><span class="cx">     pageScrollPositionBefore = document.body.scrollTop;
</span><span class="cx"> 
</span><span class="cx">     divTarget = document.getElementById('target');
</span><span class="lines">@@ -67,11 +64,9 @@
</span><span class="cx">     divScrollPositionBefore = divTarget.scrollTop;
</span><span class="cx"> 
</span><span class="cx">     // Scroll the #source until we reach the #target.
</span><del>-    var startPosX = divTarget.offsetLeft + 20;
-    debug(&quot;div display height = &quot; + divTarget.clientHeight);
-    var startPosY = Math.round(divTarget.offsetTop) + Math.round(divTarget.clientHeight) - 42; // One wheel turn before end.
-    eventSender.mouseMoveTo(startPosX, startPosY); // Make sure we are just outside the iFrame
-    debug(&quot;Mouse moved to (&quot; + startPosX + &quot;, &quot; + startPosY + &quot;)&quot;);
</del><ins>+    var startPosX = Math.round(divTarget.offsetLeft) + 20;
+    var startPosY = Math.round(divTarget.offsetTop) + 100; // One wheel turn before end.
+    eventSender.mouseMoveTo(startPosX, startPosY);
</ins><span class="cx">     eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'began', 'none', true);
</span><span class="cx">     eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'changed', 'none', true);
</span><span class="cx">     eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'changed', 'none', true);
</span><span class="lines">@@ -85,9 +80,10 @@
</span><span class="cx">     setTimeout(checkForScroll, 100);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-function setupTopLevel() {
-
</del><ins>+function setupTopLevel()
+{
</ins><span class="cx">     if (window.eventSender) {
</span><ins>+        testRunner.dumpAsText();
</ins><span class="cx">         testRunner.waitUntilDone();
</span><span class="cx"> 
</span><span class="cx">         setTimeout(scrollTest, 1000);
</span><span class="lines">@@ -109,7 +105,7 @@
</span><span class="cx">     &lt;/div&gt;
</span><span class="cx">     &lt;div class=&quot;scrollable_region&quot;&gt;
</span><span class="cx">         &lt;h3&gt;Scrollable Region&lt;/h3&gt;
</span><del>-        &lt;div id=&quot;target&quot; style='overflow-y: auto; overflow-x: hidden; max-height: 485px;'&gt;
</del><ins>+        &lt;div id=&quot;target&quot; style='overflow-y: auto; overflow-x: hidden; max-height: 350px;'&gt;
</ins><span class="cx">             &lt;table class=&quot;table&quot; style='width: 99%'&gt;
</span><span class="cx">                 &lt;tr&gt;&lt;th&gt;Count&lt;/th&gt;&lt;th&gt;DATA&lt;/th&gt;&lt;th&gt;Rev Count&lt;/th&gt;&lt;/tr&gt;
</span><span class="cx">                 &lt;tr&gt;&lt;td&gt;TOP TOP TOP TOP TOP&lt;/td&gt;&lt;td&gt;TOP TOP TOP TOP TOP&lt;/td&gt;&lt;td&gt;TOP TOP TOP TOP TOP&lt;/td&gt;&lt;/tr&gt;
</span></span></pre></div>
<a id="trunkLayoutTestsplatformmacwk1scrollbarsscrolleventiframenoscrollingwheelexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/platform/mac-wk1/scrollbars/scrollevent-iframe-no-scrolling-wheel-expected.txt (0 => 182768)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/platform/mac-wk1/scrollbars/scrollevent-iframe-no-scrolling-wheel-expected.txt                                (rev 0)
+++ trunk/LayoutTests/platform/mac-wk1/scrollbars/scrollevent-iframe-no-scrolling-wheel-expected.txt        2015-04-14 00:05:17 UTC (rev 182768)
</span><span class="lines">@@ -0,0 +1,3 @@
</span><ins>+mouseScrollByXandYContinuously: Unable to locate target view for current mouse location.Content-Type: text/plain
+Not scrolled by WheelEvent: SUCCESS
+
</ins></span></pre></div>
<a id="trunkSourceWebCoreCMakeListstxt"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/CMakeLists.txt (182767 => 182768)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/CMakeLists.txt        2015-04-13 23:51:36 UTC (rev 182767)
+++ trunk/Source/WebCore/CMakeLists.txt        2015-04-14 00:05:17 UTC (rev 182768)
</span><span class="lines">@@ -1968,6 +1968,7 @@
</span><span class="cx">     page/UserContentURLPattern.cpp
</span><span class="cx">     page/VisitedLinkStore.cpp
</span><span class="cx">     page/WheelEventDeltaTracker.cpp
</span><ins>+    page/WheelEventTestTrigger.cpp
</ins><span class="cx">     page/WindowFeatures.cpp
</span><span class="cx">     page/WindowFocusAllowedIndicator.cpp
</span><span class="cx">     page/WorkerNavigator.cpp
</span></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (182767 => 182768)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2015-04-13 23:51:36 UTC (rev 182767)
+++ trunk/Source/WebCore/ChangeLog        2015-04-14 00:05:17 UTC (rev 182768)
</span><span class="lines">@@ -1,3 +1,40 @@
</span><ins>+2015-04-10  Brent Fulgham  &lt;bfulgham@apple.com&gt;
+
+        Expand test infrastructure to support scrolling tests
+        https://bugs.webkit.org/show_bug.cgi?id=143286
+        &lt;rdar://problem/20375516&gt;
+
+        Reviewed by Simon Fraser.
+
+        No new functionality.
+
+        This series of changes adds a new singleton class, 'WheelEventTestTrigger', which encapsulates a
+        function object to be fired when scroll events are finished. The object also keeps track of reasons
+        why the test should not yet fire (e.g., 'rubberbanding' is active) so that tests do not incorrectly
+        check rendering state in the middle of an animation.
+
+        This code is not yet hooked up to the rendering system, and so does not have any effect on behavior.
+
+        * CMakeLists.txt: Add new WheelEventTestTrigger files.
+        * WebCore.vcxproj/WebCore.vcxproj: Ditto.
+        * WebCore.vcxproj/WebCore.vcxproj.filters: Ditto.
+        * WebCore.xcodeproj/project.pbxproj: Ditto.
+        * page/MainFrame.cpp:
+        (WebCore::MainFrame::MainFrame): Add new member to constructor.
+        (WebCore::MainFrame::testTrigger): Added.
+        (WebCore::MainFrame::ensureTestTrigger): Added.
+        (WebCore::MainFrame::clearTrigger): Added.
+        * page/MainFrame.h:
+        * page/WheelEventTestTrigger.cpp: Added.
+        (WebCore::WheelEventTestTrigger::WheelEventTestTrigger):
+        (WebCore::WheelEventTestTrigger::createWeakPtr):
+        (WebCore::WheelEventTestTrigger::clearAllTestDeferrals):
+        (WebCore::WheelEventTestTrigger::setTestNotificationCallback):
+        (WebCore::WheelEventTestTrigger::deferTestsForReason):
+        (WebCore::WheelEventTestTrigger::removeTestDeferralForReason):
+        (WebCore::WheelEventTestTrigger::triggerTestTimerFired):
+        * page/WheelEventTestTrigger.h: Added.
+
</ins><span class="cx"> 2015-04-13  Jer Noble  &lt;jer.noble@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         [iOS] When entering optimized fullscreen, standard fullscreen view should exit.
</span><span class="lines">@@ -3260,6 +3297,9 @@
</span><span class="cx">         3. Remove a number of unneeded null checks in EventHandler.
</span><span class="cx">         4. ScrollController must always have a client, so hold a reference instead of using a pointer.
</span><span class="cx"> 
</span><ins>+        * WebCore.vcxproj/WebCore.vcxproj: Add new WheelEventTestTrigger files.
+        * WebCore.vcxproj/WebCore.vcxproj.filters: Ditto.
+        * WebCore.xcodeproj/project.pbxproj: Ditto.
</ins><span class="cx">         * page/EventHandler.cpp:
</span><span class="cx">         (WebCore::EventHandler::platformNotifyIfEndGesture): Renamed from 'platformNotifySnapIfNecessary'.
</span><span class="cx">         (WebCore::EventHandler::handleWheelEvent): Call 'platformNotifySnapIfNecessary' at method exit points.
</span></span></pre></div>
<a id="trunkSourceWebCoreWebCorevcxprojWebCorevcxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj (182767 => 182768)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj        2015-04-13 23:51:36 UTC (rev 182767)
+++ trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj        2015-04-14 00:05:17 UTC (rev 182768)
</span><span class="lines">@@ -7222,6 +7222,7 @@
</span><span class="cx">     &lt;ClCompile Include=&quot;..\page\VisitedLinkStore.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\fileapi\WebKitBlobBuilder.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\page\WheelEventDeltaTracker.cpp&quot; /&gt;
</span><ins>+    &lt;ClCompile Include=&quot;..\page\WheelEventTestTrigger.cpp&quot; /&gt;
</ins><span class="cx">     &lt;ClCompile Include=&quot;..\page\WindowFeatures.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\page\WindowFocusAllowedIndicator.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\page\WorkerNavigator.cpp&quot; /&gt;
</span><span class="lines">@@ -19619,6 +19620,7 @@
</span><span class="cx">     &lt;ClInclude Include=&quot;..\fileapi\WebKitBlobBuilder.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\page\WebKitPoint.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\page\WheelEventDeltaTracker.h&quot; /&gt;
</span><ins>+    &lt;ClInclude Include=&quot;..\page\WheelEventTestTrigger.h&quot; /&gt;
</ins><span class="cx">     &lt;ClInclude Include=&quot;..\page\WindowFeatures.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\page\WindowFocusAllowedIndicator.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\page\WorkerNavigator.h&quot; /&gt;
</span></span></pre></div>
<a id="trunkSourceWebCoreWebCorevcxprojWebCorevcxprojfilters"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj.filters (182767 => 182768)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj.filters        2015-04-13 23:51:36 UTC (rev 182767)
+++ trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj.filters        2015-04-14 00:05:17 UTC (rev 182768)
</span><span class="lines">@@ -819,6 +819,9 @@
</span><span class="cx">     &lt;ClCompile Include=&quot;..\page\WheelEventDeltaTracker.cpp&quot;&gt;
</span><span class="cx">       &lt;Filter&gt;page&lt;/Filter&gt;
</span><span class="cx">     &lt;/ClCompile&gt;
</span><ins>+    &lt;ClCompile Include=&quot;..\page\WheelEventTestTrigger.cpp&quot;&gt;
+      &lt;Filter&gt;page&lt;/Filter&gt;
+    &lt;/ClCompile&gt;
</ins><span class="cx">     &lt;ClCompile Include=&quot;..\page\WindowFeatures.cpp&quot;&gt;
</span><span class="cx">       &lt;Filter&gt;page&lt;/Filter&gt;
</span><span class="cx">     &lt;/ClCompile&gt;
</span><span class="lines">@@ -7824,6 +7827,9 @@
</span><span class="cx">     &lt;ClInclude Include=&quot;..\page\WheelEventDeltaTracker.h&quot;&gt;
</span><span class="cx">       &lt;Filter&gt;page&lt;/Filter&gt;
</span><span class="cx">     &lt;/ClInclude&gt;
</span><ins>+    &lt;ClInclude Include=&quot;..\page\WheelEventTestTrigger.h&quot;&gt;
+      &lt;Filter&gt;page&lt;/Filter&gt;
+    &lt;/ClInclude&gt;
</ins><span class="cx">     &lt;ClInclude Include=&quot;..\page\WindowFeatures.h&quot;&gt;
</span><span class="cx">       &lt;Filter&gt;page&lt;/Filter&gt;
</span><span class="cx">     &lt;/ClInclude&gt;
</span></span></pre></div>
<a id="trunkSourceWebCoreWebCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (182767 => 182768)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj        2015-04-13 23:51:36 UTC (rev 182767)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj        2015-04-14 00:05:17 UTC (rev 182768)
</span><span class="lines">@@ -2484,6 +2484,8 @@
</span><span class="cx">                 7ACD88D314C08BD60084EDD2 /* InspectorIndexedDBAgent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7ACD88D114C08BD60084EDD2 /* InspectorIndexedDBAgent.cpp */; };
</span><span class="cx">                 7ACD88D414C08BD60084EDD2 /* InspectorIndexedDBAgent.h in Headers */ = {isa = PBXBuildFile; fileRef = 7ACD88D214C08BD60084EDD2 /* InspectorIndexedDBAgent.h */; };
</span><span class="cx">                 7ADE722610CBBB9B006B3B3A /* ContextMenuProvider.h in Headers */ = {isa = PBXBuildFile; fileRef = 7ADE722510CBBB9B006B3B3A /* ContextMenuProvider.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><ins>+                7AE335F11ACB09E200E401EF /* WheelEventTestTrigger.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7AE335EF1ACB09E200E401EF /* WheelEventTestTrigger.cpp */; };
+                7AE335F21ACB09E200E401EF /* WheelEventTestTrigger.h in Headers */ = {isa = PBXBuildFile; fileRef = 7AE335F01ACB09E200E401EF /* WheelEventTestTrigger.h */; settings = {ATTRIBUTES = (Private, ); }; };
</ins><span class="cx">                 7AF9B20218CFB2DF00C64BEF /* VTTRegion.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7AF9B1FC18CFB2DF00C64BEF /* VTTRegion.cpp */; };
</span><span class="cx">                 7AF9B20318CFB2DF00C64BEF /* VTTRegion.h in Headers */ = {isa = PBXBuildFile; fileRef = 7AF9B1FD18CFB2DF00C64BEF /* VTTRegion.h */; };
</span><span class="cx">                 7AF9B20518CFB2DF00C64BEF /* VTTRegionList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7AF9B1FF18CFB2DF00C64BEF /* VTTRegionList.cpp */; };
</span><span class="lines">@@ -9731,6 +9733,8 @@
</span><span class="cx">                 7ACD88D114C08BD60084EDD2 /* InspectorIndexedDBAgent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InspectorIndexedDBAgent.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 7ACD88D214C08BD60084EDD2 /* InspectorIndexedDBAgent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InspectorIndexedDBAgent.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 7ADE722510CBBB9B006B3B3A /* ContextMenuProvider.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ContextMenuProvider.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                7AE335EF1ACB09E200E401EF /* WheelEventTestTrigger.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WheelEventTestTrigger.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
+                7AE335F01ACB09E200E401EF /* WheelEventTestTrigger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WheelEventTestTrigger.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 7AF9B1FC18CFB2DF00C64BEF /* VTTRegion.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = VTTRegion.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 7AF9B1FD18CFB2DF00C64BEF /* VTTRegion.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VTTRegion.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 7AF9B1FE18CFB2DF00C64BEF /* VTTRegion.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = VTTRegion.idl; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -16976,6 +16980,8 @@
</span><span class="cx">                                 494BD7940F55C8EE00747828 /* WebKitPoint.idl */,
</span><span class="cx">                                 93EC449F188F4BB800661DF1 /* WheelEventDeltaTracker.cpp */,
</span><span class="cx">                                 93EC44A0188F4BB800661DF1 /* WheelEventDeltaTracker.h */,
</span><ins>+                                7AE335EF1ACB09E200E401EF /* WheelEventTestTrigger.cpp */,
+                                7AE335F01ACB09E200E401EF /* WheelEventTestTrigger.h */,
</ins><span class="cx">                                 BC8243E60D0CFD7500460C8F /* WindowFeatures.cpp */,
</span><span class="cx">                                 BC8243E70D0CFD7500460C8F /* WindowFeatures.h */,
</span><span class="cx">                                 7E99AF520B13846468FB01A5 /* WindowFocusAllowedIndicator.cpp */,
</span><span class="lines">@@ -23609,6 +23615,7 @@
</span><span class="cx">                         buildActionMask = 2147483647;
</span><span class="cx">                         files = (
</span><span class="cx">                                 FE115FAB167988CD00249134 /* AbstractDatabaseServer.h in Headers */,
</span><ins>+                                7AE335F21ACB09E200E401EF /* WheelEventTestTrigger.h in Headers */,
</ins><span class="cx">                                 41E1B1D10FF5986900576B3B /* AbstractWorker.h in Headers */,
</span><span class="cx">                                 29A8122E0FBB9C1D00510293 /* AccessibilityARIAGridCell.h in Headers */,
</span><span class="cx">                                 29A812330FBB9C1D00510293 /* AccessibilityARIAGridRow.h in Headers */,
</span><span class="lines">@@ -28075,6 +28082,7 @@
</span><span class="cx">                                 7728694E14F8882500F484DC /* EXTTextureFilterAnisotropic.cpp in Sources */,
</span><span class="cx">                                 A75E8B880E1DE2D6007F2481 /* FEBlend.cpp in Sources */,
</span><span class="cx">                                 A75E8B8A0E1DE2D6007F2481 /* FEColorMatrix.cpp in Sources */,
</span><ins>+                                7AE335F11ACB09E200E401EF /* WheelEventTestTrigger.cpp in Sources */,
</ins><span class="cx">                                 A75E8B8C0E1DE2D6007F2481 /* FEComponentTransfer.cpp in Sources */,
</span><span class="cx">                                 A75E8B8E0E1DE2D6007F2481 /* FEComposite.cpp in Sources */,
</span><span class="cx">                                 84730D781248F0B300D3A9C9 /* FEConvolveMatrix.cpp in Sources */,
</span></span></pre></div>
<a id="trunkSourceWebCorepageMainFramecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/page/MainFrame.cpp (182767 => 182768)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/page/MainFrame.cpp        2015-04-13 23:51:36 UTC (rev 182767)
+++ trunk/Source/WebCore/page/MainFrame.cpp        2015-04-14 00:05:17 UTC (rev 182768)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2013-2014 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 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">@@ -33,6 +33,7 @@
</span><span class="cx"> #include &quot;ScrollLatchingState.h&quot;
</span><span class="cx"> #include &quot;Settings.h&quot;
</span><span class="cx"> #include &quot;WheelEventDeltaTracker.h&quot;
</span><ins>+#include &quot;WheelEventTestTrigger.h&quot;
</ins><span class="cx"> #include &lt;wtf/NeverDestroyed.h&gt;
</span><span class="cx"> 
</span><span class="cx"> #if PLATFORM(MAC)
</span><span class="lines">@@ -122,7 +123,24 @@
</span><span class="cx"> {
</span><span class="cx">     m_latchingState.removeLast();
</span><span class="cx"> }
</span><del>-
</del><span class="cx"> #endif
</span><span class="cx"> 
</span><ins>+WheelEventTestTrigger* MainFrame::testTrigger() const
+{
+    return m_testTrigger.get();
</ins><span class="cx"> }
</span><ins>+
+WheelEventTestTrigger* MainFrame::ensureTestTrigger()
+{
+    if (!m_testTrigger)
+        m_testTrigger = std::make_unique&lt;WheelEventTestTrigger&gt;();
+
+    return m_testTrigger.get();
+}
+
+void MainFrame::clearTrigger()
+{
+    m_testTrigger = nullptr;
+}
+
+}
</ins></span></pre></div>
<a id="trunkSourceWebCorepageMainFrameh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/page/MainFrame.h (182767 => 182768)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/page/MainFrame.h        2015-04-13 23:51:36 UTC (rev 182767)
+++ trunk/Source/WebCore/page/MainFrame.h        2015-04-14 00:05:17 UTC (rev 182768)
</span><span class="lines">@@ -37,6 +37,7 @@
</span><span class="cx"> class ScrollLatchingState;
</span><span class="cx"> class ServicesOverlayController;
</span><span class="cx"> class WheelEventDeltaTracker;
</span><ins>+class WheelEventTestTrigger;
</ins><span class="cx"> 
</span><span class="cx"> class MainFrame final : public Frame {
</span><span class="cx"> public:
</span><span class="lines">@@ -63,6 +64,10 @@
</span><span class="cx"> 
</span><span class="cx">     WEBCORE_EXPORT DiagnosticLoggingClient&amp; diagnosticLoggingClient() const;
</span><span class="cx"> 
</span><ins>+    WEBCORE_EXPORT WheelEventTestTrigger* testTrigger() const;
+    WEBCORE_EXPORT WheelEventTestTrigger* ensureTestTrigger();
+    WEBCORE_EXPORT void clearTrigger();
+
</ins><span class="cx"> private:
</span><span class="cx">     MainFrame(Page&amp;, PageConfiguration&amp;);
</span><span class="cx"> 
</span><span class="lines">@@ -76,6 +81,8 @@
</span><span class="cx">     std::unique_ptr&lt;ServicesOverlayController&gt; m_servicesOverlayController;
</span><span class="cx"> #endif
</span><span class="cx"> #endif
</span><ins>+    std::unique_ptr&lt;WheelEventTestTrigger&gt; m_testTrigger;
+
</ins><span class="cx">     std::unique_ptr&lt;WheelEventDeltaTracker&gt; m_recentWheelEventDeltaTracker;
</span><span class="cx">     std::unique_ptr&lt;PageOverlayController&gt; m_pageOverlayController;
</span><span class="cx">     DiagnosticLoggingClient* m_diagnosticLoggingClient;
</span></span></pre></div>
<a id="trunkSourceWebCorepageWheelEventTestTriggercpp"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/page/WheelEventTestTrigger.cpp (0 => 182768)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/page/WheelEventTestTrigger.cpp                                (rev 0)
+++ trunk/Source/WebCore/page/WheelEventTestTrigger.cpp        2015-04-14 00:05:17 UTC (rev 182768)
</span><span class="lines">@@ -0,0 +1,106 @@
</span><ins>+/*
+ * Copyright (C) 2015 Apple Inc.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 3.  Neither the name of Apple Inc. (&quot;Apple&quot;) nor the names of
+ *     its contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS &quot;AS IS&quot; AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include &quot;config.h&quot;
+#include &quot;WheelEventTestTrigger.h&quot;
+
+namespace WebCore {
+
+WheelEventTestTrigger::WheelEventTestTrigger()
+    : m_testTriggerTimer(RunLoop::current(), this, &amp;WheelEventTestTrigger::triggerTestTimerFired)
+    , m_weakPtrFactory(this)
+{
+}
+
+WeakPtr&lt;WheelEventTestTrigger&gt; WheelEventTestTrigger::createWeakPtr()
+{
+    return m_weakPtrFactory.createWeakPtr();
+}
+
+void WheelEventTestTrigger::clearAllTestDeferrals()
+{
+    std::lock_guard&lt;std::mutex&gt; lock(m_testTriggerMutex);
+    m_deferTestTriggerReasons.clear();
+    m_testNotificationCallback = std::function&lt;void()&gt;();
+    m_testTriggerTimer.stop();
+}
+
+void WheelEventTestTrigger::setTestCallbackAndStartNotificationTimer(std::function&lt;void()&gt; functionCallback)
+{
+    {
+        std::lock_guard&lt;std::mutex&gt; lock(m_testTriggerMutex);
+        m_testNotificationCallback = WTF::move(functionCallback);
+    }
+    
+    if (!m_testTriggerTimer.isActive())
+        m_testTriggerTimer.startRepeating(1.0 / 60.0);
+}
+
+void WheelEventTestTrigger::deferTestsForReason(ScrollableAreaIdentifier identifier, DeferTestTriggerReason reason)
+{
+    std::lock_guard&lt;std::mutex&gt; lock(m_testTriggerMutex);
+    auto it = m_deferTestTriggerReasons.find(identifier);
+    if (it == m_deferTestTriggerReasons.end())
+        it = m_deferTestTriggerReasons.add(identifier, std::set&lt;DeferTestTriggerReason&gt;()).iterator;
+    
+    it-&gt;value.insert(reason);
+}
+
+void WheelEventTestTrigger::removeTestDeferralForReason(ScrollableAreaIdentifier identifier, DeferTestTriggerReason reason)
+{
+    std::lock_guard&lt;std::mutex&gt; lock(m_testTriggerMutex);
+    auto it = m_deferTestTriggerReasons.find(identifier);
+    if (it == m_deferTestTriggerReasons.end())
+        return;
+
+    it-&gt;value.erase(reason);
+    
+    if (it-&gt;value.empty())
+        m_deferTestTriggerReasons.remove(it);
+}
+
+void WheelEventTestTrigger::triggerTestTimerFired()
+{
+    std::function&lt;void()&gt; functionCallback;
+
+    {
+        std::lock_guard&lt;std::mutex&gt; lock(m_testTriggerMutex);
+        if (!m_deferTestTriggerReasons.isEmpty())
+            return;
+
+        functionCallback = WTF::move(m_testNotificationCallback);
+        m_testNotificationCallback = std::function&lt;void()&gt;();
+    }
+
+    m_testTriggerTimer.stop();
+
+    if (functionCallback)
+        functionCallback();
+}
+
+}
</ins></span></pre></div>
<a id="trunkSourceWebCorepageWheelEventTestTriggerh"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/page/WheelEventTestTrigger.h (0 => 182768)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/page/WheelEventTestTrigger.h                                (rev 0)
+++ trunk/Source/WebCore/page/WheelEventTestTrigger.h        2015-04-14 00:05:17 UTC (rev 182768)
</span><span class="lines">@@ -0,0 +1,72 @@
</span><ins>+/*
+ * Copyright (C) 2015 Apple Inc.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 3.  Neither the name of Apple Inc. (&quot;Apple&quot;) nor the names of
+ *     its contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS &quot;AS IS&quot; AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef WheelEventTestTrigger_h
+#define WheelEventTestTrigger_h
+
+#include &lt;mutex&gt;
+#include &lt;set&gt;
+#include &lt;wtf/HashMap.h&gt;
+#include &lt;wtf/RunLoop.h&gt;
+#include &lt;wtf/WeakPtr.h&gt;
+
+namespace WebCore {
+
+class WheelEventTestTrigger {
+    WTF_MAKE_NONCOPYABLE(WheelEventTestTrigger); WTF_MAKE_FAST_ALLOCATED;
+public:
+    WheelEventTestTrigger();
+
+    WEBCORE_EXPORT void setTestCallbackAndStartNotificationTimer(std::function&lt;void()&gt;);
+    WEBCORE_EXPORT void clearAllTestDeferrals();
+    
+    enum DeferTestTriggerReason {
+        RubberbandInProgress,
+        ScrollSnapInProgress,
+        ScrollingThreadSyncNeeded,
+        ContentScrollInProgress
+    };
+    typedef void* ScrollableAreaIdentifier;
+    void deferTestsForReason(ScrollableAreaIdentifier, DeferTestTriggerReason);
+    void removeTestDeferralForReason(ScrollableAreaIdentifier, DeferTestTriggerReason);
+    void triggerTestTimerFired();
+
+    WeakPtr&lt;WheelEventTestTrigger&gt; createWeakPtr();
+
+private:
+    std::function&lt;void()&gt; m_testNotificationCallback;
+    RunLoop::Timer&lt;WheelEventTestTrigger&gt; m_testTriggerTimer;
+    mutable std::mutex m_testTriggerMutex;
+    WTF::HashMap&lt;void*, std::set&lt;DeferTestTriggerReason&gt;&gt; m_deferTestTriggerReasons;
+
+    WeakPtrFactory&lt;WheelEventTestTrigger&gt; m_weakPtrFactory;
+};
+
+}
+
+#endif
</ins></span></pre></div>
<a id="trunkSourceWebCoreplatformPlatformExportMacrosh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/PlatformExportMacros.h (182767 => 182768)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/PlatformExportMacros.h        2015-04-13 23:51:36 UTC (rev 182767)
+++ trunk/Source/WebCore/platform/PlatformExportMacros.h        2015-04-14 00:05:17 UTC (rev 182768)
</span><span class="lines">@@ -43,7 +43,6 @@
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx"> #else // !USE(EXPORT_MACROS)
</span><del>-
</del><span class="cx"> #define WEBCORE_EXPORT
</span><span class="cx"> #define WEBCORE_TESTSUPPORT_EXPORT
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformspimacNSSharingServicePickerSPIh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/spi/mac/NSSharingServicePickerSPI.h (182767 => 182768)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/spi/mac/NSSharingServicePickerSPI.h        2015-04-13 23:51:36 UTC (rev 182767)
+++ trunk/Source/WebCore/platform/spi/mac/NSSharingServicePickerSPI.h        2015-04-14 00:05:17 UTC (rev 182768)
</span><span class="lines">@@ -43,6 +43,7 @@
</span><span class="cx"> @interface NSSharingServicePicker (Private)
</span><span class="cx"> @property NSSharingServicePickerStyle style;
</span><span class="cx"> - (NSMenu *)menu;
</span><ins>+- (void)hide;
</ins><span class="cx"> @end
</span><span class="cx"> 
</span><span class="cx"> #endif
</span></span></pre></div>
<a id="trunkSourceWebKit2ChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/ChangeLog (182767 => 182768)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/ChangeLog        2015-04-13 23:51:36 UTC (rev 182767)
+++ trunk/Source/WebKit2/ChangeLog        2015-04-14 00:05:17 UTC (rev 182768)
</span><span class="lines">@@ -1,3 +1,19 @@
</span><ins>+2015-04-10  Brent Fulgham  &lt;bfulgham@apple.com&gt;
+
+        Expand test infrastructure to support scrolling tests
+        https://bugs.webkit.org/show_bug.cgi?id=143286
+        &lt;rdar://problem/20375516&gt;
+
+        Reviewed by Simon Fraser.
+
+        Extend the WK2 testing API to include a method for setting a JSC callback function to be triggered
+        by the new WebCore::WheelEventTestTrigger singleton.
+
+        * WebProcess/InjectedBundle/API/c/WKBundlePage.cpp:
+        (WKBundlePageStartMonitoringScrollOperations): WK2 method that causes the testing system to begin tracking wheel events.
+        (WKBundlePageRegisterScrollOperationCompletionCallback): WK2 method to set the callback function for testing.
+        * WebProcess/InjectedBundle/API/c/WKBundlePage.h:
+
</ins><span class="cx"> 2015-04-13  Enrica Casucci  &lt;enrica@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Clients of WKWebView should be able to override drag functions.
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessInjectedBundleAPIcWKBundlePagecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundlePage.cpp (182767 => 182768)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundlePage.cpp        2015-04-13 23:51:36 UTC (rev 182767)
+++ trunk/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundlePage.cpp        2015-04-14 00:05:17 UTC (rev 182768)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2010, 2011, 2013 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2010, 2011, 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">@@ -59,6 +59,7 @@
</span><span class="cx"> #include &lt;WebCore/PageOverlay.h&gt;
</span><span class="cx"> #include &lt;WebCore/PageOverlayController.h&gt;
</span><span class="cx"> #include &lt;WebCore/URL.h&gt;
</span><ins>+#include &lt;WebCore/WheelEventTestTrigger.h&gt;
</ins><span class="cx"> #include &lt;wtf/StdLibExtras.h&gt;
</span><span class="cx"> 
</span><span class="cx"> using namespace WebKit;
</span><span class="lines">@@ -573,6 +574,34 @@
</span><span class="cx"> }
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><ins>+void WKBundlePageStartMonitoringScrollOperations(WKBundlePageRef pageRef)
+{
+    WebKit::WebPage* webPage = toImpl(pageRef);
+    WebCore::Page* page = webPage ? webPage-&gt;corePage() : nullptr;
+    
+    if (!page)
+        return;
+
+    page-&gt;mainFrame().ensureTestTrigger();
+}
+
+void WKBundlePageRegisterScrollOperationCompletionCallback(WKBundlePageRef pageRef, WKBundlePageTestNotificationCallback callback, void* context)
+{
+    if (!callback)
+        return;
+    
+    WebKit::WebPage* webPage = toImpl(pageRef);
+    WebCore::Page* page = webPage ? webPage-&gt;corePage() : nullptr;
+    
+    if (!page)
+        return;
+    
+    WebCore::WheelEventTestTrigger* trigger = page-&gt;mainFrame().ensureTestTrigger();
+    trigger-&gt;setTestCallbackAndStartNotificationTimer([=]() {
+        callback(context);
+    });
+}
+
</ins><span class="cx"> void WKBundlePagePostMessage(WKBundlePageRef pageRef, WKStringRef messageNameRef, WKTypeRef messageBodyRef)
</span><span class="cx"> {
</span><span class="cx">     toImpl(pageRef)-&gt;postMessage(toWTFString(messageNameRef), toImpl(messageBodyRef));
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessInjectedBundleAPIcWKBundlePageh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundlePage.h (182767 => 182768)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundlePage.h        2015-04-13 23:51:36 UTC (rev 182767)
+++ trunk/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundlePage.h        2015-04-14 00:05:17 UTC (rev 182768)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2010 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2010, 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">@@ -109,6 +109,11 @@
</span><span class="cx"> 
</span><span class="cx"> WK_EXPORT bool WKBundlePageIsUsingEphemeralSession(WKBundlePageRef page);
</span><span class="cx"> 
</span><ins>+WK_EXPORT void WKBundlePageStartMonitoringScrollOperations(WKBundlePageRef);
+
+typedef void (*WKBundlePageTestNotificationCallback)(void* context);
+WK_EXPORT void WKBundlePageRegisterScrollOperationCompletionCallback(WKBundlePageRef, WKBundlePageTestNotificationCallback, void* context);
+
</ins><span class="cx"> WK_EXPORT void WKBundlePagePostMessage(WKBundlePageRef page, WKStringRef messageName, WKTypeRef messageBody);
</span><span class="cx"> WK_EXPORT void WKBundlePagePostSynchronousMessage(WKBundlePageRef page, WKStringRef messageName, WKTypeRef messageBody, WKTypeRef* returnData);
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkToolsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Tools/ChangeLog (182767 => 182768)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/ChangeLog        2015-04-13 23:51:36 UTC (rev 182767)
+++ trunk/Tools/ChangeLog        2015-04-14 00:05:17 UTC (rev 182768)
</span><span class="lines">@@ -1,3 +1,37 @@
</span><ins>+2015-04-10  Brent Fulgham  &lt;bfulgham@apple.com&gt;
+
+        Expand test infrastructure to support scrolling tests
+        https://bugs.webkit.org/show_bug.cgi?id=143286
+        &lt;rdar://problem/20375516&gt;
+
+        Reviewed by Simon Fraser.
+
+        Extend the WK1 and WK2 test programs to support two new EventSender commands:
+        (1) monitorWheelEvents: Tells DRT and WKTR to track the wheel event and animation state, so that we can
+        block executing tests until WebKit has completed any rubberband, scroll, or scroll-snap animations.
+        (2) callAfterScrollingCompletes: Provide a callback method to be executed when WebKit determines that
+        relevant rubberband, scroll, and scroll-snap animations are finished.
+
+        * DumpRenderTree/mac/EventSendingController.mm:
+        (+[EventSendingController isSelectorExcludedFromWebScript:]): Update to recognize 'callAfterScrollingCompletes:'
+        and 'monitorWheelEvents'.
+        (+[EventSendingController webScriptNameForSelector:]): Ditto.
+        (-[EventSendingController mouseScrollByX:andY:continuously:]): Add some stderr logging to help when
+        debugging test failures.
+        (-[EventSendingController mouseScrollByX:andY:withWheel:andMomentumPhases:]): Ditto.
+        (-[EventSendingController callAfterScrollingCompletes:]): Added. Protects the JSObject representing the callback
+        function, then passes it to WebCore to be called once the test deferrals have been cleared.
+        (-[EventSendingController monitorWheelEvents:]): Added. Activates the wheel event tracking used by the
+        'callAfterScrollingCompletes' method.
+        * WebKitTestRunner/InjectedBundle/Bindings/EventSendingController.idl: Added signatures for 'callAfterScrollingCompletes'
+        and 'monitorWheelEvents'.
+        * WebKitTestRunner/InjectedBundle/EventSendingController.cpp:
+        (WTR::EventSendingController::callAfterScrollingCompletes): Added. Protects the JSObject representing the
+        callback function, then passes it to WebCore to be called once the test deferrals have been cleared
+        (WTR::EventSendingController::monitorWheelEvents): Added. Activates the wheel event tracking used by the
+        'callAfterScrollingComplates' method.
+        * WebKitTestRunner/InjectedBundle/EventSendingController.h:
+
</ins><span class="cx"> 2015-04-13  Alexey Proskuryakov  &lt;ap@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         build.webkit.org/dashboard: Crash-only queues should show failure when testing fails to start
</span></span></pre></div>
<a id="trunkToolsDumpRenderTreeDumpRenderTreexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Tools/DumpRenderTree/DumpRenderTree.xcodeproj/project.pbxproj (182767 => 182768)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/DumpRenderTree/DumpRenderTree.xcodeproj/project.pbxproj        2015-04-13 23:51:36 UTC (rev 182767)
+++ trunk/Tools/DumpRenderTree/DumpRenderTree.xcodeproj/project.pbxproj        2015-04-14 00:05:17 UTC (rev 182768)
</span><span class="lines">@@ -1133,6 +1133,7 @@
</span><span class="cx">                         buildSettings = {
</span><span class="cx">                                 INSTALL_PATH = &quot;$(SYSTEM_LIBRARY_DIR)/Frameworks/$(WEBKIT_FRAMEWORK_RESOURCES_PATH)&quot;;
</span><span class="cx">                                 PRODUCT_NAME = All;
</span><ins>+                                WTF_USE_EXPORT_MACROS = 0;
</ins><span class="cx">                         };
</span><span class="cx">                         name = Production;
</span><span class="cx">                 };
</span><span class="lines">@@ -1223,6 +1224,7 @@
</span><span class="cx">                                         &quot;-Wno-four-char-constants&quot;,
</span><span class="cx">                                         &quot;-Wno-unknown-pragmas&quot;,
</span><span class="cx">                                 );
</span><ins>+                                WTF_USE_EXPORT_MACROS = 0;
</ins><span class="cx">                         };
</span><span class="cx">                         name = Debug;
</span><span class="cx">                 };
</span><span class="lines">@@ -1240,6 +1242,7 @@
</span><span class="cx">                                         &quot;-Wno-four-char-constants&quot;,
</span><span class="cx">                                         &quot;-Wno-unknown-pragmas&quot;,
</span><span class="cx">                                 );
</span><ins>+                                WTF_USE_EXPORT_MACROS = 0;
</ins><span class="cx">                         };
</span><span class="cx">                         name = Release;
</span><span class="cx">                 };
</span></span></pre></div>
<a id="trunkToolsDumpRenderTreemacEventSendingControllermm"></a>
<div class="modfile"><h4>Modified: trunk/Tools/DumpRenderTree/mac/EventSendingController.mm (182767 => 182768)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/DumpRenderTree/mac/EventSendingController.mm        2015-04-13 23:51:36 UTC (rev 182767)
+++ trunk/Tools/DumpRenderTree/mac/EventSendingController.mm        2015-04-14 00:05:17 UTC (rev 182768)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2005, 2006, 2007, 2008, 2014 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2005, 2006, 2007, 2008, 2014-2015 Apple Inc. All rights reserved.
</ins><span class="cx">  * Copyright (C) 2006 Jonas Witt &lt;jonas.witt@gmail.com&gt;
</span><span class="cx">  * Copyright (C) 2006 Samuel Weinig &lt;sam.weinig@gmail.com&gt;
</span><span class="cx">  * Copyright (C) 2006 Alexey Proskuryakov &lt;ap@nypop.com&gt;
</span><span class="lines">@@ -35,13 +35,17 @@
</span><span class="cx"> #import &quot;DumpRenderTree.h&quot;
</span><span class="cx"> #import &quot;DumpRenderTreeDraggingInfo.h&quot;
</span><span class="cx"> #import &quot;DumpRenderTreeFileDraggingSource.h&quot;
</span><del>-
</del><span class="cx"> #import &lt;WebKit/DOMPrivate.h&gt;
</span><span class="cx"> #import &lt;WebKit/WebKit.h&gt;
</span><span class="cx"> #import &lt;WebKit/WebViewPrivate.h&gt;
</span><ins>+#import &lt;functional&gt;
</ins><span class="cx"> 
</span><span class="cx"> #if !PLATFORM(IOS)
</span><span class="cx"> #import &lt;Carbon/Carbon.h&gt; // for GetCurrentEventTime()
</span><ins>+#import &lt;JavaScriptCore/JSRetainPtr.h&gt;
+#import &lt;WebCore/MainFrame.h&gt;
+#import &lt;WebCore/Page.h&gt;
+#import &lt;WebCore/WheelEventTestTrigger.h&gt;
</ins><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx"> #if PLATFORM(IOS)
</span><span class="lines">@@ -128,6 +132,12 @@
</span><span class="cx"> @end // SyntheticTouch
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><ins>+#if !PLATFORM(IOS)
+@interface WebView (WebViewInternalForTesting)
+- (WebCore::Frame*)_mainCoreFrame;
+@end
+#endif
+
</ins><span class="cx"> @implementation EventSendingController
</span><span class="cx"> 
</span><span class="cx"> + (void)initialize
</span><span class="lines">@@ -204,6 +214,8 @@
</span><span class="cx">             || aSelector == @selector(mouseScrollByX:andY:)
</span><span class="cx">             || aSelector == @selector(mouseScrollByX:andY:withWheel:andMomentumPhases:)
</span><span class="cx">             || aSelector == @selector(continuousMouseScrollByX:andY:)
</span><ins>+            || aSelector == @selector(monitorWheelEvents)
+            || aSelector == @selector(callAfterScrollingCompletes:)
</ins><span class="cx"> #if PLATFORM(IOS)
</span><span class="cx">             || aSelector == @selector(addTouchAtX:y:)
</span><span class="cx">             || aSelector == @selector(updateTouchAtIndex:x:y:)
</span><span class="lines">@@ -261,6 +273,10 @@
</span><span class="cx">         return @&quot;continuousMouseScrollBy&quot;;
</span><span class="cx">     if (aSelector == @selector(scalePageBy:atX:andY:))
</span><span class="cx">         return @&quot;scalePageBy&quot;;
</span><ins>+    if (aSelector == @selector(monitorWheelEvents))
+        return @&quot;monitorWheelEvents&quot;;
+    if (aSelector == @selector(callAfterScrollingCompletes:))
+        return @&quot;callAfterScrollingCompletes&quot;;
</ins><span class="cx"> #if PLATFORM(IOS)
</span><span class="cx">     if (aSelector == @selector(addTouchAtX:y:))
</span><span class="cx">         return @&quot;addTouchPoint&quot;;
</span><span class="lines">@@ -687,7 +703,8 @@
</span><span class="cx">         [NSApp _setCurrentEvent:scrollEvent];
</span><span class="cx">         [subView scrollWheel:scrollEvent];
</span><span class="cx">         [NSApp _setCurrentEvent:nil];
</span><del>-    }
</del><ins>+    } else
+        printf(&quot;mouseScrollByXandYContinuously: Unable to locate target view for current mouse location.&quot;);
</ins><span class="cx"> #endif
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -746,7 +763,8 @@
</span><span class="cx">         [NSApp _setCurrentEvent:scrollEvent];
</span><span class="cx">         [targetView scrollWheel:scrollEvent];
</span><span class="cx">         [NSApp _setCurrentEvent:nil];
</span><del>-    }
</del><ins>+    } else
+        printf(&quot;mouseScrollByX...andMomentumPhases: Unable to locate target view for current mouse location.&quot;);
</ins><span class="cx"> #endif
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -1243,6 +1261,39 @@
</span><span class="cx">     
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+- (void)monitorWheelEvents
+{
+#if PLATFORM(MAC)
+    WebCore::Frame* frame = [[mainFrame webView] _mainCoreFrame];
+    if (!frame)
+        return;
+    
+    frame-&gt;mainFrame().ensureTestTrigger();
+#endif
+}
+
+- (void)callAfterScrollingCompletes:(WebScriptObject*)callback
+{
+#if PLATFORM(MAC)
+    JSObjectRef jsCallbackFunction = [callback JSObject];
+    if (!jsCallbackFunction)
+        return;
+
+    WebCore::Frame* frame = [[mainFrame webView] _mainCoreFrame];
+    if (!frame)
+        return;
+
+    WebCore::WheelEventTestTrigger* trigger = frame-&gt;mainFrame().ensureTestTrigger();
+    JSGlobalContextRef globalContext = [mainFrame globalContext];
+    JSValueProtect(globalContext, jsCallbackFunction);
+
+    trigger-&gt;setTestCallbackAndStartNotificationTimer([=](void) {
+        JSObjectCallAsFunction(globalContext, jsCallbackFunction, nullptr, 0, nullptr, nullptr);
+        JSValueUnprotect(globalContext, jsCallbackFunction);
+    });
+#endif
+}
+
</ins><span class="cx"> #if PLATFORM(IOS)
</span><span class="cx"> - (void)addTouchAtX:(int)x y:(int)y
</span><span class="cx"> {
</span></span></pre></div>
<a id="trunkToolsWebKitTestRunnerInjectedBundleBindingsEventSendingControlleridl"></a>
<div class="modfile"><h4>Modified: trunk/Tools/WebKitTestRunner/InjectedBundle/Bindings/EventSendingController.idl (182767 => 182768)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/WebKitTestRunner/InjectedBundle/Bindings/EventSendingController.idl        2015-04-13 23:51:36 UTC (rev 182767)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/Bindings/EventSendingController.idl        2015-04-14 00:05:17 UTC (rev 182768)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2010, 2011, 2014 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2010, 2011, 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">@@ -45,6 +45,9 @@
</span><span class="cx">     void zoomPageOut();
</span><span class="cx">     void scalePageBy(double scale, double x, double y);
</span><span class="cx"> 
</span><ins>+    void monitorWheelEvents();
+    void callAfterScrollingCompletes(object functionCallback);
+
</ins><span class="cx"> #if defined(ENABLE_TOUCH_EVENTS) &amp;&amp; ENABLE_TOUCH_EVENTS
</span><span class="cx">     // Touch events.
</span><span class="cx">     void addTouchPoint(long x, long y);
</span></span></pre></div>
<a id="trunkToolsWebKitTestRunnerInjectedBundleEventSendingControllercpp"></a>
<div class="modfile"><h4>Modified: trunk/Tools/WebKitTestRunner/InjectedBundle/EventSendingController.cpp (182767 => 182768)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/WebKitTestRunner/InjectedBundle/EventSendingController.cpp        2015-04-13 23:51:36 UTC (rev 182767)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/EventSendingController.cpp        2015-04-14 00:05:17 UTC (rev 182768)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2010, 2011, 2014 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2010, 2011, 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">@@ -501,6 +501,54 @@
</span><span class="cx">     WKBundlePageSetScaleAtOrigin(InjectedBundle::singleton().page()-&gt;page(), scale, origin);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void EventSendingController::monitorWheelEvents()
+{
+    WKBundlePageRef page = InjectedBundle::singleton().page()-&gt;page();
+    
+    WKBundlePageStartMonitoringScrollOperations(page);
+}
+
+struct ScrollCompletionCallbackData {
+    JSContextRef m_context;
+    JSObjectRef m_function;
+
+    ScrollCompletionCallbackData(JSContextRef context, JSObjectRef function)
+        : m_context(context), m_function(function)
+    {
+    }
+};
+
+static void executeCallback(void* context)
+{
+    if (!context)
+        return;
+
+    std::unique_ptr&lt;ScrollCompletionCallbackData&gt; callBackData(reinterpret_cast&lt;ScrollCompletionCallbackData*&gt;(context));
+
+    JSObjectCallAsFunction(callBackData-&gt;m_context, callBackData-&gt;m_function, nullptr, 0, nullptr, nullptr);
+    JSValueUnprotect(callBackData-&gt;m_context, callBackData-&gt;m_function);
+}
+
+void EventSendingController::callAfterScrollingCompletes(JSValueRef functionCallback)
+{
+    if (!functionCallback)
+        return;
+
+    WKBundlePageRef page = InjectedBundle::singleton().page()-&gt;page();
+    WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(page);
+    JSContextRef context = WKBundleFrameGetJavaScriptContext(mainFrame);
+    
+    JSObjectRef functionCallbackObject = JSValueToObject(context, functionCallback, nullptr);
+    if (!functionCallbackObject)
+        return;
+    
+    JSValueProtect(context, functionCallbackObject);
+
+    auto scrollCompletionCallbackData = std::make_unique&lt;ScrollCompletionCallbackData&gt;(context, functionCallbackObject);
+
+    WKBundlePageRegisterScrollOperationCompletionCallback(page, executeCallback, scrollCompletionCallbackData.release());
+}
+
</ins><span class="cx"> #if ENABLE(TOUCH_EVENTS)
</span><span class="cx"> void EventSendingController::addTouchPoint(int x, int y)
</span><span class="cx"> {
</span></span></pre></div>
<a id="trunkToolsWebKitTestRunnerInjectedBundleEventSendingControllerh"></a>
<div class="modfile"><h4>Modified: trunk/Tools/WebKitTestRunner/InjectedBundle/EventSendingController.h (182767 => 182768)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/WebKitTestRunner/InjectedBundle/EventSendingController.h        2015-04-13 23:51:36 UTC (rev 182767)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/EventSendingController.h        2015-04-14 00:05:17 UTC (rev 182768)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2010, 2011, 2014 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2010, 2011, 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">@@ -52,6 +52,8 @@
</span><span class="cx">     JSValueRef contextClick();
</span><span class="cx">     void leapForward(int milliseconds);
</span><span class="cx">     void scheduleAsynchronousClick();
</span><ins>+    void monitorWheelEvents();
+    void callAfterScrollingCompletes(JSValueRef functionCallback);
</ins><span class="cx"> 
</span><span class="cx">     void keyDown(JSStringRef key, JSValueRef modifierArray, int location);
</span><span class="cx">     void scheduleAsynchronousKeyDown(JSStringRef key);
</span></span></pre>
</div>
</div>

</body>
</html>