<!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>[189287] 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/189287">189287</a></dd>
<dt>Author</dt> <dd>timothy_horton@apple.com</dd>
<dt>Date</dt> <dd>2015-09-03 14:11:44 -0700 (Thu, 03 Sep 2015)</dd>
</dl>

<h3>Log Message</h3>
<pre>[Mac] Add support for testing swipes
https://bugs.webkit.org/show_bug.cgi?id=148700

Reviewed by Beth Dakin.

* WebKitTestRunner/EventSenderProxy.h:
* WebKitTestRunner/InjectedBundle/Bindings/EventSendingController.idl:
* WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl:
* WebKitTestRunner/InjectedBundle/EventSendingController.cpp:
(WTR::cgEventPhaseFromString):
(WTR::cgEventMomentumPhaseFromString):
(WTR::EventSendingController::mouseScrollByWithWheelAndMomentumPhases):
(WTR::EventSendingController::swipeGestureWithWheelAndMomentumPhases):
* WebKitTestRunner/InjectedBundle/EventSendingController.h:
* WebKitTestRunner/InjectedBundle/InjectedBundle.cpp:
(WTR::InjectedBundle::didReceiveMessageToPage):
* WebKitTestRunner/InjectedBundle/TestRunner.cpp:
(WTR::TestRunner::installDidBeginSwipeCallback):
(WTR::TestRunner::installWillEndSwipeCallback):
(WTR::TestRunner::installDidEndSwipeCallback):
(WTR::TestRunner::installDidRemoveSwipeSnapshotCallback):
(WTR::TestRunner::callDidBeginSwipeCallback):
(WTR::TestRunner::callWillEndSwipeCallback):
(WTR::TestRunner::callDidEndSwipeCallback):
(WTR::TestRunner::callDidRemoveSwipeSnapshotCallback):
* WebKitTestRunner/InjectedBundle/TestRunner.h:
* WebKitTestRunner/TestController.cpp:
(WTR::TestController::createOtherPage):
(WTR::TestController::createWebViewWithOptions):
(WTR::TestController::didReceiveMessageFromInjectedBundle):
(WTR::TestController::didBeginNavigationGesture):
(WTR::TestController::willEndNavigationGesture):
(WTR::TestController::didEndNavigationGesture):
(WTR::TestController::didRemoveNavigationGestureSnapshot):
* WebKitTestRunner/TestController.h:
* WebKitTestRunner/TestInvocation.cpp:
(WTR::TestInvocation::didBeginSwipe):
(WTR::TestInvocation::willEndSwipe):
(WTR::TestInvocation::didEndSwipe):
(WTR::TestInvocation::didRemoveSwipeSnapshot):
* WebKitTestRunner/TestInvocation.h:
Add callbacks when navigation gestures didBegin/willEnd/didEnd, and
when the snapshot is removed.

Add swipeGestureWithWheelAndMomentumPhases, just like the equivalent
mouseScrollBy function.

* WebKitTestRunner/mac/EventSenderProxy.mm:
(-[EventSenderSyntheticEvent initPressureEventAtLocation:globalLocation:stage:pressure:phase:time:eventNumber:]):
(-[EventSenderSyntheticEvent type]):
(-[EventSenderSyntheticEvent subtype]):
(-[EventSenderSyntheticEvent locationInWindow]):
(-[EventSenderSyntheticEvent location]):
(-[EventSenderSyntheticEvent momentumPhase]):
(-[EventSenderSyntheticEvent _isTouchesEnded]):
(-[EventSenderSyntheticEvent _cgsEventRecord]):
Rename EventSenderPressureEvent to EventSenderSyntheticEvent and add some
more adjustable values.

(WTR::EventSenderProxy::mouseForceDown):
(WTR::EventSenderProxy::mouseForceUp):
(WTR::EventSenderProxy::mouseForceChanged):
Adopt EventSenderSyntheticEvent.

(WTR::nsEventPhaseFromCGEventPhase):
(WTR::EventSenderProxy::swipeGestureWithWheelAndMomentumPhases):
Make use of EventSenderSyntheticEvent to synthesize swipe gesture events.

* WebKitTestRunner/mac/PlatformWebViewMac.mm:
(WTR::PlatformWebView::PlatformWebView):
Enable swipe.

* swipe/basic-cached-back-swipe-expected.txt: Added.
* swipe/basic-cached-back-swipe.html: Added.
* swipe/resources/swipe-test.js: Added.
(eventQueue.enqueueScrollEvent):
(eventQueue.enqueueSwipeEvent):
(eventQueue.hasPendingEvents):
(eventQueue._processEventQueue):
(eventQueue._processEventQueueSoon):
(shouldBe):
(log):
(dumpLog):
(initializeLog):
(startMeasuringDuration):
(measuredDurationShouldBeLessThan):
Add a test for the simplest case, a back swipe after a normal navigation
with the page cache enabled.

* TestExpectations:
* platform/mac-wk2/TestExpectations:
Disable these tests everywhere except Mac WebKit2.

