<!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>[265595] branches/safari-610.1-branch</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/265595">265595</a></dd>
<dt>Author</dt> <dd>alancoon@apple.com</dd>
<dt>Date</dt> <dd>2020-08-12 18:46:40 -0700 (Wed, 12 Aug 2020)</dd>
</dl>

<h3>Log Message</h3>
<pre>Cherry-pick <a href="http://trac.webkit.org/projects/webkit/changeset/265515">r265515</a>. rdar://problem/66943894

    iOS: Scrolling and touch events sporadically stop working after navigating
    https://bugs.webkit.org/show_bug.cgi?id=215368
    <rdar://problem/65801531>

    Reviewed by Wenson Hsieh.

    Source/WebKit:

    Test: fast/events/touch/ios/touch-event-stall-after-navigating-with-pending-asynchronous-touch-start.html

    WebPageProxy::handlePreventableTouchEvent keeps a counter of the number
    of outstanding "preventable" touch events that it is waiting to hear
    from the Web Content process about. This counter is incremented when the
    event is dispatched to the Web Content process's EventHandler queue,
    and decremented when the reply (whether it was handled or not) comes
    back from the Web Content process. While the counter is non-zero, all
    deferrable gestures remain deferred (and when it returns to zero, the
    WKDeferringGestureRecognizer gate is lifted, and events are allowed to flow).
    This means that it is very important that every event eventually reply
    about its handling status.

    Before this change, when the Web Content process is navigating, and reaches didCommitLoad,
    it cleared all queued touch events, without replying to to the UI process.
    Thus, there is a small window of time in which an incoming touch event will
    end up in the queue, *not* get dispatched/replied, and then get dropped on
    the floor in didCommitLoad. Most events do not meet this fate, because they
    are handled promptly, and commitLoad/didCommitLoad tend to be very quick.
    However, if the Web Content process ends up spending any significant amount
    of time under commitLoad (say, in an unload handler, or in media frameworks),
    any incoming touch events during that time will get lost, and the UI process'
    count of outstanding events will end up getting stuck non-zero.

    Fix this by always pretending that the page ate any events that were outstanding
    when didCommitLoad occurs, instead of just dropping them on the floor.

    * UIProcess/ios/PageClientImplIOS.mm:
    (WebKit::PageClientImpl::doneWithTouchEvent):
    * WebProcess/WebPage/EventDispatcher.cpp:
    (WebKit::EventDispatcher::takeQueuedTouchEventsForPage):
    (WebKit::EventDispatcher::clearQueuedTouchEventsForPage): Deleted.
    (WebKit::EventDispatcher::getQueuedTouchEventsForPage): Deleted.
    Also, rename getQueuedTouchEventsForPage to takeQueuedTouchEventsForPage,
    since it removes the queue from EventDispatcher's set.

    * WebProcess/WebPage/EventDispatcher.h:
    * WebProcess/WebPage/WebPage.cpp:
    (WebKit::WebPage::touchEventSync):
    (WebKit::WebPage::didCommitLoad):
    * WebProcess/WebPage/WebPage.h:
    * WebProcess/WebPage/ios/WebPageIOS.mm:
    (WebKit::WebPage::cancelAsynchronousTouchEvents):

    Tools:

    * WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl:
    * WebKitTestRunner/InjectedBundle/TestRunner.cpp:
    (WTR::TestRunner::runUIScriptImmediately):
    * WebKitTestRunner/InjectedBundle/TestRunner.h:
    * WebKitTestRunner/TestInvocation.cpp:
    (WTR::TestInvocation::didReceiveMessageFromInjectedBundle):
    (WTR::TestInvocation::runUISideScriptImmediately):
    (WTR::TestInvocation::runUISideScriptAfterUpdateCallback):
    * WebKitTestRunner/TestInvocation.h:
    Add a variant of runUISideScript that runs the script without
    waiting for a rendering update.

    It makes sense for the default runUISideScript to wait for a rendering
    update -- nearly every test is either unaffected or improved by this --
    but for the test for this bug, since we have hung the Web Content process
    main thread intentionally, we will not see a rendering update, and so
    the UI-side script will never run.

    LayoutTests:

    * fast/events/touch/ios/resources/finish-test-after-scrolling-with-touch-event-handlers.html: Added.
    * fast/events/touch/ios/touch-event-stall-after-navigating-with-pending-asynchronous-touch-start-expected.txt: Added.
    * fast/events/touch/ios/touch-event-stall-after-navigating-with-pending-asynchronous-touch-start.html: Added.
    Add a test that ensures that a page that dispatches events in beforeunload,
    receiving preventable touch events during the next page's commitLoad does not result
    in scrolling being stuck.

    Before this change, this test would time out.

    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@265515 268f45cc-cd09-0410-ab3c-d52691b4dbfc</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#branchessafari6101branchLayoutTestsChangeLog">branches/safari-610.1-branch/LayoutTests/ChangeLog</a></li>
