<!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>[259669] 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/259669">259669</a></dd>
<dt>Author</dt> <dd>wenson_hsieh@apple.com</dd>
<dt>Date</dt> <dd>2020-04-07 14:00:49 -0700 (Tue, 07 Apr 2020)</dd>
</dl>

<h3>Log Message</h3>
<pre>Preventing touch events should not prevent gestures installed above WKWebView from recognizing
https://bugs.webkit.org/show_bug.cgi?id=210080
<rdar://problem/61365814>

Reviewed by Tim Horton.

Source/WebKit:

Makes a small adjustment to native gesture deferral logic, so that gestures installed above WKWebView (in the
view hierarchy) are not prevented from recognizing by WKDeferringGestureRecognizer. This makes it possible for
WebKit clients to install custom gestures outside of WKWebView that cannot be prevented by web content, without
having to create a separate window and pass touches through to the WKWebView.

Test: fast/events/touch/ios/prevent-default-with-window-tap-gesture.html

* UIProcess/ios/WKContentViewInteraction.mm:
(-[WKContentView deferringGestureRecognizer:shouldDeferOtherGestureRecognizer:]):

Tools:

Add a UIScriptController helper method that allows a test to install a tap gesture recognizer on the UIWindow
containing the web view. This method additionally takes a JavaScript callback, which is invoked when the tap
gesture is recognized.

* TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl:
* TestRunnerShared/UIScriptContext/UIScriptContext.h:
* TestRunnerShared/UIScriptContext/UIScriptController.h:
(WTR::UIScriptController::installTapGestureOnWindow):
* WebKitTestRunner/cocoa/TestRunnerWKWebView.h:
* WebKitTestRunner/cocoa/TestRunnerWKWebView.mm:
(-[TestRunnerWKWebView resetInteractionCallbacks]):
(-[TestRunnerWKWebView didRecognizeTapOnWindow]):
(-[TestRunnerWKWebView windowTapRecognizedCallback]):
(-[TestRunnerWKWebView setWindowTapRecognizedCallback:]):
(-[TestRunnerWKWebView willMoveToWindow:]):
(-[TestRunnerWKWebView didMoveToWindow]):
(-[TestRunnerWKWebView gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer:]):
* WebKitTestRunner/ios/UIScriptControllerIOS.h:
* WebKitTestRunner/ios/UIScriptControllerIOS.mm:
(WTR::UIScriptControllerIOS::installTapGestureOnWindow):

LayoutTests:

Add a new layout test to verify that calling preventDefault() on touchstart doesn't prevent gesture recognizers
installed above the WKWebView from recognizing. To do this, we use the new UIScriptController method to add a
gesture recognizer to the window containing the web view, and then simulate a tap over an element that prevents
the touchstart event.

