<!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>[208926] 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/208926">208926</a></dd>
<dt>Author</dt> <dd>simon.fraser@apple.com</dd>
<dt>Date</dt> <dd>2016-11-19 11:02:04 -0800 (Sat, 19 Nov 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>Make it possible to test non-stable-state scrolling on iOS
https://bugs.webkit.org/show_bug.cgi?id=164905

Reviewed by Dan Bernstein.

Source/WebKit2:

Make it possible for an iOS layout test to force every visible rect update
from the UI process to the web process to be in a non-stable state. This emulates
what happens during panning and zooming interactions, and allows us to test the
scrolling and layer trees in these transient states.

This is done by adding a testing property on WKWebView, _stableStateOverride, whose
getters and setters are overridden in TestRunnerWKWebView. When non-nil, we _updateVisibleContentRectAfterScrollInView
consults the NSNumber's boolValue and uses it to override the stable state.

To facilitate this kind of testing, also add immediateScrollToOffset() and
immediateZoomToScale() to UIScriptController. Finally, add doAfterPresentationUpdate()
which provides a callback that fires after one trip to the web process and back.

* UIProcess/API/Cocoa/WKWebView.mm:
(-[WKWebView _updateVisibleContentRectAfterScrollInView:]):
(-[WKWebView _stableStateOverride]):
(-[WKWebView _setStableStateOverride:]):
* UIProcess/API/Cocoa/WKWebViewPrivate.h:

Tools:

Make it possible for an iOS layout test to force every visible rect update
from the UI process to the web process to be in a non-stable state. This emulates
what happens during panning and zooming interactions, and allows us to test the
scrolling and layer trees in these transient states.

This is done by adding a testing property on WKWebView, _stableStateOverride, whose
getters and setters are overridden in TestRunnerWKWebView. When non-nil, we _updateVisibleContentRectAfterScrollInView
consults the NSNumber's boolValue and uses it to override the stable state.

To facilitate this kind of testing, also add immediateScrollToOffset() and
immediateZoomToScale() to UIScriptController. Finally, add doAfterPresentationUpdate()
which provides a callback that fires after one trip to the web process and back.

Add code generation support for optional boolean attributes in IDL.

Align CodeGeneratorDumpRenderTree.pm and CodeGeneratorTestRunner.pm.

* DumpRenderTree/Bindings/CodeGeneratorDumpRenderTree.pm:
(_generateImplementationFile):
(_platformTypeConstructor):
(_returnExpression):
* DumpRenderTree/ios/UIScriptControllerIOS.mm:
(WTR::UIScriptController::doAfterPresentationUpdate):
(WTR::contentOffsetBoundedInValidRange):
(WTR::UIScriptController::scrollToOffset):
(WTR::UIScriptController::immediateScrollToOffset):
(WTR::UIScriptController::immediateZoomToScale):
(WTR::UIScriptController::stableStateOverride):
(WTR::UIScriptController::setStableStateOverride):
* DumpRenderTree/mac/UIScriptControllerMac.mm:
(WTR::UIScriptController::doAfterPresentationUpdate):
* TestRunnerShared/Bindings/JSWrappable.h:
(WTR::JSValueMakeBooleanOrNull):
(WTR::JSValueToNullableBoolean):
* TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl:
* TestRunnerShared/UIScriptContext/UIScriptController.cpp:
(WTR::UIScriptController::immediateScrollToOffset):
(WTR::UIScriptController::immediateZoomToScale):
(WTR::UIScriptController::stableStateOverride):
(WTR::UIScriptController::setStableStateOverride):
* TestRunnerShared/UIScriptContext/UIScriptController.h:
* WebKitTestRunner/InjectedBundle/Bindings/CodeGeneratorTestRunner.pm:
(_classRefGetter):
(_platformTypeConstructor):
(_returnExpression):
* WebKitTestRunner/cocoa/TestRunnerWKWebView.mm:
(-[TestRunnerWKWebView dealloc]):
(-[TestRunnerWKWebView _stableStateOverride]):
(-[TestRunnerWKWebView _setStableStateOverride:]):
* WebKitTestRunner/ios/TestControllerIOS.mm:
(WTR::TestController::platformResetStateToConsistentValues):
* WebKitTestRunner/ios/UIScriptControllerIOS.mm:
(WTR::UIScriptController::doAsyncTask):
(WTR::UIScriptController::doAfterPresentationUpdate):
(WTR::UIScriptController::zoomToScale):
(WTR::UIScriptController::immediateScrollToOffset):
(WTR::UIScriptController::immediateZoomToScale):
(WTR::UIScriptController::stableStateOverride):
(WTR::UIScriptController::setStableStateOverride):
* WebKitTestRunner/mac/UIScriptControllerMac.mm:
(WTR::UIScriptController::doAfterPresentationUpdate):

LayoutTests:

* scrollingcoordinator/ios/non-stable-viewport-scroll-expected.txt: Added.
* scrollingcoordinator/ios/non-stable-viewport-scroll.html: Added.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkSourceWebKit2ChangeLog">trunk/Source/WebKit2/ChangeLog</a></li>
<li><a href="#trunkSourceWebKit2UIProcessAPICocoaWKWebViewmm">trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebView.mm</a></li>
<li><a href="#trunkSourceWebKit2UIProcessAPICocoaWKWebViewPrivateh">trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebViewPrivate.h</a></li>
<li><a href="#trunkToolsChangeLog">trunk/Tools/ChangeLog</a></li>
<li><a href="#trunkToolsDumpRenderTreeBindingsCodeGeneratorDumpRenderTreepm">trunk/Tools/DumpRenderTree/Bindings/CodeGeneratorDumpRenderTree.pm</a></li>
<li><a href="#trunkToolsDumpRenderTreeiosUIScriptControllerIOSmm">trunk/Tools/DumpRenderTree/ios/UIScriptControllerIOS.mm</a></li>
<li><a href="#trunkToolsDumpRenderTreemacUIScriptControllerMacmm">trunk/Tools/DumpRenderTree/mac/UIScriptControllerMac.mm</a></li>
<li><a href="#trunkToolsTestRunnerSharedBindingsJSWrappableh">trunk/Tools/TestRunnerShared/Bindings/JSWrappable.h</a></li>
<li><a href="#trunkToolsTestRunnerSharedUIScriptContextBindingsUIScriptControlleridl">trunk/Tools/TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl</a></li>
<li><a href="#trunkToolsTestRunnerSharedUIScriptContextUIScriptControllercpp">trunk/Tools/TestRunnerShared/UIScriptContext/UIScriptController.cpp</a></li>
<li><a href="#trunkToolsTestRunnerSharedUIScriptContextUIScriptControllerh">trunk/Tools/TestRunnerShared/UIScriptContext/UIScriptController.h</a></li>
<li><a href="#trunkToolsWebKitTestRunnerInjectedBundleBindingsCodeGeneratorTestRunnerpm">trunk/Tools/WebKitTestRunner/InjectedBundle/Bindings/CodeGeneratorTestRunner.pm</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="#trunkToolsWebKitTestRunneriosTestControllerIOSmm">trunk/Tools/WebKitTestRunner/ios/TestControllerIOS.mm</a></li>
<li><a href="#trunkToolsWebKitTestRunneriosUIScriptControllerIOSmm">trunk/Tools/WebKitTestRunner/ios/UIScriptControllerIOS.mm</a></li>
<li><a href="#trunkToolsWebKitTestRunnermacUIScriptControllerMacmm">trunk/Tools/WebKitTestRunner/mac/UIScriptControllerMac.mm</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsscrollingcoordinatoriosnonstableviewportscrollexpectedtxt">trunk/LayoutTests/scrollingcoordinator/ios/non-stable-viewport-scroll-expected.txt</a></li>
<li><a href="#trunkLayoutTestsscrollingcoordinatoriosnonstableviewportscrollhtml">trunk/LayoutTests/scrollingcoordinator/ios/non-stable-viewport-scroll.html</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (208925 => 208926)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2016-11-19 17:39:25 UTC (rev 208925)
+++ trunk/LayoutTests/ChangeLog        2016-11-19 19:02:04 UTC (rev 208926)
</span><span class="lines">@@ -1,3 +1,13 @@
</span><ins>+2016-11-18  Simon Fraser  &lt;simon.fraser@apple.com&gt;
+
+        Make it possible to test non-stable-state scrolling on iOS
+        https://bugs.webkit.org/show_bug.cgi?id=164905
+
+        Reviewed by Dan Bernstein.
+
+        * scrollingcoordinator/ios/non-stable-viewport-scroll-expected.txt: Added.
+        * scrollingcoordinator/ios/non-stable-viewport-scroll.html: Added.
+
</ins><span class="cx"> 2016-11-19  Joanmarie Diggs  &lt;jdiggs@igalia.com&gt;
</span><span class="cx"> 
</span><span class="cx">         AX: [ATK] Expose aria-busy via ATK_STATE_BUSY
</span></span></pre></div>
<a id="trunkLayoutTestsscrollingcoordinatoriosnonstableviewportscrollexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/scrollingcoordinator/ios/non-stable-viewport-scroll-expected.txt (0 => 208926)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/scrollingcoordinator/ios/non-stable-viewport-scroll-expected.txt                                (rev 0)
+++ trunk/LayoutTests/scrollingcoordinator/ios/non-stable-viewport-scroll-expected.txt        2016-11-19 19:02:04 UTC (rev 208926)
</span><span class="lines">@@ -0,0 +1,33 @@
</span><ins>+fixed
+(GraphicsLayer
+  (anchor 0.00 0.00)
+  (bounds 320.00 5013.00)
+  (visible rect 0.00, 1000.00 106.67 x 189.33)
+  (coverage rect 0.00, 1000.00 106.67 x 189.33)
+  (intersects coverage rect 1)
+  (contentsScale 6.00)
+  (children 1
+    (GraphicsLayer
+      (bounds 320.00 5013.00)
+      (contentsOpaque 1)
+      (visible rect 0.00, 1000.00 106.67 x 189.33)
+      (coverage rect 0.00, 957.33 192.00 x 274.67)
+      (intersects coverage rect 1)
+      (contentsScale 6.00)
+      (children 1
+        (GraphicsLayer
+          (position 10.00 0.00)
+          (bounds 100.00 568.00)
+          (usingTiledLayer 1)
+          (contentsOpaque 1)
+          (drawsContent 1)
+          (visible rect 0.00, 0.00 100.00 x 568.00)
+          (coverage rect -10.00, 0.00 320.00 x 568.00)
+          (intersects coverage rect 1)
+          (contentsScale 6.00)
+        )
+      )
+    )
+  )
+)
+
</ins></span></pre></div>
<a id="trunkLayoutTestsscrollingcoordinatoriosnonstableviewportscrollhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/scrollingcoordinator/ios/non-stable-viewport-scroll.html (0 => 208926)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/scrollingcoordinator/ios/non-stable-viewport-scroll.html                                (rev 0)
+++ trunk/LayoutTests/scrollingcoordinator/ios/non-stable-viewport-scroll.html        2016-11-19 19:02:04 UTC (rev 208926)
</span><span class="lines">@@ -0,0 +1,59 @@
</span><ins>+&lt;!DOCTYPE html&gt; &lt;!-- webkit-test-runner [ useFlexibleViewport=true ] --&gt;
+
+&lt;html&gt;
+&lt;head&gt;
+    &lt;meta name=&quot;viewport&quot; content=&quot;initial-scale=1.0&quot;&gt;
+    &lt;style&gt;
+        body {
+            height: 5000px;
+            margin: 0;
+        }
+        
+        .fixed {
+            position: fixed;
+            top: 0;
+            left: 10px;
+            height: 100%;
+            width: 100px;
+            background-color: blue;
+        }
+    &lt;/style&gt;
+    &lt;script&gt;
+        if (window.testRunner) {
+            testRunner.waitUntilDone();
+            testRunner.dumpAsText();
+        }
+
+        function getUnstableScrollScript(x, y)
+        {
+            return `(function() {
+                uiController.stableStateOverride = false;
+                uiController.immediateZoomToScale(3);
+                uiController.immediateScrollToOffset(0, 3000);
+                
+                uiController.doAfterPresentationUpdate(function() {
+                    uiController.uiScriptComplete();
+                });
+                
+            })();`;
+        }
+
+        function doTest()
+        {
+            if (!testRunner.runUIScript)
+                return
+
+            testRunner.runUIScript(getUnstableScrollScript(), function() {
+                document.getElementById('layers').textContent = internals.layerTreeAsText(document, internals.LAYER_TREE_INCLUDES_VISIBLE_RECTS);
+                testRunner.notifyDone();
+            });
+        }
+        
+        window.addEventListener('load', doTest, false);
+    &lt;/script&gt;
+&lt;/head&gt;
+&lt;body&gt;
+&lt;div class=&quot;fixed&quot;&gt;fixed&lt;/div&gt;
+&lt;pre id=&quot;layers&quot;&gt;&lt;/pre&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkSourceWebKit2ChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/ChangeLog (208925 => 208926)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/ChangeLog        2016-11-19 17:39:25 UTC (rev 208925)
+++ trunk/Source/WebKit2/ChangeLog        2016-11-19 19:02:04 UTC (rev 208926)
</span><span class="lines">@@ -1,5 +1,31 @@
</span><span class="cx"> 2016-11-18  Simon Fraser  &lt;simon.fraser@apple.com&gt;
</span><span class="cx"> 
</span><ins>+        Make it possible to test non-stable-state scrolling on iOS
+        https://bugs.webkit.org/show_bug.cgi?id=164905
+
+        Reviewed by Dan Bernstein.
+
+        Make it possible for an iOS layout test to force every visible rect update
+        from the UI process to the web process to be in a non-stable state. This emulates
+        what happens during panning and zooming interactions, and allows us to test the
+        scrolling and layer trees in these transient states.
+
+        This is done by adding a testing property on WKWebView, _stableStateOverride, whose
+        getters and setters are overridden in TestRunnerWKWebView. When non-nil, we _updateVisibleContentRectAfterScrollInView
+        consults the NSNumber's boolValue and uses it to override the stable state.
+
+        To facilitate this kind of testing, also add immediateScrollToOffset() and
+        immediateZoomToScale() to UIScriptController. Finally, add doAfterPresentationUpdate()
+        which provides a callback that fires after one trip to the web process and back.
+
+        * UIProcess/API/Cocoa/WKWebView.mm:
+        (-[WKWebView _updateVisibleContentRectAfterScrollInView:]):
+        (-[WKWebView _stableStateOverride]):
+        (-[WKWebView _setStableStateOverride:]):
+        * UIProcess/API/Cocoa/WKWebViewPrivate.h:
+
+2016-11-18  Simon Fraser  &lt;simon.fraser@apple.com&gt;
+
</ins><span class="cx">         [iOS WK2] Eliminate a source of flakiness in layout tests by forcing WebPage into &quot;responsive&quot; mode for all tests, with an internals override
</span><span class="cx">         https://bugs.webkit.org/show_bug.cgi?id=164980
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessAPICocoaWKWebViewmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebView.mm (208925 => 208926)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebView.mm        2016-11-19 17:39:25 UTC (rev 208925)
+++ trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebView.mm        2016-11-19 19:02:04 UTC (rev 208926)
</span><span class="lines">@@ -2071,6 +2071,9 @@
</span><span class="cx">     if (isStableState &amp;&amp; [scrollView respondsToSelector:@selector(_isInterruptingDeceleration)])
</span><span class="cx">         isStableState = ![scrollView performSelector:@selector(_isInterruptingDeceleration)];
</span><span class="cx"> 
</span><ins>+    if (NSNumber *stableOverride = self._stableStateOverride)
+        isStableState = stableOverride.boolValue;
+
</ins><span class="cx">     [self _updateContentRectsWithState:isStableState];
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -4731,6 +4734,12 @@
</span><span class="cx">     return coordinator-&gt;scrollingTreeAsText();
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+- (NSNumber *)_stableStateOverride
+{
+    // For subclasses to override.
+    return nil;
+}
+
</ins><span class="cx"> #endif // PLATFORM(IOS)
</span><span class="cx"> 
</span><span class="cx"> #if PLATFORM(MAC)
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessAPICocoaWKWebViewPrivateh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebViewPrivate.h (208925 => 208926)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebViewPrivate.h        2016-11-19 17:39:25 UTC (rev 208925)
+++ trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebViewPrivate.h        2016-11-19 19:02:04 UTC (rev 208926)
</span><span class="lines">@@ -290,8 +290,10 @@
</span><span class="cx"> 
</span><span class="cx"> @property (nonatomic, readonly) NSString *_scrollingTreeAsText WK_API_AVAILABLE(ios(WK_IOS_TBA));
</span><span class="cx"> 
</span><del>-#endif
</del><ins>+@property (nonatomic, readonly) NSNumber *_stableStateOverride WK_API_AVAILABLE(ios(WK_IOS_TBA));
</ins><span class="cx"> 
</span><ins>+#endif // TARGET_OS_IPHONE
+
</ins><span class="cx"> #if !TARGET_OS_IPHONE
</span><span class="cx"> @property (nonatomic, readonly) BOOL _hasActiveVideoForControlsManager WK_API_AVAILABLE(macosx(10.12));
</span><span class="cx"> - (void)_requestControlledElementID WK_API_AVAILABLE(macosx(WK_MAC_TBA));
</span></span></pre></div>
<a id="trunkToolsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Tools/ChangeLog (208925 => 208926)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/ChangeLog        2016-11-19 17:39:25 UTC (rev 208925)
+++ trunk/Tools/ChangeLog        2016-11-19 19:02:04 UTC (rev 208926)
</span><span class="lines">@@ -1,3 +1,72 @@
</span><ins>+2016-11-18  Simon Fraser  &lt;simon.fraser@apple.com&gt;
+
+        Make it possible to test non-stable-state scrolling on iOS
+        https://bugs.webkit.org/show_bug.cgi?id=164905
+
+        Reviewed by Dan Bernstein.
+
+        Make it possible for an iOS layout test to force every visible rect update
+        from the UI process to the web process to be in a non-stable state. This emulates
+        what happens during panning and zooming interactions, and allows us to test the
+        scrolling and layer trees in these transient states.
+        
+        This is done by adding a testing property on WKWebView, _stableStateOverride, whose
+        getters and setters are overridden in TestRunnerWKWebView. When non-nil, we _updateVisibleContentRectAfterScrollInView
+        consults the NSNumber's boolValue and uses it to override the stable state.
+        
+        To facilitate this kind of testing, also add immediateScrollToOffset() and
+        immediateZoomToScale() to UIScriptController. Finally, add doAfterPresentationUpdate()
+        which provides a callback that fires after one trip to the web process and back.
+        
+        Add code generation support for optional boolean attributes in IDL.
+
+        Align CodeGeneratorDumpRenderTree.pm and CodeGeneratorTestRunner.pm.
+
+        * DumpRenderTree/Bindings/CodeGeneratorDumpRenderTree.pm:
+        (_generateImplementationFile):
+        (_platformTypeConstructor):
+        (_returnExpression):
+        * DumpRenderTree/ios/UIScriptControllerIOS.mm:
+        (WTR::UIScriptController::doAfterPresentationUpdate):
+        (WTR::contentOffsetBoundedInValidRange):
+        (WTR::UIScriptController::scrollToOffset):
+        (WTR::UIScriptController::immediateScrollToOffset):
+        (WTR::UIScriptController::immediateZoomToScale):
+        (WTR::UIScriptController::stableStateOverride):
+        (WTR::UIScriptController::setStableStateOverride):
+        * DumpRenderTree/mac/UIScriptControllerMac.mm:
+        (WTR::UIScriptController::doAfterPresentationUpdate):
+        * TestRunnerShared/Bindings/JSWrappable.h:
+        (WTR::JSValueMakeBooleanOrNull):
+        (WTR::JSValueToNullableBoolean):
+        * TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl:
+        * TestRunnerShared/UIScriptContext/UIScriptController.cpp:
+        (WTR::UIScriptController::immediateScrollToOffset):
+        (WTR::UIScriptController::immediateZoomToScale):
+        (WTR::UIScriptController::stableStateOverride):
+        (WTR::UIScriptController::setStableStateOverride):
+        * TestRunnerShared/UIScriptContext/UIScriptController.h:
+        * WebKitTestRunner/InjectedBundle/Bindings/CodeGeneratorTestRunner.pm:
+        (_classRefGetter):
+        (_platformTypeConstructor):
+        (_returnExpression):
+        * WebKitTestRunner/cocoa/TestRunnerWKWebView.mm:
+        (-[TestRunnerWKWebView dealloc]):
+        (-[TestRunnerWKWebView _stableStateOverride]):
+        (-[TestRunnerWKWebView _setStableStateOverride:]):
+        * WebKitTestRunner/ios/TestControllerIOS.mm:
+        (WTR::TestController::platformResetStateToConsistentValues):
+        * WebKitTestRunner/ios/UIScriptControllerIOS.mm:
+        (WTR::UIScriptController::doAsyncTask):
+        (WTR::UIScriptController::doAfterPresentationUpdate):
+        (WTR::UIScriptController::zoomToScale):
+        (WTR::UIScriptController::immediateScrollToOffset):
+        (WTR::UIScriptController::immediateZoomToScale):
+        (WTR::UIScriptController::stableStateOverride):
+        (WTR::UIScriptController::setStableStateOverride):
+        * WebKitTestRunner/mac/UIScriptControllerMac.mm:
+        (WTR::UIScriptController::doAfterPresentationUpdate):
+
</ins><span class="cx"> 2016-11-19  Joanmarie Diggs  &lt;jdiggs@igalia.com&gt;
</span><span class="cx"> 
</span><span class="cx">         AX: [ATK] Expose aria-busy via ATK_STATE_BUSY
</span></span></pre></div>
<a id="trunkToolsDumpRenderTreeBindingsCodeGeneratorDumpRenderTreepm"></a>
<div class="modfile"><h4>Modified: trunk/Tools/DumpRenderTree/Bindings/CodeGeneratorDumpRenderTree.pm (208925 => 208926)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/DumpRenderTree/Bindings/CodeGeneratorDumpRenderTree.pm        2016-11-19 17:39:25 UTC (rev 208925)
+++ trunk/Tools/DumpRenderTree/Bindings/CodeGeneratorDumpRenderTree.pm        2016-11-19 19:02:04 UTC (rev 208926)
</span><span class="lines">@@ -244,7 +244,7 @@
</span><span class="cx">     static JSClassRef jsClass;
</span><span class="cx">     if (!jsClass) {
</span><span class="cx">         JSClassDefinition definition = kJSClassDefinitionEmpty;
</span><del>-        definition.className = &quot;${type}&quot;;
</del><ins>+        definition.className = &quot;@{[$type-&gt;name]}&quot;;
</ins><span class="cx">         definition.parentClass = @{[$self-&gt;_parentClassRefGetterExpression($interface)]};
</span><span class="cx">         definition.staticValues = staticValues();
</span><span class="cx">         definition.staticFunctions = staticFunctions();
</span><span class="lines">@@ -431,7 +431,8 @@
</span><span class="cx"> {
</span><span class="cx">     my ($self, $type, $argumentName) = @_;
</span><span class="cx"> 
</span><del>-    return &quot;JSValueToBoolean(context, $argumentName)&quot; if $type eq &quot;boolean&quot;;
</del><ins>+    return &quot;JSValueToNullableBoolean(context, $argumentName)&quot; if $type-&gt;name eq &quot;boolean&quot; &amp;&amp; $type-&gt;isNullable;
+    return &quot;JSValueToBoolean(context, $argumentName)&quot; if $type-&gt;name eq &quot;boolean&quot;;
</ins><span class="cx">     return &quot;$argumentName&quot; if $type-&gt;name eq &quot;object&quot;;
</span><span class="cx">     return &quot;JSRetainPtr&lt;JSStringRef&gt;(Adopt, JSValueToStringCopy(context, $argumentName, 0))&quot; if $$self{codeGenerator}-&gt;IsStringType($type);
</span><span class="cx">     return &quot;JSValueToNumber(context, $argumentName, 0)&quot; if $$self{codeGenerator}-&gt;IsNonPointerType($type);
</span><span class="lines">@@ -471,6 +472,7 @@
</span><span class="cx">     my ($self, $returnType, $expression) = @_;
</span><span class="cx"> 
</span><span class="cx">     return &quot;JSValueMakeUndefined(context)&quot; if $returnType-&gt;name eq &quot;void&quot;;
</span><ins>+    return &quot;JSValueMakeBooleanOrNull(context, ${expression})&quot; if $returnType-&gt;name eq &quot;boolean&quot; &amp;&amp; $returnType-&gt;isNullable;
</ins><span class="cx">     return &quot;JSValueMakeBoolean(context, ${expression})&quot; if $returnType-&gt;name eq &quot;boolean&quot;;
</span><span class="cx">     return &quot;${expression}&quot; if $returnType-&gt;name eq &quot;object&quot;;
</span><span class="cx">     return &quot;JSValueMakeNumber(context, ${expression})&quot; if $$self{codeGenerator}-&gt;IsNonPointerType($returnType);
</span></span></pre></div>
<a id="trunkToolsDumpRenderTreeiosUIScriptControllerIOSmm"></a>
<div class="modfile"><h4>Modified: trunk/Tools/DumpRenderTree/ios/UIScriptControllerIOS.mm (208925 => 208926)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/DumpRenderTree/ios/UIScriptControllerIOS.mm        2016-11-19 17:39:25 UTC (rev 208925)
+++ trunk/Tools/DumpRenderTree/ios/UIScriptControllerIOS.mm        2016-11-19 19:02:04 UTC (rev 208926)
</span><span class="lines">@@ -49,6 +49,11 @@
</span><span class="cx">     });
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void UIScriptController::doAfterPresentationUpdate(JSValueRef callback)
+{
+    return doAsyncTask(callback);
+}
+
</ins><span class="cx"> void UIScriptController::zoomToScale(double scale, JSValueRef callback)
</span><span class="cx"> {
</span><span class="cx">     RefPtr&lt;UIScriptController&gt; protectedThis(this);
</span><span class="lines">@@ -145,10 +150,37 @@
</span><span class="cx">     return nullptr;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void UIScriptController::scrollToOffset(long, long)
</del><ins>+static CGPoint contentOffsetBoundedInValidRange(UIScrollView *scrollView, CGPoint contentOffset)
</ins><span class="cx"> {
</span><ins>+    UIEdgeInsets contentInsets = scrollView.contentInset;
+    CGSize contentSize = scrollView.contentSize;
+    CGSize scrollViewSize = scrollView.bounds.size;
+
+    CGFloat maxHorizontalOffset = contentSize.width + contentInsets.right - scrollViewSize.width;
+    contentOffset.x = std::min(maxHorizontalOffset, contentOffset.x);
+    contentOffset.x = std::max(-contentInsets.left, contentOffset.x);
+
+    CGFloat maxVerticalOffset = contentSize.height + contentInsets.bottom - scrollViewSize.height;
+    contentOffset.y = std::min(maxVerticalOffset, contentOffset.y);
+    contentOffset.y = std::max(-contentInsets.top, contentOffset.y);
+    return contentOffset;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void UIScriptController::scrollToOffset(long x, long y)
+{
+    [gWebScrollView setContentOffset:contentOffsetBoundedInValidRange(gWebScrollView, CGPointMake(x, y)) animated:YES];
+}
+
+void UIScriptController::immediateScrollToOffset(long x, long y)
+{
+    [gWebScrollView setContentOffset:contentOffsetBoundedInValidRange(gWebScrollView, CGPointMake(x, y)) animated:NO];
+}
+
+void UIScriptController::immediateZoomToScale(double scale)
+{
+    [gWebScrollView setZoomScale:scale animated:NO];
+}
+
</ins><span class="cx"> void UIScriptController::keyboardAccessoryBarNext()
</span><span class="cx"> {
</span><span class="cx"> }
</span><span class="lines">@@ -167,6 +199,16 @@
</span><span class="cx">     return gWebScrollView.maximumZoomScale;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+Optional&lt;bool&gt; UIScriptController::stableStateOverride() const
+{
+    return Nullopt;
+}
+
+void UIScriptController::setStableStateOverride(Optional&lt;bool&gt;)
+{
+}
+
+
</ins><span class="cx"> JSObjectRef UIScriptController::contentVisibleRect() const
</span><span class="cx"> {
</span><span class="cx">     CGRect contentVisibleRect = [gWebBrowserView documentVisibleRect];
</span></span></pre></div>
<a id="trunkToolsDumpRenderTreemacUIScriptControllerMacmm"></a>
<div class="modfile"><h4>Modified: trunk/Tools/DumpRenderTree/mac/UIScriptControllerMac.mm (208925 => 208926)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/DumpRenderTree/mac/UIScriptControllerMac.mm        2016-11-19 17:39:25 UTC (rev 208925)
+++ trunk/Tools/DumpRenderTree/mac/UIScriptControllerMac.mm        2016-11-19 19:02:04 UTC (rev 208926)
</span><span class="lines">@@ -46,6 +46,11 @@
</span><span class="cx">     });
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void UIScriptController::doAfterPresentationUpdate(JSValueRef callback)
+{
+    return doAsyncTask(callback);
+}
+
</ins><span class="cx"> void UIScriptController::insertText(JSStringRef, int, int)
</span><span class="cx"> {
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkToolsTestRunnerSharedBindingsJSWrappableh"></a>
<div class="modfile"><h4>Modified: trunk/Tools/TestRunnerShared/Bindings/JSWrappable.h (208925 => 208926)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/TestRunnerShared/Bindings/JSWrappable.h        2016-11-19 17:39:25 UTC (rev 208925)
+++ trunk/Tools/TestRunnerShared/Bindings/JSWrappable.h        2016-11-19 19:02:04 UTC (rev 208926)
</span><span class="lines">@@ -23,10 +23,10 @@
</span><span class="cx">  * THE POSSIBILITY OF SUCH DAMAGE.
</span><span class="cx">  */
</span><span class="cx"> 
</span><del>-#ifndef JSWrappable_h
-#define JSWrappable_h
</del><ins>+#pragma once
</ins><span class="cx"> 
</span><span class="cx"> #include &lt;JavaScriptCore/JavaScript.h&gt;
</span><ins>+#include &lt;wtf/Optional.h&gt;
</ins><span class="cx"> #include &lt;wtf/RefCounted.h&gt;
</span><span class="cx"> 
</span><span class="cx"> namespace WTR {
</span><span class="lines">@@ -37,6 +37,16 @@
</span><span class="cx">     virtual JSClassRef wrapperClass() = 0;
</span><span class="cx"> };
</span><span class="cx"> 
</span><ins>+inline JSValueRef JSValueMakeBooleanOrNull(JSContextRef context, Optional&lt;bool&gt; value)
+{
+    return value ? JSValueMakeBoolean(context, value.value()) : JSValueMakeNull(context);
+}
+
+inline Optional&lt;bool&gt; JSValueToNullableBoolean(JSContextRef context, JSValueRef value)
+{
+    return JSValueIsUndefined(context, value) || JSValueIsNull(context, value) ? Nullopt : Optional&lt;bool&gt;(JSValueToBoolean(context, value));
+}
+
</ins><span class="cx"> inline JSValueRef JSValueMakeStringOrNull(JSContextRef context, JSStringRef stringOrNull)
</span><span class="cx"> {
</span><span class="cx">     return stringOrNull ? JSValueMakeString(context, stringOrNull) : JSValueMakeNull(context);
</span><span class="lines">@@ -43,5 +53,3 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> } // namespace WTR
</span><del>-
-#endif // JSWrappable_h
</del></span></pre></div>
<a id="trunkToolsTestRunnerSharedUIScriptContextBindingsUIScriptControlleridl"></a>
<div class="modfile"><h4>Modified: trunk/Tools/TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl (208925 => 208926)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl        2016-11-19 17:39:25 UTC (rev 208925)
+++ trunk/Tools/TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl        2016-11-19 19:02:04 UTC (rev 208926)
</span><span class="lines">@@ -26,9 +26,8 @@
</span><span class="cx"> interface UIScriptController {
</span><span class="cx"> 
</span><span class="cx">     void doAsyncTask(object callback); // Used to test the harness.
</span><ins>+    void doAfterPresentationUpdate(object callback); // Call the callback after sending a message to the WebProcess and receiving a subsequent update.
</ins><span class="cx"> 
</span><del>-    void zoomToScale(double scale, object callback);
-
</del><span class="cx">     void simulateAccessibilitySettingsChangeNotification(object callback);
</span><span class="cx"> 
</span><span class="cx">     // Interaction.
</span><span class="lines">@@ -146,14 +145,23 @@
</span><span class="cx">     attribute object willBeginZoomingCallback;
</span><span class="cx">     attribute object didEndZoomingCallback;
</span><span class="cx"> 
</span><ins>+    void zoomToScale(double scale, object callback);
+
</ins><span class="cx">     void scrollToOffset(long x, long y); // Initiate an animated scroll in the UI process.
</span><span class="cx">     attribute object didEndScrollingCallback;
</span><span class="cx"> 
</span><ins>+    void immediateScrollToOffset(long x, long y); // Set the scroll position in the UI process without animation.
+    void immediateZoomToScale(double scale); // Set the zoom scale in the UI process without animation.
+
</ins><span class="cx">     // View state
</span><span class="cx">     readonly attribute double zoomScale;
</span><span class="cx">     readonly attribute double minimumZoomScale;
</span><span class="cx">     readonly attribute double maximumZoomScale;
</span><span class="cx"> 
</span><ins>+    // Overides the &quot;in stable state&quot; behavior of WKWebView (only applies to iOS)
+    // When false, content rect updates to the web process have inStableState=false, as if a scroll or zoom were in progress.
+    attribute boolean? stableStateOverride;
+
</ins><span class="cx">     readonly attribute object contentVisibleRect; // Returned object has 'left', 'top', 'width', 'height' properties.
</span><span class="cx"> 
</span><span class="cx">     readonly attribute object selectionRangeViewRects; // An array of objects with 'left', 'top', 'width', and 'height' properties.
</span></span></pre></div>
<a id="trunkToolsTestRunnerSharedUIScriptContextUIScriptControllercpp"></a>
<div class="modfile"><h4>Modified: trunk/Tools/TestRunnerShared/UIScriptContext/UIScriptController.cpp (208925 => 208926)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/TestRunnerShared/UIScriptContext/UIScriptController.cpp        2016-11-19 17:39:25 UTC (rev 208925)
+++ trunk/Tools/TestRunnerShared/UIScriptContext/UIScriptController.cpp        2016-11-19 19:02:04 UTC (rev 208926)
</span><span class="lines">@@ -60,6 +60,10 @@
</span><span class="cx"> void simulateAccessibilitySettingsChangeNotification(JSValueRef)
</span><span class="cx"> {
</span><span class="cx"> }
</span><ins>+
+void UIScriptController::doAfterPresentationUpdate(JSValueRef)
+{
+}
</ins><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx"> void UIScriptController::setDidStartFormControlInteractionCallback(JSValueRef callback)
</span><span class="lines">@@ -253,6 +257,14 @@
</span><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void UIScriptController::immediateScrollToOffset(long x, long y)
+{
+}
+
+void UIScriptController::immediateZoomToScale(double scale)
+{
+}
+
</ins><span class="cx"> void UIScriptController::keyboardAccessoryBarNext()
</span><span class="cx"> {
</span><span class="cx"> }
</span><span class="lines">@@ -276,6 +288,15 @@
</span><span class="cx">     return 1;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+Optional&lt;bool&gt; UIScriptController::stableStateOverride() const
+{
+    return Nullopt;
+}
+
+void UIScriptController::setStableStateOverride(Optional&lt;bool&gt;)
+{
+}
+
</ins><span class="cx"> JSObjectRef UIScriptController::contentVisibleRect() const
</span><span class="cx"> {
</span><span class="cx">     return nullptr;
</span></span></pre></div>
<a id="trunkToolsTestRunnerSharedUIScriptContextUIScriptControllerh"></a>
<div class="modfile"><h4>Modified: trunk/Tools/TestRunnerShared/UIScriptContext/UIScriptController.h (208925 => 208926)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/TestRunnerShared/UIScriptContext/UIScriptController.h        2016-11-19 17:39:25 UTC (rev 208925)
+++ trunk/Tools/TestRunnerShared/UIScriptContext/UIScriptController.h        2016-11-19 19:02:04 UTC (rev 208926)
</span><span class="lines">@@ -28,6 +28,7 @@
</span><span class="cx"> 
</span><span class="cx"> #include &quot;JSWrappable.h&quot;
</span><span class="cx"> #include &lt;JavaScriptCore/JSRetainPtr.h&gt;
</span><ins>+#include &lt;wtf/Optional.h&gt;
</ins><span class="cx"> #include &lt;wtf/Ref.h&gt;
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="lines">@@ -50,6 +51,8 @@
</span><span class="cx">     void makeWindowObject(JSContextRef, JSObjectRef windowObject, JSValueRef* exception);
</span><span class="cx">     
</span><span class="cx">     void doAsyncTask(JSValueRef callback);
</span><ins>+    void doAfterPresentationUpdate(JSValueRef callback);
+
</ins><span class="cx">     void zoomToScale(double scale, JSValueRef callback);
</span><span class="cx"> 
</span><span class="cx">     void simulateAccessibilitySettingsChangeNotification(JSValueRef callback);
</span><span class="lines">@@ -85,6 +88,9 @@
</span><span class="cx">     
</span><span class="cx">     void scrollToOffset(long x, long y);
</span><span class="cx"> 
</span><ins>+    void immediateScrollToOffset(long x, long y);
+    void immediateZoomToScale(double scale);
+
</ins><span class="cx">     void setDidStartFormControlInteractionCallback(JSValueRef);
</span><span class="cx">     JSValueRef didStartFormControlInteractionCallback() const;
</span><span class="cx"> 
</span><span class="lines">@@ -115,6 +121,9 @@
</span><span class="cx">     double zoomScale() const;
</span><span class="cx">     double minimumZoomScale() const;
</span><span class="cx">     double maximumZoomScale() const;
</span><ins>+    
+    Optional&lt;bool&gt; stableStateOverride() const;
+    void setStableStateOverride(Optional&lt;bool&gt;);
</ins><span class="cx"> 
</span><span class="cx">     JSObjectRef contentVisibleRect() const;
</span><span class="cx">     
</span></span></pre></div>
<a id="trunkToolsWebKitTestRunnerInjectedBundleBindingsCodeGeneratorTestRunnerpm"></a>
<div class="modfile"><h4>Modified: trunk/Tools/WebKitTestRunner/InjectedBundle/Bindings/CodeGeneratorTestRunner.pm (208925 => 208926)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/WebKitTestRunner/InjectedBundle/Bindings/CodeGeneratorTestRunner.pm        2016-11-19 17:39:25 UTC (rev 208925)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/Bindings/CodeGeneratorTestRunner.pm        2016-11-19 19:02:04 UTC (rev 208926)
</span><span class="lines">@@ -77,6 +77,7 @@
</span><span class="cx"> sub _classRefGetter
</span><span class="cx"> {
</span><span class="cx">     my ($self, $type) = @_;
</span><ins>+
</ins><span class="cx">     return $$self{codeGenerator}-&gt;WK_lcfirst(_implementationClassName($type)) . &quot;Class&quot;;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -444,6 +445,7 @@
</span><span class="cx"> {
</span><span class="cx">     my ($self, $type, $argumentName) = @_;
</span><span class="cx"> 
</span><ins>+    return &quot;JSValueToNullableBoolean(context, $argumentName)&quot; if $type-&gt;name eq &quot;boolean&quot; &amp;&amp; $type-&gt;isNullable;
</ins><span class="cx">     return &quot;JSValueToBoolean(context, $argumentName)&quot; if $type-&gt;name eq &quot;boolean&quot;;
</span><span class="cx">     return &quot;$argumentName&quot; if $type-&gt;name eq &quot;object&quot;;
</span><span class="cx">     return &quot;JSRetainPtr&lt;JSStringRef&gt;(Adopt, JSValueToStringCopy(context, $argumentName, 0))&quot; if $$self{codeGenerator}-&gt;IsStringType($type);
</span><span class="lines">@@ -484,6 +486,7 @@
</span><span class="cx">     my ($self, $returnType, $expression) = @_;
</span><span class="cx"> 
</span><span class="cx">     return &quot;JSValueMakeUndefined(context)&quot; if $returnType-&gt;name eq &quot;void&quot;;
</span><ins>+    return &quot;JSValueMakeBooleanOrNull(context, ${expression})&quot; if $returnType-&gt;name eq &quot;boolean&quot; &amp;&amp; $returnType-&gt;isNullable;
</ins><span class="cx">     return &quot;JSValueMakeBoolean(context, ${expression})&quot; if $returnType-&gt;name eq &quot;boolean&quot;;
</span><span class="cx">     return &quot;${expression}&quot; if $returnType-&gt;name eq &quot;object&quot;;
</span><span class="cx">     return &quot;JSValueMakeNumber(context, ${expression})&quot; if $$self{codeGenerator}-&gt;IsNonPointerType($returnType);
</span></span></pre></div>
<a id="trunkToolsWebKitTestRunnercocoaTestRunnerWKWebViewh"></a>
<div class="modfile"><h4>Modified: trunk/Tools/WebKitTestRunner/cocoa/TestRunnerWKWebView.h (208925 => 208926)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/WebKitTestRunner/cocoa/TestRunnerWKWebView.h        2016-11-19 17:39:25 UTC (rev 208925)
+++ trunk/Tools/WebKitTestRunner/cocoa/TestRunnerWKWebView.h        2016-11-19 19:02:04 UTC (rev 208926)
</span><span class="lines">@@ -41,12 +41,11 @@
</span><span class="cx"> @property (nonatomic, copy) void (^didHideKeyboardCallback)(void);
</span><span class="cx"> @property (nonatomic, copy) void (^didEndScrollingCallback)(void);
</span><span class="cx"> 
</span><del>-- (instancetype)initWithFrame:(CGRect)frame configuration:(WKWebViewConfiguration *)configuration;
-- (void)dealloc;
-
</del><span class="cx"> - (void)zoomToScale:(double)scale animated:(BOOL)animated completionHandler:(void (^)(void))completionHandler;
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><ins>+@property (nonatomic, retain, setter=_setStableStateOverride:) NSNumber *_stableStateOverride;
+
</ins><span class="cx"> @end
</span><span class="cx"> 
</span><span class="cx"> #endif // #if WK_API_ENABLED
</span></span></pre></div>
<a id="trunkToolsWebKitTestRunnercocoaTestRunnerWKWebViewmm"></a>
<div class="modfile"><h4>Modified: trunk/Tools/WebKitTestRunner/cocoa/TestRunnerWKWebView.mm (208925 => 208926)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/WebKitTestRunner/cocoa/TestRunnerWKWebView.mm        2016-11-19 17:39:25 UTC (rev 208925)
+++ trunk/Tools/WebKitTestRunner/cocoa/TestRunnerWKWebView.mm        2016-11-19 19:02:04 UTC (rev 208926)
</span><span class="lines">@@ -43,10 +43,14 @@
</span><span class="cx"> 
</span><span class="cx"> #if WK_API_ENABLED
</span><span class="cx"> 
</span><del>-@interface TestRunnerWKWebView ()
</del><ins>+@interface TestRunnerWKWebView () {
+    RetainPtr&lt;NSNumber *&gt; _stableStateOverride;
+}
+
</ins><span class="cx"> @property (nonatomic, copy) void (^zoomToScaleCompletionHandler)(void);
</span><span class="cx"> @property (nonatomic, copy) void (^showKeyboardCompletionHandler)(void);
</span><span class="cx"> @property (nonatomic) BOOL isShowingKeyboard;
</span><ins>+
</ins><span class="cx"> @end
</span><span class="cx"> 
</span><span class="cx"> @implementation TestRunnerWKWebView
</span><span class="lines">@@ -170,6 +174,17 @@
</span><span class="cx">     if (self.didEndScrollingCallback)
</span><span class="cx">         self.didEndScrollingCallback();
</span><span class="cx"> }
</span><ins>+
+- (NSNumber *)_stableStateOverride
+{
+    return _stableStateOverride.get();
+}
+
+- (void)_setStableStateOverride:(NSNumber *)overrideBoolean
+{
+    _stableStateOverride = overrideBoolean;
+}
+
</ins><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx"> @end
</span></span></pre></div>
<a id="trunkToolsWebKitTestRunneriosTestControllerIOSmm"></a>
<div class="modfile"><h4>Modified: trunk/Tools/WebKitTestRunner/ios/TestControllerIOS.mm (208925 => 208926)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/WebKitTestRunner/ios/TestControllerIOS.mm        2016-11-19 17:39:25 UTC (rev 208925)
+++ trunk/Tools/WebKitTestRunner/ios/TestControllerIOS.mm        2016-11-19 19:02:04 UTC (rev 208926)
</span><span class="lines">@@ -86,6 +86,7 @@
</span><span class="cx">     cocoaResetStateToConsistentValues();
</span><span class="cx"> 
</span><span class="cx">     if (PlatformWebView* webView = mainWebView()) {
</span><ins>+        webView-&gt;platformView()._stableStateOverride = nil;
</ins><span class="cx">         UIScrollView *scrollView = webView-&gt;platformView().scrollView;
</span><span class="cx">         [scrollView setZoomScale:1 animated:NO];
</span><span class="cx">         [scrollView setContentOffset:CGPointZero];
</span></span></pre></div>
<a id="trunkToolsWebKitTestRunneriosUIScriptControllerIOSmm"></a>
<div class="modfile"><h4>Modified: trunk/Tools/WebKitTestRunner/ios/UIScriptControllerIOS.mm (208925 => 208926)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/WebKitTestRunner/ios/UIScriptControllerIOS.mm        2016-11-19 17:39:25 UTC (rev 208925)
+++ trunk/Tools/WebKitTestRunner/ios/UIScriptControllerIOS.mm        2016-11-19 19:02:04 UTC (rev 208926)
</span><span class="lines">@@ -55,6 +55,18 @@
</span><span class="cx">     });
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void UIScriptController::doAfterPresentationUpdate(JSValueRef callback)
+{
+    TestRunnerWKWebView *webView = TestController::singleton().mainWebView()-&gt;platformView();
+
+    unsigned callbackID = m_context-&gt;prepareForAsyncTask(callback, CallbackTypeNonPersistent);
+    [webView _doAfterNextPresentationUpdate:^{
+        if (!m_context)
+            return;
+        m_context-&gt;asyncTaskComplete(callbackID);
+    }];
+}
+
</ins><span class="cx"> void UIScriptController::zoomToScale(double scale, JSValueRef callback)
</span><span class="cx"> {
</span><span class="cx">     TestRunnerWKWebView *webView = TestController::singleton().mainWebView()-&gt;platformView();
</span><span class="lines">@@ -357,6 +369,18 @@
</span><span class="cx">     [webView.scrollView setContentOffset:contentOffsetBoundedInValidRange(webView.scrollView, CGPointMake(x, y)) animated:YES];
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void UIScriptController::immediateScrollToOffset(long x, long y)
+{
+    TestRunnerWKWebView *webView = TestController::singleton().mainWebView()-&gt;platformView();
+    [webView.scrollView setContentOffset:contentOffsetBoundedInValidRange(webView.scrollView, CGPointMake(x, y)) animated:NO];
+}
+
+void UIScriptController::immediateZoomToScale(double scale)
+{
+    TestRunnerWKWebView *webView = TestController::singleton().mainWebView()-&gt;platformView();
+    [webView.scrollView setZoomScale:scale animated:NO];
+}
+
</ins><span class="cx"> void UIScriptController::keyboardAccessoryBarNext()
</span><span class="cx"> {
</span><span class="cx">     TestRunnerWKWebView *webView = TestController::singleton().mainWebView()-&gt;platformView();
</span><span class="lines">@@ -381,6 +405,24 @@
</span><span class="cx">     return webView.scrollView.maximumZoomScale;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+Optional&lt;bool&gt; UIScriptController::stableStateOverride() const
+{
+    TestRunnerWKWebView *webView = TestController::singleton().mainWebView()-&gt;platformView();
+    if (webView._stableStateOverride)
+        return webView._stableStateOverride.boolValue;
+
+    return Nullopt;
+}
+
+void UIScriptController::setStableStateOverride(Optional&lt;bool&gt; overrideValue)
+{
+    TestRunnerWKWebView *webView = TestController::singleton().mainWebView()-&gt;platformView();
+    if (overrideValue)
+        webView._stableStateOverride = @(overrideValue.value());
+    else
+        webView._stableStateOverride = nil;
+}
+
</ins><span class="cx"> JSObjectRef UIScriptController::contentVisibleRect() const
</span><span class="cx"> {
</span><span class="cx">     TestRunnerWKWebView *webView = TestController::singleton().mainWebView()-&gt;platformView();
</span></span></pre></div>
<a id="trunkToolsWebKitTestRunnermacUIScriptControllerMacmm"></a>
<div class="modfile"><h4>Modified: trunk/Tools/WebKitTestRunner/mac/UIScriptControllerMac.mm (208925 => 208926)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/WebKitTestRunner/mac/UIScriptControllerMac.mm        2016-11-19 17:39:25 UTC (rev 208925)
+++ trunk/Tools/WebKitTestRunner/mac/UIScriptControllerMac.mm        2016-11-19 19:02:04 UTC (rev 208926)
</span><span class="lines">@@ -56,6 +56,11 @@
</span><span class="cx">     });
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void UIScriptController::doAfterPresentationUpdate(JSValueRef callback)
+{
+    return doAsyncTask(callback);
+}
+
</ins><span class="cx"> void UIScriptController::insertText(JSStringRef text, int location, int length)
</span><span class="cx"> {
</span><span class="cx"> #if WK_API_ENABLED
</span></span></pre>
</div>
</div>

</body>
</html>