<li><a href="#branchessafari6101branchSourceWebKitChangeLog">branches/safari-610.1-branch/Source/WebKit/ChangeLog</a></li>
<li><a href="#branchessafari6101branchSourceWebKitUIProcessiosPageClientImplIOSmm">branches/safari-610.1-branch/Source/WebKit/UIProcess/ios/PageClientImplIOS.mm</a></li>
<li><a href="#branchessafari6101branchSourceWebKitWebProcessWebPageEventDispatchercpp">branches/safari-610.1-branch/Source/WebKit/WebProcess/WebPage/EventDispatcher.cpp</a></li>
<li><a href="#branchessafari6101branchSourceWebKitWebProcessWebPageEventDispatcherh">branches/safari-610.1-branch/Source/WebKit/WebProcess/WebPage/EventDispatcher.h</a></li>
<li><a href="#branchessafari6101branchSourceWebKitWebProcessWebPageWebPagecpp">branches/safari-610.1-branch/Source/WebKit/WebProcess/WebPage/WebPage.cpp</a></li>
<li><a href="#branchessafari6101branchSourceWebKitWebProcessWebPageWebPageh">branches/safari-610.1-branch/Source/WebKit/WebProcess/WebPage/WebPage.h</a></li>
<li><a href="#branchessafari6101branchSourceWebKitWebProcessWebPageiosWebPageIOSmm">branches/safari-610.1-branch/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm</a></li>
<li><a href="#branchessafari6101branchToolsChangeLog">branches/safari-610.1-branch/Tools/ChangeLog</a></li>
<li><a href="#branchessafari6101branchToolsWebKitTestRunnerInjectedBundleBindingsTestRunneridl">branches/safari-610.1-branch/Tools/WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl</a></li>
<li><a href="#branchessafari6101branchToolsWebKitTestRunnerInjectedBundleTestRunnercpp">branches/safari-610.1-branch/Tools/WebKitTestRunner/InjectedBundle/TestRunner.cpp</a></li>
<li><a href="#branchessafari6101branchToolsWebKitTestRunnerInjectedBundleTestRunnerh">branches/safari-610.1-branch/Tools/WebKitTestRunner/InjectedBundle/TestRunner.h</a></li>
<li><a href="#branchessafari6101branchToolsWebKitTestRunnerTestInvocationcpp">branches/safari-610.1-branch/Tools/WebKitTestRunner/TestInvocation.cpp</a></li>
<li><a href="#branchessafari6101branchToolsWebKitTestRunnerTestInvocationh">branches/safari-610.1-branch/Tools/WebKitTestRunner/TestInvocation.h</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li>branches/safari-610.1-branch/LayoutTests/fast/events/touch/ios/resources/</li>
<li><a href="#branchessafari6101branchLayoutTestsfasteventstouchiosresourcesfinishtestafterscrollingwithtoucheventhandlershtml">branches/safari-610.1-branch/LayoutTests/fast/events/touch/ios/resources/finish-test-after-scrolling-with-touch-event-handlers.html</a></li>
<li><a href="#branchessafari6101branchLayoutTestsfasteventstouchiostoucheventstallafternavigatingwithpendingasynchronoustouchstartexpectedtxt">branches/safari-610.1-branch/LayoutTests/fast/events/touch/ios/touch-event-stall-after-navigating-with-pending-asynchronous-touch-start-expected.txt</a></li>
<li><a href="#branchessafari6101branchLayoutTestsfasteventstouchiostoucheventstallafternavigatingwithpendingasynchronoustouchstarthtml">branches/safari-610.1-branch/LayoutTests/fast/events/touch/ios/touch-event-stall-after-navigating-with-pending-asynchronous-touch-start.html</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="branchessafari6101branchLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: branches/safari-610.1-branch/LayoutTests/ChangeLog (265594 => 265595)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-610.1-branch/LayoutTests/ChangeLog       2020-08-13 01:46:36 UTC (rev 265594)
+++ branches/safari-610.1-branch/LayoutTests/ChangeLog  2020-08-13 01:46:40 UTC (rev 265595)
</span><span class="lines">@@ -1,5 +1,112 @@
</span><span class="cx"> 2020-08-12  Alan Coon  <alancoon@apple.com>
</span><span class="cx"> 
</span><ins>+        Cherry-pick r265515. rdar://problem/66943894
+
+    iOS: Scrolling and touch events sporadically stop working after navigating
+    https://bugs.webkit.org/show_bug.cgi?id=215368
+    <rdar://problem/65801531>
+    
+    Reviewed by Wenson Hsieh.
+    
+    Source/WebKit:
+    
+    Test: fast/events/touch/ios/touch-event-stall-after-navigating-with-pending-asynchronous-touch-start.html
+    
+    WebPageProxy::handlePreventableTouchEvent keeps a counter of the number
+    of outstanding "preventable" touch events that it is waiting to hear
+    from the Web Content process about. This counter is incremented when the
+    event is dispatched to the Web Content process's EventHandler queue,
+    and decremented when the reply (whether it was handled or not) comes
+    back from the Web Content process. While the counter is non-zero, all
+    deferrable gestures remain deferred (and when it returns to zero, the
+    WKDeferringGestureRecognizer gate is lifted, and events are allowed to flow).
+    This means that it is very important that every event eventually reply
+    about its handling status.
+    
+    Before this change, when the Web Content process is navigating, and reaches didCommitLoad,
+    it cleared all queued touch events, without replying to to the UI process.
+    Thus, there is a small window of time in which an incoming touch event will
+    end up in the queue, *not* get dispatched/replied, and then get dropped on
+    the floor in didCommitLoad. Most events do not meet this fate, because they
+    are handled promptly, and commitLoad/didCommitLoad tend to be very quick.
+    However, if the Web Content process ends up spending any significant amount
+    of time under commitLoad (say, in an unload handler, or in media frameworks),
+    any incoming touch events during that time will get lost, and the UI process'
+    count of outstanding events will end up getting stuck non-zero.
+    
+    Fix this by always pretending that the page ate any events that were outstanding
+    when didCommitLoad occurs, instead of just dropping them on the floor.
+    
+    * UIProcess/ios/PageClientImplIOS.mm:
+    (WebKit::PageClientImpl::doneWithTouchEvent):
+    * WebProcess/WebPage/EventDispatcher.cpp:
+    (WebKit::EventDispatcher::takeQueuedTouchEventsForPage):
+    (WebKit::EventDispatcher::clearQueuedTouchEventsForPage): Deleted.
+    (WebKit::EventDispatcher::getQueuedTouchEventsForPage): Deleted.
+    Also, rename getQueuedTouchEventsForPage to takeQueuedTouchEventsForPage,
+    since it removes the queue from EventDispatcher's set.
+    
+    * WebProcess/WebPage/EventDispatcher.h:
+    * WebProcess/WebPage/WebPage.cpp:
+    (WebKit::WebPage::touchEventSync):
+    (WebKit::WebPage::didCommitLoad):
+    * WebProcess/WebPage/WebPage.h:
+    * WebProcess/WebPage/ios/WebPageIOS.mm:
+    (WebKit::WebPage::cancelAsynchronousTouchEvents):
+    
+    Tools:
+    
+    * WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl:
+    * WebKitTestRunner/InjectedBundle/TestRunner.cpp:
+    (WTR::TestRunner::runUIScriptImmediately):
+    * WebKitTestRunner/InjectedBundle/TestRunner.h:
+    * WebKitTestRunner/TestInvocation.cpp:
+    (WTR::TestInvocation::didReceiveMessageFromInjectedBundle):
+    (WTR::TestInvocation::runUISideScriptImmediately):
+    (WTR::TestInvocation::runUISideScriptAfterUpdateCallback):
+    * WebKitTestRunner/TestInvocation.h:
+    Add a variant of runUISideScript that runs the script without
+    waiting for a rendering update.
+    
+    It makes sense for the default runUISideScript to wait for a rendering
+    update -- nearly every test is either unaffected or improved by this --
+    but for the test for this bug, since we have hung the Web Content process
+    main thread intentionally, we will not see a rendering update, and so
+    the UI-side script will never run.
+    
+    LayoutTests:
+    
+    * fast/events/touch/ios/resources/finish-test-after-scrolling-with-touch-event-handlers.html: Added.
+    * fast/events/touch/ios/touch-event-stall-after-navigating-with-pending-asynchronous-touch-start-expected.txt: Added.
+    * fast/events/touch/ios/touch-event-stall-after-navigating-with-pending-asynchronous-touch-start.html: Added.
+    Add a test that ensures that a page that dispatches events in beforeunload,
+    receiving preventable touch events during the next page's commitLoad does not result
+    in scrolling being stuck.
+    
+    Before this change, this test would time out.
+    
+    
+    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@265515 268f45cc-cd09-0410-ab3c-d52691b4dbfc
+
+    2020-08-11  Tim Horton  <timothy_horton@apple.com>
+
+            iOS: Scrolling and touch events sporadically stop working after navigating
+            https://bugs.webkit.org/show_bug.cgi?id=215368
+            <rdar://problem/65801531>
+
+            Reviewed by Wenson Hsieh.
+
+            * fast/events/touch/ios/resources/finish-test-after-scrolling-with-touch-event-handlers.html: Added.
+            * fast/events/touch/ios/touch-event-stall-after-navigating-with-pending-asynchronous-touch-start-expected.txt: Added.
+            * fast/events/touch/ios/touch-event-stall-after-navigating-with-pending-asynchronous-touch-start.html: Added.
+            Add a test that ensures that a page that dispatches events in beforeunload,
+            receiving preventable touch events during the next page's commitLoad does not result
+            in scrolling being stuck.
+
+            Before this change, this test would time out.
+
+2020-08-12  Alan Coon  <alancoon@apple.com>
+
</ins><span class="cx">         Cherry-pick r265422. rdar://problem/66945359
</span><span class="cx"> 
</span><span class="cx">     [macOS] Drag/drop an image of a unsupported format to an file input element should convert it to a supported format
</span></span></pre></div>
<a id="branchessafari6101branchLayoutTestsfasteventstouchiosresourcesfinishtestafterscrollingwithtoucheventhandlershtml"></a>
<div class="addfile"><h4>Added: branches/safari-610.1-branch/LayoutTests/fast/events/touch/ios/resources/finish-test-after-scrolling-with-touch-event-handlers.html (0 => 265595)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-610.1-branch/LayoutTests/fast/events/touch/ios/resources/finish-test-after-scrolling-with-touch-event-handlers.html                              (rev 0)
+++ branches/safari-610.1-branch/LayoutTests/fast/events/touch/ios/resources/finish-test-after-scrolling-with-touch-event-handlers.html 2020-08-13 01:46:40 UTC (rev 265595)
</span><span class="lines">@@ -0,0 +1,54 @@
</span><ins>+<!DOCTYPE html> <!-- webkit-test-runner [ useFlexibleViewport=true internal:AsyncOverflowScrollingEnabled=true ] -->
+<html>
+<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
+<head>
+    <script src="../../../../../resources/ui-helper.js"></script>
+    <style>
+    html, body {
+        width: 100%;
+        height: 100%;
+        margin: 0;
+    }
+
+    #scroller {
+        overflow: scroll;
+        width: 200px;
+        height: 200px;
+        border: 2px solid black;
+    }
+
+    #content {
+        width: 100%;
+        height: 1000px;
+    }
+    </style>
+    <script>
+        async function finishTest() {
+            const scroller = document.getElementById("scroller");
+            scroller.addEventListener("touchstart", () => { });
+            scroller.addEventListener("touchend", () => { });
+            scroller.addEventListener("scroll", () => { 
+                content.textContent = "Scrolled!";
+                testRunner.notifyDone()
+            }, { once : true });
+
+            const eventStreamData = new UIHelper.EventStreamBuilder()
+                .begin(100, 190)
+                .move(100, 10, 1)
+                .move(100, 190, 1)
+                .move(100, 100, 0.5)
+                .end()
+                .takeResult();
+
+            await UIHelper.sendEventStream(eventStreamData);
+        }
+
+        addEventListener("load", finishTest);
+    </script>
+</head>
+<body>
+    <div id="scroller">
+        <div id="content"></div>
+    </div>
+</body>
+</html>
</ins></span></pre></div>
<a id="branchessafari6101branchLayoutTestsfasteventstouchiostoucheventstallafternavigatingwithpendingasynchronoustouchstartexpectedtxt"></a>
<div class="addfile"><h4>Added: branches/safari-610.1-branch/LayoutTests/fast/events/touch/ios/touch-event-stall-after-navigating-with-pending-asynchronous-touch-start-expected.txt (0 => 265595)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-610.1-branch/LayoutTests/fast/events/touch/ios/touch-event-stall-after-navigating-with-pending-asynchronous-touch-start-expected.txt                             (rev 0)
+++ branches/safari-610.1-branch/LayoutTests/fast/events/touch/ios/touch-event-stall-after-navigating-with-pending-asynchronous-touch-start-expected.txt        2020-08-13 01:46:40 UTC (rev 265595)
</span><span class="lines">@@ -0,0 +1 @@
</span><ins>+Scrolled!
</ins></span></pre></div>
<a id="branchessafari6101branchLayoutTestsfasteventstouchiostoucheventstallafternavigatingwithpendingasynchronoustouchstarthtml"></a>
<div class="addfile"><h4>Added: branches/safari-610.1-branch/LayoutTests/fast/events/touch/ios/touch-event-stall-after-navigating-with-pending-asynchronous-touch-start.html (0 => 265595)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-610.1-branch/LayoutTests/fast/events/touch/ios/touch-event-stall-after-navigating-with-pending-asynchronous-touch-start.html                             (rev 0)
+++ branches/safari-610.1-branch/LayoutTests/fast/events/touch/ios/touch-event-stall-after-navigating-with-pending-asynchronous-touch-start.html        2020-08-13 01:46:40 UTC (rev 265595)
</span><span class="lines">@@ -0,0 +1,33 @@
</span><ins>+<!DOCTYPE html> <!-- webkit-test-runner [ useFlexibleViewport=true internal:AsyncOverflowScrollingEnabled=true ] -->
+<html>
+<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
+<head>
+    <script src="../../../../resources/ui-helper.js"></script>
+    <script>
+        function runTest() {
+            const tapper = document.getElementById("tapper");
+            tapper.addEventListener("touchstart", () => { });
+            tapper.addEventListener("touchend", () => { });
+
+            const x = tapper.offsetLeft + (tapper.offsetWidth / 2);
+            const y = tapper.offsetTop + (tapper.offsetHeight / 2);
+
+            window.onbeforeunload = function() {
+                testRunner.runUIScriptImmediately(`
+                    uiController.doubleTapAtPoint(${x}, ${y}, .01, function() {
+                        uiController.uiScriptComplete();
+                    });`);
+            };
+
+            window.location.href = "resources/finish-test-after-scrolling-with-touch-event-handlers.html";
+        }
+
+        testRunner.dumpAsText();
+        testRunner.waitUntilDone();
+        addEventListener("load", runTest);
+    </script>
+</head>
+<body>
+    <div id="tapper">Tap Here</div>
+</body>
+</html>
</ins></span></pre></div>
<a id="branchessafari6101branchSourceWebKitChangeLog"></a>
<div class="modfile"><h4>Modified: branches/safari-610.1-branch/Source/WebKit/ChangeLog (265594 => 265595)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-610.1-branch/Source/WebKit/ChangeLog     2020-08-13 01:46:36 UTC (rev 265594)
+++ branches/safari-610.1-branch/Source/WebKit/ChangeLog        2020-08-13 01:46:40 UTC (rev 265595)
</span><span class="lines">@@ -1,5 +1,147 @@
</span><span class="cx"> 2020-08-12  Alan Coon  <alancoon@apple.com>
</span><span class="cx"> 
</span><ins>+        Cherry-pick r265515. rdar://problem/66943894
+
+    iOS: Scrolling and touch events sporadically stop working after navigating
+    https://bugs.webkit.org/show_bug.cgi?id=215368
+    <rdar://problem/65801531>
+    
+    Reviewed by Wenson Hsieh.
+    
+    Source/WebKit:
+    
+    Test: fast/events/touch/ios/touch-event-stall-after-navigating-with-pending-asynchronous-touch-start.html
+    
+    WebPageProxy::handlePreventableTouchEvent keeps a counter of the number
+    of outstanding "preventable" touch events that it is waiting to hear
+    from the Web Content process about. This counter is incremented when the
+    event is dispatched to the Web Content process's EventHandler queue,
+    and decremented when the reply (whether it was handled or not) comes
+    back from the Web Content process. While the counter is non-zero, all
+    deferrable gestures remain deferred (and when it returns to zero, the
+    WKDeferringGestureRecognizer gate is lifted, and events are allowed to flow).
+    This means that it is very important that every event eventually reply
+    about its handling status.
+    
+    Before this change, when the Web Content process is navigating, and reaches didCommitLoad,
+    it cleared all queued touch events, without replying to to the UI process.
+    Thus, there is a small window of time in which an incoming touch event will
+    end up in the queue, *not* get dispatched/replied, and then get dropped on
+    the floor in didCommitLoad. Most events do not meet this fate, because they
+    are handled promptly, and commitLoad/didCommitLoad tend to be very quick.
+    However, if the Web Content process ends up spending any significant amount
+    of time under commitLoad (say, in an unload handler, or in media frameworks),
+    any incoming touch events during that time will get lost, and the UI process'
+    count of outstanding events will end up getting stuck non-zero.
+    
+    Fix this by always pretending that the page ate any events that were outstanding
+    when didCommitLoad occurs, instead of just dropping them on the floor.
+    
+    * UIProcess/ios/PageClientImplIOS.mm:
+    (WebKit::PageClientImpl::doneWithTouchEvent):
+    * WebProcess/WebPage/EventDispatcher.cpp:
+    (WebKit::EventDispatcher::takeQueuedTouchEventsForPage):
+    (WebKit::EventDispatcher::clearQueuedTouchEventsForPage): Deleted.
+    (WebKit::EventDispatcher::getQueuedTouchEventsForPage): Deleted.
+    Also, rename getQueuedTouchEventsForPage to takeQueuedTouchEventsForPage,
+    since it removes the queue from EventDispatcher's set.
+    
+    * WebProcess/WebPage/EventDispatcher.h:
+    * WebProcess/WebPage/WebPage.cpp:
+    (WebKit::WebPage::touchEventSync):
+    (WebKit::WebPage::didCommitLoad):
+    * WebProcess/WebPage/WebPage.h:
+    * WebProcess/WebPage/ios/WebPageIOS.mm:
+    (WebKit::WebPage::cancelAsynchronousTouchEvents):
+    
+    Tools:
+    
+    * WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl:
+    * WebKitTestRunner/InjectedBundle/TestRunner.cpp:
+    (WTR::TestRunner::runUIScriptImmediately):
+    * WebKitTestRunner/InjectedBundle/TestRunner.h:
+    * WebKitTestRunner/TestInvocation.cpp:
+    (WTR::TestInvocation::didReceiveMessageFromInjectedBundle):
+    (WTR::TestInvocation::runUISideScriptImmediately):
+    (WTR::TestInvocation::runUISideScriptAfterUpdateCallback):
+    * WebKitTestRunner/TestInvocation.h:
+    Add a variant of runUISideScript that runs the script without
+    waiting for a rendering update.
+    
+    It makes sense for the default runUISideScript to wait for a rendering
+    update -- nearly every test is either unaffected or improved by this --
+    but for the test for this bug, since we have hung the Web Content process
+    main thread intentionally, we will not see a rendering update, and so
+    the UI-side script will never run.
+    
+    LayoutTests:
+    
+    * fast/events/touch/ios/resources/finish-test-after-scrolling-with-touch-event-handlers.html: Added.
+    * fast/events/touch/ios/touch-event-stall-after-navigating-with-pending-asynchronous-touch-start-expected.txt: Added.
+    * fast/events/touch/ios/touch-event-stall-after-navigating-with-pending-asynchronous-touch-start.html: Added.
+    Add a test that ensures that a page that dispatches events in beforeunload,
+    receiving preventable touch events during the next page's commitLoad does not result
+    in scrolling being stuck.
+    
+    Before this change, this test would time out.
+    
+    
+    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@265515 268f45cc-cd09-0410-ab3c-d52691b4dbfc
+
+    2020-08-11  Tim Horton  <timothy_horton@apple.com>
+
+            iOS: Scrolling and touch events sporadically stop working after navigating
+            https://bugs.webkit.org/show_bug.cgi?id=215368
+            <rdar://problem/65801531>
+
+            Reviewed by Wenson Hsieh.
+
+            Test: fast/events/touch/ios/touch-event-stall-after-navigating-with-pending-asynchronous-touch-start.html
+
+            WebPageProxy::handlePreventableTouchEvent keeps a counter of the number
+            of outstanding "preventable" touch events that it is waiting to hear
+            from the Web Content process about. This counter is incremented when the
+            event is dispatched to the Web Content process's EventHandler queue,
+            and decremented when the reply (whether it was handled or not) comes
+            back from the Web Content process. While the counter is non-zero, all
+            deferrable gestures remain deferred (and when it returns to zero, the
+            WKDeferringGestureRecognizer gate is lifted, and events are allowed to flow).
+            This means that it is very important that every event eventually reply
+            about its handling status.
+
+            Before this change, when the Web Content process is navigating, and reaches didCommitLoad,
+            it cleared all queued touch events, without replying to to the UI process.
+            Thus, there is a small window of time in which an incoming touch event will
+            end up in the queue, *not* get dispatched/replied, and then get dropped on
+            the floor in didCommitLoad. Most events do not meet this fate, because they
+            are handled promptly, and commitLoad/didCommitLoad tend to be very quick.
+            However, if the Web Content process ends up spending any significant amount
+            of time under commitLoad (say, in an unload handler, or in media frameworks),
+            any incoming touch events during that time will get lost, and the UI process'
+            count of outstanding events will end up getting stuck non-zero.
+
+            Fix this by always pretending that the page ate any events that were outstanding
+            when didCommitLoad occurs, instead of just dropping them on the floor.
+
+            * UIProcess/ios/PageClientImplIOS.mm:
+            (WebKit::PageClientImpl::doneWithTouchEvent):
+            * WebProcess/WebPage/EventDispatcher.cpp:
+            (WebKit::EventDispatcher::takeQueuedTouchEventsForPage):
+            (WebKit::EventDispatcher::clearQueuedTouchEventsForPage): Deleted.
+            (WebKit::EventDispatcher::getQueuedTouchEventsForPage): Deleted.
+            Also, rename getQueuedTouchEventsForPage to takeQueuedTouchEventsForPage,
+            since it removes the queue from EventDispatcher's set.
+
+            * WebProcess/WebPage/EventDispatcher.h:
+            * WebProcess/WebPage/WebPage.cpp:
+            (WebKit::WebPage::touchEventSync):
+            (WebKit::WebPage::didCommitLoad):
+            * WebProcess/WebPage/WebPage.h:
+            * WebProcess/WebPage/ios/WebPageIOS.mm:
+            (WebKit::WebPage::cancelAsynchronousTouchEvents):
+
+2020-08-12  Alan Coon  <alancoon@apple.com>
+
</ins><span class="cx">         Cherry-pick r265480. rdar://problem/66943866
</span><span class="cx"> 
</span><span class="cx">     AuxiliaryProcess::didReceiveInvalidMessage() for WebPage::PerformDragControllerAction IPC
</span></span></pre></div>
<a id="branchessafari6101branchSourceWebKitUIProcessiosPageClientImplIOSmm"></a>
<div class="modfile"><h4>Modified: branches/safari-610.1-branch/Source/WebKit/UIProcess/ios/PageClientImplIOS.mm (265594 => 265595)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-610.1-branch/Source/WebKit/UIProcess/ios/PageClientImplIOS.mm    2020-08-13 01:46:36 UTC (rev 265594)
+++ branches/safari-610.1-branch/Source/WebKit/UIProcess/ios/PageClientImplIOS.mm       2020-08-13 01:46:40 UTC (rev 265595)
</span><span class="lines">@@ -450,9 +450,9 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(TOUCH_EVENTS)
</span><del>-void PageClientImpl::doneWithTouchEvent(const NativeWebTouchEvent& nativeWebtouchEvent, bool eventHandled)
</del><ins>+void PageClientImpl::doneWithTouchEvent(const NativeWebTouchEvent& nativeWebTouchEvent, bool eventHandled)
</ins><span class="cx"> {
</span><del>-    [m_contentView _webTouchEvent:nativeWebtouchEvent preventsNativeGestures:eventHandled];
</del><ins>+    [m_contentView _webTouchEvent:nativeWebTouchEvent preventsNativeGestures:eventHandled];
</ins><span class="cx"> }
</span><span class="cx"> #endif
</span><span class="cx"> 
</span></span></pre></div>
<a id="branchessafari6101branchSourceWebKitWebProcessWebPageEventDispatchercpp"></a>
<div class="modfile"><h4>Modified: branches/safari-610.1-branch/Source/WebKit/WebProcess/WebPage/EventDispatcher.cpp (265594 => 265595)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-610.1-branch/Source/WebKit/WebProcess/WebPage/EventDispatcher.cpp        2020-08-13 01:46:36 UTC (rev 265594)
+++ branches/safari-610.1-branch/Source/WebKit/WebProcess/WebPage/EventDispatcher.cpp   2020-08-13 01:46:40 UTC (rev 265595)
</span><span class="lines">@@ -176,15 +176,9 @@
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(IOS_TOUCH_EVENTS)
</span><del>-void EventDispatcher::clearQueuedTouchEventsForPage(const WebPage& webPage)
</del><ins>+void EventDispatcher::takeQueuedTouchEventsForPage(const WebPage& webPage, TouchEventQueue& destinationQueue)
</ins><span class="cx"> {
</span><span class="cx">     LockHolder locker(&m_touchEventsLock);
</span><del>-    m_touchEvents.remove(webPage.identifier());
-}
-
-void EventDispatcher::getQueuedTouchEventsForPage(const WebPage& webPage, TouchEventQueue& destinationQueue)
-{
-    LockHolder locker(&m_touchEventsLock);
</del><span class="cx">     destinationQueue = m_touchEvents.take(webPage.identifier());
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="branchessafari6101branchSourceWebKitWebProcessWebPageEventDispatcherh"></a>
<div class="modfile"><h4>Modified: branches/safari-610.1-branch/Source/WebKit/WebProcess/WebPage/EventDispatcher.h (265594 => 265595)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-610.1-branch/Source/WebKit/WebProcess/WebPage/EventDispatcher.h  2020-08-13 01:46:36 UTC (rev 265594)
+++ branches/safari-610.1-branch/Source/WebKit/WebProcess/WebPage/EventDispatcher.h     2020-08-13 01:46:40 UTC (rev 265595)
</span><span class="lines">@@ -63,9 +63,7 @@
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(IOS_TOUCH_EVENTS)
</span><span class="cx">     using TouchEventQueue = Vector<std::pair<WebTouchEvent, Optional<CallbackID>>, 1>;
</span><del>-
-    void clearQueuedTouchEventsForPage(const WebPage&);
-    void getQueuedTouchEventsForPage(const WebPage&, TouchEventQueue&);
</del><ins>+    void takeQueuedTouchEventsForPage(const WebPage&, TouchEventQueue&);
</ins><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx">     void initializeConnection(IPC::Connection*);
</span></span></pre></div>
<a id="branchessafari6101branchSourceWebKitWebProcessWebPageWebPagecpp"></a>
<div class="modfile"><h4>Modified: branches/safari-610.1-branch/Source/WebKit/WebProcess/WebPage/WebPage.cpp (265594 => 265595)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-610.1-branch/Source/WebKit/WebProcess/WebPage/WebPage.cpp        2020-08-13 01:46:36 UTC (rev 265594)
+++ branches/safari-610.1-branch/Source/WebKit/WebProcess/WebPage/WebPage.cpp   2020-08-13 01:46:40 UTC (rev 265595)
</span><span class="lines">@@ -2985,7 +2985,7 @@
</span><span class="cx">     m_pendingSynchronousTouchEventReply = WTFMove(reply);
</span><span class="cx"> 
</span><span class="cx">     EventDispatcher::TouchEventQueue queuedEvents;
</span><del>-    WebProcess::singleton().eventDispatcher().getQueuedTouchEventsForPage(*this, queuedEvents);
</del><ins>+    WebProcess::singleton().eventDispatcher().takeQueuedTouchEventsForPage(*this, queuedEvents);
</ins><span class="cx">     dispatchAsynchronousTouchEvents(queuedEvents);
</span><span class="cx"> 
</span><span class="cx">     bool handled = true;
</span><span class="lines">@@ -5987,7 +5987,9 @@
</span><span class="cx">     m_lastLayerTreeTransactionIdAndPageScaleBeforeScalingPage = WTF::nullopt;
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(IOS_TOUCH_EVENTS)
</span><del>-    WebProcess::singleton().eventDispatcher().clearQueuedTouchEventsForPage(*this);
</del><ins>+    EventDispatcher::TouchEventQueue queuedEvents;
+    WebProcess::singleton().eventDispatcher().takeQueuedTouchEventsForPage(*this, queuedEvents);
+    cancelAsynchronousTouchEvents(queuedEvents);
</ins><span class="cx"> #endif
</span><span class="cx"> #endif // PLATFORM(IOS_FAMILY)
</span><span class="cx"> 
</span></span></pre></div>
<a id="branchessafari6101branchSourceWebKitWebProcessWebPageWebPageh"></a>
<div class="modfile"><h4>Modified: branches/safari-610.1-branch/Source/WebKit/WebProcess/WebPage/WebPage.h (265594 => 265595)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-610.1-branch/Source/WebKit/WebProcess/WebPage/WebPage.h  2020-08-13 01:46:36 UTC (rev 265594)
+++ branches/safari-610.1-branch/Source/WebKit/WebProcess/WebPage/WebPage.h     2020-08-13 01:46:40 UTC (rev 265595)
</span><span class="lines">@@ -759,6 +759,7 @@
</span><span class="cx"> 
</span><span class="cx"> #if PLATFORM(IOS_FAMILY) && ENABLE(IOS_TOUCH_EVENTS)
</span><span class="cx">     void dispatchAsynchronousTouchEvents(const Vector<std::pair<WebTouchEvent, Optional<CallbackID>>, 1>& queue);
</span><ins>+    void cancelAsynchronousTouchEvents(const Vector<std::pair<WebTouchEvent, Optional<CallbackID>>, 1>& queue);
</ins><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx">     bool hasRichlyEditableSelection() const;
</span></span></pre></div>
<a id="branchessafari6101branchSourceWebKitWebProcessWebPageiosWebPageIOSmm"></a>
<div class="modfile"><h4>Modified: branches/safari-610.1-branch/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm (265594 => 265595)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-610.1-branch/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm  2020-08-13 01:46:36 UTC (rev 265594)
+++ branches/safari-610.1-branch/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm     2020-08-13 01:46:40 UTC (rev 265595)
</span><span class="lines">@@ -3945,6 +3945,15 @@
</span><span class="cx">             send(Messages::WebPageProxy::BoolCallback(handled, *eventAndCallbackID.second));
</span><span class="cx">     }
</span><span class="cx"> }
</span><ins>+
+void WebPage::cancelAsynchronousTouchEvents(const Vector<std::pair<WebTouchEvent, Optional<CallbackID>>, 1>& queue)
+{
+    for (auto& eventAndCallbackID : queue) {
+        if (!eventAndCallbackID.second)
+            continue;
+        send(Messages::WebPageProxy::BoolCallback(true, *eventAndCallbackID.second));
+    }
+}
</ins><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx"> void WebPage::computePagesForPrintingAndDrawToPDF(WebCore::FrameIdentifier frameID, const PrintInfo& printInfo, CallbackID callbackID, Messages::WebPage::ComputePagesForPrintingAndDrawToPDF::DelayedReply&& reply)
</span></span></pre></div>
<a id="branchessafari6101branchToolsChangeLog"></a>
<div class="modfile"><h4>Modified: branches/safari-610.1-branch/Tools/ChangeLog (265594 => 265595)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-610.1-branch/Tools/ChangeLog     2020-08-13 01:46:36 UTC (rev 265594)
+++ branches/safari-610.1-branch/Tools/ChangeLog        2020-08-13 01:46:40 UTC (rev 265595)
</span><span class="lines">@@ -1,5 +1,121 @@
</span><span class="cx"> 2020-08-12  Alan Coon  <alancoon@apple.com>
</span><span class="cx"> 
</span><ins>+        Cherry-pick r265515. rdar://problem/66943894
+
+    iOS: Scrolling and touch events sporadically stop working after navigating
+    https://bugs.webkit.org/show_bug.cgi?id=215368
+    <rdar://problem/65801531>
+    
+    Reviewed by Wenson Hsieh.
+    
+    Source/WebKit:
+    
+    Test: fast/events/touch/ios/touch-event-stall-after-navigating-with-pending-asynchronous-touch-start.html
+    
+    WebPageProxy::handlePreventableTouchEvent keeps a counter of the number
+    of outstanding "preventable" touch events that it is waiting to hear
+    from the Web Content process about. This counter is incremented when the
+    event is dispatched to the Web Content process's EventHandler queue,
+    and decremented when the reply (whether it was handled or not) comes
+    back from the Web Content process. While the counter is non-zero, all
+    deferrable gestures remain deferred (and when it returns to zero, the
+    WKDeferringGestureRecognizer gate is lifted, and events are allowed to flow).
+    This means that it is very important that every event eventually reply
+    about its handling status.
+    
+    Before this change, when the Web Content process is navigating, and reaches didCommitLoad,
+    it cleared all queued touch events, without replying to to the UI process.
+    Thus, there is a small window of time in which an incoming touch event will
+    end up in the queue, *not* get dispatched/replied, and then get dropped on
+    the floor in didCommitLoad. Most events do not meet this fate, because they
+    are handled promptly, and commitLoad/didCommitLoad tend to be very quick.
+    However, if the Web Content process ends up spending any significant amount
+    of time under commitLoad (say, in an unload handler, or in media frameworks),
+    any incoming touch events during that time will get lost, and the UI process'
+    count of outstanding events will end up getting stuck non-zero.
+    
+    Fix this by always pretending that the page ate any events that were outstanding
+    when didCommitLoad occurs, instead of just dropping them on the floor.
+    
+    * UIProcess/ios/PageClientImplIOS.mm:
+    (WebKit::PageClientImpl::doneWithTouchEvent):
+    * WebProcess/WebPage/EventDispatcher.cpp:
+    (WebKit::EventDispatcher::takeQueuedTouchEventsForPage):
+    (WebKit::EventDispatcher::clearQueuedTouchEventsForPage): Deleted.
+    (WebKit::EventDispatcher::getQueuedTouchEventsForPage): Deleted.
+    Also, rename getQueuedTouchEventsForPage to takeQueuedTouchEventsForPage,
+    since it removes the queue from EventDispatcher's set.
+    
+    * WebProcess/WebPage/EventDispatcher.h:
+    * WebProcess/WebPage/WebPage.cpp:
+    (WebKit::WebPage::touchEventSync):
+    (WebKit::WebPage::didCommitLoad):
+    * WebProcess/WebPage/WebPage.h:
+    * WebProcess/WebPage/ios/WebPageIOS.mm:
+    (WebKit::WebPage::cancelAsynchronousTouchEvents):
+    
+    Tools:
+    
+    * WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl:
+    * WebKitTestRunner/InjectedBundle/TestRunner.cpp:
+    (WTR::TestRunner::runUIScriptImmediately):
+    * WebKitTestRunner/InjectedBundle/TestRunner.h:
+    * WebKitTestRunner/TestInvocation.cpp:
+    (WTR::TestInvocation::didReceiveMessageFromInjectedBundle):
+    (WTR::TestInvocation::runUISideScriptImmediately):
+    (WTR::TestInvocation::runUISideScriptAfterUpdateCallback):
+    * WebKitTestRunner/TestInvocation.h:
+    Add a variant of runUISideScript that runs the script without
+    waiting for a rendering update.
+    
+    It makes sense for the default runUISideScript to wait for a rendering
+    update -- nearly every test is either unaffected or improved by this --
+    but for the test for this bug, since we have hung the Web Content process
+    main thread intentionally, we will not see a rendering update, and so
+    the UI-side script will never run.
+    
+    LayoutTests:
+    
+    * fast/events/touch/ios/resources/finish-test-after-scrolling-with-touch-event-handlers.html: Added.
+    * fast/events/touch/ios/touch-event-stall-after-navigating-with-pending-asynchronous-touch-start-expected.txt: Added.
+    * fast/events/touch/ios/touch-event-stall-after-navigating-with-pending-asynchronous-touch-start.html: Added.
+    Add a test that ensures that a page that dispatches events in beforeunload,
+    receiving preventable touch events during the next page's commitLoad does not result
+    in scrolling being stuck.
+    
+    Before this change, this test would time out.
+    
+    
+    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@265515 268f45cc-cd09-0410-ab3c-d52691b4dbfc
+
+    2020-08-11  Tim Horton  <timothy_horton@apple.com>
+
+            iOS: Scrolling and touch events sporadically stop working after navigating
+            https://bugs.webkit.org/show_bug.cgi?id=215368
+            <rdar://problem/65801531>
+
+            Reviewed by Wenson Hsieh.
+
+            * WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl:
+            * WebKitTestRunner/InjectedBundle/TestRunner.cpp:
+            (WTR::TestRunner::runUIScriptImmediately):
+            * WebKitTestRunner/InjectedBundle/TestRunner.h:
+            * WebKitTestRunner/TestInvocation.cpp:
+            (WTR::TestInvocation::didReceiveMessageFromInjectedBundle):
+            (WTR::TestInvocation::runUISideScriptImmediately):
+            (WTR::TestInvocation::runUISideScriptAfterUpdateCallback):
+            * WebKitTestRunner/TestInvocation.h:
+            Add a variant of runUISideScript that runs the script without
+            waiting for a rendering update.
+
+            It makes sense for the default runUISideScript to wait for a rendering
+            update -- nearly every test is either unaffected or improved by this --
+            but for the test for this bug, since we have hung the Web Content process
+            main thread intentionally, we will not see a rendering update, and so
+            the UI-side script will never run.
+
+2020-08-12  Alan Coon  <alancoon@apple.com>
+
</ins><span class="cx">         Cherry-pick r265480. rdar://problem/66943866
</span><span class="cx"> 
</span><span class="cx">     AuxiliaryProcess::didReceiveInvalidMessage() for WebPage::PerformDragControllerAction IPC
</span></span></pre></div>
<a id="branchessafari6101branchToolsWebKitTestRunnerInjectedBundleBindingsTestRunneridl"></a>
<div class="modfile"><h4>Modified: branches/safari-610.1-branch/Tools/WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl (265594 => 265595)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-610.1-branch/Tools/WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl       2020-08-13 01:46:36 UTC (rev 265594)
+++ branches/safari-610.1-branch/Tools/WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl  2020-08-13 01:46:40 UTC (rev 265595)
</span><span class="lines">@@ -275,6 +275,7 @@
</span><span class="cx"> 
</span><span class="cx">     // UI Process Testing
</span><span class="cx">     void runUIScript(DOMString script, object callback);
</span><ins>+    void runUIScriptImmediately(DOMString script, object callback);
</ins><span class="cx"> 
</span><span class="cx">     void clearTestRunnerCallbacks();
</span><span class="cx"> 
</span></span></pre></div>
<a id="branchessafari6101branchToolsWebKitTestRunnerInjectedBundleTestRunnercpp"></a>
<div class="modfile"><h4>Modified: branches/safari-610.1-branch/Tools/WebKitTestRunner/InjectedBundle/TestRunner.cpp (265594 => 265595)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-610.1-branch/Tools/WebKitTestRunner/InjectedBundle/TestRunner.cpp        2020-08-13 01:46:36 UTC (rev 265594)
+++ branches/safari-610.1-branch/Tools/WebKitTestRunner/InjectedBundle/TestRunner.cpp   2020-08-13 01:46:40 UTC (rev 265595)
</span><span class="lines">@@ -1322,6 +1322,27 @@
</span><span class="cx">     WKBundlePagePostMessage(InjectedBundle::singleton().page()->page(), messageName.get(), testDictionary.get());
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void TestRunner::runUIScriptImmediately(JSStringRef script, JSValueRef callback)
+{
+    unsigned callbackID = nextUIScriptCallbackID();
+    cacheTestRunnerCallback(callbackID, callback);
+
+    WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("RunUIProcessScriptImmediately"));
+
+    WKRetainPtr<WKMutableDictionaryRef> testDictionary = adoptWK(WKMutableDictionaryCreate());
+
+    WKRetainPtr<WKStringRef> scriptKey = adoptWK(WKStringCreateWithUTF8CString("Script"));
+    WKRetainPtr<WKStringRef> scriptValue = adoptWK(WKStringCreateWithJSString(script));
+
+    WKRetainPtr<WKStringRef> callbackIDKey = adoptWK(WKStringCreateWithUTF8CString("CallbackID"));
+    WKRetainPtr<WKUInt64Ref> callbackIDValue = adoptWK(WKUInt64Create(callbackID));
+
+    WKDictionarySetItem(testDictionary.get(), scriptKey.get(), scriptValue.get());
+    WKDictionarySetItem(testDictionary.get(), callbackIDKey.get(), callbackIDValue.get());
+
+    WKBundlePagePostMessage(InjectedBundle::singleton().page()->page(), messageName.get(), testDictionary.get());
+}
+
</ins><span class="cx"> void TestRunner::runUIScriptCallback(unsigned callbackID, JSStringRef result)
</span><span class="cx"> {
</span><span class="cx">     WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(InjectedBundle::singleton().page()->page());
</span></span></pre></div>
<a id="branchessafari6101branchToolsWebKitTestRunnerInjectedBundleTestRunnerh"></a>
<div class="modfile"><h4>Modified: branches/safari-610.1-branch/Tools/WebKitTestRunner/InjectedBundle/TestRunner.h (265594 => 265595)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-610.1-branch/Tools/WebKitTestRunner/InjectedBundle/TestRunner.h  2020-08-13 01:46:36 UTC (rev 265594)
+++ branches/safari-610.1-branch/Tools/WebKitTestRunner/InjectedBundle/TestRunner.h     2020-08-13 01:46:40 UTC (rev 265595)
</span><span class="lines">@@ -350,6 +350,7 @@
</span><span class="cx">     void setDidCancelClientRedirect(bool value) { m_didCancelClientRedirect = value; }
</span><span class="cx"> 
</span><span class="cx">     void runUIScript(JSStringRef script, JSValueRef callback);
</span><ins>+    void runUIScriptImmediately(JSStringRef script, JSValueRef callback);
</ins><span class="cx">     void runUIScriptCallback(unsigned callbackID, JSStringRef result);
</span><span class="cx"> 
</span><span class="cx">     // Contextual menu actions
</span></span></pre></div>
<a id="branchessafari6101branchToolsWebKitTestRunnerTestInvocationcpp"></a>
<div class="modfile"><h4>Modified: branches/safari-610.1-branch/Tools/WebKitTestRunner/TestInvocation.cpp (265594 => 265595)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-610.1-branch/Tools/WebKitTestRunner/TestInvocation.cpp   2020-08-13 01:46:36 UTC (rev 265594)
+++ branches/safari-610.1-branch/Tools/WebKitTestRunner/TestInvocation.cpp      2020-08-13 01:46:40 UTC (rev 265595)
</span><span class="lines">@@ -775,6 +775,20 @@
</span><span class="cx">         return;
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    if (WKStringIsEqualToUTF8CString(messageName, "RunUIProcessScriptImmediately")) {
+        WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
+        WKRetainPtr<WKStringRef> scriptKey = adoptWK(WKStringCreateWithUTF8CString("Script"));
+        WKRetainPtr<WKStringRef> callbackIDKey = adoptWK(WKStringCreateWithUTF8CString("CallbackID"));
+
+        UIScriptInvocationData* invocationData = new UIScriptInvocationData();
+        invocationData->testInvocation = this;
+        invocationData->callbackID = (unsigned)WKUInt64GetValue(static_cast<WKUInt64Ref>(WKDictionaryGetItemForKey(messageBodyDictionary, callbackIDKey.get())));
+        invocationData->scriptString = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, scriptKey.get()));
+        m_pendingUIScriptInvocationData = invocationData;
+        runUISideScriptImmediately(nullptr, invocationData);
+        return;
+    }
+
</ins><span class="cx">     if (WKStringIsEqualToUTF8CString(messageName, "InstallCustomMenuAction")) {
</span><span class="cx">         auto messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
</span><span class="cx">         WKRetainPtr<WKStringRef> nameKey = adoptWK(WKStringCreateWithUTF8CString("name"));
</span><span class="lines">@@ -1840,7 +1854,7 @@
</span><span class="cx">     return nullptr;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void TestInvocation::runUISideScriptAfterUpdateCallback(WKErrorRef, void* context)
</del><ins>+void TestInvocation::runUISideScriptImmediately(WKErrorRef, void* context)
</ins><span class="cx"> {
</span><span class="cx">     UIScriptInvocationData* data = static_cast<UIScriptInvocationData*>(context);
</span><span class="cx">     if (TestInvocation* invocation = data->testInvocation) {
</span><span class="lines">@@ -1850,6 +1864,11 @@
</span><span class="cx">     delete data;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void TestInvocation::runUISideScriptAfterUpdateCallback(WKErrorRef error, void* context)
+{
+    runUISideScriptImmediately(error, context);
+}
+
</ins><span class="cx"> void TestInvocation::runUISideScript(WKStringRef script, unsigned scriptCallbackID)
</span><span class="cx"> {
</span><span class="cx">     m_pendingUIScriptInvocationData = nullptr;
</span></span></pre></div>
<a id="branchessafari6101branchToolsWebKitTestRunnerTestInvocationh"></a>
<div class="modfile"><h4>Modified: branches/safari-610.1-branch/Tools/WebKitTestRunner/TestInvocation.h (265594 => 265595)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-610.1-branch/Tools/WebKitTestRunner/TestInvocation.h     2020-08-13 01:46:36 UTC (rev 265594)
+++ branches/safari-610.1-branch/Tools/WebKitTestRunner/TestInvocation.h        2020-08-13 01:46:40 UTC (rev 265595)
</span><span class="lines">@@ -128,6 +128,7 @@
</span><span class="cx">         TestInvocation* testInvocation;
</span><span class="cx">     };
</span><span class="cx">     static void runUISideScriptAfterUpdateCallback(WKErrorRef, void* context);
</span><ins>+    static void runUISideScriptImmediately(WKErrorRef, void* context);
</ins><span class="cx"> 
</span><span class="cx">     bool shouldLogHistoryClientCallbacks() const;
</span><span class="cx"> 
</span></span></pre>
</div>
</div>

</body>
</html>