* fast/events/touch/ios/prevent-default-with-window-tap-gesture-expected.txt: Added.
* fast/events/touch/ios/prevent-default-with-window-tap-gesture.html: Added.
* resources/ui-helper.js:
(window.UIHelper.async activateElementAfterInstallingTapGestureOnWindow.return.new.Promise.):
(window.UIHelper.async activateElementAfterInstallingTapGestureOnWindow.return.new.Promise):
(window.UIHelper.async activateElementAfterInstallingTapGestureOnWindow):
(window.UIHelper):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkLayoutTestsresourcesuihelperjs">trunk/LayoutTests/resources/ui-helper.js</a></li>
<li><a href="#trunkSourceWebKitChangeLog">trunk/Source/WebKit/ChangeLog</a></li>
<li><a href="#trunkSourceWebKitUIProcessiosWKContentViewInteractionmm">trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm</a></li>
<li><a href="#trunkToolsChangeLog">trunk/Tools/ChangeLog</a></li>
<li><a href="#trunkToolsTestRunnerSharedUIScriptContextBindingsUIScriptControlleridl">trunk/Tools/TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl</a></li>
<li><a href="#trunkToolsTestRunnerSharedUIScriptContextUIScriptContexth">trunk/Tools/TestRunnerShared/UIScriptContext/UIScriptContext.h</a></li>
<li><a href="#trunkToolsTestRunnerSharedUIScriptContextUIScriptControllerh">trunk/Tools/TestRunnerShared/UIScriptContext/UIScriptController.h</a></li>
<li><a href="#trunkToolsWebKitTestRunnercocoaTestRunnerWKWebViewh">trunk/Tools/WebKitTestRunner/cocoa/TestRunnerWKWebView.h</a></li>
<li><a href="#trunkToolsWebKitTestRunnercocoaTestRunnerWKWebViewmm">trunk/Tools/WebKitTestRunner/cocoa/TestRunnerWKWebView.mm</a></li>
<li><a href="#trunkToolsWebKitTestRunneriosUIScriptControllerIOSh">trunk/Tools/WebKitTestRunner/ios/UIScriptControllerIOS.h</a></li>
<li><a href="#trunkToolsWebKitTestRunneriosUIScriptControllerIOSmm">trunk/Tools/WebKitTestRunner/ios/UIScriptControllerIOS.mm</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsfasteventstouchiospreventdefaultwithwindowtapgestureexpectedtxt">trunk/LayoutTests/fast/events/touch/ios/prevent-default-with-window-tap-gesture-expected.txt</a></li>
<li><a href="#trunkLayoutTestsfasteventstouchiospreventdefaultwithwindowtapgesturehtml">trunk/LayoutTests/fast/events/touch/ios/prevent-default-with-window-tap-gesture.html</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (259668 => 259669)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog      2020-04-07 20:49:06 UTC (rev 259668)
+++ trunk/LayoutTests/ChangeLog 2020-04-07 21:00:49 UTC (rev 259669)
</span><span class="lines">@@ -1,3 +1,24 @@
</span><ins>+2020-04-07  Wenson Hsieh  <wenson_hsieh@apple.com>
+
+        Preventing touch events should not prevent gestures installed above WKWebView from recognizing
+        https://bugs.webkit.org/show_bug.cgi?id=210080
+        <rdar://problem/61365814>
+
+        Reviewed by Tim Horton.
+
+        Add a new layout test to verify that calling preventDefault() on touchstart doesn't prevent gesture recognizers
+        installed above the WKWebView from recognizing. To do this, we use the new UIScriptController method to add a
+        gesture recognizer to the window containing the web view, and then simulate a tap over an element that prevents
+        the touchstart event.
+
+        * fast/events/touch/ios/prevent-default-with-window-tap-gesture-expected.txt: Added.
+        * fast/events/touch/ios/prevent-default-with-window-tap-gesture.html: Added.
+        * resources/ui-helper.js:
+        (window.UIHelper.async activateElementAfterInstallingTapGestureOnWindow.return.new.Promise.):
+        (window.UIHelper.async activateElementAfterInstallingTapGestureOnWindow.return.new.Promise):
+        (window.UIHelper.async activateElementAfterInstallingTapGestureOnWindow):
+        (window.UIHelper):
+
</ins><span class="cx"> 2020-04-07  Truitt Savell  <tsavell@apple.com>
</span><span class="cx"> 
</span><span class="cx">         Fix my conflict Markers
</span></span></pre></div>
<a id="trunkLayoutTestsfasteventstouchiospreventdefaultwithwindowtapgestureexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/events/touch/ios/prevent-default-with-window-tap-gesture-expected.txt (0 => 259669)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/events/touch/ios/prevent-default-with-window-tap-gesture-expected.txt                             (rev 0)
+++ trunk/LayoutTests/fast/events/touch/ios/prevent-default-with-window-tap-gesture-expected.txt        2020-04-07 21:00:49 UTC (rev 259669)
</span><span class="lines">@@ -0,0 +1,11 @@
</span><ins>+This test verifies that a gesture recognizer installed on the window containing the web view is not prevented from recognizing if the web page prevents default on touchstart. This test requires WebKitTestRunner.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS Tap gesture on window recognized
+PASS receivedTouchStart is true
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestsfasteventstouchiospreventdefaultwithwindowtapgesturehtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/events/touch/ios/prevent-default-with-window-tap-gesture.html (0 => 259669)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/events/touch/ios/prevent-default-with-window-tap-gesture.html                             (rev 0)
+++ trunk/LayoutTests/fast/events/touch/ios/prevent-default-with-window-tap-gesture.html        2020-04-07 21:00:49 UTC (rev 259669)
</span><span class="lines">@@ -0,0 +1,36 @@
</span><ins>+<!DOCTYPE html>
+<html>
+<head>
+<script src="../../../../resources/js-test.js"></script>
+<script src="../../../../resources/ui-helper.js"></script>
+<style>
+    #target {
+        border: solid 1px tomato;
+        width: 200px;
+        height: 200px;
+    }
+</style>
+<script>
+    jsTestIsAsync = true;
+
+    addEventListener("load", async () => {
+        description("This test verifies that a gesture recognizer installed on the window containing the web view is not prevented from recognizing if the web page prevents default on touchstart. This test requires WebKitTestRunner.");
+
+        receivedTouchStart = false;
+        const target = document.getElementById("target");
+        target.addEventListener("touchstart", event => {
+            receivedTouchStart = true;
+            event.preventDefault();
+        });
+        await UIHelper.activateElementAfterInstallingTapGestureOnWindow(target);
+
+        testPassed("Tap gesture on window recognized");
+        shouldBeTrue("receivedTouchStart");
+        finishJSTest();
+    });
+</script>
+</head>
+<body>
+    <div id="target"></div>
+</body>
+</html>
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="trunkLayoutTestsresourcesuihelperjs"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/resources/ui-helper.js (259668 => 259669)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/resources/ui-helper.js 2020-04-07 20:49:06 UTC (rev 259668)
+++ trunk/LayoutTests/resources/ui-helper.js    2020-04-07 21:00:49 UTC (rev 259669)
</span><span class="lines">@@ -1148,6 +1148,27 @@
</span><span class="cx">                 })();`, resolve);
</span><span class="cx">         });
</span><span class="cx">     }
</span><ins>+
+    static async activateElementAfterInstallingTapGestureOnWindow(element)
+    {
+        if (!this.isWebKit2() || !this.isIOSFamily())
+            return activateElement(element);
+
+        const x = element.offsetLeft + element.offsetWidth / 2;
+        const y = element.offsetTop + element.offsetHeight / 2;
+        return new Promise(resolve => {
+            testRunner.runUIScript(`
+                (function() {
+                    let progress = 0;
+                    function incrementProgress() {
+                        if (++progress == 2)
+                            uiController.uiScriptComplete();
+                    }
+                    uiController.installTapGestureOnWindow(incrementProgress);
+                    uiController.singleTapAtPoint(${x}, ${y}, incrementProgress);
+                })();`, resolve);
+        });
+    }
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> UIHelper.EventStreamBuilder = class {
</span></span></pre></div>
<a id="trunkSourceWebKitChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/ChangeLog (259668 => 259669)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/ChangeLog    2020-04-07 20:49:06 UTC (rev 259668)
+++ trunk/Source/WebKit/ChangeLog       2020-04-07 21:00:49 UTC (rev 259669)
</span><span class="lines">@@ -1,3 +1,21 @@
</span><ins>+2020-04-07  Wenson Hsieh  <wenson_hsieh@apple.com>
+
+        Preventing touch events should not prevent gestures installed above WKWebView from recognizing
+        https://bugs.webkit.org/show_bug.cgi?id=210080
+        <rdar://problem/61365814>
+
+        Reviewed by Tim Horton.
+
+        Makes a small adjustment to native gesture deferral logic, so that gestures installed above WKWebView (in the
+        view hierarchy) are not prevented from recognizing by WKDeferringGestureRecognizer. This makes it possible for
+        WebKit clients to install custom gestures outside of WKWebView that cannot be prevented by web content, without
+        having to create a separate window and pass touches through to the WKWebView.
+
+        Test: fast/events/touch/ios/prevent-default-with-window-tap-gesture.html
+
+        * UIProcess/ios/WKContentViewInteraction.mm:
+        (-[WKContentView deferringGestureRecognizer:shouldDeferOtherGestureRecognizer:]):
+
</ins><span class="cx"> 2020-04-07  Brian Burg  <bburg@apple.com>
</span><span class="cx"> 
</span><span class="cx">         Web Automation: Automation.inspectBrowsingContext should bring Web Inspector to front automatically
</span></span></pre></div>
<a id="trunkSourceWebKitUIProcessiosWKContentViewInteractionmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm (259668 => 259669)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm    2020-04-07 20:49:06 UTC (rev 259668)
+++ trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm       2020-04-07 21:00:49 UTC (rev 259669)
</span><span class="lines">@@ -6939,6 +6939,20 @@
</span><span class="cx">     if ([_webView _isNavigationSwipeGestureRecognizer:gestureRecognizer])
</span><span class="cx">         return NO;
</span><span class="cx"> 
</span><ins>+    auto webView = _webView.getAutoreleased();
+    auto view = gestureRecognizer.view;
+    BOOL gestureIsInstalledOnOrUnderWebView = NO;
+    while (view) {
+        if (view == webView) {
+            gestureIsInstalledOnOrUnderWebView = YES;
+            break;
+        }
+        view = view.superview;
+    }
+
+    if (!gestureIsInstalledOnOrUnderWebView)
+        return NO;
+
</ins><span class="cx"> #if ENABLE(IOS_TOUCH_EVENTS)
</span><span class="cx">     auto isOneFingerMultipleTapGesture = [](UIGestureRecognizer *gesture) -> BOOL {
</span><span class="cx">         if (![gesture isKindOfClass:UITapGestureRecognizer.class])
</span></span></pre></div>
<a id="trunkToolsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Tools/ChangeLog (259668 => 259669)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/ChangeLog    2020-04-07 20:49:06 UTC (rev 259668)
+++ trunk/Tools/ChangeLog       2020-04-07 21:00:49 UTC (rev 259669)
</span><span class="lines">@@ -1,3 +1,32 @@
</span><ins>+2020-04-07  Wenson Hsieh  <wenson_hsieh@apple.com>
+
+        Preventing touch events should not prevent gestures installed above WKWebView from recognizing
+        https://bugs.webkit.org/show_bug.cgi?id=210080
+        <rdar://problem/61365814>
+
+        Reviewed by Tim Horton.
+
+        Add a UIScriptController helper method that allows a test to install a tap gesture recognizer on the UIWindow
+        containing the web view. This method additionally takes a JavaScript callback, which is invoked when the tap
+        gesture is recognized.
+
+        * TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl:
+        * TestRunnerShared/UIScriptContext/UIScriptContext.h:
+        * TestRunnerShared/UIScriptContext/UIScriptController.h:
+        (WTR::UIScriptController::installTapGestureOnWindow):
+        * WebKitTestRunner/cocoa/TestRunnerWKWebView.h:
+        * WebKitTestRunner/cocoa/TestRunnerWKWebView.mm:
+        (-[TestRunnerWKWebView resetInteractionCallbacks]):
+        (-[TestRunnerWKWebView didRecognizeTapOnWindow]):
+        (-[TestRunnerWKWebView windowTapRecognizedCallback]):
+        (-[TestRunnerWKWebView setWindowTapRecognizedCallback:]):
+        (-[TestRunnerWKWebView willMoveToWindow:]):
+        (-[TestRunnerWKWebView didMoveToWindow]):
+        (-[TestRunnerWKWebView gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer:]):
+        * WebKitTestRunner/ios/UIScriptControllerIOS.h:
+        * WebKitTestRunner/ios/UIScriptControllerIOS.mm:
+        (WTR::UIScriptControllerIOS::installTapGestureOnWindow):
+
</ins><span class="cx"> 2020-04-07  Alexey Shvayka  <shvaikalesh@gmail.com>
</span><span class="cx"> 
</span><span class="cx">         test262/Runner.pm ignores "async" flag
</span></span></pre></div>
<a id="trunkToolsTestRunnerSharedUIScriptContextBindingsUIScriptControlleridl"></a>
<div class="modfile"><h4>Modified: trunk/Tools/TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl (259668 => 259669)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl     2020-04-07 20:49:06 UTC (rev 259668)
+++ trunk/Tools/TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl        2020-04-07 21:00:49 UTC (rev 259669)
</span><span class="lines">@@ -322,6 +322,8 @@
</span><span class="cx">     void removeViewFromWindow(object callback);
</span><span class="cx">     void addViewToWindow(object callback);
</span><span class="cx"> 
</span><ins>+    void installTapGestureOnWindow(object callback);
+
</ins><span class="cx">     void overridePreference(DOMString preference, DOMString value);
</span><span class="cx"> 
</span><span class="cx">     void setSafeAreaInsets(double top, double right, double bottom, double left);
</span></span></pre></div>
<a id="trunkToolsTestRunnerSharedUIScriptContextUIScriptContexth"></a>
<div class="modfile"><h4>Modified: trunk/Tools/TestRunnerShared/UIScriptContext/UIScriptContext.h (259668 => 259669)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/TestRunnerShared/UIScriptContext/UIScriptContext.h   2020-04-07 20:49:06 UTC (rev 259668)
+++ trunk/Tools/TestRunnerShared/UIScriptContext/UIScriptContext.h      2020-04-07 21:00:49 UTC (rev 259669)
</span><span class="lines">@@ -64,6 +64,7 @@
</span><span class="cx">     CallbackTypeDidShowContextMenu,
</span><span class="cx">     CallbackTypeDidDismissContextMenu,
</span><span class="cx">     CallbackTypeWillCreateNewPage,
</span><ins>+    CallbackTypeWindowTapRecognized,
</ins><span class="cx">     CallbackTypeNonPersistent = firstNonPersistentCallbackID
</span><span class="cx"> } CallbackType;
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkToolsTestRunnerSharedUIScriptContextUIScriptControllerh"></a>
<div class="modfile"><h4>Modified: trunk/Tools/TestRunnerShared/UIScriptContext/UIScriptController.h (259668 => 259669)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/TestRunnerShared/UIScriptContext/UIScriptController.h        2020-04-07 20:49:06 UTC (rev 259668)
+++ trunk/Tools/TestRunnerShared/UIScriptContext/UIScriptController.h   2020-04-07 21:00:49 UTC (rev 259669)
</span><span class="lines">@@ -117,6 +117,8 @@
</span><span class="cx">     virtual void removeViewFromWindow(JSValueRef) { notImplemented(); }
</span><span class="cx">     virtual void addViewToWindow(JSValueRef) { notImplemented(); }
</span><span class="cx"> 
</span><ins>+    virtual void installTapGestureOnWindow(JSValueRef) { notImplemented(); }
+
</ins><span class="cx">     // Compositing
</span><span class="cx"> 
</span><span class="cx">     virtual JSObjectRef propertiesOfLayerWithID(uint64_t layerID) const { notImplemented(); return nullptr; }
</span></span></pre></div>
<a id="trunkToolsWebKitTestRunnercocoaTestRunnerWKWebViewh"></a>
<div class="modfile"><h4>Modified: trunk/Tools/WebKitTestRunner/cocoa/TestRunnerWKWebView.h (259668 => 259669)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/WebKitTestRunner/cocoa/TestRunnerWKWebView.h 2020-04-07 20:49:06 UTC (rev 259668)
+++ trunk/Tools/WebKitTestRunner/cocoa/TestRunnerWKWebView.h    2020-04-07 21:00:49 UTC (rev 259669)
</span><span class="lines">@@ -45,6 +45,7 @@
</span><span class="cx"> @property (nonatomic, copy) void (^didDismissPopoverCallback)(void);
</span><span class="cx"> @property (nonatomic, copy) void (^didEndScrollingCallback)(void);
</span><span class="cx"> @property (nonatomic, copy) void (^rotationDidEndCallback)(void);
</span><ins>+@property (nonatomic, copy) void (^windowTapRecognizedCallback)(void);
</ins><span class="cx"> @property (nonatomic, copy) NSString *accessibilitySpeakSelectionContent;
</span><span class="cx"> 
</span><span class="cx"> - (void)setAllowedMenuActions:(NSArray<NSString *> *)actions;
</span></span></pre></div>
<a id="trunkToolsWebKitTestRunnercocoaTestRunnerWKWebViewmm"></a>
<div class="modfile"><h4>Modified: trunk/Tools/WebKitTestRunner/cocoa/TestRunnerWKWebView.mm (259668 => 259669)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/WebKitTestRunner/cocoa/TestRunnerWKWebView.mm        2020-04-07 20:49:06 UTC (rev 259668)
+++ trunk/Tools/WebKitTestRunner/cocoa/TestRunnerWKWebView.mm   2020-04-07 21:00:49 UTC (rev 259669)
</span><span class="lines">@@ -55,12 +55,20 @@
</span><span class="cx">     BlockPtr<void()> callback;
</span><span class="cx"> };
</span><span class="cx"> 
</span><del>-@interface TestRunnerWKWebView () <WKUIDelegatePrivate> {
</del><ins>+@interface TestRunnerWKWebView () <WKUIDelegatePrivate
+#if PLATFORM(IOS_FAMILY)
+    , UIGestureRecognizerDelegate
+#endif
+> {
</ins><span class="cx">     RetainPtr<NSNumber> m_stableStateOverride;
</span><span class="cx">     BOOL _isInteractingWithFormControl;
</span><span class="cx">     BOOL _scrollingUpdatesDisabled;
</span><span class="cx">     Optional<CustomMenuActionInfo> _customMenuActionInfo;
</span><span class="cx">     RetainPtr<NSArray<NSString *>> _allowedMenuActions;
</span><ins>+#if PLATFORM(IOS_FAMILY)
+    RetainPtr<UITapGestureRecognizer> _windowTapGestureRecognizer;
+    BlockPtr<void()> _windowTapRecognizedCallback;
+#endif
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> @property (nonatomic, copy) void (^zoomToScaleCompletionHandler)(void);
</span><span class="lines">@@ -172,6 +180,7 @@
</span><span class="cx">     self.didDismissPopoverCallback = nil;
</span><span class="cx">     self.didEndScrollingCallback = nil;
</span><span class="cx">     self.rotationDidEndCallback = nil;
</span><ins>+    self.windowTapRecognizedCallback = nil;
</ins><span class="cx"> #endif // PLATFORM(IOS_FAMILY)
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -409,6 +418,50 @@
</span><span class="cx">         self.rotationDidEndCallback();
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+- (void)didRecognizeTapOnWindow
+{
+    ASSERT(self.windowTapRecognizedCallback);
+    if (self.windowTapRecognizedCallback)
+        self.windowTapRecognizedCallback();
+}
+
+- (void(^)())windowTapRecognizedCallback
+{
+    return _windowTapRecognizedCallback.get();
+}
+
+- (void)setWindowTapRecognizedCallback:(void(^)())windowTapRecognizedCallback
+{
+    _windowTapRecognizedCallback = windowTapRecognizedCallback;
+
+    if (windowTapRecognizedCallback && !_windowTapGestureRecognizer) {
+        ASSERT(self.window);
+        _windowTapGestureRecognizer = adoptNS([[UITapGestureRecognizer alloc] init]);
+        [_windowTapGestureRecognizer setDelegate:self];
+        [_windowTapGestureRecognizer addTarget:self action:@selector(didRecognizeTapOnWindow)];
+        [self.window addGestureRecognizer:_windowTapGestureRecognizer.get()];
+    } else if (!windowTapRecognizedCallback && _windowTapGestureRecognizer) {
+        [self.window removeGestureRecognizer:_windowTapGestureRecognizer.get()];
+        _windowTapGestureRecognizer = nil;
+    }
+}
+
+- (void)willMoveToWindow:(UIWindow *)window
+{
+    [super willMoveToWindow:window];
+
+    if (_windowTapGestureRecognizer)
+        [self.window removeGestureRecognizer:_windowTapGestureRecognizer.get()];
+}
+
+- (void)didMoveToWindow
+{
+    [super didMoveToWindow];
+
+    if (_windowTapGestureRecognizer)
+        [self.window addGestureRecognizer:_windowTapGestureRecognizer.get()];
+}
+
</ins><span class="cx"> - (void)_accessibilityDidGetSpeakSelectionContent:(NSString *)content
</span><span class="cx"> {
</span><span class="cx">     self.accessibilitySpeakSelectionContent = content;
</span><span class="lines">@@ -449,6 +502,13 @@
</span><span class="cx">     [self _invokeHideKeyboardCallbackIfNecessary];
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+#pragma mark - UIGestureRecognizerDelegate
+
+- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
+{
+    return gestureRecognizer == _windowTapGestureRecognizer;
+}
+
</ins><span class="cx"> #endif // PLATFORM(IOS_FAMILY)
</span><span class="cx"> 
</span><span class="cx"> @end
</span></span></pre></div>
<a id="trunkToolsWebKitTestRunneriosUIScriptControllerIOSh"></a>
<div class="modfile"><h4>Modified: trunk/Tools/WebKitTestRunner/ios/UIScriptControllerIOS.h (259668 => 259669)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/WebKitTestRunner/ios/UIScriptControllerIOS.h 2020-04-07 20:49:06 UTC (rev 259668)
+++ trunk/Tools/WebKitTestRunner/ios/UIScriptControllerIOS.h    2020-04-07 21:00:49 UTC (rev 259669)
</span><span class="lines">@@ -140,6 +140,7 @@
</span><span class="cx">     void setHardwareKeyboardAttached(bool) override;
</span><span class="cx">     void setAllowsViewportShrinkToFit(bool) override;
</span><span class="cx">     void copyText(JSStringRef) override;
</span><ins>+    void installTapGestureOnWindow(JSValueRef) override;
</ins><span class="cx"> 
</span><span class="cx">     void setDidStartFormControlInteractionCallback(JSValueRef) override;
</span><span class="cx">     void setDidEndFormControlInteractionCallback(JSValueRef) override;
</span></span></pre></div>
<a id="trunkToolsWebKitTestRunneriosUIScriptControllerIOSmm"></a>
<div class="modfile"><h4>Modified: trunk/Tools/WebKitTestRunner/ios/UIScriptControllerIOS.mm (259668 => 259669)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/WebKitTestRunner/ios/UIScriptControllerIOS.mm        2020-04-07 20:49:06 UTC (rev 259668)
+++ trunk/Tools/WebKitTestRunner/ios/UIScriptControllerIOS.mm   2020-04-07 21:00:49 UTC (rev 259669)
</span><span class="lines">@@ -1263,6 +1263,16 @@
</span><span class="cx">     UIPasteboard.generalPasteboard.string = text->string();
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void UIScriptControllerIOS::installTapGestureOnWindow(JSValueRef callback)
+{
+    m_context->registerCallback(callback, CallbackTypeWindowTapRecognized);
+    webView().windowTapRecognizedCallback = makeBlockPtr([this, strongThis = makeRef(*this)] {
+        if (!m_context)
+            return;
+        m_context->fireCallback(CallbackTypeWindowTapRecognized);
+    }).get();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><ins>+}
+
</ins><span class="cx"> #endif // PLATFORM(IOS_FAMILY)
</span></span></pre>
</div>
</div>

</body>
</html>