* UIProcess/API/mac/WKView.mm:
(takeWindowSnapshot):
(-[WKView _takeViewSnapshot]):
Fall back to the non-hardware snapshotting path if the hardware path fails,
which usually happens if the view is fully off-screen (as in the case
of WebKitTestRunner).</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkLayoutTestsTestExpectations">trunk/LayoutTests/TestExpectations</a></li>
<li><a href="#trunkLayoutTestsplatformmacmavericksTestExpectations">trunk/LayoutTests/platform/mac-mavericks/TestExpectations</a></li>
<li><a href="#trunkLayoutTestsplatformmacwk2TestExpectations">trunk/LayoutTests/platform/mac-wk2/TestExpectations</a></li>
<li><a href="#trunkSourceWebKit2ChangeLog">trunk/Source/WebKit2/ChangeLog</a></li>
<li><a href="#trunkSourceWebKit2UIProcessAPImacWKViewmm">trunk/Source/WebKit2/UIProcess/API/mac/WKView.mm</a></li>
<li><a href="#trunkToolsChangeLog">trunk/Tools/ChangeLog</a></li>
<li><a href="#trunkToolsWebKitTestRunnerEventSenderProxyh">trunk/Tools/WebKitTestRunner/EventSenderProxy.h</a></li>
<li><a href="#trunkToolsWebKitTestRunnerInjectedBundleBindingsEventSendingControlleridl">trunk/Tools/WebKitTestRunner/InjectedBundle/Bindings/EventSendingController.idl</a></li>
<li><a href="#trunkToolsWebKitTestRunnerInjectedBundleBindingsTestRunneridl">trunk/Tools/WebKitTestRunner/InjectedBundle/Bindings/TestRunner.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>
<li><a href="#trunkToolsWebKitTestRunnerInjectedBundleInjectedBundlecpp">trunk/Tools/WebKitTestRunner/InjectedBundle/InjectedBundle.cpp</a></li>
<li><a href="#trunkToolsWebKitTestRunnerInjectedBundleTestRunnercpp">trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.cpp</a></li>
<li><a href="#trunkToolsWebKitTestRunnerInjectedBundleTestRunnerh">trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.h</a></li>
<li><a href="#trunkToolsWebKitTestRunnerInjectedBundleiosEventSenderProxyIOSmm">trunk/Tools/WebKitTestRunner/InjectedBundle/ios/EventSenderProxyIOS.mm</a></li>
<li><a href="#trunkToolsWebKitTestRunnerPlatformWebViewh">trunk/Tools/WebKitTestRunner/PlatformWebView.h</a></li>
<li><a href="#trunkToolsWebKitTestRunnerTestControllercpp">trunk/Tools/WebKitTestRunner/TestController.cpp</a></li>
<li><a href="#trunkToolsWebKitTestRunnerTestControllerh">trunk/Tools/WebKitTestRunner/TestController.h</a></li>
<li><a href="#trunkToolsWebKitTestRunnerTestInvocationcpp">trunk/Tools/WebKitTestRunner/TestInvocation.cpp</a></li>
<li><a href="#trunkToolsWebKitTestRunnerTestInvocationh">trunk/Tools/WebKitTestRunner/TestInvocation.h</a></li>
<li><a href="#trunkToolsWebKitTestRunnercocoaTestControllerCocoamm">trunk/Tools/WebKitTestRunner/cocoa/TestControllerCocoa.mm</a></li>
<li><a href="#trunkToolsWebKitTestRunnereflEventSenderProxyEflcpp">trunk/Tools/WebKitTestRunner/efl/EventSenderProxyEfl.cpp</a></li>
<li><a href="#trunkToolsWebKitTestRunnereflPlatformWebViewEflcpp">trunk/Tools/WebKitTestRunner/efl/PlatformWebViewEfl.cpp</a></li>
<li><a href="#trunkToolsWebKitTestRunnergtkEventSenderProxyGtkcpp">trunk/Tools/WebKitTestRunner/gtk/EventSenderProxyGtk.cpp</a></li>
<li><a href="#trunkToolsWebKitTestRunnergtkPlatformWebViewGtkcpp">trunk/Tools/WebKitTestRunner/gtk/PlatformWebViewGtk.cpp</a></li>
<li><a href="#trunkToolsWebKitTestRunneriosPlatformWebViewIOSmm">trunk/Tools/WebKitTestRunner/ios/PlatformWebViewIOS.mm</a></li>
<li><a href="#trunkToolsWebKitTestRunneriosTestControllerIOSmm">trunk/Tools/WebKitTestRunner/ios/TestControllerIOS.mm</a></li>
<li><a href="#trunkToolsWebKitTestRunnermacEventSenderProxymm">trunk/Tools/WebKitTestRunner/mac/EventSenderProxy.mm</a></li>
<li><a href="#trunkToolsWebKitTestRunnermacPlatformWebViewMacmm">trunk/Tools/WebKitTestRunner/mac/PlatformWebViewMac.mm</a></li>
<li><a href="#trunkToolsWebKitTestRunnermacTestControllerMacmm">trunk/Tools/WebKitTestRunner/mac/TestControllerMac.mm</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li>trunk/LayoutTests/swipe/</li>
<li><a href="#trunkLayoutTestsswipebasiccachedbackswipeexpectedtxt">trunk/LayoutTests/swipe/basic-cached-back-swipe-expected.txt</a></li>
<li><a href="#trunkLayoutTestsswipebasiccachedbackswipehtml">trunk/LayoutTests/swipe/basic-cached-back-swipe.html</a></li>
<li>trunk/LayoutTests/swipe/resources/</li>
<li><a href="#trunkLayoutTestsswiperesourcesswipetestjs">trunk/LayoutTests/swipe/resources/swipe-test.js</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (189286 => 189287)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2015-09-03 21:03:46 UTC (rev 189286)
+++ trunk/LayoutTests/ChangeLog        2015-09-03 21:11:44 UTC (rev 189287)
</span><span class="lines">@@ -1,3 +1,31 @@
</span><ins>+2015-09-03  Tim Horton  &lt;timothy_horton@apple.com&gt;
+
+        [Mac] Add support for testing swipes
+        https://bugs.webkit.org/show_bug.cgi?id=148700
+
+        Reviewed by Beth Dakin.
+
+        * swipe/basic-cached-back-swipe-expected.txt: Added.
+        * swipe/basic-cached-back-swipe.html: Added.
+        * swipe/resources/swipe-test.js: Added.
+        (eventQueue.enqueueScrollEvent):
+        (eventQueue.enqueueSwipeEvent):
+        (eventQueue.hasPendingEvents):
+        (eventQueue._processEventQueue):
+        (eventQueue._processEventQueueSoon):
+        (shouldBe):
+        (log):
+        (dumpLog):
+        (initializeLog):
+        (startMeasuringDuration):
+        (measuredDurationShouldBeLessThan):
+        Add a test for the simplest case, a back swipe after a normal navigation
+        with the page cache enabled.
+
+        * TestExpectations:
+        * platform/mac-wk2/TestExpectations:
+        Disable these tests everywhere except Mac WebKit2.
+
</ins><span class="cx"> 2015-09-03  Alexey Proskuryakov  &lt;ap@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Test Russian &quot;.рф&quot; domain support
</span></span></pre></div>
<a id="trunkLayoutTestsTestExpectations"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/TestExpectations (189286 => 189287)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/TestExpectations        2015-09-03 21:03:46 UTC (rev 189286)
+++ trunk/LayoutTests/TestExpectations        2015-09-03 21:11:44 UTC (rev 189287)
</span><span class="lines">@@ -13,6 +13,7 @@
</span><span class="cx"> editing/mac [ Skip ]
</span><span class="cx"> editing/pasteboard/gtk [ Skip ]
</span><span class="cx"> tiled-drawing [ Skip ]
</span><ins>+swipe [ Skip ]
</ins><span class="cx"> 
</span><span class="cx"> fast/forms/attributed-strings.html [ Skip ]
</span><span class="cx"> fast/scrolling/latching [ Skip ]
</span></span></pre></div>
<a id="trunkLayoutTestsplatformmacmavericksTestExpectations"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/platform/mac-mavericks/TestExpectations (189286 => 189287)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/platform/mac-mavericks/TestExpectations        2015-09-03 21:03:46 UTC (rev 189286)
+++ trunk/LayoutTests/platform/mac-mavericks/TestExpectations        2015-09-03 21:11:44 UTC (rev 189287)
</span><span class="lines">@@ -22,3 +22,6 @@
</span><span class="cx"> 
</span><span class="cx"> # Colorspaces on CA OpenGL layers not available in Mavericks and Yosemite
</span><span class="cx"> fast/canvas/webgl/match-page-color-space.html [ Skip ]
</span><ins>+
+# Swipe tests don't work on Mavericks (needs investigation)
+swipe [ Skip ]
</ins></span></pre></div>
<a id="trunkLayoutTestsplatformmacwk2TestExpectations"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/platform/mac-wk2/TestExpectations (189286 => 189287)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/platform/mac-wk2/TestExpectations        2015-09-03 21:03:46 UTC (rev 189286)
+++ trunk/LayoutTests/platform/mac-wk2/TestExpectations        2015-09-03 21:11:44 UTC (rev 189287)
</span><span class="lines">@@ -6,6 +6,7 @@
</span><span class="cx"> #//////////////////////////////////////////////////////////////////////////////////////////
</span><span class="cx"> 
</span><span class="cx"> tiled-drawing [ Pass ]
</span><ins>+swipe [ Pass ]
</ins><span class="cx"> 
</span><span class="cx"> #//////////////////////////////////////////////////////////////////////////////////////////
</span><span class="cx"> # End platform-specific directories.
</span></span></pre></div>
<a id="trunkLayoutTestsswipebasiccachedbackswipeexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/swipe/basic-cached-back-swipe-expected.txt (0 => 189287)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/swipe/basic-cached-back-swipe-expected.txt                                (rev 0)
+++ trunk/LayoutTests/swipe/basic-cached-back-swipe-expected.txt        2015-09-03 21:11:44 UTC (rev 189287)
</span><span class="lines">@@ -0,0 +1,11 @@
</span><ins>+swipe event (delta 0 0, phase 'maybegin')
+scroll event (delta 1 0, phase 'began')
+scroll event (delta 1 0, phase 'changed')
+didBeginSwipe
+swipe event (delta 1 0, phase 'changed')
+swipe event (delta 256 0, phase 'changed')
+swipe event (delta 0 0, phase 'ended')
+willEndSwipe
+didEndSwipe
+didRemoveSwipeSnapshot
+
</ins></span></pre></div>
<a id="trunkLayoutTestsswipebasiccachedbackswipehtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/swipe/basic-cached-back-swipe.html (0 => 189287)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/swipe/basic-cached-back-swipe.html                                (rev 0)
+++ trunk/LayoutTests/swipe/basic-cached-back-swipe.html        2015-09-03 21:11:44 UTC (rev 189287)
</span><span class="lines">@@ -0,0 +1,98 @@
</span><ins>+&lt;head&gt;
+&lt;style&gt;
+html {
+    font-size: 32pt;
+}
+&lt;/style&gt;
+&lt;script src=&quot;resources/swipe-test.js&quot;&gt;&lt;/script&gt;
+&lt;script&gt;
+function startSwipeGesture()
+{
+    eventSender.mouseMoveTo(100, 100);
+
+    eventQueue.enqueueSwipeEvent(0, 0, 'maybegin');
+    eventQueue.enqueueScrollEvent(1, 0, 'began');
+    eventQueue.enqueueScrollEvent(1, 0, 'changed');
+}
+
+function completeSwipeGesture()
+{
+    eventQueue.enqueueSwipeEvent(1, 0, 'changed');
+    eventQueue.enqueueSwipeEvent(256, 0, 'changed');
+    eventQueue.enqueueSwipeEvent(0, 0, 'ended');
+}
+
+function didBeginSwipeCallback()
+{
+    log(&quot;didBeginSwipe&quot;);
+
+    shouldBe(false, eventQueue.hasPendingEvents(), &quot;Event queue should be empty. Both scroll events should be required to start the swipe because of the swipe-start hysteresis.&quot;);
+
+    completeSwipeGesture();
+}
+
+function willEndSwipeCallback()
+{
+    log(&quot;willEndSwipe&quot;);
+
+    shouldBe(false, isFirstPage(), &quot;The swipe should not yet have navigated away from the second page.&quot;);
+}
+
+function didEndSwipeCallback()
+{
+    log(&quot;didEndSwipe&quot;);
+
+    shouldBe(0, eventQueue.hasPendingEvents(), &quot;Event queue should be empty. The swipe isn't complete until we see the end of the gesture.&quot;);
+    startMeasuringDuration(&quot;snapshotRemoval&quot;);
+}
+
+function didRemoveSwipeSnapshotCallback()
+{
+    log(&quot;didRemoveSwipeSnapshot&quot;);
+    
+    shouldBe(true, isFirstPage(), &quot;The swipe should have navigated back to the first page.&quot;);
+    measuredDurationShouldBeLessThan(&quot;snapshotRemoval&quot;, 1000, &quot;Because we're using the page cache, it shouldn't be long between the gesture completing and the snapshot being removed.&quot;)
+
+    dumpLog();
+    testRunner.notifyDone();
+}
+
+function isFirstPage()
+{
+    return window.location.href.indexOf(&quot;second&quot;) == -1;
+}
+
+window.onload = function () {
+    if (!window.eventSender || !window.testRunner) {
+        document.body.innerHTML = &quot;This test must be run in WebKitTestRunner.&quot;;
+        return;
+    }
+
+    document.body.innerHTML = isFirstPage() ? &quot;first&quot; : &quot;second&quot;;
+
+    if (isFirstPage()) {
+        initializeLog();
+
+        testRunner.setNavigationGesturesEnabled(true);
+
+        testRunner.installDidBeginSwipeCallback(didBeginSwipeCallback);
+        testRunner.installWillEndSwipeCallback(willEndSwipeCallback);
+        testRunner.installDidEndSwipeCallback(didEndSwipeCallback);
+        testRunner.installDidRemoveSwipeSnapshotCallback(didRemoveSwipeSnapshotCallback);
+
+        testRunner.overridePreference(&quot;WebKitUsesPageCachePreferenceKey&quot;, 1);
+        testRunner.dumpAsText();
+        testRunner.waitUntilDone();
+
+        setTimeout(function () { 
+            window.location.href = window.location.href + &quot;?second&quot;;
+        }, 0);
+        return;
+    }
+
+    startSwipeGesture();
+};
+&lt;/script&gt;
+&lt;/head&gt;
+&lt;body&gt;
+&lt;/body&gt;
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="trunkLayoutTestsswiperesourcesswipetestjs"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/swipe/resources/swipe-test.js (0 => 189287)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/swipe/resources/swipe-test.js                                (rev 0)
+++ trunk/LayoutTests/swipe/resources/swipe-test.js        2015-09-03 21:11:44 UTC (rev 189287)
</span><span class="lines">@@ -0,0 +1,70 @@
</span><ins>+var eventQueue = {
+    enqueueScrollEvent: function (x, y, phase) {
+        this._queue.push(function () {
+            log(&quot;scroll event (delta &quot; + x + &quot; &quot; + y + &quot;, phase '&quot; + phase + &quot;')&quot;);
+            window.eventSender.mouseScrollByWithWheelAndMomentumPhases(x, y, phase, 'none');
+        });
+        this._processEventQueueSoon();
+    },
+
+    enqueueSwipeEvent: function (x, y, phase) {
+        this._queue.push(function () {
+            log(&quot;swipe event (delta &quot; + x + &quot; &quot; + y + &quot;, phase '&quot; + phase + &quot;')&quot;);
+            window.eventSender.swipeGestureWithWheelAndMomentumPhases(x, y, phase, 'none');
+        });
+        this._processEventQueueSoon();
+    },
+
+    hasPendingEvents: function () {
+        return this._queue.length != 0;
+    },
+
+    _queue: [],
+
+    _processEventQueue: function () {
+        if (!this._queue.length)
+            return;
+
+        var item = this._queue.shift();
+        item();
+        this._processEventQueueSoon();
+    },
+
+    _processEventQueueSoon: function () {
+        clearTimeout(this._processingTimeout);
+        this._processingTimeout = setTimeout(this._processEventQueue.bind(this), 0);
+    }
+}
+
+function shouldBe(expected, actual, message)
+{
+    if (expected != actual)
+        log(&quot;Failure. &quot; + message + &quot; (expected: &quot; + expected + &quot;, actual: &quot; + actual + &quot;)&quot;);
+}
+
+function log(s)
+{
+    window.localStorage[&quot;swipeLogging&quot;] += s + &quot;&lt;br/&gt;&quot;;
+}
+
+function dumpLog()
+{
+    window.document.body.innerHTML = window.localStorage[&quot;swipeLogging&quot;];
+}
+
+function initializeLog()
+{
+    window.localStorage[&quot;swipeLogging&quot;] = &quot;&quot;;
+}
+
+function startMeasuringDuration(key)
+{
+    window.localStorage[key + &quot;swipeStartTime&quot;] = Date.now();
+}
+
+function measuredDurationShouldBeLessThan(key, timeInMS, message)
+{
+    var duration = Date.now() - window.localStorage[key + &quot;swipeStartTime&quot;];
+    if (duration &gt;= timeInMS)
+        log(&quot;Failure. &quot; + message + &quot; (expected: &quot; + timeInMS + &quot;, actual: &quot; + duration + &quot;)&quot;);
+}
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="trunkSourceWebKit2ChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/ChangeLog (189286 => 189287)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/ChangeLog        2015-09-03 21:03:46 UTC (rev 189286)
+++ trunk/Source/WebKit2/ChangeLog        2015-09-03 21:11:44 UTC (rev 189287)
</span><span class="lines">@@ -1,3 +1,17 @@
</span><ins>+2015-09-03  Tim Horton  &lt;timothy_horton@apple.com&gt;
+
+        [Mac] Add support for testing swipes
+        https://bugs.webkit.org/show_bug.cgi?id=148700
+
+        Reviewed by Beth Dakin.
+
+        * UIProcess/API/mac/WKView.mm:
+        (takeWindowSnapshot):
+        (-[WKView _takeViewSnapshot]):
+        Fall back to the non-hardware snapshotting path if the hardware path fails,
+        which usually happens if the view is fully off-screen (as in the case
+        of WebKitTestRunner).
+
</ins><span class="cx"> 2015-09-02  Tim Horton  &lt;timothy_horton@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Add a modern API way to know that the navigation gesture snapshot was removed, for WebKitTestRunner
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessAPImacWKViewmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/API/mac/WKView.mm (189286 => 189287)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/API/mac/WKView.mm        2015-09-03 21:03:46 UTC (rev 189286)
+++ trunk/Source/WebKit2/UIProcess/API/mac/WKView.mm        2015-09-03 21:11:44 UTC (rev 189287)
</span><span class="lines">@@ -3343,6 +3343,24 @@
</span><span class="cx">     return _data-&gt;_rootLayer.get();
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+static RetainPtr&lt;CGImageRef&gt; takeWindowSnapshot(CGSWindowID windowID, bool captureAtNominalResolution)
+{
+    CGSWindowCaptureOptions options = kCGSCaptureIgnoreGlobalClipShape;
+    if (captureAtNominalResolution)
+        options |= kCGSWindowCaptureNominalResolution;
+    RetainPtr&lt;CFArrayRef&gt; windowSnapshotImages = adoptCF(CGSHWCaptureWindowList(CGSMainConnectionID(), &amp;windowID, 1, options));
+
+    if (windowSnapshotImages &amp;&amp; CFArrayGetCount(windowSnapshotImages.get()))
+        return (CGImageRef)CFArrayGetValueAtIndex(windowSnapshotImages.get(), 0);
+
+    // Fall back to the non-hardware capture path if we didn't get a snapshot
+    // (which usually happens if the window is fully off-screen).
+    CGWindowImageOption imageOptions = kCGWindowImageBoundsIgnoreFraming | kCGWindowImageShouldBeOpaque;
+    if (captureAtNominalResolution)
+        imageOptions |= kCGWindowImageNominalResolution;
+    return adoptCF(CGWindowListCreateImage(CGRectNull, kCGWindowListOptionIncludingWindow, windowID, imageOptions));
+}
+
</ins><span class="cx"> - (PassRefPtr&lt;ViewSnapshot&gt;)_takeViewSnapshot
</span><span class="cx"> {
</span><span class="cx">     NSWindow *window = self.window;
</span><span class="lines">@@ -3353,21 +3371,19 @@
</span><span class="cx"> 
</span><span class="cx">     CGSWindowCaptureOptions options = kCGSCaptureIgnoreGlobalClipShape;
</span><span class="cx">     RetainPtr&lt;CFArrayRef&gt; windowSnapshotImages = adoptCF(CGSHWCaptureWindowList(CGSMainConnectionID(), &amp;windowID, 1, options));
</span><del>-    if (!windowSnapshotImages || !CFArrayGetCount(windowSnapshotImages.get()))
</del><ins>+
+    RetainPtr&lt;CGImageRef&gt; windowSnapshotImage = takeWindowSnapshot(windowID, false);
+    if (!windowSnapshotImage)
</ins><span class="cx">         return nullptr;
</span><span class="cx"> 
</span><del>-    RetainPtr&lt;CGImageRef&gt; windowSnapshotImage = (CGImageRef)CFArrayGetValueAtIndex(windowSnapshotImages.get(), 0);
-
</del><span class="cx">     // Work around &lt;rdar://problem/17084993&gt;; re-request the snapshot at kCGWindowImageNominalResolution if it was captured at the wrong scale.
</span><span class="cx">     CGFloat desiredSnapshotWidth = window.frame.size.width * window.screen.backingScaleFactor;
</span><del>-    if (CGImageGetWidth(windowSnapshotImage.get()) != desiredSnapshotWidth) {
-        options |= kCGSWindowCaptureNominalResolution;
-        windowSnapshotImages = adoptCF(CGSHWCaptureWindowList(CGSMainConnectionID(), &amp;windowID, 1, options));
-        if (!windowSnapshotImages || !CFArrayGetCount(windowSnapshotImages.get()))
-            return nullptr;
-        windowSnapshotImage = (CGImageRef)CFArrayGetValueAtIndex(windowSnapshotImages.get(), 0);
-    }
</del><ins>+    if (CGImageGetWidth(windowSnapshotImage.get()) != desiredSnapshotWidth)
+        windowSnapshotImage = takeWindowSnapshot(windowID, true);
</ins><span class="cx"> 
</span><ins>+    if (!windowSnapshotImage)
+        return nullptr;
+
</ins><span class="cx">     [self _ensureGestureController];
</span><span class="cx"> 
</span><span class="cx">     NSRect windowCaptureRect;
</span></span></pre></div>
<a id="trunkToolsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Tools/ChangeLog (189286 => 189287)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/ChangeLog        2015-09-03 21:03:46 UTC (rev 189286)
+++ trunk/Tools/ChangeLog        2015-09-03 21:11:44 UTC (rev 189287)
</span><span class="lines">@@ -1,3 +1,77 @@
</span><ins>+2015-09-03  Tim Horton  &lt;timothy_horton@apple.com&gt;
+
+        [Mac] Add support for testing swipes
+        https://bugs.webkit.org/show_bug.cgi?id=148700
+
+        Reviewed by Beth Dakin.
+
+        * WebKitTestRunner/EventSenderProxy.h:
+        * WebKitTestRunner/InjectedBundle/Bindings/EventSendingController.idl:
+        * WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl:
+        * WebKitTestRunner/InjectedBundle/EventSendingController.cpp:
+        (WTR::cgEventPhaseFromString):
+        (WTR::cgEventMomentumPhaseFromString):
+        (WTR::EventSendingController::mouseScrollByWithWheelAndMomentumPhases):
+        (WTR::EventSendingController::swipeGestureWithWheelAndMomentumPhases):
+        * WebKitTestRunner/InjectedBundle/EventSendingController.h:
+        * WebKitTestRunner/InjectedBundle/InjectedBundle.cpp:
+        (WTR::InjectedBundle::didReceiveMessageToPage):
+        * WebKitTestRunner/InjectedBundle/TestRunner.cpp:
+        (WTR::TestRunner::installDidBeginSwipeCallback):
+        (WTR::TestRunner::installWillEndSwipeCallback):
+        (WTR::TestRunner::installDidEndSwipeCallback):
+        (WTR::TestRunner::installDidRemoveSwipeSnapshotCallback):
+        (WTR::TestRunner::callDidBeginSwipeCallback):
+        (WTR::TestRunner::callWillEndSwipeCallback):
+        (WTR::TestRunner::callDidEndSwipeCallback):
+        (WTR::TestRunner::callDidRemoveSwipeSnapshotCallback):
+        * WebKitTestRunner/InjectedBundle/TestRunner.h:
+        * WebKitTestRunner/TestController.cpp:
+        (WTR::TestController::createOtherPage):
+        (WTR::TestController::createWebViewWithOptions):
+        (WTR::TestController::didReceiveMessageFromInjectedBundle):
+        (WTR::TestController::didBeginNavigationGesture):
+        (WTR::TestController::willEndNavigationGesture):
+        (WTR::TestController::didEndNavigationGesture):
+        (WTR::TestController::didRemoveNavigationGestureSnapshot):
+        * WebKitTestRunner/TestController.h:
+        * WebKitTestRunner/TestInvocation.cpp:
+        (WTR::TestInvocation::didBeginSwipe):
+        (WTR::TestInvocation::willEndSwipe):
+        (WTR::TestInvocation::didEndSwipe):
+        (WTR::TestInvocation::didRemoveSwipeSnapshot):
+        * WebKitTestRunner/TestInvocation.h:
+        Add callbacks when navigation gestures didBegin/willEnd/didEnd, and
+        when the snapshot is removed.
+
+        Add swipeGestureWithWheelAndMomentumPhases, just like the equivalent
+        mouseScrollBy function.
+
+        * WebKitTestRunner/mac/EventSenderProxy.mm:
+        (-[EventSenderSyntheticEvent initPressureEventAtLocation:globalLocation:stage:pressure:phase:time:eventNumber:]):
+        (-[EventSenderSyntheticEvent type]):
+        (-[EventSenderSyntheticEvent subtype]):
+        (-[EventSenderSyntheticEvent locationInWindow]):
+        (-[EventSenderSyntheticEvent location]):
+        (-[EventSenderSyntheticEvent momentumPhase]):
+        (-[EventSenderSyntheticEvent _isTouchesEnded]):
+        (-[EventSenderSyntheticEvent _cgsEventRecord]):
+        Rename EventSenderPressureEvent to EventSenderSyntheticEvent and add some
+        more adjustable values.
+
+        (WTR::EventSenderProxy::mouseForceDown):
+        (WTR::EventSenderProxy::mouseForceUp):
+        (WTR::EventSenderProxy::mouseForceChanged):
+        Adopt EventSenderSyntheticEvent.
+
+        (WTR::nsEventPhaseFromCGEventPhase):
+        (WTR::EventSenderProxy::swipeGestureWithWheelAndMomentumPhases):
+        Make use of EventSenderSyntheticEvent to synthesize swipe gesture events.
+
+        * WebKitTestRunner/mac/PlatformWebViewMac.mm:
+        (WTR::PlatformWebView::PlatformWebView):
+        Enable swipe.
+
</ins><span class="cx"> 2015-09-03  Myles C. Maxfield  &lt;mmaxfield@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         [WK2] Allow tagging tests with metadata which needs to be known at web process creation time
</span></span></pre></div>
<a id="trunkToolsWebKitTestRunnerEventSenderProxyh"></a>
<div class="modfile"><h4>Modified: trunk/Tools/WebKitTestRunner/EventSenderProxy.h (189286 => 189287)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/WebKitTestRunner/EventSenderProxy.h        2015-09-03 21:03:46 UTC (rev 189286)
+++ trunk/Tools/WebKitTestRunner/EventSenderProxy.h        2015-09-03 21:11:44 UTC (rev 189287)
</span><span class="lines">@@ -64,6 +64,7 @@
</span><span class="cx">     void mouseMoveTo(double x, double y);
</span><span class="cx">     void mouseScrollBy(int x, int y);
</span><span class="cx">     void mouseScrollByWithWheelAndMomentumPhases(int x, int y, int phase, int momentum);
</span><ins>+    void swipeGestureWithWheelAndMomentumPhases(int x, int y, int phase, int momentum);
</ins><span class="cx">     void continuousMouseScrollBy(int x, int y, bool paged);
</span><span class="cx"> 
</span><span class="cx">     void leapForward(int milliseconds);
</span></span></pre></div>
<a id="trunkToolsWebKitTestRunnerInjectedBundleBindingsEventSendingControlleridl"></a>
<div class="modfile"><h4>Modified: trunk/Tools/WebKitTestRunner/InjectedBundle/Bindings/EventSendingController.idl (189286 => 189287)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/WebKitTestRunner/InjectedBundle/Bindings/EventSendingController.idl        2015-09-03 21:03:46 UTC (rev 189286)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/Bindings/EventSendingController.idl        2015-09-03 21:11:44 UTC (rev 189287)
</span><span class="lines">@@ -32,6 +32,7 @@
</span><span class="cx">     void mouseForceChanged(double force);
</span><span class="cx">     void mouseScrollBy(long x, long y);
</span><span class="cx">     void mouseScrollByWithWheelAndMomentumPhases(long x, long y, DOMString phase, DOMString momentum);
</span><ins>+    void swipeGestureWithWheelAndMomentumPhases(long x, long y, DOMString phase, DOMString momentum);
</ins><span class="cx">     void continuousMouseScrollBy(long x, long y, optional boolean paged);
</span><span class="cx">     object contextClick();
</span><span class="cx">     void scheduleAsynchronousClick();
</span></span></pre></div>
<a id="trunkToolsWebKitTestRunnerInjectedBundleBindingsTestRunneridl"></a>
<div class="modfile"><h4>Modified: trunk/Tools/WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl (189286 => 189287)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl        2015-09-03 21:03:46 UTC (rev 189286)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl        2015-09-03 21:11:44 UTC (rev 189287)
</span><span class="lines">@@ -76,6 +76,7 @@
</span><span class="cx">     void setAsynchronousSpellCheckingEnabled(boolean value);
</span><span class="cx">     void setPrinting();
</span><span class="cx">     void setShouldDecideNavigationPolicyAfterDelay(boolean value);
</span><ins>+    void setNavigationGesturesEnabled(boolean value);
</ins><span class="cx"> 
</span><span class="cx">     // Special DOM functions.
</span><span class="cx">     void clearBackForwardList();
</span><span class="lines">@@ -204,5 +205,11 @@
</span><span class="cx">     // Hooks to the JSC compiler.
</span><span class="cx">     object numberOfDFGCompiles(object function);
</span><span class="cx">     object neverInlineFunction(object function);
</span><ins>+
+    // Swipe gestures
+    void installDidBeginSwipeCallback(object callback);
+    void installWillEndSwipeCallback(object callback);
+    void installDidEndSwipeCallback(object callback);
+    void installDidRemoveSwipeSnapshotCallback(object callback);
</ins><span class="cx"> };
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkToolsWebKitTestRunnerInjectedBundleEventSendingControllercpp"></a>
<div class="modfile"><h4>Modified: trunk/Tools/WebKitTestRunner/InjectedBundle/EventSendingController.cpp (189286 => 189287)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/WebKitTestRunner/InjectedBundle/EventSendingController.cpp        2015-09-03 21:03:46 UTC (rev 189286)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/EventSendingController.cpp        2015-09-03 21:11:44 UTC (rev 189287)
</span><span class="lines">@@ -391,6 +391,40 @@
</span><span class="cx">     WKBundlePagePostMessage(InjectedBundle::singleton().page()-&gt;page(), EventSenderMessageName.get(), EventSenderMessageBody.get());
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+static uint64_t cgEventPhaseFromString(JSStringRef phaseStr)
+{
+    if (JSStringIsEqualToUTF8CString(phaseStr, &quot;none&quot;))
+        return 0;
+    if (JSStringIsEqualToUTF8CString(phaseStr, &quot;began&quot;))
+        return 1; // kCGScrollPhaseBegan
+    if (JSStringIsEqualToUTF8CString(phaseStr, &quot;changed&quot;))
+        return 2; // kCGScrollPhaseChanged
+    if (JSStringIsEqualToUTF8CString(phaseStr, &quot;ended&quot;))
+        return 4; // kCGScrollPhaseEnded
+    if (JSStringIsEqualToUTF8CString(phaseStr, &quot;cancelled&quot;))
+        return 8; // kCGScrollPhaseCancelled
+    if (JSStringIsEqualToUTF8CString(phaseStr, &quot;maybegin&quot;))
+        return 128; // kCGScrollPhaseMayBegin
+
+    ASSERT_NOT_REACHED();
+    return 0;
+}
+
+static uint64_t cgEventMomentumPhaseFromString(JSStringRef phaseStr)
+{
+    if (JSStringIsEqualToUTF8CString(phaseStr, &quot;none&quot;))
+        return 0; // kCGMomentumScrollPhaseNone
+    if (JSStringIsEqualToUTF8CString(phaseStr, &quot;begin&quot;))
+        return 1; // kCGMomentumScrollPhaseBegin
+    if (JSStringIsEqualToUTF8CString(phaseStr, &quot;continue&quot;))
+        return 2; // kCGMomentumScrollPhaseContinue
+    if (JSStringIsEqualToUTF8CString(phaseStr, &quot;end&quot;))
+        return 3; // kCGMomentumScrollPhaseEnd
+
+    ASSERT_NOT_REACHED();
+    return 0;
+}
+
</ins><span class="cx"> void EventSendingController::mouseScrollByWithWheelAndMomentumPhases(int x, int y, JSStringRef phaseStr, JSStringRef momentumStr)
</span><span class="cx"> {
</span><span class="cx">     WKRetainPtr&lt;WKStringRef&gt; EventSenderMessageName(AdoptWK, WKStringCreateWithUTF8CString(&quot;EventSender&quot;));
</span><span class="lines">@@ -408,34 +442,45 @@
</span><span class="cx">     WKRetainPtr&lt;WKDoubleRef&gt; yRef(AdoptWK, WKDoubleCreate(y));
</span><span class="cx">     WKDictionarySetItem(EventSenderMessageBody.get(), yKey.get(), yRef.get());
</span><span class="cx"> 
</span><del>-    uint64_t phase = 0;
-    if (JSStringIsEqualToUTF8CString(phaseStr, &quot;none&quot;))
-        phase = 0;
-    else if (JSStringIsEqualToUTF8CString(phaseStr, &quot;began&quot;))
-        phase = 1; // kCGScrollPhaseBegan
-    else if (JSStringIsEqualToUTF8CString(phaseStr, &quot;changed&quot;))
-        phase = 2; // kCGScrollPhaseChanged
-    else if (JSStringIsEqualToUTF8CString(phaseStr, &quot;ended&quot;))
-        phase = 4; // kCGScrollPhaseEnded
-    else if (JSStringIsEqualToUTF8CString(phaseStr, &quot;cancelled&quot;))
-        phase = 8; // kCGScrollPhaseCancelled
-    else if (JSStringIsEqualToUTF8CString(phaseStr, &quot;maybegin&quot;))
-        phase = 128; // kCGScrollPhaseMayBegin
</del><ins>+    uint64_t phase = cgEventPhaseFromString(phaseStr);
+    uint64_t momentum = cgEventMomentumPhaseFromString(momentumStr);
</ins><span class="cx"> 
</span><span class="cx">     WKRetainPtr&lt;WKStringRef&gt; phaseKey(AdoptWK, WKStringCreateWithUTF8CString(&quot;Phase&quot;));
</span><span class="cx">     WKRetainPtr&lt;WKUInt64Ref&gt; phaseRef(AdoptWK, WKUInt64Create(phase));
</span><span class="cx">     WKDictionarySetItem(EventSenderMessageBody.get(), phaseKey.get(), phaseRef.get());
</span><span class="cx"> 
</span><del>-    uint64_t momentum = 0;
-    if (JSStringIsEqualToUTF8CString(momentumStr, &quot;none&quot;))
-        momentum = 0; // kCGMomentumScrollPhaseNone
-    else if (JSStringIsEqualToUTF8CString(momentumStr, &quot;begin&quot;))
-        momentum = 1; // kCGMomentumScrollPhaseBegin
-    else if (JSStringIsEqualToUTF8CString(momentumStr, &quot;continue&quot;))
-        momentum = 2; // kCGMomentumScrollPhaseContinue
-    else if (JSStringIsEqualToUTF8CString(momentumStr, &quot;end&quot;))
-        momentum = 3; // kCGMomentumScrollPhaseEnd
</del><ins>+    WKRetainPtr&lt;WKStringRef&gt; momentumKey(AdoptWK, WKStringCreateWithUTF8CString(&quot;Momentum&quot;));
+    WKRetainPtr&lt;WKUInt64Ref&gt; momentumRef(AdoptWK, WKUInt64Create(momentum));
+    WKDictionarySetItem(EventSenderMessageBody.get(), momentumKey.get(), momentumRef.get());
</ins><span class="cx"> 
</span><ins>+    WKBundlePageForceRepaint(InjectedBundle::singleton().page()-&gt;page()); // Triggers a scrolling tree commit.
+    WKBundlePagePostMessage(InjectedBundle::singleton().page()-&gt;page(), EventSenderMessageName.get(), EventSenderMessageBody.get());
+}
+
+void EventSendingController::swipeGestureWithWheelAndMomentumPhases(int x, int y, JSStringRef phaseStr, JSStringRef momentumStr)
+{
+    WKRetainPtr&lt;WKStringRef&gt; EventSenderMessageName(AdoptWK, WKStringCreateWithUTF8CString(&quot;EventSender&quot;));
+    WKRetainPtr&lt;WKMutableDictionaryRef&gt; EventSenderMessageBody(AdoptWK, WKMutableDictionaryCreate());
+
+    WKRetainPtr&lt;WKStringRef&gt; subMessageKey(AdoptWK, WKStringCreateWithUTF8CString(&quot;SubMessage&quot;));
+    WKRetainPtr&lt;WKStringRef&gt; subMessageName(AdoptWK, WKStringCreateWithUTF8CString(&quot;SwipeGestureWithWheelAndMomentumPhases&quot;));
+    WKDictionarySetItem(EventSenderMessageBody.get(), subMessageKey.get(), subMessageName.get());
+
+    WKRetainPtr&lt;WKStringRef&gt; xKey(AdoptWK, WKStringCreateWithUTF8CString(&quot;X&quot;));
+    WKRetainPtr&lt;WKDoubleRef&gt; xRef(AdoptWK, WKDoubleCreate(x));
+    WKDictionarySetItem(EventSenderMessageBody.get(), xKey.get(), xRef.get());
+
+    WKRetainPtr&lt;WKStringRef&gt; yKey(AdoptWK, WKStringCreateWithUTF8CString(&quot;Y&quot;));
+    WKRetainPtr&lt;WKDoubleRef&gt; yRef(AdoptWK, WKDoubleCreate(y));
+    WKDictionarySetItem(EventSenderMessageBody.get(), yKey.get(), yRef.get());
+
+    uint64_t phase = cgEventPhaseFromString(phaseStr);
+    uint64_t momentum = cgEventMomentumPhaseFromString(momentumStr);
+
+    WKRetainPtr&lt;WKStringRef&gt; phaseKey(AdoptWK, WKStringCreateWithUTF8CString(&quot;Phase&quot;));
+    WKRetainPtr&lt;WKUInt64Ref&gt; phaseRef(AdoptWK, WKUInt64Create(phase));
+    WKDictionarySetItem(EventSenderMessageBody.get(), phaseKey.get(), phaseRef.get());
+
</ins><span class="cx">     WKRetainPtr&lt;WKStringRef&gt; momentumKey(AdoptWK, WKStringCreateWithUTF8CString(&quot;Momentum&quot;));
</span><span class="cx">     WKRetainPtr&lt;WKUInt64Ref&gt; momentumRef(AdoptWK, WKUInt64Create(momentum));
</span><span class="cx">     WKDictionarySetItem(EventSenderMessageBody.get(), momentumKey.get(), momentumRef.get());
</span></span></pre></div>
<a id="trunkToolsWebKitTestRunnerInjectedBundleEventSendingControllerh"></a>
<div class="modfile"><h4>Modified: trunk/Tools/WebKitTestRunner/InjectedBundle/EventSendingController.h (189286 => 189287)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/WebKitTestRunner/InjectedBundle/EventSendingController.h        2015-09-03 21:03:46 UTC (rev 189286)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/EventSendingController.h        2015-09-03 21:11:44 UTC (rev 189287)
</span><span class="lines">@@ -51,6 +51,7 @@
</span><span class="cx">     void mouseForceChanged(double force);
</span><span class="cx">     void mouseScrollBy(int x, int y);
</span><span class="cx">     void mouseScrollByWithWheelAndMomentumPhases(int x, int y, JSStringRef phase, JSStringRef momentum);
</span><ins>+    void swipeGestureWithWheelAndMomentumPhases(int x, int y, JSStringRef phase, JSStringRef momentum);
</ins><span class="cx">     void continuousMouseScrollBy(int x, int y, bool paged);
</span><span class="cx">     JSValueRef contextClick();
</span><span class="cx">     void leapForward(int milliseconds);
</span></span></pre></div>
<a id="trunkToolsWebKitTestRunnerInjectedBundleInjectedBundlecpp"></a>
<div class="modfile"><h4>Modified: trunk/Tools/WebKitTestRunner/InjectedBundle/InjectedBundle.cpp (189286 => 189287)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/WebKitTestRunner/InjectedBundle/InjectedBundle.cpp        2015-09-03 21:03:46 UTC (rev 189286)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/InjectedBundle.cpp        2015-09-03 21:11:44 UTC (rev 189287)
</span><span class="lines">@@ -215,6 +215,26 @@
</span><span class="cx">         return;
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    if (WKStringIsEqualToUTF8CString(messageName, &quot;CallDidBeginSwipeCallback&quot;)) {
+        m_testRunner-&gt;callDidBeginSwipeCallback();
+        return;
+    }
+
+    if (WKStringIsEqualToUTF8CString(messageName, &quot;CallWillEndSwipeCallback&quot;)) {
+        m_testRunner-&gt;callWillEndSwipeCallback();
+        return;
+    }
+
+    if (WKStringIsEqualToUTF8CString(messageName, &quot;CallDidEndSwipeCallback&quot;)) {
+        m_testRunner-&gt;callDidEndSwipeCallback();
+        return;
+    }
+
+    if (WKStringIsEqualToUTF8CString(messageName, &quot;CallDidRemoveSwipeSnapshotCallback&quot;)) {
+        m_testRunner-&gt;callDidRemoveSwipeSnapshotCallback();
+        return;
+    }
+
</ins><span class="cx">     if (WKStringIsEqualToUTF8CString(messageName, &quot;WorkQueueProcessedCallback&quot;)) {
</span><span class="cx">         if (!topLoadingFrame() &amp;&amp; !m_testRunner-&gt;waitToDump())
</span><span class="cx">             InjectedBundle::page()-&gt;dump();
</span></span></pre></div>
<a id="trunkToolsWebKitTestRunnerInjectedBundleTestRunnercpp"></a>
<div class="modfile"><h4>Modified: trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.cpp (189286 => 189287)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.cpp        2015-09-03 21:03:46 UTC (rev 189286)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.cpp        2015-09-03 21:11:44 UTC (rev 189287)
</span><span class="lines">@@ -509,7 +509,11 @@
</span><span class="cx">     AddChromeInputFieldCallbackID = 1,
</span><span class="cx">     RemoveChromeInputFieldCallbackID,
</span><span class="cx">     FocusWebViewCallbackID,
</span><del>-    SetBackingScaleFactorCallbackID
</del><ins>+    SetBackingScaleFactorCallbackID,
+    DidBeginSwipeCallbackID,
+    WillEndSwipeCallbackID,
+    DidEndSwipeCallbackID,
+    DidRemoveSwipeSnapshotCallbackID
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> static void cacheTestRunnerCallback(unsigned index, JSValueRef callback)
</span><span class="lines">@@ -860,4 +864,51 @@
</span><span class="cx">     WKBundlePagePostMessage(InjectedBundle::singleton().page()-&gt;page(), messageName.get(), messageBody.get());
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void TestRunner::setNavigationGesturesEnabled(bool value)
+{
+    WKRetainPtr&lt;WKStringRef&gt; messageName(AdoptWK, WKStringCreateWithUTF8CString(&quot;SetNavigationGesturesEnabled&quot;));
+    WKRetainPtr&lt;WKBooleanRef&gt; messageBody(AdoptWK, WKBooleanCreate(value));
+    WKBundlePagePostMessage(InjectedBundle::singleton().page()-&gt;page(), messageName.get(), messageBody.get());
+}
+
+void TestRunner::installDidBeginSwipeCallback(JSValueRef callback)
+{
+    cacheTestRunnerCallback(DidBeginSwipeCallbackID, callback);
+}
+
+void TestRunner::installWillEndSwipeCallback(JSValueRef callback)
+{
+    cacheTestRunnerCallback(WillEndSwipeCallbackID, callback);
+}
+
+void TestRunner::installDidEndSwipeCallback(JSValueRef callback)
+{
+    cacheTestRunnerCallback(DidEndSwipeCallbackID, callback);
+}
+
+void TestRunner::installDidRemoveSwipeSnapshotCallback(JSValueRef callback)
+{
+    cacheTestRunnerCallback(DidRemoveSwipeSnapshotCallbackID, callback);
+}
+
+void TestRunner::callDidBeginSwipeCallback()
+{
+    callTestRunnerCallback(DidBeginSwipeCallbackID);
+}
+
+void TestRunner::callWillEndSwipeCallback()
+{
+    callTestRunnerCallback(WillEndSwipeCallbackID);
+}
+
+void TestRunner::callDidEndSwipeCallback()
+{
+    callTestRunnerCallback(DidEndSwipeCallbackID);
+}
+
+void TestRunner::callDidRemoveSwipeSnapshotCallback()
+{
+    callTestRunnerCallback(DidRemoveSwipeSnapshotCallbackID);
+}
+
</ins><span class="cx"> } // namespace WTR
</span></span></pre></div>
<a id="trunkToolsWebKitTestRunnerInjectedBundleTestRunnerh"></a>
<div class="modfile"><h4>Modified: trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.h (189286 => 189287)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.h        2015-09-03 21:03:46 UTC (rev 189286)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.h        2015-09-03 21:11:44 UTC (rev 189287)
</span><span class="lines">@@ -285,7 +285,17 @@
</span><span class="cx"> 
</span><span class="cx">     bool shouldDecideNavigationPolicyAfterDelay() const { return m_shouldDecideNavigationPolicyAfterDelay; }
</span><span class="cx">     void setShouldDecideNavigationPolicyAfterDelay(bool);
</span><ins>+    void setNavigationGesturesEnabled(bool);
</ins><span class="cx"> 
</span><ins>+    void installDidBeginSwipeCallback(JSValueRef);
+    void installWillEndSwipeCallback(JSValueRef);
+    void installDidEndSwipeCallback(JSValueRef);
+    void installDidRemoveSwipeSnapshotCallback(JSValueRef);
+    void callDidBeginSwipeCallback();
+    void callWillEndSwipeCallback();
+    void callDidEndSwipeCallback();
+    void callDidRemoveSwipeSnapshotCallback();
+
</ins><span class="cx"> private:
</span><span class="cx">     TestRunner();
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkToolsWebKitTestRunnerInjectedBundleiosEventSenderProxyIOSmm"></a>
<div class="modfile"><h4>Modified: trunk/Tools/WebKitTestRunner/InjectedBundle/ios/EventSenderProxyIOS.mm (189286 => 189287)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/WebKitTestRunner/InjectedBundle/ios/EventSenderProxyIOS.mm        2015-09-03 21:03:46 UTC (rev 189286)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/ios/EventSenderProxyIOS.mm        2015-09-03 21:11:44 UTC (rev 189287)
</span><span class="lines">@@ -103,6 +103,11 @@
</span><span class="cx">     // Write me.
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void EventSenderProxy::swipeGestureWithWheelAndMomentumPhases(int, int, int, int)
+{
+    // Write me.
+}
+
</ins><span class="cx"> void EventSenderProxy::continuousMouseScrollBy(int x, int y, bool paged)
</span><span class="cx"> {
</span><span class="cx">     // Write me.
</span></span></pre></div>
<a id="trunkToolsWebKitTestRunnerPlatformWebViewh"></a>
<div class="modfile"><h4>Modified: trunk/Tools/WebKitTestRunner/PlatformWebView.h (189286 => 189287)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/WebKitTestRunner/PlatformWebView.h        2015-09-03 21:03:46 UTC (rev 189286)
+++ trunk/Tools/WebKitTestRunner/PlatformWebView.h        2015-09-03 21:11:44 UTC (rev 189287)
</span><span class="lines">@@ -86,6 +86,7 @@
</span><span class="cx">     const ViewOptions&amp; options() const { return m_options; }
</span><span class="cx"> 
</span><span class="cx">     void changeWindowScaleIfNeeded(float newScale);
</span><ins>+    void setNavigationGesturesEnabled(bool);
</ins><span class="cx"> 
</span><span class="cx"> #if PLATFORM(GTK)
</span><span class="cx">     void dismissAllPopupMenus();
</span></span></pre></div>
<a id="trunkToolsWebKitTestRunnerTestControllercpp"></a>
<div class="modfile"><h4>Modified: trunk/Tools/WebKitTestRunner/TestController.cpp (189286 => 189287)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/WebKitTestRunner/TestController.cpp        2015-09-03 21:03:46 UTC (rev 189286)
+++ trunk/Tools/WebKitTestRunner/TestController.cpp        2015-09-03 21:11:44 UTC (rev 189287)
</span><span class="lines">@@ -294,10 +294,10 @@
</span><span class="cx">         didReceiveAuthenticationChallenge,
</span><span class="cx">         processDidCrash,
</span><span class="cx">         copyWebCryptoMasterKey,
</span><del>-        0, // didBeginNavigationGesture
-        0, // willEndNavigationGesture
-        0, // didEndNavigationGesture
-        0, // didRemoveNavigationGestureSnapshot
</del><ins>+        didBeginNavigationGesture,
+        willEndNavigationGesture,
+        didEndNavigationGesture,
+        didRemoveNavigationGestureSnapshot
</ins><span class="cx">     };
</span><span class="cx">     WKPageSetPageNavigationClient(newPage, &amp;pageNavigationClient.base);
</span><span class="cx"> 
</span><span class="lines">@@ -539,10 +539,10 @@
</span><span class="cx">         didReceiveAuthenticationChallenge,
</span><span class="cx">         processDidCrash,
</span><span class="cx">         copyWebCryptoMasterKey,
</span><del>-        0, // didBeginNavigationGesture
-        0, // willEndNavigationGesture
-        0, // didEndNavigationGesture
-        0, // didRemoveNavigationGestureSnapshot
</del><ins>+        didBeginNavigationGesture,
+        willEndNavigationGesture,
+        didEndNavigationGesture,
+        didRemoveNavigationGestureSnapshot
</ins><span class="cx">     };
</span><span class="cx">     WKPageSetPageNavigationClient(m_mainWebView-&gt;page(), &amp;pageNavigationClient.base);
</span><span class="cx"> 
</span><span class="lines">@@ -746,6 +746,8 @@
</span><span class="cx"> 
</span><span class="cx">     m_shouldDecideNavigationPolicyAfterDelay = false;
</span><span class="cx"> 
</span><ins>+    setNavigationGesturesEnabled(false);
+
</ins><span class="cx">     WKPageLoadURL(m_mainWebView-&gt;page(), blankURL());
</span><span class="cx">     runUntil(m_doneResetting, shortTimeout);
</span><span class="cx">     return m_doneResetting;
</span><span class="lines">@@ -1137,6 +1139,23 @@
</span><span class="cx">             return;
</span><span class="cx">         }
</span><span class="cx"> 
</span><ins>+        if (WKStringIsEqualToUTF8CString(subMessageName, &quot;SwipeGestureWithWheelAndMomentumPhases&quot;)) {
+            WKRetainPtr&lt;WKStringRef&gt; xKey = adoptWK(WKStringCreateWithUTF8CString(&quot;X&quot;));
+            double x = WKDoubleGetValue(static_cast&lt;WKDoubleRef&gt;(WKDictionaryGetItemForKey(messageBodyDictionary, xKey.get())));
+
+            WKRetainPtr&lt;WKStringRef&gt; yKey = adoptWK(WKStringCreateWithUTF8CString(&quot;Y&quot;));
+            double y = WKDoubleGetValue(static_cast&lt;WKDoubleRef&gt;(WKDictionaryGetItemForKey(messageBodyDictionary, yKey.get())));
+
+            WKRetainPtr&lt;WKStringRef&gt; phaseKey = adoptWK(WKStringCreateWithUTF8CString(&quot;Phase&quot;));
+            int phase = static_cast&lt;int&gt;(WKUInt64GetValue(static_cast&lt;WKUInt64Ref&gt;(WKDictionaryGetItemForKey(messageBodyDictionary, phaseKey.get()))));
+            WKRetainPtr&lt;WKStringRef&gt; momentumKey = adoptWK(WKStringCreateWithUTF8CString(&quot;Momentum&quot;));
+            int momentum = static_cast&lt;int&gt;(WKUInt64GetValue(static_cast&lt;WKUInt64Ref&gt;(WKDictionaryGetItemForKey(messageBodyDictionary, momentumKey.get()))));
+
+            m_eventSenderProxy-&gt;swipeGestureWithWheelAndMomentumPhases(x, y, phase, momentum);
+
+            return;
+        }
+
</ins><span class="cx">         ASSERT_NOT_REACHED();
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="lines">@@ -1373,6 +1392,26 @@
</span><span class="cx">     static_cast&lt;TestController*&gt;(const_cast&lt;void*&gt;(clientInfo))-&gt;processDidCrash();
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void TestController::didBeginNavigationGesture(WKPageRef page, const void *clientInfo)
+{
+    static_cast&lt;TestController*&gt;(const_cast&lt;void*&gt;(clientInfo))-&gt;didBeginNavigationGesture(page);
+}
+
+void TestController::willEndNavigationGesture(WKPageRef page, WKBackForwardListItemRef backForwardListItem, const void *clientInfo)
+{
+    static_cast&lt;TestController*&gt;(const_cast&lt;void*&gt;(clientInfo))-&gt;willEndNavigationGesture(page, backForwardListItem);
+}
+
+void TestController::didEndNavigationGesture(WKPageRef page, WKBackForwardListItemRef backForwardListItem, const void *clientInfo)
+{
+    static_cast&lt;TestController*&gt;(const_cast&lt;void*&gt;(clientInfo))-&gt;didEndNavigationGesture(page, backForwardListItem);
+}
+
+void TestController::didRemoveNavigationGestureSnapshot(WKPageRef page, const void *clientInfo)
+{
+    static_cast&lt;TestController*&gt;(const_cast&lt;void*&gt;(clientInfo))-&gt;didRemoveNavigationGestureSnapshot(page);
+}
+
</ins><span class="cx"> WKPluginLoadPolicy TestController::decidePolicyForPluginLoad(WKPageRef page, WKPluginLoadPolicy currentPluginLoadPolicy, WKDictionaryRef pluginInformation, WKStringRef* unavailabilityDescription, const void* clientInfo)
</span><span class="cx"> {
</span><span class="cx">     return static_cast&lt;TestController*&gt;(const_cast&lt;void*&gt;(clientInfo))-&gt;decidePolicyForPluginLoad(page, currentPluginLoadPolicy, pluginInformation, unavailabilityDescription);
</span><span class="lines">@@ -1470,6 +1509,26 @@
</span><span class="cx">         exit(1);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void TestController::didBeginNavigationGesture(WKPageRef)
+{
+    m_currentInvocation-&gt;didBeginSwipe();
+}
+
+void TestController::willEndNavigationGesture(WKPageRef, WKBackForwardListItemRef)
+{
+    m_currentInvocation-&gt;willEndSwipe();
+}
+
+void TestController::didEndNavigationGesture(WKPageRef, WKBackForwardListItemRef)
+{
+    m_currentInvocation-&gt;didEndSwipe();
+}
+
+void TestController::didRemoveNavigationGestureSnapshot(WKPageRef)
+{
+    m_currentInvocation-&gt;didRemoveSwipeSnapshot();
+}
+
</ins><span class="cx"> void TestController::simulateWebNotificationClick(uint64_t notificationID)
</span><span class="cx"> {
</span><span class="cx">     m_webNotificationProvider.simulateWebNotificationClick(notificationID);
</span><span class="lines">@@ -1688,6 +1747,11 @@
</span><span class="cx">     m_currentInvocation-&gt;outputText(String::format(&quot;WebView updated the title for history URL \&quot;%s\&quot; to \&quot;%s\&quot;.\n&quot;, toSTD(urlStringWK).c_str(), toSTD(title).c_str()));
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void TestController::setNavigationGesturesEnabled(bool value)
+{
+    m_mainWebView-&gt;setNavigationGesturesEnabled(value);
+}
+
</ins><span class="cx"> #if !PLATFORM(COCOA)
</span><span class="cx"> void TestController::platformWillRunTest(const TestInvocation&amp;)
</span><span class="cx"> {
</span></span></pre></div>
<a id="trunkToolsWebKitTestRunnerTestControllerh"></a>
<div class="modfile"><h4>Modified: trunk/Tools/WebKitTestRunner/TestController.h (189286 => 189287)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/WebKitTestRunner/TestController.h        2015-09-03 21:03:46 UTC (rev 189286)
+++ trunk/Tools/WebKitTestRunner/TestController.h        2015-09-03 21:11:44 UTC (rev 189287)
</span><span class="lines">@@ -126,6 +126,8 @@
</span><span class="cx"> 
</span><span class="cx">     void setShouldDecideNavigationPolicyAfterDelay(bool value) { m_shouldDecideNavigationPolicyAfterDelay = value; }
</span><span class="cx"> 
</span><ins>+    void setNavigationGesturesEnabled(bool value);
+
</ins><span class="cx"> private:
</span><span class="cx">     void initialize(int argc, const char* argv[]);
</span><span class="cx">     void createWebViewWithOptions(const ViewOptions&amp;);
</span><span class="lines">@@ -142,6 +144,9 @@
</span><span class="cx">     static PlatformWebView* platformCreateOtherPage(PlatformWebView* parentView, WKPageConfigurationRef, const ViewOptions&amp;);
</span><span class="cx">     void platformResetPreferencesToConsistentValues();
</span><span class="cx">     void platformResetStateToConsistentValues();
</span><ins>+#if PLATFORM(COCOA)
+    void cocoaResetStateToConsistentValues();
+#endif
</ins><span class="cx">     void platformConfigureViewForTest(const TestInvocation&amp;);
</span><span class="cx">     void platformWillRunTest(const TestInvocation&amp;);
</span><span class="cx">     void platformRunUntil(bool&amp; done, double timeout);
</span><span class="lines">@@ -186,6 +191,15 @@
</span><span class="cx">     static void processDidCrash(WKPageRef, const void* clientInfo);
</span><span class="cx">     void processDidCrash();
</span><span class="cx"> 
</span><ins>+    static void didBeginNavigationGesture(WKPageRef, const void*);
+    static void willEndNavigationGesture(WKPageRef, WKBackForwardListItemRef, const void*);
+    static void didEndNavigationGesture(WKPageRef, WKBackForwardListItemRef, const void*);
+    static void didRemoveNavigationGestureSnapshot(WKPageRef, const void*);
+    void didBeginNavigationGesture(WKPageRef);
+    void willEndNavigationGesture(WKPageRef, WKBackForwardListItemRef);
+    void didEndNavigationGesture(WKPageRef, WKBackForwardListItemRef);
+    void didRemoveNavigationGestureSnapshot(WKPageRef);
+
</ins><span class="cx">     static WKPluginLoadPolicy decidePolicyForPluginLoad(WKPageRef, WKPluginLoadPolicy currentPluginLoadPolicy, WKDictionaryRef pluginInformation, WKStringRef* unavailabilityDescription, const void* clientInfo);
</span><span class="cx">     WKPluginLoadPolicy decidePolicyForPluginLoad(WKPageRef, WKPluginLoadPolicy currentPluginLoadPolicy, WKDictionaryRef pluginInformation, WKStringRef* unavailabilityDescription);
</span><span class="cx">     
</span></span></pre></div>
<a id="trunkToolsWebKitTestRunnerTestInvocationcpp"></a>
<div class="modfile"><h4>Modified: trunk/Tools/WebKitTestRunner/TestInvocation.cpp (189286 => 189287)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/WebKitTestRunner/TestInvocation.cpp        2015-09-03 21:03:46 UTC (rev 189286)
+++ trunk/Tools/WebKitTestRunner/TestInvocation.cpp        2015-09-03 21:11:44 UTC (rev 189287)
</span><span class="lines">@@ -635,6 +635,13 @@
</span><span class="cx">         return;
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    if (WKStringIsEqualToUTF8CString(messageName, &quot;SetNavigationGesturesEnabled&quot;)) {
+        ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID());
+        WKBooleanRef value = static_cast&lt;WKBooleanRef&gt;(messageBody);
+        TestController::singleton().setNavigationGesturesEnabled(WKBooleanGetValue(value));
+        return;
+    }
+
</ins><span class="cx">     ASSERT_NOT_REACHED();
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -685,4 +692,28 @@
</span><span class="cx">     m_textOutput.append(text);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void TestInvocation::didBeginSwipe()
+{
+    WKRetainPtr&lt;WKStringRef&gt; messageName = adoptWK(WKStringCreateWithUTF8CString(&quot;CallDidBeginSwipeCallback&quot;));
+    WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()-&gt;page(), messageName.get(), 0);
+}
+
+void TestInvocation::willEndSwipe()
+{
+    WKRetainPtr&lt;WKStringRef&gt; messageName = adoptWK(WKStringCreateWithUTF8CString(&quot;CallWillEndSwipeCallback&quot;));
+    WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()-&gt;page(), messageName.get(), 0);
+}
+
+void TestInvocation::didEndSwipe()
+{
+    WKRetainPtr&lt;WKStringRef&gt; messageName = adoptWK(WKStringCreateWithUTF8CString(&quot;CallDidEndSwipeCallback&quot;));
+    WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()-&gt;page(), messageName.get(), 0);
+}
+
+void TestInvocation::didRemoveSwipeSnapshot()
+{
+    WKRetainPtr&lt;WKStringRef&gt; messageName = adoptWK(WKStringCreateWithUTF8CString(&quot;CallDidRemoveSwipeSnapshotCallback&quot;));
+    WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()-&gt;page(), messageName.get(), 0);
+}
+
</ins><span class="cx"> } // namespace WTR
</span></span></pre></div>
<a id="trunkToolsWebKitTestRunnerTestInvocationh"></a>
<div class="modfile"><h4>Modified: trunk/Tools/WebKitTestRunner/TestInvocation.h (189286 => 189287)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/WebKitTestRunner/TestInvocation.h        2015-09-03 21:03:46 UTC (rev 189286)
+++ trunk/Tools/WebKitTestRunner/TestInvocation.h        2015-09-03 21:11:44 UTC (rev 189287)
</span><span class="lines">@@ -54,6 +54,12 @@
</span><span class="cx">     void dumpWebProcessUnresponsiveness();
</span><span class="cx">     static void dumpWebProcessUnresponsiveness(const char* errorMessage);
</span><span class="cx">     void outputText(const WTF::String&amp;);
</span><ins>+
+    void didBeginSwipe();
+    void willEndSwipe();
+    void didEndSwipe();
+    void didRemoveSwipeSnapshot();
+
</ins><span class="cx"> private:
</span><span class="cx">     void dumpResults();
</span><span class="cx">     static void dump(const char* textToStdout, const char* textToStderr = 0, bool seenError = false);
</span></span></pre></div>
<a id="trunkToolsWebKitTestRunnercocoaTestControllerCocoamm"></a>
<div class="modfile"><h4>Modified: trunk/Tools/WebKitTestRunner/cocoa/TestControllerCocoa.mm (189286 => 189287)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/WebKitTestRunner/cocoa/TestControllerCocoa.mm        2015-09-03 21:03:46 UTC (rev 189286)
+++ trunk/Tools/WebKitTestRunner/cocoa/TestControllerCocoa.mm        2015-09-03 21:11:44 UTC (rev 189287)
</span><span class="lines">@@ -108,7 +108,7 @@
</span><span class="cx">         [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:endDate];
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void TestController::platformResetStateToConsistentValues()
</del><ins>+void TestController::cocoaResetStateToConsistentValues()
</ins><span class="cx"> {
</span><span class="cx"> #if WK_API_ENABLED
</span><span class="cx">     __block bool doneRemoving = false;
</span></span></pre></div>
<a id="trunkToolsWebKitTestRunnereflEventSenderProxyEflcpp"></a>
<div class="modfile"><h4>Modified: trunk/Tools/WebKitTestRunner/efl/EventSenderProxyEfl.cpp (189286 => 189287)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/WebKitTestRunner/efl/EventSenderProxyEfl.cpp        2015-09-03 21:03:46 UTC (rev 189286)
+++ trunk/Tools/WebKitTestRunner/efl/EventSenderProxyEfl.cpp        2015-09-03 21:11:44 UTC (rev 189287)
</span><span class="lines">@@ -399,6 +399,11 @@
</span><span class="cx">     mouseScrollBy(x, y);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void EventSenderProxy::swipeGestureWithWheelAndMomentumPhases(int, int, int, int)
+{
+    notImplemented();
+}
+
</ins><span class="cx"> void EventSenderProxy::leapForward(int milliseconds)
</span><span class="cx"> {
</span><span class="cx">     if (m_eventQueue.isEmpty())
</span></span></pre></div>
<a id="trunkToolsWebKitTestRunnereflPlatformWebViewEflcpp"></a>
<div class="modfile"><h4>Modified: trunk/Tools/WebKitTestRunner/efl/PlatformWebViewEfl.cpp (189286 => 189287)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/WebKitTestRunner/efl/PlatformWebViewEfl.cpp        2015-09-03 21:03:46 UTC (rev 189286)
+++ trunk/Tools/WebKitTestRunner/efl/PlatformWebViewEfl.cpp        2015-09-03 21:11:44 UTC (rev 189287)
</span><span class="lines">@@ -156,5 +156,9 @@
</span><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void PlatformWebView::setNavigationGesturesEnabled(bool)
+{
+}
+
</ins><span class="cx"> } // namespace WTR
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkToolsWebKitTestRunnergtkEventSenderProxyGtkcpp"></a>
<div class="modfile"><h4>Modified: trunk/Tools/WebKitTestRunner/gtk/EventSenderProxyGtk.cpp (189286 => 189287)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/WebKitTestRunner/gtk/EventSenderProxyGtk.cpp        2015-09-03 21:03:46 UTC (rev 189286)
+++ trunk/Tools/WebKitTestRunner/gtk/EventSenderProxyGtk.cpp        2015-09-03 21:11:44 UTC (rev 189287)
</span><span class="lines">@@ -451,6 +451,11 @@
</span><span class="cx">     mouseScrollBy(x, y);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void EventSenderProxy::swipeGestureWithWheelAndMomentumPhases(int, int, int, int)
+{
+    notImplemented();
+}
+
</ins><span class="cx"> void EventSenderProxy::leapForward(int milliseconds)
</span><span class="cx"> {
</span><span class="cx">     if (m_eventQueue.isEmpty())
</span></span></pre></div>
<a id="trunkToolsWebKitTestRunnergtkPlatformWebViewGtkcpp"></a>
<div class="modfile"><h4>Modified: trunk/Tools/WebKitTestRunner/gtk/PlatformWebViewGtk.cpp (189286 => 189287)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/WebKitTestRunner/gtk/PlatformWebViewGtk.cpp        2015-09-03 21:03:46 UTC (rev 189286)
+++ trunk/Tools/WebKitTestRunner/gtk/PlatformWebViewGtk.cpp        2015-09-03 21:11:44 UTC (rev 189287)
</span><span class="lines">@@ -158,5 +158,9 @@
</span><span class="cx">     }, nullptr);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void PlatformWebView::setNavigationGesturesEnabled(bool)
+{
+}
+
</ins><span class="cx"> } // namespace WTR
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkToolsWebKitTestRunneriosPlatformWebViewIOSmm"></a>
<div class="modfile"><h4>Modified: trunk/Tools/WebKitTestRunner/ios/PlatformWebViewIOS.mm (189286 => 189287)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/WebKitTestRunner/ios/PlatformWebViewIOS.mm        2015-09-03 21:03:46 UTC (rev 189286)
+++ trunk/Tools/WebKitTestRunner/ios/PlatformWebViewIOS.mm        2015-09-03 21:11:44 UTC (rev 189287)
</span><span class="lines">@@ -207,4 +207,8 @@
</span><span class="cx">     return true;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void PlatformWebView::setNavigationGesturesEnabled(bool enabled)
+{
+}
+
</ins><span class="cx"> } // namespace WTR
</span></span></pre></div>
<a id="trunkToolsWebKitTestRunneriosTestControllerIOSmm"></a>
<div class="modfile"><h4>Modified: trunk/Tools/WebKitTestRunner/ios/TestControllerIOS.mm (189286 => 189287)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/WebKitTestRunner/ios/TestControllerIOS.mm        2015-09-03 21:03:46 UTC (rev 189286)
+++ trunk/Tools/WebKitTestRunner/ios/TestControllerIOS.mm        2015-09-03 21:11:44 UTC (rev 189287)
</span><span class="lines">@@ -86,6 +86,11 @@
</span><span class="cx">     WKPreferencesSetMinimumZoomFontSize(preferences, 0);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void TestController::platformResetStateToConsistentValues()
+{
+    cocoaResetStateToConsistentValues();
+}
+
</ins><span class="cx"> void TestController::platformConfigureViewForTest(const TestInvocation&amp; test)
</span><span class="cx"> {
</span><span class="cx">     if (shouldMakeViewportFlexible(test)) {
</span></span></pre></div>
<a id="trunkToolsWebKitTestRunnermacEventSenderProxymm"></a>
<div class="modfile"><h4>Modified: trunk/Tools/WebKitTestRunner/mac/EventSenderProxy.mm (189286 => 189287)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/WebKitTestRunner/mac/EventSenderProxy.mm        2015-09-03 21:03:46 UTC (rev 189286)
+++ trunk/Tools/WebKitTestRunner/mac/EventSenderProxy.mm        2015-09-03 21:11:44 UTC (rev 189287)
</span><span class="lines">@@ -40,25 +40,42 @@
</span><span class="cx"> - (void)_setCurrentEvent:(NSEvent *)event;
</span><span class="cx"> @end
</span><span class="cx"> 
</span><del>-#if defined(__LP64__) &amp;&amp; __MAC_OS_X_VERSION_MAX_ALLOWED &gt;= 101003
-@interface EventSenderPressureEvent : NSEvent {
</del><ins>+#if defined(__LP64__)
+struct WKTRCGSEventRecord {
+    char offset1[150];
+    uint8_t phase;
+    char offset2[13];
+    float deltaX;
+    float deltaY;
+    char offset3[76];
+} __attribute__((packed));
+#endif
+
+@interface EventSenderSyntheticEvent : NSEvent {
</ins><span class="cx"> @public
</span><span class="cx">     NSPoint _eventSender_locationInWindow;
</span><span class="cx">     NSPoint _eventSender_location;
</span><span class="cx">     NSInteger _eventSender_stage;
</span><span class="cx">     float _eventSender_pressure;
</span><span class="cx">     NSEventPhase _eventSender_phase;
</span><ins>+    NSEventPhase _eventSender_momentumPhase;
</ins><span class="cx">     NSTimeInterval _eventSender_timestamp;
</span><span class="cx">     NSInteger _eventSender_eventNumber;
</span><ins>+    short _eventSender_subtype;
+    NSEventType _eventSender_type;
+
+#if defined(__LP64__)
+    WKTRCGSEventRecord _eventSender_cgsEventRecord;
+#endif
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-- (id)initAtLocation:(NSPoint)location globalLocation:(NSPoint)globalLocation stage:(NSInteger)stage pressure:(float)pressure phase:(NSEventPhase)phase time:(NSTimeInterval)time eventNumber:(NSInteger)eventNumber;
</del><ins>+- (id)initPressureEventAtLocation:(NSPoint)location globalLocation:(NSPoint)globalLocation stage:(NSInteger)stage pressure:(float)pressure phase:(NSEventPhase)phase time:(NSTimeInterval)time eventNumber:(NSInteger)eventNumber;
</ins><span class="cx"> - (NSTimeInterval)timestamp;
</span><span class="cx"> @end
</span><span class="cx"> 
</span><del>-@implementation EventSenderPressureEvent
</del><ins>+@implementation EventSenderSyntheticEvent
</ins><span class="cx"> 
</span><del>-- (id)initAtLocation:(NSPoint)location globalLocation:(NSPoint)globalLocation stage:(NSInteger)stage pressure:(float)pressure phase:(NSEventPhase)phase time:(NSTimeInterval)time eventNumber:(NSInteger)eventNumber
</del><ins>+- (id)initPressureEventAtLocation:(NSPoint)location globalLocation:(NSPoint)globalLocation stage:(NSInteger)stage pressure:(float)pressure phase:(NSEventPhase)phase time:(NSTimeInterval)time eventNumber:(NSInteger)eventNumber
</ins><span class="cx"> {
</span><span class="cx">     self = [super init];
</span><span class="cx"> 
</span><span class="lines">@@ -72,6 +89,9 @@
</span><span class="cx">     _eventSender_phase = phase;
</span><span class="cx">     _eventSender_timestamp = time;
</span><span class="cx">     _eventSender_eventNumber = eventNumber;
</span><ins>+#if defined(__LP64__) &amp;&amp; __MAC_OS_X_VERSION_MIN_REQUIRED &gt;= 101003
+    _eventSender_type = NSEventTypePressure;
+#endif
</ins><span class="cx"> 
</span><span class="cx">     return self;
</span><span class="cx"> }
</span><span class="lines">@@ -83,17 +103,29 @@
</span><span class="cx"> 
</span><span class="cx"> - (NSEventType)type
</span><span class="cx"> {
</span><del>-    return NSEventTypePressure;
</del><ins>+    return _eventSender_type;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><ins>+#if __MAC_OS_X_VERSION_MIN_REQUIRED &gt;= 10100
+- (NSEventSubtype)subtype
+{
+    return (NSEventSubtype)_eventSender_subtype;
+}
+#else
+- (short)subtype
+{
+    return _eventSender_subtype;
+}
+#endif
+
</ins><span class="cx"> - (NSPoint)locationInWindow
</span><span class="cx"> {
</span><del>-    return self-&gt;_eventSender_location;
</del><ins>+    return _eventSender_location;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> - (NSPoint)location
</span><span class="cx"> {
</span><del>-    return self-&gt;_eventSender_locationInWindow;
</del><ins>+    return _eventSender_locationInWindow;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> - (NSInteger)stage
</span><span class="lines">@@ -111,13 +143,29 @@
</span><span class="cx">     return _eventSender_phase;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+- (NSEventPhase)momentumPhase
+{
+    return _eventSender_momentumPhase;
+}
+
</ins><span class="cx"> - (NSInteger)eventNumber
</span><span class="cx"> {
</span><span class="cx">     return _eventSender_eventNumber;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+- (BOOL)_isTouchesEnded
+{
+    return false;
+}
+
+#if defined(__LP64__)
+- (WKTRCGSEventRecord)_cgsEventRecord
+{
+    return _eventSender_cgsEventRecord;
+}
+#endif
+
</ins><span class="cx"> @end
</span><del>-#endif // defined(__LP64__) &amp;&amp; __MAC_OS_X_VERSION_MAX_ALLOWED &gt;= 101003
</del><span class="cx"> 
</span><span class="cx"> namespace WTR {
</span><span class="cx"> 
</span><span class="lines">@@ -290,17 +338,17 @@
</span><span class="cx">     m_clickPosition = m_position;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-#if defined(__LP64__) &amp;&amp; __MAC_OS_X_VERSION_MAX_ALLOWED &gt;= 101003
</del><ins>+#if defined(__LP64__) &amp;&amp; __MAC_OS_X_VERSION_MIN_REQUIRED &gt;= 101003
</ins><span class="cx"> void EventSenderProxy::mouseForceDown()
</span><span class="cx"> {
</span><del>-    EventSenderPressureEvent *firstEvent = [[EventSenderPressureEvent alloc] initAtLocation:NSMakePoint(m_position.x, m_position.y)
</del><ins>+    EventSenderSyntheticEvent *firstEvent = [[EventSenderSyntheticEvent alloc] initPressureEventAtLocation:NSMakePoint(m_position.x, m_position.y)
</ins><span class="cx">         globalLocation:([m_testController-&gt;mainWebView()-&gt;platformWindow() convertRectToScreen:NSMakeRect(m_position.x, m_position.y, 1, 1)].origin)
</span><span class="cx">         stage:1
</span><span class="cx">         pressure:0.9
</span><span class="cx">         phase:NSEventPhaseChanged
</span><span class="cx">         time:absoluteTimeForEventTime(currentEventTime())
</span><span class="cx">         eventNumber:++eventNumber];
</span><del>-    EventSenderPressureEvent *secondEvent = [[EventSenderPressureEvent alloc] initAtLocation:NSMakePoint(m_position.x, m_position.y)
</del><ins>+    EventSenderSyntheticEvent *secondEvent = [[EventSenderSyntheticEvent alloc] initPressureEventAtLocation:NSMakePoint(m_position.x, m_position.y)
</ins><span class="cx">         globalLocation:([m_testController-&gt;mainWebView()-&gt;platformWindow() convertRectToScreen:NSMakeRect(m_position.x, m_position.y, 1, 1)].origin)
</span><span class="cx">         stage:2
</span><span class="cx">         pressure:0.1
</span><span class="lines">@@ -332,14 +380,14 @@
</span><span class="cx"> 
</span><span class="cx"> void EventSenderProxy::mouseForceUp()
</span><span class="cx"> {
</span><del>-    EventSenderPressureEvent *firstEvent = [[EventSenderPressureEvent alloc] initAtLocation:NSMakePoint(m_position.x, m_position.y)
</del><ins>+    EventSenderSyntheticEvent *firstEvent = [[EventSenderSyntheticEvent alloc] initPressureEventAtLocation:NSMakePoint(m_position.x, m_position.y)
</ins><span class="cx">         globalLocation:([m_testController-&gt;mainWebView()-&gt;platformWindow() convertRectToScreen:NSMakeRect(m_position.x, m_position.y, 1, 1)].origin)
</span><span class="cx">         stage:2
</span><span class="cx">         pressure:0.1
</span><span class="cx">         phase:NSEventPhaseChanged
</span><span class="cx">         time:absoluteTimeForEventTime(currentEventTime())
</span><span class="cx">         eventNumber:++eventNumber];
</span><del>-    EventSenderPressureEvent *secondEvent = [[EventSenderPressureEvent alloc] initAtLocation:NSMakePoint(m_position.x, m_position.y)
</del><ins>+    EventSenderSyntheticEvent *secondEvent = [[EventSenderSyntheticEvent alloc] initPressureEventAtLocation:NSMakePoint(m_position.x, m_position.y)
</ins><span class="cx">         globalLocation:([m_testController-&gt;mainWebView()-&gt;platformWindow() convertRectToScreen:NSMakeRect(m_position.x, m_position.y, 1, 1)].origin)
</span><span class="cx">         stage:1
</span><span class="cx">         pressure:0.9
</span><span class="lines">@@ -372,7 +420,7 @@
</span><span class="cx"> 
</span><span class="cx"> void EventSenderProxy::mouseForceChanged(float force)
</span><span class="cx"> {
</span><del>-    EventSenderPressureEvent *event = [[EventSenderPressureEvent alloc] initAtLocation:NSMakePoint(m_position.x, m_position.y)
</del><ins>+    EventSenderSyntheticEvent *event = [[EventSenderSyntheticEvent alloc] initPressureEventAtLocation:NSMakePoint(m_position.x, m_position.y)
</ins><span class="cx">         globalLocation:([m_testController-&gt;mainWebView()-&gt;platformWindow() convertRectToScreen:NSMakeRect(m_position.x, m_position.y, 1, 1)].origin)
</span><span class="cx">         stage:force &lt; 1 ? 1 : 2
</span><span class="cx">         pressure:force
</span><span class="lines">@@ -407,7 +455,7 @@
</span><span class="cx"> void EventSenderProxy::mouseForceChanged(float)
</span><span class="cx"> {
</span><span class="cx"> }
</span><del>-#endif // defined(__LP64__) &amp;&amp; __MAC_OS_X_VERSION_MAX_ALLOWED &gt;= 101003
</del><ins>+#endif // defined(__LP64__) &amp;&amp; __MAC_OS_X_VERSION_MIN_REQUIRED &gt;= 101003
</ins><span class="cx"> 
</span><span class="cx"> void EventSenderProxy::mouseMoveTo(double x, double y)
</span><span class="cx"> {
</span><span class="lines">@@ -705,4 +753,51 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+static NSEventPhase nsEventPhaseFromCGEventPhase(int phase)
+{
+    switch (phase) {
+    case 0: // kCGSGesturePhaseNone
+        return NSEventPhaseNone;
+    case 1: // kCGSGesturePhaseBegan
+        return NSEventPhaseBegan;
+    case 2: // kCGSGesturePhaseChanged
+        return NSEventPhaseChanged;
+    case 4: // kCGSGesturePhaseEnded
+        return NSEventPhaseEnded;
+    case 8: // kCGSGesturePhaseCancelled
+        return NSEventPhaseCancelled;
+    case 128: // kCGSGesturePhaseMayBegin
+        return NSEventPhaseMayBegin;
+    }
+
+    ASSERT_NOT_REACHED();
+    return NSEventPhaseNone;
+}
+
+void EventSenderProxy::swipeGestureWithWheelAndMomentumPhases(int x, int y, int phase, int momentum)
+{
+    EventSenderSyntheticEvent *event = [[EventSenderSyntheticEvent alloc] init];
+
+    // &quot;mayBegin&quot; a swipe is actually a scroll wheel event.
+    event-&gt;_eventSender_type = (phase == 128) ? NSScrollWheel : NSEventTypeGesture;
+    event-&gt;_eventSender_subtype = 6; // kIOHIDEventTypeScroll
+    event-&gt;_eventSender_locationInWindow = NSMakePoint(m_position.x, m_position.y);
+    event-&gt;_eventSender_location = ([m_testController-&gt;mainWebView()-&gt;platformWindow() convertRectToScreen:NSMakeRect(m_position.x, m_position.y, 1, 1)].origin);
+    event-&gt;_eventSender_phase = nsEventPhaseFromCGEventPhase(phase);
+    event-&gt;_eventSender_momentumPhase = nsEventPhaseFromCGEventPhase(momentum);
+    event-&gt;_eventSender_timestamp = absoluteTimeForEventTime(currentEventTime());
+    event-&gt;_eventSender_eventNumber = ++eventNumber;
+
+#if defined(__LP64__)
+    event-&gt;_eventSender_cgsEventRecord.phase = phase;
+    event-&gt;_eventSender_cgsEventRecord.deltaX = (float)x;
+    event-&gt;_eventSender_cgsEventRecord.deltaY = (float)y;
+#else
+    NSLog(@&quot;Synthetic swipe gestures are not implemented for 32-bit WebKitTestRunner.&quot;);
+#endif
+
+    NSLog(@&quot;sending swipe event %d %d phase %d&quot;, x, y, phase);
+    [NSApp sendEvent:event];
+}
+
</ins><span class="cx"> } // namespace WTR
</span></span></pre></div>
<a id="trunkToolsWebKitTestRunnermacPlatformWebViewMacmm"></a>
<div class="modfile"><h4>Modified: trunk/Tools/WebKitTestRunner/mac/PlatformWebViewMac.mm (189286 => 189287)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/WebKitTestRunner/mac/PlatformWebViewMac.mm        2015-09-03 21:03:46 UTC (rev 189286)
+++ trunk/Tools/WebKitTestRunner/mac/PlatformWebViewMac.mm        2015-09-03 21:11:44 UTC (rev 189287)
</span><span class="lines">@@ -269,4 +269,9 @@
</span><span class="cx">     setWindowFrame(wkFrame);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void PlatformWebView::setNavigationGesturesEnabled(bool enabled)
+{
+    [platformView() setAllowsBackForwardNavigationGestures:enabled];
+}
+
</ins><span class="cx"> } // namespace WTR
</span></span></pre></div>
<a id="trunkToolsWebKitTestRunnermacTestControllerMacmm"></a>
<div class="modfile"><h4>Modified: trunk/Tools/WebKitTestRunner/mac/TestControllerMac.mm (189286 => 189287)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/WebKitTestRunner/mac/TestControllerMac.mm        2015-09-03 21:03:46 UTC (rev 189286)
+++ trunk/Tools/WebKitTestRunner/mac/TestControllerMac.mm        2015-09-03 21:11:44 UTC (rev 189287)
</span><span class="lines">@@ -86,6 +86,15 @@
</span><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void TestController::platformResetStateToConsistentValues()
+{
+    cocoaResetStateToConsistentValues();
+
+    while ([NSApp nextEventMatchingMask:NSEventMaskGesture | NSScrollWheelMask untilDate:nil inMode:NSDefaultRunLoopMode dequeue:YES]) {
+        // Clear out (and ignore) any pending gesture and scroll wheel events.
+    }
+}
+
</ins><span class="cx"> void TestController::updatePlatformSpecificViewOptionsForTest(ViewOptions&amp; viewOptions, const TestInvocation&amp; test) const
</span><span class="cx"> {
</span><span class="cx">     viewOptions.useThreadedScrolling = shouldUseThreadedScrolling(test);
</span></span></pre>
</div>
</div>

</body>
</html>