Reorganize UIScriptController into platform-specific subclasses
authortimothy_horton@apple.com <timothy_horton@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 29 Jul 2019 02:10:56 +0000 (02:10 +0000)
committertimothy_horton@apple.com <timothy_horton@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 29 Jul 2019 02:10:56 +0000 (02:10 +0000)
https://bugs.webkit.org/show_bug.cgi?id=200027

Reviewed by Simon Fraser.

Instead of a mishmash of #ifdefs and extraneous empty functions,
reorganize UIScriptController so that we have a base class
with functions that assert if called (to make it harder to
accidentally write a test that depends on unimplemented
functionality), and override them in platform specific subclasses
as functionality is added.

* DumpRenderTree/DumpRenderTree.xcodeproj/project.pbxproj:
* DumpRenderTree/ios/UIScriptControllerIOS.h: Added.
* DumpRenderTree/ios/UIScriptControllerIOS.mm:
* DumpRenderTree/mac/UIScriptControllerMac.h: Added.
* DumpRenderTree/mac/UIScriptControllerMac.mm:
* TestRunnerShared/UIScriptContext/UIScriptController.cpp:
* TestRunnerShared/UIScriptContext/UIScriptController.h:
* WebKitTestRunner/WebKitTestRunner.xcodeproj/project.pbxproj:
* WebKitTestRunner/cocoa/UIScriptControllerCocoa.h: Added.
* WebKitTestRunner/cocoa/UIScriptControllerCocoa.mm: Added.
* WebKitTestRunner/gtk/UIScriptControllerGtk.cpp:
* WebKitTestRunner/gtk/UIScriptControllerGtk.h: Added.
* WebKitTestRunner/ios/UIScriptControllerIOS.h: Added.
* WebKitTestRunner/ios/UIScriptControllerIOS.mm:
* WebKitTestRunner/mac/UIScriptControllerMac.h: Added.
* WebKitTestRunner/mac/UIScriptControllerMac.mm:

* http/tests/contentdispositionattachmentsandbox/resources/referer-header-stripped.js:
(onload):
This test both uses event sender to click, and UIScriptController to "tap".
Since singleTapAtPoint is unimplemented on macOS, it really just ended
up doing nothing, but now it asserts. Only click or tap, but not both.

* platform/mac/TestExpectations:
* platform/win/TestExpectations:
Skip some tests for unimplemented or unsupported features.

* platform/mac/fast/events/autoscroll-when-input-is-offscreen-expected.txt: Removed.
* platform/mac/fast/events/autoscroll-with-software-keyboard-expected.txt: Removed.
Remove unneeded test results.

* swipe/resources/swipe-test.js:
(playEventStream):
playBackEventStream is unimplemented on iOS. Also, it's not necessary
for simulated swipe to send events at all on iOS, so just bail, which
is equivalent to what used to happen.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@247898 268f45cc-cd09-0410-ab3c-d52691b4dbfc

24 files changed:
LayoutTests/ChangeLog
LayoutTests/http/tests/contentdispositionattachmentsandbox/resources/referer-header-stripped.js
LayoutTests/platform/mac/TestExpectations
LayoutTests/platform/mac/fast/events/autoscroll-when-input-is-offscreen-expected.txt [deleted file]
LayoutTests/platform/mac/fast/events/autoscroll-with-software-keyboard-expected.txt [deleted file]
LayoutTests/platform/win/TestExpectations
LayoutTests/swipe/resources/swipe-test.js
Tools/ChangeLog
Tools/DumpRenderTree/DumpRenderTree.xcodeproj/project.pbxproj
Tools/DumpRenderTree/ios/UIScriptControllerIOS.h [new file with mode: 0644]
Tools/DumpRenderTree/ios/UIScriptControllerIOS.mm
Tools/DumpRenderTree/mac/UIScriptControllerMac.h [new file with mode: 0644]
Tools/DumpRenderTree/mac/UIScriptControllerMac.mm
Tools/TestRunnerShared/UIScriptContext/UIScriptController.cpp
Tools/TestRunnerShared/UIScriptContext/UIScriptController.h
Tools/WebKitTestRunner/WebKitTestRunner.xcodeproj/project.pbxproj
Tools/WebKitTestRunner/cocoa/UIScriptControllerCocoa.h [new file with mode: 0644]
Tools/WebKitTestRunner/cocoa/UIScriptControllerCocoa.mm [moved from Tools/WebKitTestRunner/UIScriptControllerCocoa.mm with 63% similarity]
Tools/WebKitTestRunner/gtk/UIScriptControllerGtk.cpp
Tools/WebKitTestRunner/gtk/UIScriptControllerGtk.h [new file with mode: 0644]
Tools/WebKitTestRunner/ios/UIScriptControllerIOS.h [new file with mode: 0644]
Tools/WebKitTestRunner/ios/UIScriptControllerIOS.mm
Tools/WebKitTestRunner/mac/UIScriptControllerMac.h [new file with mode: 0644]
Tools/WebKitTestRunner/mac/UIScriptControllerMac.mm

index 264a0ae..fc51150 100644 (file)
@@ -1,3 +1,30 @@
+2019-07-28  Tim Horton  <timothy_horton@apple.com>
+
+        Reorganize UIScriptController into platform-specific subclasses
+        https://bugs.webkit.org/show_bug.cgi?id=200027
+
+        Reviewed by Simon Fraser.
+
+        * http/tests/contentdispositionattachmentsandbox/resources/referer-header-stripped.js:
+        (onload):
+        This test both uses event sender to click, and UIScriptController to "tap".
+        Since singleTapAtPoint is unimplemented on macOS, it really just ended
+        up doing nothing, but now it asserts. Only click or tap, but not both.
+
+        * platform/mac/TestExpectations:
+        * platform/win/TestExpectations:
+        Skip some tests for unimplemented or unsupported features.
+
+        * platform/mac/fast/events/autoscroll-when-input-is-offscreen-expected.txt: Removed.
+        * platform/mac/fast/events/autoscroll-with-software-keyboard-expected.txt: Removed.
+        Remove unneeded test results.
+
+        * swipe/resources/swipe-test.js:
+        (playEventStream):
+        playBackEventStream is unimplemented on iOS. Also, it's not necessary
+        for simulated swipe to send events at all on iOS, so just bail, which
+        is equivalent to what used to happen.
+
 2019-07-27  Andres Gonzalez  <andresg_22@apple.com>
 
         Expose the aria-label attribute for <video> elements.
index c645c17..eb6f989 100644 (file)
@@ -18,9 +18,7 @@ onload = function() {
             eventSender.mouseMoveTo(x, y);
             eventSender.mouseDown();
             eventSender.mouseUp();
-        }
-
-        if (testRunner.runUIScript)
+        } else if (testRunner.runUIScript)
             testRunner.runUIScript("(function() { uiController.singleTapAtPoint(" + x + ", " + y + "); })()");
     }
 }
\ No newline at end of file
index 16d9a67..92815d7 100644 (file)
@@ -227,6 +227,10 @@ storage/storagequota-query-usage.html
 storage/storagequota-request-quota.html
 fast/workers/worker-storagequota-query-usage.html
 
+# Software keyboard is not supported.
+fast/events/autoscroll-with-software-keyboard.html [ Skip ]
+fast/events/autoscroll-when-input-is-offscreen.html [ Skip ]
+
 # HTTP 204 (No Content) should be ignored
 webkit.org/b/60206 http/tests/navigation/response204.html
 
@@ -1098,8 +1102,8 @@ webkit.org/b/187622 [ Debug ] inspector/view/asynchronous-layout.html [ Pass Tim
 
 webkit.org/b/149128 fast/text/control-characters [ ImageOnlyFailure ]
 
-# Touch events is not enabled on Mac
-webkit.org/b/149592 fast/shadow-dom/touch-event-ios.html [ Failure ]
+# Touch events are not enabled on Mac
+webkit.org/b/149592 fast/shadow-dom/touch-event-ios.html [ Skip ]
 
 webkit.org/b/149819 [ Debug Sierra+ ] compositing/video/video-poster.html [ Pass Crash ]
 
diff --git a/LayoutTests/platform/mac/fast/events/autoscroll-when-input-is-offscreen-expected.txt b/LayoutTests/platform/mac/fast/events/autoscroll-when-input-is-offscreen-expected.txt
deleted file mode 100644 (file)
index 522e657..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-This test focuses a form, them scrolls to the bottom of the page. Then text is entered in the form, and we check to make sure the page has scrolled so that the input is visible again.
-FAIL: page has failed to scroll when entering text into a form that is offscreen.
-
diff --git a/LayoutTests/platform/mac/fast/events/autoscroll-with-software-keyboard-expected.txt b/LayoutTests/platform/mac/fast/events/autoscroll-with-software-keyboard-expected.txt
deleted file mode 100644 (file)
index e788cac..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-This test presses return until the cursor would be behind the keyboard, forcing the content to be scrolled to stay in view with a software keyboard on screen.
-FAIL: page has failed to scroll when caret is behind software keyboard.
-FAIL: page has failed to scroll when caret is beyond the edge of the screen.
-
index b2e5923..01a2147 100644 (file)
@@ -210,6 +210,17 @@ webkit.org/b/29287 http/tests/local/fileapi/ [ Skip ]
 webkit.org/b/29287 http/tests/local/blob/send-hybrid-blob.html [ Skip ]
 webkit.org/b/29287 http/tests/local/formdata/ [ Skip ]
 
+# Software keyboard is not supported.
+fast/events/autoscroll-with-software-keyboard.html [ Skip ]
+fast/events/autoscroll-when-input-is-offscreen.html [ Skip ]
+
+# UIScriptController::zoomToScale is not supported.
+fast/visual-viewport/client-coordinates-relative-to-layout-viewport.html [ Skip ]
+fast/visual-viewport/client-rects-relative-to-layout-viewport.html [ Skip ]
+
+# UIScriptController::removeViewFromWindow/addViewToWindow is not supported.
+pageoverlay/overlay-remove-reinsert-view.html [ Skip ]
+
 # TODO Need Blob.slice support
 http/tests/local/blob/send-sliced-data-blob.html [ Skip ]
 
@@ -3085,8 +3096,8 @@ webkit.org/b/152411 http/tests/contentdispositionattachmentsandbox/referer-heade
 webkit.org/b/152411 http/tests/contentdispositionattachmentsandbox/referer-header-stripped-with-meta-referer-unsafe-url.html [ Failure ]
 webkit.org/b/152411 http/tests/contentdispositionattachmentsandbox/referer-header-stripped.html [ Failure ]
 
-# Touch events is not enabled on Windows
-webkit.org/b/149592 fast/shadow-dom/touch-event-ios.html [ Failure ]
+# Touch events are not enabled on Windows
+webkit.org/b/149592 fast/shadow-dom/touch-event-ios.html [ Skip ]
 
 # The SVG -> OTF Font converter outputs 'kern' tables instead of 'GPOS' tables.
 webkit.org/b/137204 fast/text/svg-font-face-with-kerning.html [ Failure ]
@@ -3562,8 +3573,6 @@ fast/text/system-font-fallback-emoji.html [ Failure ]
 fast/text/web-font-load-invisible-during-loading.html [ Failure ]
 fast/url/standard-url.html [ Failure ]
 fast/url/tab-and-newline-stripping.html [ Failure ]
-fast/visual-viewport/client-coordinates-relative-to-layout-viewport.html [ Failure ]
-fast/visual-viewport/client-rects-relative-to-layout-viewport.html [ Failure ]
 fast/visual-viewport/rubberbanding-viewport-rects-extended-background.html [ Failure ]
 http/tests/frame-throttling/raf-throttle-in-cross-origin-subframe.html [ Failure ]
 http/tests/misc/form-blob-challenge.html [ Failure ]
@@ -3579,7 +3588,6 @@ http/tests/security/credentials-iframes.html [ Failure ]
 http/tests/security/cross-frame-access-callback-explicit-domain-ALLOW.html [ Failure ]
 http/tests/security/xss-DENIED-xsl-external-entity-redirect.xml [ Failure ]
 js/shared-array-buffer-webgl.html [ Failure ]
-pageoverlay/overlay-remove-reinsert-view.html [ Failure ]
 storage/indexeddb/version-change-event-basic.html [ Failure ]
 storage/indexeddb/wasm-exceptions.html [ Failure ]
 streams/pipe-to.html [ Failure ]
index 0c2365d..b4340ff 100644 (file)
@@ -64,6 +64,12 @@ function completeSwipeGesture(callback)
 function playEventStream(stream, callback)
 {
     log("playEventStream");
+    if (testRunner.isIOSFamily) {
+        // FIXME: This test should probably not log playEventStream
+        // on iOS, where it doesn't actually do it.
+        setTimeout(callback, 0);
+        return;
+    }
     testRunner.runUIScript(`
     (function() {
         uiController.playBackEventStream(\`${stream}\`, function() {
index c7fe3ab..dadd1b8 100644 (file)
@@ -1,3 +1,34 @@
+2019-07-28  Tim Horton  <timothy_horton@apple.com>
+
+        Reorganize UIScriptController into platform-specific subclasses
+        https://bugs.webkit.org/show_bug.cgi?id=200027
+
+        Reviewed by Simon Fraser.
+
+        Instead of a mishmash of #ifdefs and extraneous empty functions,
+        reorganize UIScriptController so that we have a base class
+        with functions that assert if called (to make it harder to
+        accidentally write a test that depends on unimplemented
+        functionality), and override them in platform specific subclasses
+        as functionality is added.
+
+        * DumpRenderTree/DumpRenderTree.xcodeproj/project.pbxproj:
+        * DumpRenderTree/ios/UIScriptControllerIOS.h: Added.
+        * DumpRenderTree/ios/UIScriptControllerIOS.mm:
+        * DumpRenderTree/mac/UIScriptControllerMac.h: Added.
+        * DumpRenderTree/mac/UIScriptControllerMac.mm:
+        * TestRunnerShared/UIScriptContext/UIScriptController.cpp:
+        * TestRunnerShared/UIScriptContext/UIScriptController.h:
+        * WebKitTestRunner/WebKitTestRunner.xcodeproj/project.pbxproj:
+        * WebKitTestRunner/cocoa/UIScriptControllerCocoa.h: Added.
+        * WebKitTestRunner/cocoa/UIScriptControllerCocoa.mm: Added.
+        * WebKitTestRunner/gtk/UIScriptControllerGtk.cpp:
+        * WebKitTestRunner/gtk/UIScriptControllerGtk.h: Added.
+        * WebKitTestRunner/ios/UIScriptControllerIOS.h: Added.
+        * WebKitTestRunner/ios/UIScriptControllerIOS.mm:
+        * WebKitTestRunner/mac/UIScriptControllerMac.h: Added.
+        * WebKitTestRunner/mac/UIScriptControllerMac.mm:
+
 2019-07-28  Fujii Hironori  <Hironori.Fujii@sony.com>
 
         [Win][MiniBrowser] Remove PageLoadTestClient
index d140c38..92ba3cb 100644 (file)
                29CFBA0F122736E600BC30C0 /* AccessibilityTextMarker.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AccessibilityTextMarker.cpp; sourceTree = "<group>"; };
                29CFBA2D12273A1000BC30C0 /* AccessibilityTextMarkerMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = AccessibilityTextMarkerMac.mm; path = mac/AccessibilityTextMarkerMac.mm; sourceTree = "<group>"; };
                2CE88FA117124CEE00734FC0 /* JavaScriptThreading.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JavaScriptThreading.cpp; sourceTree = "<group>"; };
+               2D0BEE1422E599B60092B738 /* UIScriptControllerMac.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = UIScriptControllerMac.h; path = mac/UIScriptControllerMac.h; sourceTree = "<group>"; };
+               2D0BEE1622EACE8E0092B738 /* UIScriptControllerIOS.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = UIScriptControllerIOS.h; path = ios/UIScriptControllerIOS.h; sourceTree = "<group>"; };
                2D403EA215087142005358D2 /* LayoutTestHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = LayoutTestHelper.m; path = mac/LayoutTestHelper.m; sourceTree = "<group>"; };
                2D403F19150871F9005358D2 /* LayoutTestHelper */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = LayoutTestHelper; sourceTree = BUILT_PRODUCTS_DIR; };
                31117B3A15D9A56A00163BC8 /* MockWebNotificationProvider.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MockWebNotificationProvider.h; path = mac/MockWebNotificationProvider.h; sourceTree = "<group>"; };
                0F6A0DFF1D6E0F8600F1C9A8 /* ios */ = {
                        isa = PBXGroup;
                        children = (
+                               2D0BEE1622EACE8E0092B738 /* UIScriptControllerIOS.h */,
                                0F18E70C1D6BAC8C0027E547 /* UIScriptControllerIOS.mm */,
                        );
                        name = ios;
                0F6A0E001D6E0F8A00F1C9A8 /* mac */ = {
                        isa = PBXGroup;
                        children = (
+                               2D0BEE1422E599B60092B738 /* UIScriptControllerMac.h */,
                                0F18E70E1D6BACB60027E547 /* UIScriptControllerMac.mm */,
                        );
                        name = mac;
diff --git a/Tools/DumpRenderTree/ios/UIScriptControllerIOS.h b/Tools/DumpRenderTree/ios/UIScriptControllerIOS.h
new file mode 100644 (file)
index 0000000..88181e9
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2019 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#import "UIScriptController.h"
+
+#if PLATFORM(IOS_FAMILY)
+
+namespace WTR {
+
+class UIScriptControllerIOS : public UIScriptController {
+public:
+    explicit UIScriptControllerIOS(UIScriptContext& context)
+        : UIScriptController(context)
+    {
+    }
+
+    void doAsyncTask(JSValueRef callback) override;
+    void zoomToScale(double scale, JSValueRef callback) override;
+    double zoomScale() const override;
+    double contentOffsetX() const override;
+    double contentOffsetY() const override;
+    void scrollToOffset(long x, long y) override;
+    void immediateScrollToOffset(long x, long y) override;
+    void immediateZoomToScale(double scale) override;
+    double minimumZoomScale() const override;
+    double maximumZoomScale() const override;
+    JSObjectRef contentVisibleRect() const override;
+};
+
+}
+#endif // PLATFORM(IOS_FAMILY)
index c6f55a3..42a6b95 100644 (file)
@@ -24,7 +24,7 @@
  */
 
 #import "config.h"
-#import "UIScriptController.h"
+#import "UIScriptControllerIOS.h"
 
 #if PLATFORM(IOS_FAMILY)
 
@@ -37,12 +37,13 @@ extern DumpRenderTreeBrowserView *gWebBrowserView;
 extern DumpRenderTreeWebScrollView *gWebScrollView;
 
 namespace WTR {
-    
-void UIScriptController::checkForOutstandingCallbacks()
+
+Ref<UIScriptController> UIScriptController::create(UIScriptContext& context)
 {
+    return adoptRef(*new UIScriptControllerIOS(context));
 }
 
-void UIScriptController::doAsyncTask(JSValueRef callback)
+void UIScriptControllerIOS::doAsyncTask(JSValueRef callback)
 {
     unsigned callbackID = m_context->prepareForAsyncTask(callback, CallbackTypeNonPersistent);
 
@@ -53,174 +54,25 @@ void UIScriptController::doAsyncTask(JSValueRef callback)
     });
 }
 
-void UIScriptController::doAfterPresentationUpdate(JSValueRef callback)
-{
-    return doAsyncTask(callback);
-}
-
-void UIScriptController::doAfterNextStablePresentationUpdate(JSValueRef callback)
-{
-    doAsyncTask(callback);
-}
-
-void UIScriptController::ensurePositionInformationIsUpToDateAt(long x, long y, JSValueRef callback)
-{
-    return doAsyncTask(callback);
-}
-
-void UIScriptController::doAfterVisibleContentRectUpdate(JSValueRef callback)
+void UIScriptControllerIOS::zoomToScale(double scale, JSValueRef callback)
 {
-    doAsyncTask(callback);
-}
+    unsigned callbackID = m_context->prepareForAsyncTask(callback, CallbackTypeNonPersistent);
 
-void UIScriptController::zoomToScale(double scale, JSValueRef callback)
-{
     RefPtr<UIScriptController> protectedThis(this);
-    unsigned callbackID = protectedThis->context()->prepareForAsyncTask(callback, CallbackTypeNonPersistent);
-
     dispatch_async(dispatch_get_main_queue(), ^{
         [gWebScrollView zoomToScale:scale animated:YES completionHandler:^{
-            if (!protectedThis->context())
+            if (!m_context)
                 return;
-            protectedThis->context()->asyncTaskComplete(callbackID);
+            m_context->asyncTaskComplete(callbackID);
         }];
     });
 }
 
-void UIScriptController::resignFirstResponder()
-{
-}
-
-void UIScriptController::setViewScale(double)
-{
-}
-
-void UIScriptController::setMinimumEffectiveWidth(double)
-{
-}
-
-void UIScriptController::setAllowsViewportShrinkToFit(bool)
-{
-}
-
-void UIScriptController::simulateAccessibilitySettingsChangeNotification(JSValueRef)
-{
-}
-
-double UIScriptController::zoomScale() const
+double UIScriptControllerIOS::zoomScale() const
 {
     return gWebScrollView.zoomScale;
 }
 
-void UIScriptController::touchDownAtPoint(long x, long y, long touchCount, JSValueRef callback)
-{
-}
-
-void UIScriptController::liftUpAtPoint(long x, long y, long touchCount, JSValueRef callback)
-{
-}
-
-void UIScriptController::singleTapAtPoint(long x, long y, JSValueRef callback)
-{
-}
-
-void UIScriptController::singleTapAtPointWithModifiers(long x, long y, JSValueRef modifierArray, JSValueRef callback)
-{
-}
-
-void UIScriptController::doubleTapAtPoint(long x, long y, JSValueRef callback)
-{
-}
-
-void UIScriptController::dragFromPointToPoint(long startX, long startY, long endX, long endY, double durationSeconds, JSValueRef callback)
-{
-}
-    
-void UIScriptController::longPressAtPoint(long x, long y, JSValueRef)
-{
-}
-
-void UIScriptController::stylusDownAtPoint(long x, long y, float azimuthAngle, float altitudeAngle, float pressure, JSValueRef callback)
-{
-}
-
-void UIScriptController::stylusMoveToPoint(long x, long y, float azimuthAngle, float altitudeAngle, float pressure, JSValueRef callback)
-{
-}
-
-void UIScriptController::stylusUpAtPoint(long x, long y, JSValueRef callback)
-{
-}
-
-void UIScriptController::stylusTapAtPoint(long x, long y, float azimuthAngle, float altitudeAngle, float pressure, JSValueRef callback)
-{
-}
-
-void UIScriptController::stylusTapAtPointWithModifiers(long x, long y, float azimuthAngle, float altitudeAngle, float pressure, JSValueRef modifierArray, JSValueRef callback)
-{
-}
-
-void UIScriptController::sendEventStream(JSStringRef eventsJSON, JSValueRef callback)
-{
-}
-
-void UIScriptController::enterText(JSStringRef)
-{
-}
-
-void UIScriptController::typeCharacterUsingHardwareKeyboard(JSStringRef character, JSValueRef callback)
-{
-}
-
-void UIScriptController::keyDown(JSStringRef, JSValueRef)
-{
-}
-
-void UIScriptController::dismissFormAccessoryView()
-{
-}
-
-void UIScriptController::dismissFilePicker(JSValueRef)
-{
-}
-
-void UIScriptController::setTimePickerValue(long, long)
-{
-}
-
-void UIScriptController::setShareSheetCompletesImmediatelyWithResolution(bool)
-{
-}
-
-void UIScriptController::selectFormAccessoryPickerRow(long rowIndex)
-{
-}
-
-bool UIScriptController::isPresentingModally() const
-{
-    return false;
-}
-
-JSRetainPtr<JSStringRef> UIScriptController::textContentType() const
-{
-    return nullptr;
-}
-
-JSRetainPtr<JSStringRef> UIScriptController::selectFormPopoverTitle() const
-{
-    return nullptr;
-}
-
-JSRetainPtr<JSStringRef> UIScriptController::formInputLabel() const
-{
-    return nullptr;
-}
-    
-JSObjectRef UIScriptController::contentsOfUserInterfaceItem(JSStringRef interfaceItem) const
-{
-    return nullptr;
-}
-
 static CGPoint contentOffsetBoundedInValidRange(UIScrollView *scrollView, CGPoint contentOffset)
 {
     UIEdgeInsets contentInsets = scrollView.contentInset;
@@ -237,323 +89,48 @@ static CGPoint contentOffsetBoundedInValidRange(UIScrollView *scrollView, CGPoin
     return contentOffset;
 }
 
-double UIScriptController::contentOffsetX() const
+double UIScriptControllerIOS::contentOffsetX() const
 {
     return [gWebScrollView contentOffset].x;
 }
 
-double UIScriptController::contentOffsetY() const
+double UIScriptControllerIOS::contentOffsetY() const
 {
     return [gWebScrollView contentOffset].y;
 }
 
-bool UIScriptController::scrollUpdatesDisabled() const
-{
-    return false;
-}
-
-void UIScriptController::setScrollUpdatesDisabled(bool)
-{
-}
-
-void UIScriptController::scrollToOffset(long x, long y)
+void UIScriptControllerIOS::scrollToOffset(long x, long y)
 {
     [gWebScrollView setContentOffset:contentOffsetBoundedInValidRange(gWebScrollView, CGPointMake(x, y)) animated:YES];
 }
 
-void UIScriptController::immediateScrollToOffset(long x, long y)
+void UIScriptControllerIOS::immediateScrollToOffset(long x, long y)
 {
     [gWebScrollView setContentOffset:contentOffsetBoundedInValidRange(gWebScrollView, CGPointMake(x, y)) animated:NO];
 }
 
-void UIScriptController::immediateScrollElementAtContentPointToOffset(long x, long y, long xScrollOffset, long yScrollOffset)
-{
-}
-
-void UIScriptController::immediateZoomToScale(double scale)
+void UIScriptControllerIOS::immediateZoomToScale(double scale)
 {
     [gWebScrollView setZoomScale:scale animated:NO];
 }
 
-void UIScriptController::keyboardAccessoryBarNext()
-{
-}
-
-void UIScriptController::keyboardAccessoryBarPrevious()
-{
-}
-
-void UIScriptController::applyAutocorrection(JSStringRef, JSStringRef, JSValueRef)
-{
-}
-
-bool UIScriptController::isShowingKeyboard() const
-{
-    return false;
-}
-
-bool UIScriptController::hasInputSession() const
-{
-    return false;
-}
-
-double UIScriptController::minimumZoomScale() const
+double UIScriptControllerIOS::minimumZoomScale() const
 {
     return gWebScrollView.minimumZoomScale;
 }
 
-double UIScriptController::maximumZoomScale() const
+double UIScriptControllerIOS::maximumZoomScale() const
 {
     return gWebScrollView.maximumZoomScale;
 }
 
-Optional<bool> UIScriptController::stableStateOverride() const
-{
-    return WTF::nullopt;
-}
-
-void UIScriptController::setStableStateOverride(Optional<bool>)
-{
-}
-
-JSObjectRef UIScriptController::contentVisibleRect() const
+JSObjectRef UIScriptControllerIOS::contentVisibleRect() const
 {
     CGRect contentVisibleRect = [gWebBrowserView documentVisibleRect];
     WebCore::FloatRect rect(contentVisibleRect.origin.x, contentVisibleRect.origin.y, contentVisibleRect.size.width, contentVisibleRect.size.height);
     return m_context->objectFromRect(rect);
 }
 
-void UIScriptController::platformSetDidStartFormControlInteractionCallback()
-{
-}
-
-void UIScriptController::platformSetDidEndFormControlInteractionCallback()
-{
-}
-    
-void UIScriptController::platformSetDidShowForcePressPreviewCallback()
-{
-}
-
-void UIScriptController::platformSetDidDismissForcePressPreviewCallback()
-{
-}
-
-void UIScriptController::platformSetWillBeginZoomingCallback()
-{
-}
-
-void UIScriptController::platformSetDidEndZoomingCallback()
-{
-}
-
-void UIScriptController::platformSetDidShowKeyboardCallback()
-{
-}
-
-void UIScriptController::platformSetDidHideKeyboardCallback()
-{
-}
-
-void UIScriptController::platformSetDidShowMenuCallback()
-{
-}
-
-void UIScriptController::platformSetDidHideMenuCallback()
-{
-}
-
-bool UIScriptController::isShowingPopover() const
-{
-    return false;
-}
-
-void UIScriptController::platformSetWillPresentPopoverCallback()
-{
-}
-
-void UIScriptController::platformSetDidDismissPopoverCallback()
-{
-}
-
-JSObjectRef UIScriptController::rectForMenuAction(JSStringRef) const
-{
-    return nullptr;
-}
-
-JSObjectRef UIScriptController::menuRect() const
-{
-    return nullptr;
-}
-
-bool UIScriptController::isShowingMenu() const
-{
-    return false;
-}
-
-bool UIScriptController::isDismissingMenu() const
-{
-    return false;
-}
-
-void UIScriptController::platformSetDidEndScrollingCallback()
-{
-}
-
-void UIScriptController::platformClearAllCallbacks()
-{
-}
-
-JSObjectRef UIScriptController::textSelectionRangeRects() const
-{
-    return nullptr;
-}
-
-JSObjectRef UIScriptController::textSelectionCaretRect() const
-{
-    return nullptr;
-}
-
-JSObjectRef UIScriptController::inputViewBounds() const
-{
-    return nullptr;
-}
-
-void UIScriptController::removeAllDynamicDictionaries()
-{
-}
-
-JSRetainPtr<JSStringRef> UIScriptController::scrollingTreeAsText() const
-{
-    return nullptr;
-}
-
-JSObjectRef UIScriptController::propertiesOfLayerWithID(uint64_t layerID) const
-{
-    return nullptr;
-}
-
-void UIScriptController::retrieveSpeakSelectionContent(JSValueRef)
-{
-}
-
-JSRetainPtr<JSStringRef> UIScriptController::accessibilitySpeakSelectionContent() const
-{
-    return nullptr;
-}
-
-void UIScriptController::simulateRotation(DeviceOrientation*, JSValueRef)
-{
-}
-
-void UIScriptController::simulateRotationLikeSafari(DeviceOrientation*, JSValueRef)
-{
-}
-
-void UIScriptController::findString(JSStringRef, unsigned long options, unsigned long maxCount)
-{
-}
-
-void UIScriptController::removeViewFromWindow(JSValueRef)
-{
-}
-
-void UIScriptController::addViewToWindow(JSValueRef)
-{
-}
-
-void UIScriptController::setSafeAreaInsets(double, double, double, double)
-{
-}
-
-void UIScriptController::beginBackSwipe(JSValueRef callback)
-{
-}
-
-void UIScriptController::completeBackSwipe(JSValueRef callback)
-{
-}
-
-JSObjectRef UIScriptController::selectionStartGrabberViewRect() const
-{
-    return nullptr;
-}
-
-JSObjectRef UIScriptController::selectionEndGrabberViewRect() const
-{
-    return nullptr;
-}
-
-JSObjectRef UIScriptController::selectionCaretViewRect() const
-{
-    return nullptr;
-}
-
-JSObjectRef UIScriptController::selectionRangeViewRects() const
-{
-    return nullptr;
-}
-
-bool UIScriptController::isShowingDataListSuggestions() const
-{
-    return false;
-}
-
-JSObjectRef UIScriptController::calendarType() const
-{
-    return nullptr;
-}
-
-void UIScriptController::setDefaultCalendarType(JSStringRef calendarIdentifier)
-{
-}
-
-void UIScriptController::overridePreference(JSStringRef, JSStringRef)
-{
-}
-
-void UIScriptController::drawSquareInEditableImage()
-{
-}
-
-long UIScriptController::numberOfStrokesInEditableImage()
-{
-    return 0;
-}
-
-void UIScriptController::toggleCapsLock(JSValueRef callback)
-{
-    doAsyncTask(callback);
-}
-
-JSObjectRef UIScriptController::attachmentInfo(JSStringRef)
-{
-    return nullptr;
-}
-
-void UIScriptController::setKeyboardInputModeIdentifier(JSStringRef)
-{
-}
-
-JSRetainPtr<JSStringRef> UIScriptController::lastUndoLabel() const
-{
-    return nullptr;
-}
-
-JSRetainPtr<JSStringRef> UIScriptController::firstRedoLabel() const
-{
-    return nullptr;
-}
-
-NSUndoManager *UIScriptController::platformUndoManager() const
-{
-    return nil;
-}
-
-void UIScriptController::setHardwareKeyboardAttached(bool)
-{
-}
-
 }
 
 #endif // PLATFORM(IOS_FAMILY)
diff --git a/Tools/DumpRenderTree/mac/UIScriptControllerMac.h b/Tools/DumpRenderTree/mac/UIScriptControllerMac.h
new file mode 100644 (file)
index 0000000..d26407c
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2019 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#import "UIScriptController.h"
+
+#if PLATFORM(MAC)
+
+namespace WTR {
+
+class UIScriptControllerMac : public UIScriptController {
+public:
+    explicit UIScriptControllerMac(UIScriptContext& context)
+        : UIScriptController(context)
+    {
+    }
+
+    void doAsyncTask(JSValueRef) override;
+    void replaceTextAtRange(JSStringRef, int, int) override;
+    void zoomToScale(double, JSValueRef) override;
+    double zoomScale() const override;
+    JSObjectRef contentsOfUserInterfaceItem(JSStringRef) const override;
+    void overridePreference(JSStringRef, JSStringRef) override;
+    void removeViewFromWindow(JSValueRef) override;
+    void addViewToWindow(JSValueRef) override;
+    void toggleCapsLock(JSValueRef) override;
+    void simulateAccessibilitySettingsChangeNotification(JSValueRef) override;
+    NSUndoManager *platformUndoManager() const override;
+};
+
+}
+
+#endif // PLATFORM(MAC)
index f26d2a0..7989eb4 100644 (file)
@@ -24,7 +24,7 @@
  */
 
 #import "config.h"
-#import "UIScriptController.h"
+#import "UIScriptControllerMac.h"
 
 #import "DumpRenderTree.h"
 #import "UIScriptContext.h"
 
 namespace WTR {
 
-void UIScriptController::doAsyncTask(JSValueRef callback)
+Ref<UIScriptController> UIScriptController::create(UIScriptContext& context)
+{
+    return adoptRef(*new UIScriptControllerMac(context));
+}
+
+void UIScriptControllerMac::doAsyncTask(JSValueRef callback)
 {
     unsigned callbackID = m_context->prepareForAsyncTask(callback, CallbackTypeNonPersistent);
 
@@ -51,27 +56,7 @@ void UIScriptController::doAsyncTask(JSValueRef callback)
     });
 }
 
-void UIScriptController::doAfterPresentationUpdate(JSValueRef callback)
-{
-    return doAsyncTask(callback);
-}
-
-void UIScriptController::doAfterNextStablePresentationUpdate(JSValueRef callback)
-{
-    doAsyncTask(callback);
-}
-
-void UIScriptController::ensurePositionInformationIsUpToDateAt(long x, long y, JSValueRef callback)
-{
-    doAsyncTask(callback);
-}
-
-void UIScriptController::doAfterVisibleContentRectUpdate(JSValueRef callback)
-{
-    doAsyncTask(callback);
-}
-
-void UIScriptController::replaceTextAtRange(JSStringRef text, int location, int length)
+void UIScriptControllerMac::replaceTextAtRange(JSStringRef text, int location, int length)
 {
     auto textToInsert = adoptCF(JSStringCopyCFString(kCFAllocatorDefault, text));
     auto rangeAttribute = adoptNS([[NSDictionary alloc] initWithObjectsAndKeys:NSStringFromRange(NSMakeRange(location == -1 ? NSNotFound : location, length)), NSTextInputReplacementRangeAttributeName, nil]);
@@ -80,41 +65,28 @@ void UIScriptController::replaceTextAtRange(JSStringRef text, int location, int
     [mainFrame.webView insertText:textAndRange.get()];
 }
 
-void UIScriptController::zoomToScale(double scale, JSValueRef callback)
+void UIScriptControllerMac::zoomToScale(double scale, JSValueRef callback)
 {
-    unsigned callbackID = m_context->prepareForAsyncTask(callback, CallbackTypeNonPersistent);
-
     WebView *webView = [mainFrame webView];
     [webView _scaleWebView:scale atOrigin:NSZeroPoint];
 
-    dispatch_async(dispatch_get_main_queue(), ^{
-        if (!m_context)
-            return;
-        m_context->asyncTaskComplete(callbackID);
-    });
-}
-
-void UIScriptController::resignFirstResponder()
-{
-}
-
-void UIScriptController::setViewScale(double)
-{
+    doAsyncTask(callback);
 }
 
-void UIScriptController::setMinimumEffectiveWidth(double)
+double UIScriptControllerMac::zoomScale() const
 {
+    return mainFrame.webView._viewScaleFactor;
 }
 
-void UIScriptController::setAllowsViewportShrinkToFit(bool)
+void UIScriptControllerMac::simulateAccessibilitySettingsChangeNotification(JSValueRef callback)
 {
-}
+    NSNotificationCenter *center = [[NSWorkspace sharedWorkspace] notificationCenter];
+    [center postNotificationName:NSWorkspaceAccessibilityDisplayOptionsDidChangeNotification object:[mainFrame webView]];
 
-void UIScriptController::simulateAccessibilitySettingsChangeNotification(JSValueRef)
-{
+    doAsyncTask(callback);
 }
 
-JSObjectRef UIScriptController::contentsOfUserInterfaceItem(JSStringRef interfaceItem) const
+JSObjectRef UIScriptControllerMac::contentsOfUserInterfaceItem(JSStringRef interfaceItem) const
 {
 #if JSC_OBJC_API_ENABLED
     WebView *webView = [mainFrame webView];
@@ -127,7 +99,7 @@ JSObjectRef UIScriptController::contentsOfUserInterfaceItem(JSStringRef interfac
 #endif
 }
 
-void UIScriptController::overridePreference(JSStringRef preferenceRef, JSStringRef valueRef)
+void UIScriptControllerMac::overridePreference(JSStringRef preferenceRef, JSStringRef valueRef)
 {
     WebPreferences *preferences = mainFrame.webView.preferences;
 
@@ -136,19 +108,7 @@ void UIScriptController::overridePreference(JSStringRef preferenceRef, JSStringR
         preferences.minimumFontSize = [(__bridge NSString *)value.get() doubleValue];
 }
 
-void UIScriptController::simulateRotation(DeviceOrientation*, JSValueRef)
-{
-}
-
-void UIScriptController::simulateRotationLikeSafari(DeviceOrientation*, JSValueRef)
-{
-}
-
-void UIScriptController::findString(JSStringRef, unsigned long options, unsigned long maxCount)
-{
-}
-
-void UIScriptController::removeViewFromWindow(JSValueRef callback)
+void UIScriptControllerMac::removeViewFromWindow(JSValueRef callback)
 {
     unsigned callbackID = m_context->prepareForAsyncTask(callback, CallbackTypeNonPersistent);
 
@@ -162,7 +122,7 @@ void UIScriptController::removeViewFromWindow(JSValueRef callback)
     });
 }
 
-void UIScriptController::addViewToWindow(JSValueRef callback)
+void UIScriptControllerMac::addViewToWindow(JSValueRef callback)
 {
     unsigned callbackID = m_context->prepareForAsyncTask(callback, CallbackTypeNonPersistent);
 
@@ -176,65 +136,12 @@ void UIScriptController::addViewToWindow(JSValueRef callback)
     });
 }
 
-void UIScriptController::beginBackSwipe(JSValueRef callback)
-{
-}
-
-void UIScriptController::completeBackSwipe(JSValueRef callback)
-{
-}
-
-void UIScriptController::platformPlayBackEventStream(JSStringRef, JSValueRef)
-{
-}
-
-void UIScriptController::firstResponderSuppressionForWebView(bool)
-{
-}
-
-void UIScriptController::makeWindowContentViewFirstResponder()
-{
-}
-
-bool UIScriptController::isWindowContentViewFirstResponder() const
-{
-    return false;
-}
-
-bool UIScriptController::isShowingDataListSuggestions() const
-{
-    return false;
-}
-
-void UIScriptController::setShareSheetCompletesImmediatelyWithResolution(bool)
-{
-}
-    
-JSObjectRef UIScriptController::calendarType() const
-{
-    return nullptr;
-}
-
-void UIScriptController::setDefaultCalendarType(JSStringRef calendarIdentifier)
-{
-}
-
-void UIScriptController::toggleCapsLock(JSValueRef callback)
+void UIScriptControllerMac::toggleCapsLock(JSValueRef callback)
 {
     doAsyncTask(callback);
 }
 
-JSRetainPtr<JSStringRef> UIScriptController::lastUndoLabel() const
-{
-    return nullptr;
-}
-
-JSRetainPtr<JSStringRef> UIScriptController::firstRedoLabel() const
-{
-    return nullptr;
-}
-
-NSUndoManager *UIScriptController::platformUndoManager() const
+NSUndoManager *UIScriptControllerMac::platformUndoManager() const
 {
     return nil;
 }
index 85c926e..f896604 100644 (file)
@@ -58,16 +58,17 @@ DeviceOrientation* toDeviceOrientation(JSContextRef context, JSValueRef value)
     return nullptr;
 }
 
-UIScriptController::UIScriptController(UIScriptContext& context)
-    : m_context(&context)
+#if !PLATFORM(GTK) && !PLATFORM(COCOA)
+Ref<UIScriptController> UIScriptController::create(UIScriptContext& context)
 {
+    return adoptRef(*new UIScriptController(context));
 }
+#endif
 
-#if !PLATFORM(IOS_FAMILY)
-void UIScriptController::checkForOutstandingCallbacks()
+UIScriptController::UIScriptController(UIScriptContext& context)
+    : m_context(&context)
 {
 }
-#endif
 
 void UIScriptController::contextDestroyed()
 {
@@ -84,36 +85,9 @@ JSClassRef UIScriptController::wrapperClass()
     return JSUIScriptController::uIScriptControllerClass();
 }
 
-#if !PLATFORM(COCOA)
-void UIScriptController::doAsyncTask(JSValueRef)
-{
-}
-
-void simulateAccessibilitySettingsChangeNotification(JSValueRef)
-{
-}
-
-void UIScriptController::doAfterPresentationUpdate(JSValueRef)
-{
-}
-
-void UIScriptController::doAfterNextStablePresentationUpdate(JSValueRef)
-{
-}
-
-void UIScriptController::ensurePositionInformationIsUpToDateAt(long x, long y, JSValueRef)
-{
-}
-
-void UIScriptController::doAfterVisibleContentRectUpdate(JSValueRef)
-{
-}
-#endif
-
 void UIScriptController::setDidStartFormControlInteractionCallback(JSValueRef callback)
 {
     m_context->registerCallback(callback, CallbackTypeDidStartFormControlInteraction);
-    platformSetDidStartFormControlInteractionCallback();
 }
 
 JSValueRef UIScriptController::didStartFormControlInteractionCallback() const
@@ -124,7 +98,6 @@ JSValueRef UIScriptController::didStartFormControlInteractionCallback() const
 void UIScriptController::setDidEndFormControlInteractionCallback(JSValueRef callback)
 {
     m_context->registerCallback(callback, CallbackTypeDidEndFormControlInteraction);
-    platformSetDidEndFormControlInteractionCallback();
 }
 
 JSValueRef UIScriptController::didEndFormControlInteractionCallback() const
@@ -135,7 +108,6 @@ JSValueRef UIScriptController::didEndFormControlInteractionCallback() const
 void UIScriptController::setDidShowForcePressPreviewCallback(JSValueRef callback)
 {
     m_context->registerCallback(callback, CallbackTypeDidShowForcePressPreview);
-    platformSetDidShowForcePressPreviewCallback();
 }
 
 JSValueRef UIScriptController::didShowForcePressPreviewCallback() const
@@ -146,7 +118,6 @@ JSValueRef UIScriptController::didShowForcePressPreviewCallback() const
 void UIScriptController::setDidDismissForcePressPreviewCallback(JSValueRef callback)
 {
     m_context->registerCallback(callback, CallbackTypeDidDismissForcePressPreview);
-    platformSetDidDismissForcePressPreviewCallback();
 }
 
 JSValueRef UIScriptController::didDismissForcePressPreviewCallback() const
@@ -157,7 +128,6 @@ JSValueRef UIScriptController::didDismissForcePressPreviewCallback() const
 void UIScriptController::setWillBeginZoomingCallback(JSValueRef callback)
 {
     m_context->registerCallback(callback, CallbackTypeWillBeginZooming);
-    platformSetWillBeginZoomingCallback();
 }
 
 JSValueRef UIScriptController::willBeginZoomingCallback() const
@@ -168,7 +138,6 @@ JSValueRef UIScriptController::willBeginZoomingCallback() const
 void UIScriptController::setDidEndZoomingCallback(JSValueRef callback)
 {
     m_context->registerCallback(callback, CallbackTypeDidEndZooming);
-    platformSetDidEndZoomingCallback();
 }
 
 JSValueRef UIScriptController::didEndZoomingCallback() const
@@ -179,7 +148,6 @@ JSValueRef UIScriptController::didEndZoomingCallback() const
 void UIScriptController::setDidEndScrollingCallback(JSValueRef callback)
 {
     m_context->registerCallback(callback, CallbackTypeDidEndScrolling);
-    platformSetDidEndScrollingCallback();
 }
 
 JSValueRef UIScriptController::didEndScrollingCallback() const
@@ -190,7 +158,6 @@ JSValueRef UIScriptController::didEndScrollingCallback() const
 void UIScriptController::setDidShowKeyboardCallback(JSValueRef callback)
 {
     m_context->registerCallback(callback, CallbackTypeDidShowKeyboard);
-    platformSetDidShowKeyboardCallback();
 }
 
 JSValueRef UIScriptController::didShowKeyboardCallback() const
@@ -201,7 +168,6 @@ JSValueRef UIScriptController::didShowKeyboardCallback() const
 void UIScriptController::setDidHideKeyboardCallback(JSValueRef callback)
 {
     m_context->registerCallback(callback, CallbackTypeDidHideKeyboard);
-    platformSetDidHideKeyboardCallback();
 }
 
 JSValueRef UIScriptController::didHideKeyboardCallback() const
@@ -212,7 +178,6 @@ JSValueRef UIScriptController::didHideKeyboardCallback() const
 void UIScriptController::setDidShowMenuCallback(JSValueRef callback)
 {
     m_context->registerCallback(callback, CallbackTypeDidShowMenu);
-    platformSetDidShowMenuCallback();
 }
 
 JSValueRef UIScriptController::didShowMenuCallback() const
@@ -223,7 +188,6 @@ JSValueRef UIScriptController::didShowMenuCallback() const
 void UIScriptController::setDidHideMenuCallback(JSValueRef callback)
 {
     m_context->registerCallback(callback, CallbackTypeDidHideMenu);
-    platformSetDidHideMenuCallback();
 }
 
 JSValueRef UIScriptController::didHideMenuCallback() const
@@ -234,7 +198,6 @@ JSValueRef UIScriptController::didHideMenuCallback() const
 void UIScriptController::setWillPresentPopoverCallback(JSValueRef callback)
 {
     m_context->registerCallback(callback, CallbackTypeWillPresentPopover);
-    platformSetWillPresentPopoverCallback();
 }
 
 JSValueRef UIScriptController::willPresentPopoverCallback() const
@@ -245,7 +208,6 @@ JSValueRef UIScriptController::willPresentPopoverCallback() const
 void UIScriptController::setDidDismissPopoverCallback(JSValueRef callback)
 {
     m_context->registerCallback(callback, CallbackTypeDidDismissPopover);
-    platformSetDidDismissPopoverCallback();
 }
 
 JSValueRef UIScriptController::didDismissPopoverCallback() const
@@ -253,497 +215,10 @@ JSValueRef UIScriptController::didDismissPopoverCallback() const
     return m_context->callbackWithID(CallbackTypeDidDismissPopover);
 }
 
-#if !PLATFORM(COCOA)
-
-void UIScriptController::zoomToScale(double, JSValueRef)
-{
-}
-
-void UIScriptController::setViewScale(double)
-{
-}
-
-void UIScriptController::setMinimumEffectiveWidth(double)
-{
-}
-
-void UIScriptController::setAllowsViewportShrinkToFit(bool)
-{
-}
-
-void UIScriptController::resignFirstResponder()
-{
-}
-
-void UIScriptController::simulateAccessibilitySettingsChangeNotification(JSValueRef)
-{
-}
-
-JSObjectRef UIScriptController::contentsOfUserInterfaceItem(JSStringRef interfaceItem) const
-{
-    return nullptr;
-}
-    
-void UIScriptController::setDefaultCalendarType(JSStringRef calendarIdentifier)
-{
-}
-
-JSObjectRef UIScriptController::calendarType() const
-{
-    return nullptr;
-}
-
-void UIScriptController::toggleCapsLock(JSValueRef)
-{
-}
-
-#endif // !PLATFORM(COCOA)
-
-void UIScriptController::playBackEventStream(JSStringRef stream, JSValueRef callback)
-{
-    platformPlayBackEventStream(stream, callback);
-}
-
-#if !PLATFORM(IOS_FAMILY)
-void UIScriptController::touchDownAtPoint(long x, long y, long touchCount, JSValueRef)
-{
-}
-
-void UIScriptController::liftUpAtPoint(long x, long y, long touchCount, JSValueRef)
-{
-}
-
-void UIScriptController::singleTapAtPoint(long x, long y, JSValueRef)
-{
-}
-
-void UIScriptController::singleTapAtPointWithModifiers(long x, long y, JSValueRef modifierArray, JSValueRef callback)
-{
-}
-
-void UIScriptController::doubleTapAtPoint(long x, long y, JSValueRef)
-{
-}
-
-void UIScriptController::dragFromPointToPoint(long startX, long startY, long endX, long endY, double durationSeconds, JSValueRef callback)
-{
-}
-    
-void UIScriptController::longPressAtPoint(long x, long y, JSValueRef)
-{
-}
-
-void UIScriptController::stylusDownAtPoint(long x, long y, float azimuthAngle, float altitudeAngle, float pressure, JSValueRef callback)
-{
-}
-
-void UIScriptController::stylusMoveToPoint(long x, long y, float azimuthAngle, float altitudeAngle, float pressure, JSValueRef callback)
-{
-}
-
-void UIScriptController::stylusUpAtPoint(long x, long y, JSValueRef callback)
-{
-}
-
-void UIScriptController::stylusTapAtPoint(long x, long y, float azimuthAngle, float altitudeAngle, float pressure, JSValueRef callback)
-{
-}
-
-void UIScriptController::stylusTapAtPointWithModifiers(long x, long y, float azimuthAngle, float altitudeAngle, float pressure, JSValueRef modifierArray, JSValueRef callback)
-{
-}
-
-void UIScriptController::sendEventStream(JSStringRef eventsJSON, JSValueRef callback)
-{
-}
-
-void UIScriptController::enterText(JSStringRef)
-{
-}
-
-void UIScriptController::typeCharacterUsingHardwareKeyboard(JSStringRef, JSValueRef)
-{
-}
-
-void UIScriptController::keyDown(JSStringRef, JSValueRef)
-{
-}
-
-void UIScriptController::dismissFormAccessoryView()
-{
-}
-
-void UIScriptController::dismissFilePicker(JSValueRef)
-{
-}
-
-void UIScriptController::setTimePickerValue(long, long)
-{
-}
-
-void UIScriptController::selectFormAccessoryPickerRow(long)
-{
-}
-
-JSRetainPtr<JSStringRef> UIScriptController::textContentType() const
-{
-    return nullptr;
-}
-
-JSRetainPtr<JSStringRef> UIScriptController::selectFormPopoverTitle() const
-{
-    return nullptr;
-}
-
-JSRetainPtr<JSStringRef> UIScriptController::formInputLabel() const
-{
-    return nullptr;
-}
-
-bool UIScriptController::isPresentingModally() const
-{
-    return false;
-}
-
-double UIScriptController::contentOffsetX() const
-{
-    return 0;
-}
-
-double UIScriptController::contentOffsetY() const
-{
-    return 0;
-}
-
-bool UIScriptController::scrollUpdatesDisabled() const
-{
-    return false;
-}
-
-void UIScriptController::setScrollUpdatesDisabled(bool)
-{
-}
-
-void UIScriptController::scrollToOffset(long x, long y)
-{
-}
-
-void UIScriptController::immediateScrollToOffset(long x, long y)
-{
-}
-
-void UIScriptController::immediateScrollElementAtContentPointToOffset(long x, long y, long xScrollOffset, long yScrollOffset)
-{
-}
-
-void UIScriptController::immediateZoomToScale(double scale)
-{
-}
-
-void UIScriptController::keyboardAccessoryBarNext()
-{
-}
-
-void UIScriptController::keyboardAccessoryBarPrevious()
-{
-}
-
-void UIScriptController::applyAutocorrection(JSStringRef, JSStringRef, JSValueRef)
-{
-}
-
-bool UIScriptController::isShowingKeyboard() const
-{
-    return false;
-}
-
-bool UIScriptController::hasInputSession() const
-{
-    return false;
-}
-
-double UIScriptController::zoomScale() const
-{
-    return 1;
-}
-
-double UIScriptController::minimumZoomScale() const
-{
-    return 1;
-}
-
-double UIScriptController::maximumZoomScale() const
-{
-    return 1;
-}
-
-Optional<bool> UIScriptController::stableStateOverride() const
-{
-    return WTF::nullopt;
-}
-
-void UIScriptController::setStableStateOverride(Optional<bool>)
-{
-}
-
-JSObjectRef UIScriptController::contentVisibleRect() const
-{
-    return nullptr;
-}
-
-JSObjectRef UIScriptController::textSelectionRangeRects() const
-{
-    return nullptr;
-}
-
-JSObjectRef UIScriptController::textSelectionCaretRect() const
-{
-    return nullptr;
-}
-
-JSObjectRef UIScriptController::selectionStartGrabberViewRect() const
-{
-    return nullptr;
-}
-
-JSObjectRef UIScriptController::selectionCaretViewRect() const
-{
-    return nullptr;
-}
-
-JSObjectRef UIScriptController::selectionRangeViewRects() const
-{
-    return nullptr;
-}
-
-JSObjectRef UIScriptController::selectionEndGrabberViewRect() const
-{
-    return nullptr;
-}
-
-JSObjectRef UIScriptController::inputViewBounds() const
-{
-    return nullptr;
-}
-
-void UIScriptController::removeAllDynamicDictionaries()
-{
-}
-
-JSRetainPtr<JSStringRef> UIScriptController::scrollingTreeAsText() const
-{
-    return nullptr;
-}
-
-JSObjectRef UIScriptController::propertiesOfLayerWithID(uint64_t layerID) const
-{
-    return nullptr;
-}
-
-void UIScriptController::platformSetDidStartFormControlInteractionCallback()
-{
-}
-
-void UIScriptController::platformSetDidEndFormControlInteractionCallback()
-{
-}
-    
-void UIScriptController::platformSetDidShowForcePressPreviewCallback()
-{
-}
-
-void UIScriptController::platformSetDidDismissForcePressPreviewCallback()
-{
-}
-
-void UIScriptController::platformSetWillBeginZoomingCallback()
-{
-}
-
-void UIScriptController::platformSetDidEndZoomingCallback()
-{
-}
-
-void UIScriptController::platformSetDidEndScrollingCallback()
-{
-}
-
-void UIScriptController::platformSetDidShowKeyboardCallback()
-{
-}
-
-void UIScriptController::platformSetDidHideKeyboardCallback()
-{
-}
-
-void UIScriptController::platformSetDidShowMenuCallback()
-{
-}
-
-void UIScriptController::platformSetDidHideMenuCallback()
-{
-}
-
-bool UIScriptController::isShowingPopover() const
-{
-    return false;
-}
-
-void UIScriptController::platformSetWillPresentPopoverCallback()
-{
-}
-
-void UIScriptController::platformSetDidDismissPopoverCallback()
-{
-}
-
-JSObjectRef UIScriptController::menuRect() const
-{
-    return nullptr;
-}
-
-JSObjectRef UIScriptController::rectForMenuAction(JSStringRef) const
-{
-    return nullptr;
-}
-
-bool UIScriptController::isDismissingMenu() const
-{
-    return false;
-}
-
-bool UIScriptController::isShowingMenu() const
-{
-    return false;
-}
-
-void UIScriptController::platformClearAllCallbacks()
-{
-}
-
-void UIScriptController::retrieveSpeakSelectionContent(JSValueRef)
-{
-}
-
-JSRetainPtr<JSStringRef> UIScriptController::accessibilitySpeakSelectionContent() const
-{
-    return nullptr;
-}
-
-void UIScriptController::setSafeAreaInsets(double top, double right, double bottom, double left)
-{
-}
-
-void UIScriptController::drawSquareInEditableImage()
-{
-}
-
-long UIScriptController::numberOfStrokesInEditableImage()
-{
-    return 0;
-}
-
-JSObjectRef UIScriptController::attachmentInfo(JSStringRef)
-{
-    return nullptr;
-}
-
-void UIScriptController::setKeyboardInputModeIdentifier(JSStringRef)
-{
-}
-
-void UIScriptController::setHardwareKeyboardAttached(bool)
-{
-}
-
-#endif
-
-#if !PLATFORM(COCOA)
-
-void UIScriptController::simulateRotation(DeviceOrientation*, JSValueRef callback)
-{
-}
-
-void UIScriptController::simulateRotationLikeSafari(DeviceOrientation*, JSValueRef callback)
-{
-}
-
-void UIScriptController::findString(JSStringRef, unsigned long options, unsigned long maxCount)
-{
-}
-
-void UIScriptController::removeViewFromWindow(JSValueRef)
-{
-}
-
-void UIScriptController::addViewToWindow(JSValueRef)
-{
-}
-
-#if !PLATFORM(GTK)
-void UIScriptController::beginBackSwipe(JSValueRef callback)
-{
-}
-
-void UIScriptController::completeBackSwipe(JSValueRef callback)
-{
-}
-#endif
-
-void UIScriptController::setShareSheetCompletesImmediatelyWithResolution(bool)
-{
-}
-
-bool UIScriptController::isShowingDataListSuggestions() const
-{
-    return false;
-}
-
-void UIScriptController::overridePreference(JSStringRef, JSStringRef)
-{
-}
-
-JSRetainPtr<JSStringRef> UIScriptController::lastUndoLabel() const
-{
-    return nullptr;
-}
-
-JSRetainPtr<JSStringRef> UIScriptController::firstRedoLabel() const
-{
-    return nullptr;
-}
-
-#endif // !PLATFORM(COCOA)
-
-#if !PLATFORM(MAC)
-
-void UIScriptController::replaceTextAtRange(JSStringRef, int, int)
-{
-}
-
-void UIScriptController::platformPlayBackEventStream(JSStringRef, JSValueRef)
-{
-}
-
-void UIScriptController::firstResponderSuppressionForWebView(bool)
-{
-}
-
-void UIScriptController::makeWindowContentViewFirstResponder()
-{
-}
-
-bool UIScriptController::isWindowContentViewFirstResponder() const
-{
-    return false;
-}
-
-#endif
-
 void UIScriptController::uiScriptComplete(JSStringRef result)
 {
     m_context->requestUIScriptCompletion(result);
-    platformClearAllCallbacks();
+    clearAllCallbacks();
 }
 
 }
index fc380fa..c6990c3 100644 (file)
@@ -54,227 +54,257 @@ DeviceOrientation* toDeviceOrientation(JSContextRef, JSValueRef);
 
 class UIScriptController : public JSWrappable {
 public:
-    static Ref<UIScriptController> create(UIScriptContext& context)
-    {
-        return adoptRef(*new UIScriptController(context));
-    }
+    static Ref<UIScriptController> create(UIScriptContext&);
+
+    void uiScriptComplete(JSStringRef result);
+
+    void notImplemented() const { RELEASE_ASSERT_NOT_REACHED(); }
 
     void contextDestroyed();
-    void checkForOutstandingCallbacks();
+    virtual void checkForOutstandingCallbacks() { /* notImplemented(); */ }
 
     void makeWindowObject(JSContextRef, JSObjectRef windowObject, JSValueRef* exception);
+
+    // Transaction helpers
     
-    void doAsyncTask(JSValueRef callback);
-    void doAfterPresentationUpdate(JSValueRef callback);
-    void doAfterNextStablePresentationUpdate(JSValueRef callback);
-    void ensurePositionInformationIsUpToDateAt(long x, long y, JSValueRef callback);
-    void doAfterVisibleContentRectUpdate(JSValueRef callback);
+    virtual void doAsyncTask(JSValueRef callback) { notImplemented(); }
+    virtual void doAfterPresentationUpdate(JSValueRef callback) { doAsyncTask(callback); }
+    virtual void doAfterNextStablePresentationUpdate(JSValueRef callback) { doAsyncTask(callback); }
+    virtual void ensurePositionInformationIsUpToDateAt(long x, long y, JSValueRef callback) { doAsyncTask(callback); }
+    virtual void doAfterVisibleContentRectUpdate(JSValueRef callback) { doAsyncTask(callback); }
 
-    void zoomToScale(double scale, JSValueRef callback);
-    void setViewScale(double);
-    void setMinimumEffectiveWidth(double);
-    void setAllowsViewportShrinkToFit(bool);
+    // Preferences
 
-    void resignFirstResponder();
+    // FIXME: Why does this exist? Why is it implemented in a platform specific way?
+    // Should we just use the other API?
+    virtual void overridePreference(JSStringRef preference, JSStringRef value) { notImplemented(); }
 
-    void simulateAccessibilitySettingsChangeNotification(JSValueRef callback);
+    // Zooming
 
-    void touchDownAtPoint(long x, long y, long touchCount, JSValueRef callback);
-    void liftUpAtPoint(long x, long y, long touchCount, JSValueRef callback);
-    void singleTapAtPoint(long x, long y, JSValueRef callback);
-    void singleTapAtPointWithModifiers(long x, long y, JSValueRef modifierArray, JSValueRef callback);
-    void doubleTapAtPoint(long x, long y, JSValueRef callback);
-    void dragFromPointToPoint(long startX, long startY, long endX, long endY, double durationSeconds, JSValueRef callback);
+    virtual void zoomToScale(double scale, JSValueRef callback) { notImplemented(); }
+    virtual void immediateZoomToScale(double scale) { notImplemented(); }
+    virtual void setViewScale(double) { notImplemented(); }
+    virtual double zoomScale() const { notImplemented(); return 1; }
+    virtual double minimumZoomScale() const { notImplemented(); return 1; }
+    virtual double maximumZoomScale() const { notImplemented(); return 1; }
 
-    void stylusDownAtPoint(long x, long y, float azimuthAngle, float altitudeAngle, float pressure, JSValueRef callback);
-    void stylusMoveToPoint(long x, long y, float azimuthAngle, float altitudeAngle, float pressure, JSValueRef callback);
-    void stylusUpAtPoint(long x, long y, JSValueRef callback);
-    void stylusTapAtPoint(long x, long y, float azimuthAngle, float altitudeAngle, float pressure, JSValueRef callback);
-    void stylusTapAtPointWithModifiers(long x, long y, float azimuthAngle, float altitudeAngle, float pressure, JSValueRef modifierArray, JSValueRef callback);
+    // Viewports
 
-    void longPressAtPoint(long x, long y, JSValueRef callback);
+    virtual void setMinimumEffectiveWidth(double) { notImplemented(); }
+    virtual void setAllowsViewportShrinkToFit(bool) { notImplemented(); }
 
-    void sendEventStream(JSStringRef eventsJSON, JSValueRef callback);
+    virtual Optional<bool> stableStateOverride() const { notImplemented(); return WTF::nullopt; }
+    virtual void setStableStateOverride(Optional<bool>) { notImplemented(); }
 
-    void enterText(JSStringRef);
-    void typeCharacterUsingHardwareKeyboard(JSStringRef character, JSValueRef callback);
+    virtual JSObjectRef contentVisibleRect() const { notImplemented(); return nullptr; }
+    
+    virtual void setSafeAreaInsets(double top, double right, double bottom, double left) { notImplemented(); }
 
-    void keyDown(JSStringRef character, JSValueRef modifierArray);
-    void toggleCapsLock(JSValueRef callback);
+    // View Parenting and Visibility
 
-    void keyboardAccessoryBarNext();
-    void keyboardAccessoryBarPrevious();
+    virtual void resignFirstResponder() { notImplemented(); }
 
-    void applyAutocorrection(JSStringRef newString, JSStringRef oldString, JSValueRef callback);
-    
-    void dismissFilePicker(JSValueRef callback);
-    void dismissFormAccessoryView();
-    void selectFormAccessoryPickerRow(long);
-    JSRetainPtr<JSStringRef> textContentType() const;
-    JSRetainPtr<JSStringRef> selectFormPopoverTitle() const;
-    JSRetainPtr<JSStringRef> formInputLabel() const;
-    void setTimePickerValue(long hour, long minute);
+    virtual void firstResponderSuppressionForWebView(bool) { notImplemented(); }
+    virtual void makeWindowContentViewFirstResponder() { notImplemented(); }
+    virtual bool isWindowContentViewFirstResponder() const { notImplemented(); return false; }
 
-    void setShareSheetCompletesImmediatelyWithResolution(bool resolved);
+    virtual void removeViewFromWindow(JSValueRef) { notImplemented(); }
+    virtual void addViewToWindow(JSValueRef) { notImplemented(); }
 
-    bool isShowingDataListSuggestions() const;
+    // Compositing
 
-    JSObjectRef contentsOfUserInterfaceItem(JSStringRef) const;
-    void overridePreference(JSStringRef preference, JSStringRef value);
+    virtual JSObjectRef propertiesOfLayerWithID(uint64_t layerID) const { notImplemented(); return nullptr; }
 
-    bool isPresentingModally() const;
-    
-    double contentOffsetX() const;
-    double contentOffsetY() const;
+    // Scrolling
 
-    bool scrollUpdatesDisabled() const;
-    void setScrollUpdatesDisabled(bool);
+    virtual bool scrollUpdatesDisabled() const { notImplemented(); return false; }
+    virtual void setScrollUpdatesDisabled(bool) { notImplemented(); }
 
-    void scrollToOffset(long x, long y);
+    virtual void scrollToOffset(long x, long y) { notImplemented(); }
 
-    void immediateScrollToOffset(long x, long y);
-    void immediateScrollElementAtContentPointToOffset(long x, long y, long xScrollOffset, long yScrollOffset);
-    void immediateZoomToScale(double scale);
+    virtual void immediateScrollToOffset(long x, long y) { notImplemented(); }
+    virtual void immediateScrollElementAtContentPointToOffset(long x, long y, long xScrollOffset, long yScrollOffset) { notImplemented(); }
 
-    void beginBackSwipe(JSValueRef callback);
-    void completeBackSwipe(JSValueRef callback);
+    virtual double contentOffsetX() const { notImplemented(); return 0; }
+    virtual double contentOffsetY() const { notImplemented(); return 0; }
 
-    void setDidStartFormControlInteractionCallback(JSValueRef);
-    JSValueRef didStartFormControlInteractionCallback() const;
+    virtual JSRetainPtr<JSStringRef> scrollingTreeAsText() const { notImplemented(); return nullptr; }
 
-    void setDidEndFormControlInteractionCallback(JSValueRef);
-    JSValueRef didEndFormControlInteractionCallback() const;
-    
-    void setDidShowForcePressPreviewCallback(JSValueRef);
-    JSValueRef didShowForcePressPreviewCallback() const;
-    
-    void setDidDismissForcePressPreviewCallback(JSValueRef);
-    JSValueRef didDismissForcePressPreviewCallback() const;
+    // Touches
 
-    void setWillBeginZoomingCallback(JSValueRef);
-    JSValueRef willBeginZoomingCallback() const;
+    virtual void touchDownAtPoint(long x, long y, long touchCount, JSValueRef callback) { notImplemented(); }
+    virtual void liftUpAtPoint(long x, long y, long touchCount, JSValueRef callback) { notImplemented(); }
+    virtual void singleTapAtPoint(long x, long y, JSValueRef callback) { notImplemented(); }
+    virtual void singleTapAtPointWithModifiers(long x, long y, JSValueRef modifierArray, JSValueRef callback) { notImplemented(); }
+    virtual void doubleTapAtPoint(long x, long y, JSValueRef callback) { notImplemented(); }
+    virtual void dragFromPointToPoint(long startX, long startY, long endX, long endY, double durationSeconds, JSValueRef callback) { notImplemented(); }
+    virtual void longPressAtPoint(long x, long y, JSValueRef callback) { notImplemented(); }
 
-    void setDidEndZoomingCallback(JSValueRef);
-    JSValueRef didEndZoomingCallback() const;
+    // Keyboard
 
-    void setDidShowKeyboardCallback(JSValueRef);
-    JSValueRef didShowKeyboardCallback() const;
+    virtual void enterText(JSStringRef) { notImplemented(); }
+    virtual void typeCharacterUsingHardwareKeyboard(JSStringRef character, JSValueRef callback) { notImplemented(); }
 
-    void setDidHideKeyboardCallback(JSValueRef);
-    JSValueRef didHideKeyboardCallback() const;
+    virtual void keyDown(JSStringRef character, JSValueRef modifierArray) { notImplemented(); }
+    virtual void toggleCapsLock(JSValueRef callback) { notImplemented(); }
 
-    bool isShowingKeyboard() const;
-    bool hasInputSession() const;
+    virtual void keyboardAccessoryBarNext() { notImplemented(); }
+    virtual void keyboardAccessoryBarPrevious() { notImplemented(); }
 
-    void setDidHideMenuCallback(JSValueRef);
-    JSValueRef didHideMenuCallback() const;
-    void setDidShowMenuCallback(JSValueRef);
-    JSValueRef didShowMenuCallback() const;
+    virtual void applyAutocorrection(JSStringRef newString, JSStringRef oldString, JSValueRef callback) { notImplemented(); }
 
-    bool isShowingPopover() const;
-    void setDidDismissPopoverCallback(JSValueRef);
-    JSValueRef didDismissPopoverCallback() const;
-    void setWillPresentPopoverCallback(JSValueRef);
-    JSValueRef willPresentPopoverCallback() const;
+    virtual bool isShowingKeyboard() const { notImplemented(); return false; }
+    virtual bool hasInputSession() const { notImplemented(); return false; }
 
-    bool isDismissingMenu() const;
-    bool isShowingMenu() const;
-    JSObjectRef rectForMenuAction(JSStringRef action) const;
-    JSObjectRef menuRect() const;
+    virtual void setHardwareKeyboardAttached(bool) { /* notImplemented(); */ }
 
-    void setDidEndScrollingCallback(JSValueRef);
-    JSValueRef didEndScrollingCallback() const;
+    virtual void setKeyboardInputModeIdentifier(JSStringRef) { notImplemented(); }
 
-    void playBackEventStream(JSStringRef stream, JSValueRef callback);
+    virtual void replaceTextAtRange(JSStringRef, int location, int length) { notImplemented(); }
+    virtual void removeAllDynamicDictionaries() { notImplemented(); }
 
-    double zoomScale() const;
-    double minimumZoomScale() const;
-    double maximumZoomScale() const;
-    
-    Optional<bool> stableStateOverride() const;
-    void setStableStateOverride(Optional<bool>);
+    // Stylus
 
-    JSObjectRef contentVisibleRect() const;
-    
-    JSObjectRef textSelectionRangeRects() const;
-    JSObjectRef textSelectionCaretRect() const;
-    JSObjectRef selectionStartGrabberViewRect() const;
-    JSObjectRef selectionEndGrabberViewRect() const;
-    JSObjectRef selectionCaretViewRect() const;
-    JSObjectRef selectionRangeViewRects() const;
-    JSObjectRef calendarType() const;
-    void setDefaultCalendarType(JSStringRef calendarIdentifier);
-    JSObjectRef inputViewBounds() const;
-
-    void setKeyboardInputModeIdentifier(JSStringRef);
-
-    void replaceTextAtRange(JSStringRef, int location, int length);
-    void removeAllDynamicDictionaries();
-    
-    JSRetainPtr<JSStringRef> scrollingTreeAsText() const;
+    virtual void stylusDownAtPoint(long x, long y, float azimuthAngle, float altitudeAngle, float pressure, JSValueRef callback) { notImplemented(); }
+    virtual void stylusMoveToPoint(long x, long y, float azimuthAngle, float altitudeAngle, float pressure, JSValueRef callback) { notImplemented(); }
+    virtual void stylusUpAtPoint(long x, long y, JSValueRef callback) { notImplemented(); }
+    virtual void stylusTapAtPoint(long x, long y, float azimuthAngle, float altitudeAngle, float pressure, JSValueRef callback) { notImplemented(); }
+    virtual void stylusTapAtPointWithModifiers(long x, long y, float azimuthAngle, float altitudeAngle, float pressure, JSValueRef modifierArray, JSValueRef callback) { notImplemented(); }
 
-    JSObjectRef propertiesOfLayerWithID(uint64_t layerID) const;
+    // Event Stream
 
-    void uiScriptComplete(JSStringRef result);
+    virtual void sendEventStream(JSStringRef eventsJSON, JSValueRef callback) { notImplemented(); }
+    virtual void playBackEventStream(JSStringRef stream, JSValueRef callback) { notImplemented(); } // Are these even the same thing!?
+
+    // Form Controls
     
-    void retrieveSpeakSelectionContent(JSValueRef);
-    JSRetainPtr<JSStringRef> accessibilitySpeakSelectionContent() const;
+    virtual void dismissFilePicker(JSValueRef callback) { notImplemented(); }
+    virtual void dismissFormAccessoryView() { notImplemented(); }
+    virtual void selectFormAccessoryPickerRow(long) { notImplemented(); }
+    virtual JSRetainPtr<JSStringRef> textContentType() const { notImplemented(); return nullptr; }
+    virtual JSRetainPtr<JSStringRef> selectFormPopoverTitle() const { notImplemented(); return nullptr; }
+    virtual JSRetainPtr<JSStringRef> formInputLabel() const { notImplemented(); return nullptr; }
+    virtual void setTimePickerValue(long hour, long minute) { notImplemented(); }
+    virtual bool isShowingDataListSuggestions() const { notImplemented(); return false; }
+    virtual JSObjectRef calendarType() const { notImplemented(); return nullptr; }
+    virtual void setDefaultCalendarType(JSStringRef calendarIdentifier) { notImplemented(); }
+    virtual JSObjectRef inputViewBounds() const { notImplemented(); return nullptr; }
+
+    // Share Sheet
+
+    virtual void setShareSheetCompletesImmediatelyWithResolution(bool resolved) { notImplemented(); }
+
+    // Find in Page
+
+    virtual void findString(JSStringRef, unsigned long options, unsigned long maxCount) { notImplemented(); }
+
+    // Accessibility
+
+    virtual void simulateAccessibilitySettingsChangeNotification(JSValueRef callback) { notImplemented(); }
+    virtual void retrieveSpeakSelectionContent(JSValueRef) { notImplemented(); }
+    virtual JSRetainPtr<JSStringRef> accessibilitySpeakSelectionContent() const { notImplemented(); return nullptr; }
+    virtual JSObjectRef contentsOfUserInterfaceItem(JSStringRef) const { notImplemented(); return nullptr; }
+
+    // Swipe
+
+    virtual void beginBackSwipe(JSValueRef callback) { notImplemented(); }
+    virtual void completeBackSwipe(JSValueRef callback) { notImplemented(); }
+
+    // Child View Controllers
+
+    virtual bool isShowingPopover() const { notImplemented(); return false; }
+    virtual bool isPresentingModally() const { notImplemented(); return false; }
+
+    // Context Menus
+
+    virtual bool isDismissingMenu() const { notImplemented(); return false; }
+    virtual bool isShowingMenu() const { notImplemented(); return false; }
+    virtual JSObjectRef rectForMenuAction(JSStringRef action) const { notImplemented(); return nullptr; }
+    virtual JSObjectRef menuRect() const { notImplemented(); return nullptr; }
+
+    // Selection
+
+    virtual JSObjectRef textSelectionRangeRects() const { notImplemented(); return nullptr; }
+    virtual JSObjectRef textSelectionCaretRect() const { notImplemented(); return nullptr; }
+    virtual JSObjectRef selectionStartGrabberViewRect() const { notImplemented(); return nullptr; }
+    virtual JSObjectRef selectionEndGrabberViewRect() const { notImplemented(); return nullptr; }
+    virtual JSObjectRef selectionCaretViewRect() const { notImplemented(); return nullptr; }
+    virtual JSObjectRef selectionRangeViewRects() const { notImplemented(); return nullptr; }
+
+    // Rotation
+
+    virtual void simulateRotation(DeviceOrientation*, JSValueRef) { notImplemented(); }
+    virtual void simulateRotationLikeSafari(DeviceOrientation*, JSValueRef) { notImplemented(); }
+
+    // Editable Images
+
+    virtual void drawSquareInEditableImage() { notImplemented(); }
+    virtual long numberOfStrokesInEditableImage() { notImplemented(); return 0; }
+
+    // Undo/Redo
+
+    virtual JSRetainPtr<JSStringRef> lastUndoLabel() const { notImplemented(); return nullptr; }
+    virtual JSRetainPtr<JSStringRef> firstRedoLabel() const { notImplemented(); return nullptr; }
+
+    // Attachment Elements
+
+    virtual JSObjectRef attachmentInfo(JSStringRef attachmentIdentifier) { notImplemented(); return nullptr; }
+
+    // Callbacks
     
-    void simulateRotation(DeviceOrientation*, JSValueRef);
-    void simulateRotationLikeSafari(DeviceOrientation*, JSValueRef);
+    virtual void setDidStartFormControlInteractionCallback(JSValueRef);
+    JSValueRef didStartFormControlInteractionCallback() const;
 
-    void findString(JSStringRef, unsigned long options, unsigned long maxCount);
+    virtual void setDidEndFormControlInteractionCallback(JSValueRef);
+    JSValueRef didEndFormControlInteractionCallback() const;
+    
+    virtual void setDidShowForcePressPreviewCallback(JSValueRef);
+    JSValueRef didShowForcePressPreviewCallback() const;
+    
+    virtual void setDidDismissForcePressPreviewCallback(JSValueRef);
+    JSValueRef didDismissForcePressPreviewCallback() const;
 
-    // These use a callback to allow the client to know when view visibility state updates get to the web process.
-    void removeViewFromWindow(JSValueRef);
-    void addViewToWindow(JSValueRef);
+    virtual void setWillBeginZoomingCallback(JSValueRef);
+    JSValueRef willBeginZoomingCallback() const;
 
-    void setSafeAreaInsets(double top, double right, double bottom, double left);
+    virtual void setDidEndZoomingCallback(JSValueRef);
+    JSValueRef didEndZoomingCallback() const;
 
-    void firstResponderSuppressionForWebView(bool);
-    void makeWindowContentViewFirstResponder();
-    bool isWindowContentViewFirstResponder() const;
+    virtual void setDidShowKeyboardCallback(JSValueRef);
+    JSValueRef didShowKeyboardCallback() const;
 
-    void drawSquareInEditableImage();
-    long numberOfStrokesInEditableImage();
+    virtual void setDidHideKeyboardCallback(JSValueRef);
+    JSValueRef didHideKeyboardCallback() const;
 
-    JSRetainPtr<JSStringRef> lastUndoLabel() const;
-    JSRetainPtr<JSStringRef> firstRedoLabel() const;
+    virtual void setDidHideMenuCallback(JSValueRef);
+    JSValueRef didHideMenuCallback() const;
+    virtual void setDidShowMenuCallback(JSValueRef);
+    JSValueRef didShowMenuCallback() const;
 
-    JSObjectRef attachmentInfo(JSStringRef attachmentIdentifier);
+    virtual void setDidDismissPopoverCallback(JSValueRef);
+    JSValueRef didDismissPopoverCallback() const;
+    virtual void setWillPresentPopoverCallback(JSValueRef);
+    JSValueRef willPresentPopoverCallback() const;
 
-    void setHardwareKeyboardAttached(bool);
+    virtual void setDidEndScrollingCallback(JSValueRef);
+    JSValueRef didEndScrollingCallback() const;
 
-private:
-    UIScriptController(UIScriptContext&);
+protected:
+    explicit UIScriptController(UIScriptContext&);
     
     UIScriptContext* context() { return m_context; }
 
-    void platformSetDidStartFormControlInteractionCallback();
-    void platformSetDidEndFormControlInteractionCallback();
-    void platformSetDidShowForcePressPreviewCallback();
-    void platformSetDidDismissForcePressPreviewCallback();
-    void platformSetWillBeginZoomingCallback();
-    void platformSetDidEndZoomingCallback();
-    void platformSetDidShowKeyboardCallback();
-    void platformSetDidHideKeyboardCallback();
-    void platformSetDidShowMenuCallback();
-    void platformSetDidHideMenuCallback();
-    void platformSetWillPresentPopoverCallback();
-    void platformSetDidDismissPopoverCallback();
-    void platformSetDidEndScrollingCallback();
-    void platformClearAllCallbacks();
-    void platformPlayBackEventStream(JSStringRef, JSValueRef);
+    virtual void clearAllCallbacks() { /* notImplemented(); */ }
 
 #if PLATFORM(COCOA)
-    NSUndoManager *platformUndoManager() const;
+    virtual NSUndoManager *platformUndoManager() const { notImplemented(); return nullptr; }
 #endif
 
 #if PLATFORM(IOS_FAMILY)
-    UIView *platformContentView() const;
+    virtual UIView *platformContentView() const { notImplemented(); return nullptr; }
 #endif
 #if PLATFORM(MAC)
-    NSView *platformContentView() const;
+    virtual NSView *platformContentView() const { notImplemented(); return nullptr; }
 #endif
 
     JSClassRef wrapperClass() final;
index 18fc359..143ddb2 100644 (file)
@@ -78,6 +78,8 @@
                29A8FCDD145F0337009045A6 /* JSAccessibilityTextMarkerRange.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 29A8FCE1345E7021006AA5A6 /* JSAccessibilityTextMarkerRange.cpp */; };
                29A8FCE2145F037B009045A6 /* AccessibilityTextMarkerRange.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 29A8FCE1145F037B009045A6 /* AccessibilityTextMarkerRange.cpp */; };
                29A8FCE5145F0464009045A6 /* AccessibilityTextMarkerRangeMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = 29A8FCE4145F0464009045A6 /* AccessibilityTextMarkerRangeMac.mm */; };
+               2D058E0922E2EE2200E4C145 /* UIScriptControllerCocoa.h in Headers */ = {isa = PBXBuildFile; fileRef = 2D058E0822E2EE2200E4C145 /* UIScriptControllerCocoa.h */; };
+               2D058E0B22E2EF6D00E4C145 /* UIScriptControllerMac.h in Headers */ = {isa = PBXBuildFile; fileRef = 2D058E0A22E2EF6D00E4C145 /* UIScriptControllerMac.h */; };
                2DB6187E1D7D58D400978D19 /* CoreGraphicsTestSPI.h in Headers */ = {isa = PBXBuildFile; fileRef = 2DB6187D1D7D58D400978D19 /* CoreGraphicsTestSPI.h */; };
                2DD4C49A1D6E7D3B0007379C /* EventSerializerMac.h in Headers */ = {isa = PBXBuildFile; fileRef = 2DD4C4981D6E7D3B0007379C /* EventSerializerMac.h */; };
                2DD4C49B1D6E7D3B0007379C /* EventSerializerMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2DD4C4991D6E7D3B0007379C /* EventSerializerMac.mm */; };
                0F73B5571BA7929E004B3EF4 /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; };
                0F73B55B1BA89042004B3EF4 /* UIScriptControllerIOS.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = UIScriptControllerIOS.mm; sourceTree = "<group>"; };
                0F87B6111BACAD6F004EC572 /* UIScriptControllerMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = UIScriptControllerMac.mm; sourceTree = "<group>"; };
-               0F87B6141BACC4B9004EC572 /* TestRunnerWKWebView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TestRunnerWKWebView.h; path = cocoa/TestRunnerWKWebView.h; sourceTree = "<group>"; };
-               0F87B6151BACC4B9004EC572 /* TestRunnerWKWebView.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = TestRunnerWKWebView.mm; path = cocoa/TestRunnerWKWebView.mm; sourceTree = "<group>"; };
+               0F87B6141BACC4B9004EC572 /* TestRunnerWKWebView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TestRunnerWKWebView.h; sourceTree = "<group>"; };
+               0F87B6151BACC4B9004EC572 /* TestRunnerWKWebView.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = TestRunnerWKWebView.mm; sourceTree = "<group>"; };
                0FEB909E1905A776000FDBF3 /* InjectedBundlePageCocoa.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = InjectedBundlePageCocoa.mm; sourceTree = "<group>"; };
-               0FEB90A21905BC6A000FDBF3 /* CrashReporterInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CrashReporterInfo.h; path = cocoa/CrashReporterInfo.h; sourceTree = "<group>"; };
-               0FEB90A31905BC6A000FDBF3 /* CrashReporterInfo.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = CrashReporterInfo.mm; path = cocoa/CrashReporterInfo.mm; sourceTree = "<group>"; };
+               0FEB90A21905BC6A000FDBF3 /* CrashReporterInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CrashReporterInfo.h; sourceTree = "<group>"; };
+               0FEB90A31905BC6A000FDBF3 /* CrashReporterInfo.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = CrashReporterInfo.mm; sourceTree = "<group>"; };
                0FEBF8581BB61DF20028722D /* HIDEventGenerator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HIDEventGenerator.h; sourceTree = "<group>"; };
                0FEBF8591BB61DF20028722D /* HIDEventGenerator.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = HIDEventGenerator.mm; sourceTree = "<group>"; };
                1A3326051B75396500F89F62 /* TestOptions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TestOptions.h; sourceTree = "<group>"; };
                29A8FCE1345E7021006AA5A6 /* JSAccessibilityTextMarkerRange.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSAccessibilityTextMarkerRange.cpp; sourceTree = "<group>"; };
                29A8FCE1345E7021006AA5A7 /* JSAccessibilityTextMarkerRange.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSAccessibilityTextMarkerRange.h; sourceTree = "<group>"; };
                29A8FCE4145F0464009045A6 /* AccessibilityTextMarkerRangeMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = AccessibilityTextMarkerRangeMac.mm; sourceTree = "<group>"; };
+               2D058E0822E2EE2200E4C145 /* UIScriptControllerCocoa.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIScriptControllerCocoa.h; sourceTree = "<group>"; };
+               2D058E0A22E2EF6D00E4C145 /* UIScriptControllerMac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIScriptControllerMac.h; sourceTree = "<group>"; };
+               2D0BEE1722EAD1360092B738 /* UIScriptControllerIOS.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = UIScriptControllerIOS.h; sourceTree = "<group>"; };
                2D0FF14A2192C78300C975D6 /* PencilKitTestSPI.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = PencilKitTestSPI.h; path = ../TestRunnerShared/spi/PencilKitTestSPI.h; sourceTree = "<group>"; };
                2DB6187D1D7D58D400978D19 /* CoreGraphicsTestSPI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CoreGraphicsTestSPI.h; path = ../TestRunnerShared/spi/CoreGraphicsTestSPI.h; sourceTree = "<group>"; };
-               2DCE2CD11B84524500C7F832 /* TestControllerCocoa.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = TestControllerCocoa.mm; path = cocoa/TestControllerCocoa.mm; sourceTree = "<group>"; };
+               2DCE2CD11B84524500C7F832 /* TestControllerCocoa.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = TestControllerCocoa.mm; sourceTree = "<group>"; };
                2DD4C4981D6E7D3B0007379C /* EventSerializerMac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = EventSerializerMac.h; path = mac/EventSerializerMac.h; sourceTree = "<group>"; };
                2DD4C4991D6E7D3B0007379C /* EventSerializerMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = EventSerializerMac.mm; path = mac/EventSerializerMac.mm; sourceTree = "<group>"; };
                2DFA98461D7F70CF00AFF2C9 /* SharedEventStreamsMac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SharedEventStreamsMac.h; path = mac/SharedEventStreamsMac.h; sourceTree = "<group>"; };
                378D442213346D00006A777B /* config.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = config.h; sourceTree = "<group>"; };
                41230E16138C78BF00BCCFCA /* libWebCoreTestSupport.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; path = libWebCoreTestSupport.dylib; sourceTree = BUILT_PRODUCTS_DIR; };
                4181731B138AD39D0057AAA4 /* WebCoreTestSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WebCoreTestSupport.h; path = WebCoreTestSupport/WebCoreTestSupport.h; sourceTree = BUILT_PRODUCTS_DIR; };
-               41C5378C21F1333C008B1FAD /* TestWebsiteDataStoreDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TestWebsiteDataStoreDelegate.h; path = cocoa/TestWebsiteDataStoreDelegate.h; sourceTree = "<group>"; };
-               41C5378D21F1333C008B1FAD /* TestWebsiteDataStoreDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = TestWebsiteDataStoreDelegate.mm; path = cocoa/TestWebsiteDataStoreDelegate.mm; sourceTree = "<group>"; };
+               41C5378C21F1333C008B1FAD /* TestWebsiteDataStoreDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TestWebsiteDataStoreDelegate.h; sourceTree = "<group>"; };
+               41C5378D21F1333C008B1FAD /* TestWebsiteDataStoreDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = TestWebsiteDataStoreDelegate.mm; sourceTree = "<group>"; };
                41D5B62522DD9D36000F4C4A /* FakeHelvetica-SingleExtendedCharacter.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; name = "FakeHelvetica-SingleExtendedCharacter.ttf"; path = "fonts/FakeHelvetica-SingleExtendedCharacter.ttf"; sourceTree = "<group>"; };
                4429FC5E1627089600F66D8B /* WorkQueueManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WorkQueueManager.cpp; sourceTree = "<group>"; };
                4429FC611627089600F66D8B /* WorkQueueManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WorkQueueManager.h; sourceTree = "<group>"; };
                                0F87B6151BACC4B9004EC572 /* TestRunnerWKWebView.mm */,
                                41C5378C21F1333C008B1FAD /* TestWebsiteDataStoreDelegate.h */,
                                41C5378D21F1333C008B1FAD /* TestWebsiteDataStoreDelegate.mm */,
+                               2D058E0822E2EE2200E4C145 /* UIScriptControllerCocoa.h */,
                                F46240AF2170128300917B16 /* UIScriptControllerCocoa.mm */,
                        );
-                       name = cocoa;
+                       path = cocoa;
                        sourceTree = "<group>";
                };
                1AB674ADFE9D54B511CA2CBB /* Products */ = {
                                0FEBF8591BB61DF20028722D /* HIDEventGenerator.mm */,
                                2EE52D131890A9FB0010ED21 /* PlatformWebViewIOS.mm */,
                                2EE52D141890A9FB0010ED21 /* TestControllerIOS.mm */,
+                               2D0BEE1722EAD1360092B738 /* UIScriptControllerIOS.h */,
                                0F73B55B1BA89042004B3EF4 /* UIScriptControllerIOS.mm */,
                        );
                        path = ios;
                                E1C642C217CBCC7300D66A3C /* PoseAsClass.h */,
                                E1C642C117CBCC7300D66A3C /* PoseAsClass.mm */,
                                BC8C795B11D2785D004535A1 /* TestControllerMac.mm */,
+                               2D058E0A22E2EF6D00E4C145 /* UIScriptControllerMac.h */,
                                0F87B6111BACAD6F004EC572 /* UIScriptControllerMac.mm */,
                                E132AA3917CD5F1000611DF0 /* WebKitTestRunnerDraggingInfo.h */,
                                E132AA3817CD5F1000611DF0 /* WebKitTestRunnerDraggingInfo.mm */,
                                2DD4C49A1D6E7D3B0007379C /* EventSerializerMac.h in Headers */,
                                0F73B5521BA78968004B3EF4 /* JSUIScriptController.h in Headers */,
                                2DFA98481D7F70CF00AFF2C9 /* SharedEventStreamsMac.h in Headers */,
+                               2D058E0922E2EE2200E4C145 /* UIScriptControllerCocoa.h in Headers */,
+                               2D058E0B22E2EF6D00E4C145 /* UIScriptControllerMac.h in Headers */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
diff --git a/Tools/WebKitTestRunner/cocoa/UIScriptControllerCocoa.h b/Tools/WebKitTestRunner/cocoa/UIScriptControllerCocoa.h
new file mode 100644 (file)
index 0000000..1c077b5
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2019 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#import "UIScriptController.h"
+
+OBJC_CLASS TestRunnerWKWebView;
+
+namespace WTR {
+
+class UIScriptControllerCocoa : public UIScriptController {
+public:
+    void setViewScale(double) override;
+    void setMinimumEffectiveWidth(double) override;
+    void resignFirstResponder() override;
+    void doAsyncTask(JSValueRef) override;
+    void setShareSheetCompletesImmediatelyWithResolution(bool) override;
+    void removeViewFromWindow(JSValueRef) override;
+    void addViewToWindow(JSValueRef) override;
+    void overridePreference(JSStringRef, JSStringRef) override;
+    void findString(JSStringRef, unsigned long, unsigned long) override;
+    JSObjectRef contentsOfUserInterfaceItem(JSStringRef) const override;
+    void setDefaultCalendarType(JSStringRef) override;
+    JSRetainPtr<JSStringRef> lastUndoLabel() const override;
+    JSRetainPtr<JSStringRef> firstRedoLabel() const override;
+    NSUndoManager *platformUndoManager() const override;
+
+protected:
+    explicit UIScriptControllerCocoa(UIScriptContext&);
+    TestRunnerWKWebView *webView() const;
+};
+
+} // namespace WTR
@@ -24,7 +24,7 @@
  */
 
 #import "config.h"
-#import "UIScriptController.h"
+#import "UIScriptControllerCocoa.h"
 
 #import "PlatformWebView.h"
 #import "StringFunctions.h"
 
 namespace WTR {
 
-void UIScriptController::setViewScale(double scale)
+UIScriptControllerCocoa::UIScriptControllerCocoa(UIScriptContext& context)
+    : UIScriptController(context)
 {
-    TestController::singleton().mainWebView()->platformView()._viewScale = scale;
 }
 
-void UIScriptController::setMinimumEffectiveWidth(double effectiveWidth)
+TestRunnerWKWebView *UIScriptControllerCocoa::webView() const
 {
-    TestController::singleton().mainWebView()->platformView()._minimumEffectiveDeviceWidth = effectiveWidth;
+    return TestController::singleton().mainWebView()->platformView();
 }
 
-void UIScriptController::setAllowsViewportShrinkToFit(bool allows)
+void UIScriptControllerCocoa::setViewScale(double scale)
 {
-#if PLATFORM(IOS_FAMILY)
-    TestController::singleton().mainWebView()->platformView()._allowsViewportShrinkToFit = allows;
-#else
-    UNUSED_PARAM(allows);
-#endif
+    webView()._viewScale = scale;
+}
+
+void UIScriptControllerCocoa::setMinimumEffectiveWidth(double effectiveWidth)
+{
+    webView()._minimumEffectiveDeviceWidth = effectiveWidth;
 }
 
-void UIScriptController::resignFirstResponder()
+void UIScriptControllerCocoa::resignFirstResponder()
 {
-    [TestController::singleton().mainWebView()->platformView() resignFirstResponder];
+    [webView() resignFirstResponder];
 }
 
-void UIScriptController::doAsyncTask(JSValueRef callback)
+void UIScriptControllerCocoa::doAsyncTask(JSValueRef callback)
 {
     unsigned callbackID = m_context->prepareForAsyncTask(callback, CallbackTypeNonPersistent);
 
@@ -71,13 +72,12 @@ void UIScriptController::doAsyncTask(JSValueRef callback)
     });
 }
 
-void UIScriptController::setShareSheetCompletesImmediatelyWithResolution(bool resolved)
+void UIScriptControllerCocoa::setShareSheetCompletesImmediatelyWithResolution(bool resolved)
 {
-    TestRunnerWKWebView *webView = TestController::singleton().mainWebView()->platformView();
-    [webView _setShareSheetCompletesImmediatelyWithResolutionForTesting:resolved];
+    [webView() _setShareSheetCompletesImmediatelyWithResolutionForTesting:resolved];
 }
 
-void UIScriptController::removeViewFromWindow(JSValueRef callback)
+void UIScriptControllerCocoa::removeViewFromWindow(JSValueRef callback)
 {
     // FIXME: On iOS, we never invoke the completion callback that's passed in. Fixing this causes the layout
     // test pageoverlay/overlay-remove-reinsert-view.html to start failing consistently on iOS. It seems like
@@ -100,7 +100,7 @@ void UIScriptController::removeViewFromWindow(JSValueRef callback)
 #endif // PLATFORM(MAC)
 }
 
-void UIScriptController::addViewToWindow(JSValueRef callback)
+void UIScriptControllerCocoa::addViewToWindow(JSValueRef callback)
 {
 #if PLATFORM(MAC)
     unsigned callbackID = m_context->prepareForAsyncTask(callback, CallbackTypeNonPersistent);
@@ -120,10 +120,9 @@ void UIScriptController::addViewToWindow(JSValueRef callback)
 #endif // PLATFORM(MAC)
 }
 
-void UIScriptController::overridePreference(JSStringRef preferenceRef, JSStringRef valueRef)
+void UIScriptControllerCocoa::overridePreference(JSStringRef preferenceRef, JSStringRef valueRef)
 {
-    TestRunnerWKWebView *webView = TestController::singleton().mainWebView()->platformView();
-    WKPreferences *preferences = webView.configuration.preferences;
+    WKPreferences *preferences = webView().configuration.preferences;
 
     String preference = toWTFString(toWK(preferenceRef));
     String value = toWTFString(toWK(valueRef));
@@ -131,35 +130,33 @@ void UIScriptController::overridePreference(JSStringRef preferenceRef, JSStringR
         preferences.minimumFontSize = value.toDouble();
 }
 
-void UIScriptController::findString(JSStringRef string, unsigned long options, unsigned long maxCount)
+void UIScriptControllerCocoa::findString(JSStringRef string, unsigned long options, unsigned long maxCount)
 {
-    TestRunnerWKWebView *webView = TestController::singleton().mainWebView()->platformView();
-    [webView _findString:toWTFString(toWK(string)) options:options maxCount:maxCount];
+    [webView() _findString:toWTFString(toWK(string)) options:options maxCount:maxCount];
 }
 
-JSObjectRef UIScriptController::contentsOfUserInterfaceItem(JSStringRef interfaceItem) const
+JSObjectRef UIScriptControllerCocoa::contentsOfUserInterfaceItem(JSStringRef interfaceItem) const
 {
-    TestRunnerWKWebView *webView = TestController::singleton().mainWebView()->platformView();
-    NSDictionary *contentDictionary = [webView _contentsOfUserInterfaceItem:toWTFString(toWK(interfaceItem))];
+    NSDictionary *contentDictionary = [webView() _contentsOfUserInterfaceItem:toWTFString(toWK(interfaceItem))];
     return JSValueToObject(m_context->jsContext(), [JSValue valueWithObject:contentDictionary inContext:[JSContext contextWithJSGlobalContextRef:m_context->jsContext()]].JSValueRef, nullptr);
 }
 
-void UIScriptController::setDefaultCalendarType(JSStringRef calendarIdentifier)
+void UIScriptControllerCocoa::setDefaultCalendarType(JSStringRef calendarIdentifier)
 {
     TestController::singleton().setDefaultCalendarType((__bridge NSString *)adoptCF(JSStringCopyCFString(kCFAllocatorDefault, calendarIdentifier)).get());
 }
 
-JSRetainPtr<JSStringRef> UIScriptController::lastUndoLabel() const
+JSRetainPtr<JSStringRef> UIScriptControllerCocoa::lastUndoLabel() const
 {
     return adopt(JSStringCreateWithCFString((__bridge CFStringRef)platformUndoManager().undoActionName));
 }
 
-JSRetainPtr<JSStringRef> UIScriptController::firstRedoLabel() const
+JSRetainPtr<JSStringRef> UIScriptControllerCocoa::firstRedoLabel() const
 {
     return adopt(JSStringCreateWithCFString((__bridge CFStringRef)platformUndoManager().redoActionName));
 }
 
-NSUndoManager *UIScriptController::platformUndoManager() const
+NSUndoManager *UIScriptControllerCocoa::platformUndoManager() const
 {
     return platformContentView().undoManager;
 }
index 6321cce..cdde17f 100644 (file)
@@ -24,7 +24,7 @@
  */
 
 #include "config.h"
-#include "UIScriptController.h"
+#include "UIScriptControllerGtk.h"
 
 #include "PlatformWebView.h"
 #include "TestController.h"
 
 namespace WTR {
 
-void UIScriptController::beginBackSwipe(JSValueRef callback)
+Ref<UIScriptController> UIScriptController::create(UIScriptContext& context)
+{
+    return adoptRef(*new UIScriptControllerGtk(context));
+}
+
+void UIScriptControllerGtk::beginBackSwipe(JSValueRef callback)
 {
     auto* webView = TestController::singleton().mainWebView()->platformView();
 
     WKViewBeginBackSwipeForTesting(webView);
 }
 
-void UIScriptController::completeBackSwipe(JSValueRef callback)
+void UIScriptControllerGtk::completeBackSwipe(JSValueRef callback)
 {
     auto* webView = TestController::singleton().mainWebView()->platformView();
 
diff --git a/Tools/WebKitTestRunner/gtk/UIScriptControllerGtk.h b/Tools/WebKitTestRunner/gtk/UIScriptControllerGtk.h
new file mode 100644 (file)
index 0000000..83b3bbe
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2019 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "PlatformWebView.h"
+#include "TestController.h"
+#include "UIScriptController.h"
+#include <WebKit/WKViewPrivate.h>
+
+namespace WTR {
+
+class UIScriptControllerGtk : public UIScriptController {
+public:
+    explicit UIScriptControllerGtk(UIScriptContext& context)
+        : UIScriptController(context)
+    {
+    }
+
+    void beginBackSwipe(JSValueRef) override;
+    void completeBackSwipe(JSValueRef) override;
+};
+
+} // namespace WTR
diff --git a/Tools/WebKitTestRunner/ios/UIScriptControllerIOS.h b/Tools/WebKitTestRunner/ios/UIScriptControllerIOS.h
new file mode 100644 (file)
index 0000000..efcd187
--- /dev/null
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2019 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#import "UIScriptControllerCocoa.h"
+
+#if PLATFORM(IOS_FAMILY)
+
+namespace WTR {
+
+class UIScriptControllerIOS : public UIScriptControllerCocoa {
+public:
+    explicit UIScriptControllerIOS(UIScriptContext& context)
+        : UIScriptControllerCocoa(context)
+    {
+    }
+
+    void checkForOutstandingCallbacks() override;
+    void doAfterPresentationUpdate(JSValueRef) override;
+    void doAfterNextStablePresentationUpdate(JSValueRef) override;
+    void ensurePositionInformationIsUpToDateAt(long x, long y, JSValueRef) override;
+    void doAfterVisibleContentRectUpdate(JSValueRef) override;
+    void zoomToScale(double scale, JSValueRef) override;
+    void retrieveSpeakSelectionContent(JSValueRef) override;
+    JSRetainPtr<JSStringRef> accessibilitySpeakSelectionContent() const override;
+    void simulateAccessibilitySettingsChangeNotification(JSValueRef) override;
+    double zoomScale() const override;
+    void touchDownAtPoint(long x, long y, long touchCount, JSValueRef) override;
+    void liftUpAtPoint(long x, long y, long touchCount, JSValueRef) override;
+    void singleTapAtPoint(long x, long y, JSValueRef) override;
+    void singleTapAtPointWithModifiers(long x, long y, JSValueRef modifierArray, JSValueRef) override;
+    void doubleTapAtPoint(long x, long y, JSValueRef) override;
+    void stylusDownAtPoint(long x, long y, float azimuthAngle, float altitudeAngle, float pressure, JSValueRef) override;
+    void stylusMoveToPoint(long x, long y, float azimuthAngle, float altitudeAngle, float pressure, JSValueRef) override;
+    void stylusUpAtPoint(long x, long y, JSValueRef) override;
+    void stylusTapAtPoint(long x, long y, float azimuthAngle, float altitudeAngle, float pressure, JSValueRef) override;
+    void stylusTapAtPointWithModifiers(long x, long y, float azimuthAngle, float altitudeAngle, float pressure, JSValueRef modifierArray, JSValueRef) override;
+    void sendEventStream(JSStringRef eventsJSON, JSValueRef) override;
+    void dragFromPointToPoint(long startX, long startY, long endX, long endY, double durationSeconds, JSValueRef) override;
+    void longPressAtPoint(long x, long y, JSValueRef) override;
+    void enterText(JSStringRef text) override;
+    void typeCharacterUsingHardwareKeyboard(JSStringRef character, JSValueRef) override;
+    void keyDown(JSStringRef character, JSValueRef modifierArray) override;
+    void dismissFormAccessoryView() override;
+    void dismissFilePicker(JSValueRef) override;
+    JSRetainPtr<JSStringRef> selectFormPopoverTitle() const override;
+    JSRetainPtr<JSStringRef> textContentType() const override;
+    JSRetainPtr<JSStringRef> formInputLabel() const override;
+    void selectFormAccessoryPickerRow(long rowIndex) override;
+    void setTimePickerValue(long hour, long minute) override;
+    bool isPresentingModally() const override;
+    double contentOffsetX() const override;
+    double contentOffsetY() const override;
+    bool scrollUpdatesDisabled() const override;
+    void setScrollUpdatesDisabled(bool) override;
+    void scrollToOffset(long x, long y) override;
+    void immediateScrollToOffset(long x, long y) override;
+    void immediateScrollElementAtContentPointToOffset(long x, long y, long xScrollOffset, long yScrollOffset) override;
+    void immediateZoomToScale(double scale) override;
+    void keyboardAccessoryBarNext() override;
+    void keyboardAccessoryBarPrevious() override;
+    bool isShowingKeyboard() const override;
+    bool hasInputSession() const override;
+    void applyAutocorrection(JSStringRef newString, JSStringRef oldString, JSValueRef) override;
+    double minimumZoomScale() const override;
+    double maximumZoomScale() const override;
+    Optional<bool> stableStateOverride() const override;
+    void setStableStateOverride(Optional<bool> overrideValue) override;
+    JSObjectRef contentVisibleRect() const override;
+    JSObjectRef textSelectionRangeRects() const override;
+    JSObjectRef textSelectionCaretRect() const override;
+    JSObjectRef selectionStartGrabberViewRect() const override;
+    JSObjectRef selectionEndGrabberViewRect() const override;
+    JSObjectRef selectionCaretViewRect() const override;
+    JSObjectRef selectionRangeViewRects() const override;
+    JSObjectRef inputViewBounds() const override;
+    void removeAllDynamicDictionaries() override;
+    JSRetainPtr<JSStringRef> scrollingTreeAsText() const override;
+    JSObjectRef propertiesOfLayerWithID(uint64_t layerID) const override;
+    void simulateRotation(DeviceOrientation*, JSValueRef) override;
+    void simulateRotationLikeSafari(DeviceOrientation*, JSValueRef) override;
+    bool isShowingPopover() const override;
+    JSObjectRef rectForMenuAction(JSStringRef) const override;
+    JSObjectRef menuRect() const override;
+    bool isDismissingMenu() const override;
+    bool isShowingMenu() const override;
+    void setSafeAreaInsets(double top, double right, double bottom, double left) override;
+    void beginBackSwipe(JSValueRef) override;
+    void completeBackSwipe(JSValueRef) override;
+    bool isShowingDataListSuggestions() const override;
+    void drawSquareInEditableImage() override;
+    long numberOfStrokesInEditableImage() override;
+    void setKeyboardInputModeIdentifier(JSStringRef) override;
+    void toggleCapsLock(JSValueRef) override;
+    JSObjectRef attachmentInfo(JSStringRef) override;
+    UIView *platformContentView() const override;
+    JSObjectRef calendarType() const override;
+    void setHardwareKeyboardAttached(bool) override;
+    void setAllowsViewportShrinkToFit(bool) override;
+
+    void setDidStartFormControlInteractionCallback(JSValueRef) override;
+    void setDidEndFormControlInteractionCallback(JSValueRef) override;
+    void setDidShowForcePressPreviewCallback(JSValueRef) override;
+    void setDidDismissForcePressPreviewCallback(JSValueRef) override;
+    void setWillBeginZoomingCallback(JSValueRef) override;
+    void setDidEndZoomingCallback(JSValueRef) override;
+    void setDidShowKeyboardCallback(JSValueRef) override;
+    void setDidHideKeyboardCallback(JSValueRef) override;
+    void setDidShowMenuCallback(JSValueRef) override;
+    void setDidHideMenuCallback(JSValueRef) override;
+    void setWillPresentPopoverCallback(JSValueRef) override;
+    void setDidDismissPopoverCallback(JSValueRef) override;
+    void setDidEndScrollingCallback(JSValueRef) override;
+    void clearAllCallbacks() override;
+};
+
+}
+
+#endif // PLATFORM(IOS_FAMILY)
index e67a23d..dac2926 100644 (file)
@@ -24,7 +24,7 @@
  */
 
 #import "config.h"
-#import "UIScriptController.h"
+#import "UIScriptControllerIOS.h"
 
 #if PLATFORM(IOS_FAMILY)
 
@@ -128,96 +128,88 @@ static NSArray<UIView *> *findAllViewsInHierarchyOfType(UIView *view, Class view
     return views.autorelease();
 }
 
-void UIScriptController::checkForOutstandingCallbacks()
+Ref<UIScriptController> UIScriptController::create(UIScriptContext& context)
+{
+    return adoptRef(*new UIScriptControllerIOS(context));
+}
+
+void UIScriptControllerIOS::checkForOutstandingCallbacks()
 {
     if (![[HIDEventGenerator sharedHIDEventGenerator] checkForOutstandingCallbacks])
         [NSException raise:@"WebKitTestRunnerTestProblem" format:@"The test completed before all synthesized events had been handled. Perhaps you're calling notifyDone() too early?"];
 }
 
-void UIScriptController::doAfterPresentationUpdate(JSValueRef callback)
+void UIScriptControllerIOS::doAfterPresentationUpdate(JSValueRef callback)
 {
-    TestRunnerWKWebView *webView = TestController::singleton().mainWebView()->platformView();
-
     unsigned callbackID = m_context->prepareForAsyncTask(callback, CallbackTypeNonPersistent);
-    [webView _doAfterNextPresentationUpdate:^{
+    [webView() _doAfterNextPresentationUpdate:^{
         if (!m_context)
             return;
         m_context->asyncTaskComplete(callbackID);
     }];
 }
 
-void UIScriptController::doAfterNextStablePresentationUpdate(JSValueRef callback)
+void UIScriptControllerIOS::doAfterNextStablePresentationUpdate(JSValueRef callback)
 {
-    TestRunnerWKWebView *webView = TestController::singleton().mainWebView()->platformView();
-
     unsigned callbackID = m_context->prepareForAsyncTask(callback, CallbackTypeNonPersistent);
-    [webView _doAfterNextStablePresentationUpdate:^() {
+    [webView() _doAfterNextStablePresentationUpdate:^() {
         if (m_context)
             m_context->asyncTaskComplete(callbackID);
     }];
 }
 
-void UIScriptController::ensurePositionInformationIsUpToDateAt(long x, long y, JSValueRef callback)
+void UIScriptControllerIOS::ensurePositionInformationIsUpToDateAt(long x, long y, JSValueRef callback)
 {
-    TestRunnerWKWebView *webView = TestController::singleton().mainWebView()->platformView();
-
     unsigned callbackID = m_context->prepareForAsyncTask(callback, CallbackTypeNonPersistent);
-    [webView _requestActivatedElementAtPosition:CGPointMake(x, y) completionBlock:^(_WKActivatedElementInfo *) {
+    [webView() _requestActivatedElementAtPosition:CGPointMake(x, y) completionBlock:^(_WKActivatedElementInfo *) {
         if (!m_context)
             return;
         m_context->asyncTaskComplete(callbackID);
     }];
 }
 
-void UIScriptController::doAfterVisibleContentRectUpdate(JSValueRef callback)
+void UIScriptControllerIOS::doAfterVisibleContentRectUpdate(JSValueRef callback)
 {
-    TestRunnerWKWebView *webView = TestController::singleton().mainWebView()->platformView();
-
     unsigned callbackID = m_context->prepareForAsyncTask(callback, CallbackTypeNonPersistent);
-    [webView _doAfterNextVisibleContentRectUpdate:^ {
+    [webView() _doAfterNextVisibleContentRectUpdate:^ {
         if (!m_context)
             return;
         m_context->asyncTaskComplete(callbackID);
     }];
 }
 
-void UIScriptController::zoomToScale(double scale, JSValueRef callback)
+void UIScriptControllerIOS::zoomToScale(double scale, JSValueRef callback)
 {
-    TestRunnerWKWebView *webView = TestController::singleton().mainWebView()->platformView();
-
     unsigned callbackID = m_context->prepareForAsyncTask(callback, CallbackTypeNonPersistent);
 
-    [webView zoomToScale:scale animated:YES completionHandler:^{
+    [webView() zoomToScale:scale animated:YES completionHandler:^{
         if (!m_context)
             return;
         m_context->asyncTaskComplete(callbackID);
     }];
 }
 
-void UIScriptController::retrieveSpeakSelectionContent(JSValueRef callback)
+void UIScriptControllerIOS::retrieveSpeakSelectionContent(JSValueRef callback)
 {
-    TestRunnerWKWebView *webView = TestController::singleton().mainWebView()->platformView();
-    
     unsigned callbackID = m_context->prepareForAsyncTask(callback, CallbackTypeNonPersistent);
     
-    [webView accessibilityRetrieveSpeakSelectionContentWithCompletionHandler:^() {
+    [webView() accessibilityRetrieveSpeakSelectionContentWithCompletionHandler:^() {
         if (!m_context)
             return;
         m_context->asyncTaskComplete(callbackID);
     }];
 }
 
-JSRetainPtr<JSStringRef> UIScriptController::accessibilitySpeakSelectionContent() const
+JSRetainPtr<JSStringRef> UIScriptControllerIOS::accessibilitySpeakSelectionContent() const
 {
-    TestRunnerWKWebView *webView = TestController::singleton().mainWebView()->platformView();
-    return adopt(JSStringCreateWithCFString((CFStringRef)webView.accessibilitySpeakSelectionContent));
+    return adopt(JSStringCreateWithCFString((CFStringRef)webView().accessibilitySpeakSelectionContent));
 }
 
-void UIScriptController::simulateAccessibilitySettingsChangeNotification(JSValueRef callback)
+void UIScriptControllerIOS::simulateAccessibilitySettingsChangeNotification(JSValueRef callback)
 {
     unsigned callbackID = m_context->prepareForAsyncTask(callback, CallbackTypeNonPersistent);
 
-    auto* webView = TestController::singleton().mainWebView()->platformView();
+    auto* webView = this->webView();
     NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
     [center postNotificationName:UIAccessibilityInvertColorsStatusDidChangeNotification object:webView];
 
@@ -228,10 +220,9 @@ void UIScriptController::simulateAccessibilitySettingsChangeNotification(JSValue
     }];
 }
 
-double UIScriptController::zoomScale() const
+double UIScriptControllerIOS::zoomScale() const
 {
-    TestRunnerWKWebView *webView = TestController::singleton().mainWebView()->platformView();
-    return webView.scrollView.zoomScale;
+    return webView().scrollView.zoomScale;
 }
 
 static CGPoint globalToContentCoordinates(TestRunnerWKWebView *webView, long x, long y)
@@ -243,11 +234,11 @@ static CGPoint globalToContentCoordinates(TestRunnerWKWebView *webView, long x,
     return point;
 }
 
-void UIScriptController::touchDownAtPoint(long x, long y, long touchCount, JSValueRef callback)
+void UIScriptControllerIOS::touchDownAtPoint(long x, long y, long touchCount, JSValueRef callback)
 {
     unsigned callbackID = m_context->prepareForAsyncTask(callback, CallbackTypeNonPersistent);
 
-    auto location = globalToContentCoordinates(TestController::singleton().mainWebView()->platformView(), x, y);
+    auto location = globalToContentCoordinates(webView(), x, y);
     [[HIDEventGenerator sharedHIDEventGenerator] touchDown:location touchCount:touchCount completionBlock:^{
         if (!m_context)
             return;
@@ -255,11 +246,11 @@ void UIScriptController::touchDownAtPoint(long x, long y, long touchCount, JSVal
     }];
 }
 
-void UIScriptController::liftUpAtPoint(long x, long y, long touchCount, JSValueRef callback)
+void UIScriptControllerIOS::liftUpAtPoint(long x, long y, long touchCount, JSValueRef callback)
 {
     unsigned callbackID = m_context->prepareForAsyncTask(callback, CallbackTypeNonPersistent);
     
-    auto location = globalToContentCoordinates(TestController::singleton().mainWebView()->platformView(), x, y);
+    auto location = globalToContentCoordinates(webView(), x, y);
     [[HIDEventGenerator sharedHIDEventGenerator] liftUp:location touchCount:touchCount completionBlock:^{
         if (!m_context)
             return;
@@ -267,12 +258,12 @@ void UIScriptController::liftUpAtPoint(long x, long y, long touchCount, JSValueR
     }];
 }
 
-void UIScriptController::singleTapAtPoint(long x, long y, JSValueRef callback)
+void UIScriptControllerIOS::singleTapAtPoint(long x, long y, JSValueRef callback)
 {
     singleTapAtPointWithModifiers(x, y, nullptr, callback);
 }
 
-void UIScriptController::singleTapAtPointWithModifiers(long x, long y, JSValueRef modifierArray, JSValueRef callback)
+void UIScriptControllerIOS::singleTapAtPointWithModifiers(long x, long y, JSValueRef modifierArray, JSValueRef callback)
 {
     unsigned callbackID = m_context->prepareForAsyncTask(callback, CallbackTypeNonPersistent);
 
@@ -280,7 +271,7 @@ void UIScriptController::singleTapAtPointWithModifiers(long x, long y, JSValueRe
     for (auto& modifierFlag : modifierFlags)
         [[HIDEventGenerator sharedHIDEventGenerator] keyDown:modifierFlag];
 
-    [[HIDEventGenerator sharedHIDEventGenerator] tap:globalToContentCoordinates(TestController::singleton().mainWebView()->platformView(), x, y) completionBlock:^{
+    [[HIDEventGenerator sharedHIDEventGenerator] tap:globalToContentCoordinates(webView(), x, y) completionBlock:^{
         if (!m_context)
             return;
         for (size_t i = modifierFlags.size(); i; ) {
@@ -295,22 +286,22 @@ void UIScriptController::singleTapAtPointWithModifiers(long x, long y, JSValueRe
     }];
 }
 
-void UIScriptController::doubleTapAtPoint(long x, long y, JSValueRef callback)
+void UIScriptControllerIOS::doubleTapAtPoint(long x, long y, JSValueRef callback)
 {
     unsigned callbackID = m_context->prepareForAsyncTask(callback, CallbackTypeNonPersistent);
 
-    [[HIDEventGenerator sharedHIDEventGenerator] doubleTap:globalToContentCoordinates(TestController::singleton().mainWebView()->platformView(), x, y) completionBlock:^{
+    [[HIDEventGenerator sharedHIDEventGenerator] doubleTap:globalToContentCoordinates(webView(), x, y) completionBlock:^{
         if (!m_context)
             return;
         m_context->asyncTaskComplete(callbackID);
     }];
 }
 
-void UIScriptController::stylusDownAtPoint(long x, long y, float azimuthAngle, float altitudeAngle, float pressure, JSValueRef callback)
+void UIScriptControllerIOS::stylusDownAtPoint(long x, long y, float azimuthAngle, float altitudeAngle, float pressure, JSValueRef callback)
 {
     unsigned callbackID = m_context->prepareForAsyncTask(callback, CallbackTypeNonPersistent);
 
-    auto location = globalToContentCoordinates(TestController::singleton().mainWebView()->platformView(), x, y);
+    auto location = globalToContentCoordinates(webView(), x, y);
     [[HIDEventGenerator sharedHIDEventGenerator] stylusDownAtPoint:location azimuthAngle:azimuthAngle altitudeAngle:altitudeAngle pressure:pressure completionBlock:^{
         if (!m_context)
             return;
@@ -318,11 +309,11 @@ void UIScriptController::stylusDownAtPoint(long x, long y, float azimuthAngle, f
     }];
 }
 
-void UIScriptController::stylusMoveToPoint(long x, long y, float azimuthAngle, float altitudeAngle, float pressure, JSValueRef callback)
+void UIScriptControllerIOS::stylusMoveToPoint(long x, long y, float azimuthAngle, float altitudeAngle, float pressure, JSValueRef callback)
 {
     unsigned callbackID = m_context->prepareForAsyncTask(callback, CallbackTypeNonPersistent);
 
-    auto location = globalToContentCoordinates(TestController::singleton().mainWebView()->platformView(), x, y);
+    auto location = globalToContentCoordinates(webView(), x, y);
     [[HIDEventGenerator sharedHIDEventGenerator] stylusMoveToPoint:location azimuthAngle:azimuthAngle altitudeAngle:altitudeAngle pressure:pressure completionBlock:^{
         if (!m_context)
             return;
@@ -330,11 +321,11 @@ void UIScriptController::stylusMoveToPoint(long x, long y, float azimuthAngle, f
     }];
 }
 
-void UIScriptController::stylusUpAtPoint(long x, long y, JSValueRef callback)
+void UIScriptControllerIOS::stylusUpAtPoint(long x, long y, JSValueRef callback)
 {
     unsigned callbackID = m_context->prepareForAsyncTask(callback, CallbackTypeNonPersistent);
 
-    auto location = globalToContentCoordinates(TestController::singleton().mainWebView()->platformView(), x, y);
+    auto location = globalToContentCoordinates(webView(), x, y);
     [[HIDEventGenerator sharedHIDEventGenerator] stylusUpAtPoint:location completionBlock:^{
         if (!m_context)
             return;
@@ -342,12 +333,12 @@ void UIScriptController::stylusUpAtPoint(long x, long y, JSValueRef callback)
     }];
 }
 
-void UIScriptController::stylusTapAtPoint(long x, long y, float azimuthAngle, float altitudeAngle, float pressure, JSValueRef callback)
+void UIScriptControllerIOS::stylusTapAtPoint(long x, long y, float azimuthAngle, float altitudeAngle, float pressure, JSValueRef callback)
 {
     stylusTapAtPointWithModifiers(x, y, azimuthAngle, altitudeAngle, pressure, nullptr, callback);
 }
 
-void UIScriptController::stylusTapAtPointWithModifiers(long x, long y, float azimuthAngle, float altitudeAngle, float pressure, JSValueRef modifierArray, JSValueRef callback)
+void UIScriptControllerIOS::stylusTapAtPointWithModifiers(long x, long y, float azimuthAngle, float altitudeAngle, float pressure, JSValueRef modifierArray, JSValueRef callback)
 {
     unsigned callbackID = m_context->prepareForAsyncTask(callback, CallbackTypeNonPersistent);
 
@@ -355,7 +346,7 @@ void UIScriptController::stylusTapAtPointWithModifiers(long x, long y, float azi
     for (auto& modifierFlag : modifierFlags)
         [[HIDEventGenerator sharedHIDEventGenerator] keyDown:modifierFlag];
 
-    auto location = globalToContentCoordinates(TestController::singleton().mainWebView()->platformView(), x, y);
+    auto location = globalToContentCoordinates(webView(), x, y);
     [[HIDEventGenerator sharedHIDEventGenerator] stylusTapAtPoint:location azimuthAngle:azimuthAngle altitudeAngle:altitudeAngle pressure:pressure completionBlock:^{
         if (!m_context)
             return;
@@ -371,36 +362,38 @@ void UIScriptController::stylusTapAtPointWithModifiers(long x, long y, float azi
     }];
 }
 
-void convertCoordinates(NSMutableDictionary *event)
+void convertCoordinates(TestRunnerWKWebView *webView, NSMutableDictionary *event)
 {
     if (event[HIDEventTouchesKey]) {
         for (NSMutableDictionary *touch in event[HIDEventTouchesKey]) {
-            auto location = globalToContentCoordinates(TestController::singleton().mainWebView()->platformView(), (long)[touch[HIDEventXKey] doubleValue], (long)[touch[HIDEventYKey]doubleValue]);
+            auto location = globalToContentCoordinates(webView, (long)[touch[HIDEventXKey] doubleValue], (long)[touch[HIDEventYKey]doubleValue]);
             touch[HIDEventXKey] = @(location.x);
             touch[HIDEventYKey] = @(location.y);
         }
     }
 }
 
-void UIScriptController::sendEventStream(JSStringRef eventsJSON, JSValueRef callback)
+void UIScriptControllerIOS::sendEventStream(JSStringRef eventsJSON, JSValueRef callback)
 {
     unsigned callbackID = m_context->prepareForAsyncTask(callback, CallbackTypeNonPersistent);
 
     String jsonString = eventsJSON->string();
     auto eventInfo = dynamic_objc_cast<NSDictionary>([NSJSONSerialization JSONObjectWithData:[(NSString *)jsonString dataUsingEncoding:NSUTF8StringEncoding] options:NSJSONReadingMutableContainers | NSJSONReadingMutableLeaves error:nil]);
+
+    auto *webView = this->webView();
     
     for (NSMutableDictionary *event in eventInfo[TopLevelEventInfoKey]) {
         if (![event[HIDEventCoordinateSpaceKey] isEqualToString:HIDEventCoordinateSpaceTypeContent])
             continue;
         
         if (event[HIDEventStartEventKey])
-            convertCoordinates(event[HIDEventStartEventKey]);
+            convertCoordinates(webView, event[HIDEventStartEventKey]);
         
         if (event[HIDEventEndEventKey])
-            convertCoordinates(event[HIDEventEndEventKey]);
+            convertCoordinates(webView, event[HIDEventEndEventKey]);
         
         if (event[HIDEventTouchesKey])
-            convertCoordinates(event);
+            convertCoordinates(webView, event);
     }
     
     if (!eventInfo || ![eventInfo isKindOfClass:[NSDictionary class]]) {
@@ -415,12 +408,12 @@ void UIScriptController::sendEventStream(JSStringRef eventsJSON, JSValueRef call
     }];
 }
 
-void UIScriptController::dragFromPointToPoint(long startX, long startY, long endX, long endY, double durationSeconds, JSValueRef callback)
+void UIScriptControllerIOS::dragFromPointToPoint(long startX, long startY, long endX, long endY, double durationSeconds, JSValueRef callback)
 {
     unsigned callbackID = m_context->prepareForAsyncTask(callback, CallbackTypeNonPersistent);
 
-    CGPoint startPoint = globalToContentCoordinates(TestController::singleton().mainWebView()->platformView(), startX, startY);
-    CGPoint endPoint = globalToContentCoordinates(TestController::singleton().mainWebView()->platformView(), endX, endY);
+    CGPoint startPoint = globalToContentCoordinates(webView(), startX, startY);
+    CGPoint endPoint = globalToContentCoordinates(webView(), endX, endY);
     
     [[HIDEventGenerator sharedHIDEventGenerator] dragWithStartPoint:startPoint endPoint:endPoint duration:durationSeconds completionBlock:^{
         if (!m_context)
@@ -429,25 +422,24 @@ void UIScriptController::dragFromPointToPoint(long startX, long startY, long end
     }];
 }
     
-void UIScriptController::longPressAtPoint(long x, long y, JSValueRef callback)
+void UIScriptControllerIOS::longPressAtPoint(long x, long y, JSValueRef callback)
 {
     unsigned callbackID = m_context->prepareForAsyncTask(callback, CallbackTypeNonPersistent);
     
-    [[HIDEventGenerator sharedHIDEventGenerator] longPress:globalToContentCoordinates(TestController::singleton().mainWebView()->platformView(), x, y) completionBlock:^{
+    [[HIDEventGenerator sharedHIDEventGenerator] longPress:globalToContentCoordinates(webView(), x, y) completionBlock:^{
         if (!m_context)
             return;
         m_context->asyncTaskComplete(callbackID);
     }];
 }
 
-void UIScriptController::enterText(JSStringRef text)
+void UIScriptControllerIOS::enterText(JSStringRef text)
 {
-    TestRunnerWKWebView *webView = TestController::singleton().mainWebView()->platformView();
     auto textAsCFString = adoptCF(JSStringCopyCFString(kCFAllocatorDefault, text));
-    [webView _simulateTextEntered:(NSString *)textAsCFString.get()];
+    [webView() _simulateTextEntered:(NSString *)textAsCFString.get()];
 }
 
-void UIScriptController::typeCharacterUsingHardwareKeyboard(JSStringRef character, JSValueRef callback)
+void UIScriptControllerIOS::typeCharacterUsingHardwareKeyboard(JSStringRef character, JSValueRef callback)
 {
     unsigned callbackID = m_context->prepareForAsyncTask(callback, CallbackTypeNonPersistent);
 
@@ -468,7 +460,7 @@ static UIPhysicalKeyboardEvent *createUIPhysicalKeyboardEvent(NSString *hidInput
     return keyboardEvent;
 }
 
-void UIScriptController::keyDown(JSStringRef character, JSValueRef modifierArray)
+void UIScriptControllerIOS::keyDown(JSStringRef character, JSValueRef modifierArray)
 {
     // Character can be either a single Unicode code point or the name of a special key (e.g. "downArrow").
     // HIDEventGenerator knows how to map these special keys to the appropriate keycode.
@@ -489,15 +481,14 @@ void UIScriptController::keyDown(JSStringRef character, JSValueRef modifierArray
     [[HIDEventGenerator sharedHIDEventGenerator] sendMarkerHIDEventWithCompletionBlock:^{ /* Do nothing */ }];
 }
 
-void UIScriptController::dismissFormAccessoryView()
+void UIScriptControllerIOS::dismissFormAccessoryView()
 {
-    TestRunnerWKWebView *webView = TestController::singleton().mainWebView()->platformView();
-    [webView dismissFormAccessoryView];
+    [webView() dismissFormAccessoryView];
 }
 
-void UIScriptController::dismissFilePicker(JSValueRef callback)
+void UIScriptControllerIOS::dismissFilePicker(JSValueRef callback)
 {
-    TestRunnerWKWebView *webView = TestController::singleton().mainWebView()->platformView();
+    TestRunnerWKWebView *webView = this->webView();
     [webView _dismissFilePicker];
 
     // Round-trip with the WebProcess to make sure it has been notified of the dismissal.
@@ -508,40 +499,34 @@ void UIScriptController::dismissFilePicker(JSValueRef callback)
     }];
 }
 
-JSRetainPtr<JSStringRef> UIScriptController::selectFormPopoverTitle() const
+JSRetainPtr<JSStringRef> UIScriptControllerIOS::selectFormPopoverTitle() const
 {
-    TestRunnerWKWebView *webView = TestController::singleton().mainWebView()->platformView();
-    return adopt(JSStringCreateWithCFString((CFStringRef)webView.selectFormPopoverTitle));
+    return adopt(JSStringCreateWithCFString((CFStringRef)webView().selectFormPopoverTitle));
 }
 
-JSRetainPtr<JSStringRef> UIScriptController::textContentType() const
+JSRetainPtr<JSStringRef> UIScriptControllerIOS::textContentType() const
 {
-    TestRunnerWKWebView *webView = TestController::singleton().mainWebView()->platformView();
-    return adopt(JSStringCreateWithCFString((CFStringRef)(webView.textContentTypeForTesting ?: @"")));
+    return adopt(JSStringCreateWithCFString((CFStringRef)(webView().textContentTypeForTesting ?: @"")));
 }
 
-JSRetainPtr<JSStringRef> UIScriptController::formInputLabel() const
+JSRetainPtr<JSStringRef> UIScriptControllerIOS::formInputLabel() const
 {
-    TestRunnerWKWebView *webView = TestController::singleton().mainWebView()->platformView();
-    return adopt(JSStringCreateWithCFString((CFStringRef)webView.formInputLabel));
+    return adopt(JSStringCreateWithCFString((CFStringRef)webView().formInputLabel));
 }
 
-void UIScriptController::selectFormAccessoryPickerRow(long rowIndex)
+void UIScriptControllerIOS::selectFormAccessoryPickerRow(long rowIndex)
 {
-    TestRunnerWKWebView *webView = TestController::singleton().mainWebView()->platformView();
-    [webView selectFormAccessoryPickerRow:rowIndex];
+    [webView() selectFormAccessoryPickerRow:rowIndex];
 }
 
-void UIScriptController::setTimePickerValue(long hour, long minute)
+void UIScriptControllerIOS::setTimePickerValue(long hour, long minute)
 {
-    TestRunnerWKWebView *webView = TestController::singleton().mainWebView()->platformView();
-    [webView setTimePickerValueToHour:hour minute:minute];
+    [webView() setTimePickerValueToHour:hour minute:minute];
 }
 
-bool UIScriptController::isPresentingModally() const
+bool UIScriptControllerIOS::isPresentingModally() const
 {
-    TestRunnerWKWebView *webView = TestController::singleton().mainWebView()->platformView();
-    return !!webView.window.rootViewController.presentedViewController;
+    return !!webView().window.rootViewController.presentedViewController;
 }
 
 static CGPoint contentOffsetBoundedInValidRange(UIScrollView *scrollView, CGPoint contentOffset)
@@ -560,39 +545,35 @@ static CGPoint contentOffsetBoundedInValidRange(UIScrollView *scrollView, CGPoin
     return contentOffset;
 }
 
-double UIScriptController::contentOffsetX() const
+double UIScriptControllerIOS::contentOffsetX() const
 {
-    TestRunnerWKWebView *webView = TestController::singleton().mainWebView()->platformView();
-    return webView.scrollView.contentOffset.x;
+    return webView().scrollView.contentOffset.x;
 }
 
-double UIScriptController::contentOffsetY() const
+double UIScriptControllerIOS::contentOffsetY() const
 {
-    TestRunnerWKWebView *webView = TestController::singleton().mainWebView()->platformView();
-    return webView.scrollView.contentOffset.y;
+    return webView().scrollView.contentOffset.y;
 }
 
-bool UIScriptController::scrollUpdatesDisabled() const
+bool UIScriptControllerIOS::scrollUpdatesDisabled() const
 {
-    TestRunnerWKWebView *webView = TestController::singleton().mainWebView()->platformView();
-    return webView._scrollingUpdatesDisabledForTesting;
+    return webView()._scrollingUpdatesDisabledForTesting;
 }
 
-void UIScriptController::setScrollUpdatesDisabled(bool disabled)
+void UIScriptControllerIOS::setScrollUpdatesDisabled(bool disabled)
 {
-    TestRunnerWKWebView *webView = TestController::singleton().mainWebView()->platformView();
-    webView._scrollingUpdatesDisabledForTesting = disabled;
+    webView()._scrollingUpdatesDisabledForTesting = disabled;
 }
 
-void UIScriptController::scrollToOffset(long x, long y)
+void UIScriptControllerIOS::scrollToOffset(long x, long y)
 {
-    TestRunnerWKWebView *webView = TestController::singleton().mainWebView()->platformView();
+    TestRunnerWKWebView *webView = this->webView();
     [webView.scrollView setContentOffset:contentOffsetBoundedInValidRange(webView.scrollView, CGPointMake(x, y)) animated:YES];
 }
 
-void UIScriptController::immediateScrollToOffset(long x, long y)
+void UIScriptControllerIOS::immediateScrollToOffset(long x, long y)
 {
-    TestRunnerWKWebView *webView = TestController::singleton().mainWebView()->platformView();
+    TestRunnerWKWebView *webView = this->webView();
     [webView.scrollView setContentOffset:contentOffsetBoundedInValidRange(webView.scrollView, CGPointMake(x, y)) animated:NO];
 }
 
@@ -606,7 +587,7 @@ static UIScrollView *enclosingScrollViewIncludingSelf(UIView *view)
     return nil;
 }
 
-void UIScriptController::immediateScrollElementAtContentPointToOffset(long x, long y, long xScrollOffset, long yScrollOffset)
+void UIScriptControllerIOS::immediateScrollElementAtContentPointToOffset(long x, long y, long xScrollOffset, long yScrollOffset)
 {
     UIView *contentView = platformContentView();
     UIView *hitView = [contentView hitTest:CGPointMake(x, y) withEvent:nil];
@@ -614,39 +595,36 @@ void UIScriptController::immediateScrollElementAtContentPointToOffset(long x, lo
     [enclosingScrollView setContentOffset:CGPointMake(xScrollOffset, yScrollOffset)];
 }
 
-void UIScriptController::immediateZoomToScale(double scale)
+void UIScriptControllerIOS::immediateZoomToScale(double scale)
 {
-    TestRunnerWKWebView *webView = TestController::singleton().mainWebView()->platformView();
-    [webView.scrollView setZoomScale:scale animated:NO];
+    [webView().scrollView setZoomScale:scale animated:NO];
 }
 
-void UIScriptController::keyboardAccessoryBarNext()
+void UIScriptControllerIOS::keyboardAccessoryBarNext()
 {
-    TestRunnerWKWebView *webView = TestController::singleton().mainWebView()->platformView();
-    [webView keyboardAccessoryBarNext];
+    [webView() keyboardAccessoryBarNext];
 }
 
-void UIScriptController::keyboardAccessoryBarPrevious()
+void UIScriptControllerIOS::keyboardAccessoryBarPrevious()
 {
-    TestRunnerWKWebView *webView = TestController::singleton().mainWebView()->platformView();
-    [webView keyboardAccessoryBarPrevious];
+    [webView() keyboardAccessoryBarPrevious];
 }
 
-bool UIScriptController::isShowingKeyboard() const
+bool UIScriptControllerIOS::isShowingKeyboard() const
 {
-    return TestController::singleton().mainWebView()->platformView().showingKeyboard;
+    return webView().showingKeyboard;
 }
 
-bool UIScriptController::hasInputSession() const
+bool UIScriptControllerIOS::hasInputSession() const
 {
-    return TestController::singleton().mainWebView()->platformView().isInteractingWithFormControl;
+    return webView().isInteractingWithFormControl;
 }
 
-void UIScriptController::applyAutocorrection(JSStringRef newString, JSStringRef oldString, JSValueRef callback)
+void UIScriptControllerIOS::applyAutocorrection(JSStringRef newString, JSStringRef oldString, JSValueRef callback)
 {
     unsigned callbackID = m_context->prepareForAsyncTask(callback, CallbackTypeNonPersistent);
 
-    TestRunnerWKWebView *webView = TestController::singleton().mainWebView()->platformView();
+    TestRunnerWKWebView *webView = this->webView();
     [webView applyAutocorrection:toWTFString(toWK(newString)) toString:toWTFString(toWK(oldString)) withCompletionHandler:^ {
         // applyAutocorrection can call its completion handler synchronously,
         // which makes UIScriptController unhappy (see bug 172884).
@@ -658,62 +636,58 @@ void UIScriptController::applyAutocorrection(JSStringRef newString, JSStringRef
     }];
 }
 
-double UIScriptController::minimumZoomScale() const
+double UIScriptControllerIOS::minimumZoomScale() const
 {
-    TestRunnerWKWebView *webView = TestController::singleton().mainWebView()->platformView();
-    return webView.scrollView.minimumZoomScale;
+    return webView().scrollView.minimumZoomScale;
 }
 
-double UIScriptController::maximumZoomScale() const
+double UIScriptControllerIOS::maximumZoomScale() const
 {
-    TestRunnerWKWebView *webView = TestController::singleton().mainWebView()->platformView();
-    return webView.scrollView.maximumZoomScale;
+    return webView().scrollView.maximumZoomScale;
 }
 
-Optional<bool> UIScriptController::stableStateOverride() const
+Optional<bool> UIScriptControllerIOS::stableStateOverride() const
 {
-    TestRunnerWKWebView *webView = TestController::singleton().mainWebView()->platformView();
+    TestRunnerWKWebView *webView = this->webView();
     if (webView._stableStateOverride)
         return webView._stableStateOverride.boolValue;
 
     return WTF::nullopt;
 }
 
-void UIScriptController::setStableStateOverride(Optional<bool> overrideValue)
+void UIScriptControllerIOS::setStableStateOverride(Optional<bool> overrideValue)
 {
-    TestRunnerWKWebView *webView = TestController::singleton().mainWebView()->platformView();
+    TestRunnerWKWebView *webView = this->webView();
     if (overrideValue)
         webView._stableStateOverride = @(overrideValue.value());
     else
         webView._stableStateOverride = nil;
 }
 
-JSObjectRef UIScriptController::contentVisibleRect() const
+JSObjectRef UIScriptControllerIOS::contentVisibleRect() const
 {
-    TestRunnerWKWebView *webView = TestController::singleton().mainWebView()->platformView();
-
-    CGRect contentVisibleRect = webView._contentVisibleRect;
+    CGRect contentVisibleRect = webView()._contentVisibleRect;
     
     WebCore::FloatRect rect(contentVisibleRect.origin.x, contentVisibleRect.origin.y, contentVisibleRect.size.width, contentVisibleRect.size.height);
     return m_context->objectFromRect(rect);
 }
 
-JSObjectRef UIScriptController::textSelectionRangeRects() const
+JSObjectRef UIScriptControllerIOS::textSelectionRangeRects() const
 {
     auto selectionRects = adoptNS([[NSMutableArray alloc] init]);
-    NSArray *rects = TestController::singleton().mainWebView()->platformView()._uiTextSelectionRects;
+    NSArray *rects = webView()._uiTextSelectionRects;
     for (NSValue *rect in rects)
         [selectionRects addObject:toNSDictionary(rect.CGRectValue)];
 
     return JSValueToObject(m_context->jsContext(), [JSValue valueWithObject:selectionRects.get() inContext:[JSContext contextWithJSGlobalContextRef:m_context->jsContext()]].JSValueRef, nullptr);
 }
 
-JSObjectRef UIScriptController::textSelectionCaretRect() const
+JSObjectRef UIScriptControllerIOS::textSelectionCaretRect() const
 {
-    return JSValueToObject(m_context->jsContext(), [JSValue valueWithObject:toNSDictionary(TestController::singleton().mainWebView()->platformView()._uiTextCaretRect) inContext:[JSContext contextWithJSGlobalContextRef:m_context->jsContext()]].JSValueRef, nullptr);
+    return JSValueToObject(m_context->jsContext(), [JSValue valueWithObject:toNSDictionary(webView()._uiTextCaretRect) inContext:[JSContext contextWithJSGlobalContextRef:m_context->jsContext()]].JSValueRef, nullptr);
 }
 
-JSObjectRef UIScriptController::selectionStartGrabberViewRect() const
+JSObjectRef UIScriptControllerIOS::selectionStartGrabberViewRect() const
 {
     UIView *contentView = platformContentView();
     UIView *selectionRangeView = [contentView valueForKeyPath:@"interactionAssistant.selectionView.rangeView"];
@@ -723,7 +697,7 @@ JSObjectRef UIScriptController::selectionStartGrabberViewRect() const
     return JSValueToObject(jsContext, [JSValue valueWithObject:toNSDictionary(frameInContentCoordinates) inContext:[JSContext contextWithJSGlobalContextRef:jsContext]].JSValueRef, nullptr);
 }
 
-JSObjectRef UIScriptController::selectionEndGrabberViewRect() const
+JSObjectRef UIScriptControllerIOS::selectionEndGrabberViewRect() const
 {
     UIView *contentView = platformContentView();
     UIView *selectionRangeView = [contentView valueForKeyPath:@"interactionAssistant.selectionView.rangeView"];
@@ -733,7 +707,7 @@ JSObjectRef UIScriptController::selectionEndGrabberViewRect() const
     return JSValueToObject(jsContext, [JSValue valueWithObject:toNSDictionary(frameInContentCoordinates) inContext:[JSContext contextWithJSGlobalContextRef:jsContext]].JSValueRef, nullptr);
 }
 
-JSObjectRef UIScriptController::selectionCaretViewRect() const
+JSObjectRef UIScriptControllerIOS::selectionCaretViewRect() const
 {
     UIView *contentView = platformContentView();
     UIView *caretView = [contentView valueForKeyPath:@"interactionAssistant.selectionView.caretView"];
@@ -741,7 +715,7 @@ JSObjectRef UIScriptController::selectionCaretViewRect() const
     return JSValueToObject(m_context->jsContext(), [JSValue valueWithObject:toNSDictionary(rectInContentViewCoordinates) inContext:[JSContext contextWithJSGlobalContextRef:m_context->jsContext()]].JSValueRef, nullptr);
 }
 
-JSObjectRef UIScriptController::selectionRangeViewRects() const
+JSObjectRef UIScriptControllerIOS::selectionRangeViewRects() const
 {
     UIView *contentView = platformContentView();
     UIView *rangeView = [contentView valueForKeyPath:@"interactionAssistant.selectionView.rangeView"];
@@ -755,25 +729,24 @@ JSObjectRef UIScriptController::selectionRangeViewRects() const
     return JSValueToObject(m_context->jsContext(), [JSValue valueWithObject:rectsAsDictionaries.get() inContext:[JSContext contextWithJSGlobalContextRef:m_context->jsContext()]].JSValueRef, nullptr);
 }
 
-JSObjectRef UIScriptController::inputViewBounds() const
+JSObjectRef UIScriptControllerIOS::inputViewBounds() const
 {
-    return JSValueToObject(m_context->jsContext(), [JSValue valueWithObject:toNSDictionary(TestController::singleton().mainWebView()->platformView()._inputViewBounds) inContext:[JSContext contextWithJSGlobalContextRef:m_context->jsContext()]].JSValueRef, nullptr);
+    return JSValueToObject(m_context->jsContext(), [JSValue valueWithObject:toNSDictionary(webView()._inputViewBounds) inContext:[JSContext contextWithJSGlobalContextRef:m_context->jsContext()]].JSValueRef, nullptr);
 }
 
-void UIScriptController::removeAllDynamicDictionaries()
+void UIScriptControllerIOS::removeAllDynamicDictionaries()
 {
     [UIKeyboard removeAllDynamicDictionaries];
 }
 
-JSRetainPtr<JSStringRef> UIScriptController::scrollingTreeAsText() const
+JSRetainPtr<JSStringRef> UIScriptControllerIOS::scrollingTreeAsText() const
 {
-    TestRunnerWKWebView *webView = TestController::singleton().mainWebView()->platformView();
-    return adopt(JSStringCreateWithCFString((CFStringRef)[webView _scrollingTreeAsText]));
+    return adopt(JSStringCreateWithCFString((CFStringRef)[webView() _scrollingTreeAsText]));
 }
 
-JSObjectRef UIScriptController::propertiesOfLayerWithID(uint64_t layerID) const
+JSObjectRef UIScriptControllerIOS::propertiesOfLayerWithID(uint64_t layerID) const
 {
-    return JSValueToObject(m_context->jsContext(), [JSValue valueWithObject:[TestController::singleton().mainWebView()->platformView() _propertiesOfLayerWithID:layerID] inContext:[JSContext contextWithJSGlobalContextRef:m_context->jsContext()]].JSValueRef, nullptr);
+    return JSValueToObject(m_context->jsContext(), [JSValue valueWithObject:[webView() _propertiesOfLayerWithID:layerID] inContext:[JSContext contextWithJSGlobalContextRef:m_context->jsContext()]].JSValueRef, nullptr);
 }
 
 static UIDeviceOrientation toUIDeviceOrientation(DeviceOrientation* orientation)
@@ -795,9 +768,9 @@ static UIDeviceOrientation toUIDeviceOrientation(DeviceOrientation* orientation)
     return UIDeviceOrientationPortrait;
 }
 
-void UIScriptController::simulateRotation(DeviceOrientation* orientation, JSValueRef callback)
+void UIScriptControllerIOS::simulateRotation(DeviceOrientation* orientation, JSValueRef callback)
 {
-    TestRunnerWKWebView *webView = TestController::singleton().mainWebView()->platformView();
+    TestRunnerWKWebView *webView = this->webView();
     webView.usesSafariLikeRotation = NO;
     
     unsigned callbackID = m_context->prepareForAsyncTask(callback, CallbackTypeNonPersistent);
@@ -811,9 +784,9 @@ void UIScriptController::simulateRotation(DeviceOrientation* orientation, JSValu
     [[UIDevice currentDevice] setOrientation:toUIDeviceOrientation(orientation) animated:YES];
 }
 
-void UIScriptController::simulateRotationLikeSafari(DeviceOrientation* orientation, JSValueRef callback)
+void UIScriptControllerIOS::simulateRotationLikeSafari(DeviceOrientation* orientation, JSValueRef callback)
 {
-    TestRunnerWKWebView *webView = TestController::singleton().mainWebView()->platformView();
+    TestRunnerWKWebView *webView = this->webView();
     webView.usesSafariLikeRotation = YES;
     
     unsigned callbackID = m_context->prepareForAsyncTask(callback, CallbackTypeNonPersistent);
@@ -827,128 +800,132 @@ void UIScriptController::simulateRotationLikeSafari(DeviceOrientation* orientati
     [[UIDevice currentDevice] setOrientation:toUIDeviceOrientation(orientation) animated:YES];
 }
 
-void UIScriptController::platformSetDidStartFormControlInteractionCallback()
+void UIScriptControllerIOS::setDidStartFormControlInteractionCallback(JSValueRef callback)
 {
-    TestRunnerWKWebView *webView = TestController::singleton().mainWebView()->platformView();
-    webView.didStartFormControlInteractionCallback = ^{
+    UIScriptController::setDidStartFormControlInteractionCallback(callback);
+    webView().didStartFormControlInteractionCallback = ^{
         if (!m_context)
             return;
         m_context->fireCallback(CallbackTypeDidStartFormControlInteraction);
     };
 }
 
-void UIScriptController::platformSetDidEndFormControlInteractionCallback()
+void UIScriptControllerIOS::setDidEndFormControlInteractionCallback(JSValueRef callback)
 {
-    TestRunnerWKWebView *webView = TestController::singleton().mainWebView()->platformView();
-    webView.didEndFormControlInteractionCallback = ^{
+    UIScriptController::setDidEndFormControlInteractionCallback(callback);
+    webView().didEndFormControlInteractionCallback = ^{
         if (!m_context)
             return;
         m_context->fireCallback(CallbackTypeDidEndFormControlInteraction);
     };
 }
     
-void UIScriptController::platformSetDidShowForcePressPreviewCallback()
+void UIScriptControllerIOS::setDidShowForcePressPreviewCallback(JSValueRef callback)
 {
-    TestRunnerWKWebView *webView = TestController::singleton().mainWebView()->platformView();
-    webView.didShowForcePressPreviewCallback = ^ {
+    UIScriptController::setDidShowForcePressPreviewCallback(callback);
+    webView().didShowForcePressPreviewCallback = ^ {
         if (!m_context)
             return;
         m_context->fireCallback(CallbackTypeDidShowForcePressPreview);
     };
 }
 
-void UIScriptController::platformSetDidDismissForcePressPreviewCallback()
+void UIScriptControllerIOS::setDidDismissForcePressPreviewCallback(JSValueRef callback)
 {
-    TestRunnerWKWebView *webView = TestController::singleton().mainWebView()->platformView();
-    webView.didDismissForcePressPreviewCallback = ^ {
+    UIScriptController::setDidDismissForcePressPreviewCallback(callback);
+    webView().didDismissForcePressPreviewCallback = ^ {
         if (!m_context)
             return;
         m_context->fireCallback(CallbackTypeDidEndFormControlInteraction);
     };
 }
 
-void UIScriptController::platformSetWillBeginZoomingCallback()
+void UIScriptControllerIOS::setWillBeginZoomingCallback(JSValueRef callback)
 {
-    TestRunnerWKWebView *webView = TestController::singleton().mainWebView()->platformView();
-    webView.willBeginZoomingCallback = ^{
+    UIScriptController::setWillBeginZoomingCallback(callback);
+    webView().willBeginZoomingCallback = ^{
         if (!m_context)
             return;
         m_context->fireCallback(CallbackTypeWillBeginZooming);
     };
 }
 
-void UIScriptController::platformSetDidEndZoomingCallback()
+void UIScriptControllerIOS::setDidEndZoomingCallback(JSValueRef callback)
 {
-    TestRunnerWKWebView *webView = TestController::singleton().mainWebView()->platformView();
-    webView.didEndZoomingCallback = ^{
+    UIScriptController::setDidEndZoomingCallback(callback);
+    webView().didEndZoomingCallback = ^{
         if (!m_context)
             return;
         m_context->fireCallback(CallbackTypeDidEndZooming);
     };
 }
 
-void UIScriptController::platformSetDidShowKeyboardCallback()
+void UIScriptControllerIOS::setDidShowKeyboardCallback(JSValueRef callback)
 {
-    TestRunnerWKWebView *webView = TestController::singleton().mainWebView()->platformView();
-    webView.didShowKeyboardCallback = ^{
+    UIScriptController::setDidShowKeyboardCallback(callback);
+    webView().didShowKeyboardCallback = ^{
         if (!m_context)
             return;
         m_context->fireCallback(CallbackTypeDidShowKeyboard);
     };
 }
 
-void UIScriptController::platformSetDidHideKeyboardCallback()
+void UIScriptControllerIOS::setDidHideKeyboardCallback(JSValueRef callback)
 {
-    TestRunnerWKWebView *webView = TestController::singleton().mainWebView()->platformView();
-    webView.didHideKeyboardCallback = ^{
+    UIScriptController::setDidHideKeyboardCallback(callback);
+    webView().didHideKeyboardCallback = ^{
         if (!m_context)
             return;
         m_context->fireCallback(CallbackTypeDidHideKeyboard);
     };
 }
 
-void UIScriptController::platformSetDidShowMenuCallback()
+void UIScriptControllerIOS::setDidShowMenuCallback(JSValueRef callback)
 {
-    TestController::singleton().mainWebView()->platformView().didShowMenuCallback = ^{
+    UIScriptController::setDidShowMenuCallback(callback);
+    webView().didShowMenuCallback = ^{
         if (!m_context)
             return;
         m_context->fireCallback(CallbackTypeDidShowMenu);
     };
 }
 
-void UIScriptController::platformSetDidHideMenuCallback()
+void UIScriptControllerIOS::setDidHideMenuCallback(JSValueRef callback)
 {
-    TestController::singleton().mainWebView()->platformView().didHideMenuCallback = ^{
+    UIScriptController::setDidHideMenuCallback(callback);
+    webView().didHideMenuCallback = ^{
         if (!m_context)
             return;
         m_context->fireCallback(CallbackTypeDidHideMenu);
     };
 }
 
-bool UIScriptController::isShowingPopover() const
+bool UIScriptControllerIOS::isShowingPopover() const
 {
-    return TestController::singleton().mainWebView()->platformView().showingPopover;
+    return webView().showingPopover;
 }
 
-void UIScriptController::platformSetWillPresentPopoverCallback()
+void UIScriptControllerIOS::setWillPresentPopoverCallback(JSValueRef callback)
 {
-    TestController::singleton().mainWebView()->platformView().willPresentPopoverCallback = ^{
+    UIScriptController::setWillPresentPopoverCallback(callback);
+    webView().willPresentPopoverCallback = ^{
         if (!m_context)
             return;
         m_context->fireCallback(CallbackTypeWillPresentPopover);
     };
 }
 
-void UIScriptController::platformSetDidDismissPopoverCallback()
+void UIScriptControllerIOS::setDidDismissPopoverCallback(JSValueRef callback)
 {
-    TestController::singleton().mainWebView()->platformView().didDismissPopoverCallback = ^{
+    UIScriptController::setDidDismissPopoverCallback(callback);
+    webView().didDismissPopoverCallback = ^{
         if (!m_context)
             return;
         m_context->fireCallback(CallbackTypeDidDismissPopover);
     };
 }
 
-JSObjectRef UIScriptController::rectForMenuAction(JSStringRef jsAction) const
+JSObjectRef UIScriptControllerIOS::rectForMenuAction(JSStringRef jsAction) const
 {
     auto action = adoptCF(JSStringCopyCFString(kCFAllocatorDefault, jsAction));
 
@@ -978,7 +955,7 @@ JSObjectRef UIScriptController::rectForMenuAction(JSStringRef jsAction) const
     return m_context->objectFromRect(WebCore::FloatRect(rectInRootViewCoordinates.origin.x, rectInRootViewCoordinates.origin.y, rectInRootViewCoordinates.size.width, rectInRootViewCoordinates.size.height));
 }
 
-JSObjectRef UIScriptController::menuRect() const
+JSObjectRef UIScriptControllerIOS::menuRect() const
 {
     UIView *calloutBar = UICalloutBar.activeCalloutBar;
     if (!calloutBar.window)
@@ -988,51 +965,48 @@ JSObjectRef UIScriptController::menuRect() const
     return m_context->objectFromRect(WebCore::FloatRect(rectInRootViewCoordinates.origin.x, rectInRootViewCoordinates.origin.y, rectInRootViewCoordinates.size.width, rectInRootViewCoordinates.size.height));
 }
 
-bool UIScriptController::isDismissingMenu() const
+bool UIScriptControllerIOS::isDismissingMenu() const
 {
-    return TestController::singleton().mainWebView()->platformView().dismissingMenu;
+    return webView().dismissingMenu;
 }
 
-bool UIScriptController::isShowingMenu() const
+bool UIScriptControllerIOS::isShowingMenu() const
 {
-    return TestController::singleton().mainWebView()->platformView().showingMenu;
+    return webView().showingMenu;
 }
 
-void UIScriptController::platformSetDidEndScrollingCallback()
+void UIScriptControllerIOS::setDidEndScrollingCallback(JSValueRef callback)
 {
-    TestRunnerWKWebView *webView = TestController::singleton().mainWebView()->platformView();
-    webView.didEndScrollingCallback = ^{
+    UIScriptController::setDidEndScrollingCallback(callback);
+    webView().didEndScrollingCallback = ^{
         if (!m_context)
             return;
         m_context->fireCallback(CallbackTypeDidEndScrolling);
     };
 }
 
-void UIScriptController::platformClearAllCallbacks()
+void UIScriptControllerIOS::clearAllCallbacks()
 {
-    [TestController::singleton().mainWebView()->platformView() resetInteractionCallbacks];
+    [webView() resetInteractionCallbacks];
 }
 
-void UIScriptController::setSafeAreaInsets(double top, double right, double bottom, double left)
+void UIScriptControllerIOS::setSafeAreaInsets(double top, double right, double bottom, double left)
 {
     UIEdgeInsets insets = UIEdgeInsetsMake(top, left, bottom, right);
-    TestRunnerWKWebView *webView = TestController::singleton().mainWebView()->platformView();
-    webView.overrideSafeAreaInsets = insets;
+    webView().overrideSafeAreaInsets = insets;
 }
 
-void UIScriptController::beginBackSwipe(JSValueRef callback)
+void UIScriptControllerIOS::beginBackSwipe(JSValueRef callback)
 {
-    TestRunnerWKWebView *webView = TestController::singleton().mainWebView()->platformView();
-    [webView _beginBackSwipeForTesting];
+    [webView() _beginBackSwipeForTesting];
 }
 
-void UIScriptController::completeBackSwipe(JSValueRef callback)
+void UIScriptControllerIOS::completeBackSwipe(JSValueRef callback)
 {
-    TestRunnerWKWebView *webView = TestController::singleton().mainWebView()->platformView();
-    [webView _completeBackSwipeForTesting];
+    [webView() _completeBackSwipeForTesting];
 }
 
-bool UIScriptController::isShowingDataListSuggestions() const
+bool UIScriptControllerIOS::isShowingDataListSuggestions() const
 {
     Class remoteKeyboardWindowClass = NSClassFromString(@"UIRemoteKeyboardWindow");
     Class suggestionsPickerViewClass = NSClassFromString(@"WKDataListSuggestionsPickerView");
@@ -1059,10 +1033,9 @@ bool UIScriptController::isShowingDataListSuggestions() const
 #if HAVE(PENCILKIT)
 static PKCanvasView *findEditableImageCanvas()
 {
-    TestRunnerWKWebView *webView = TestController::singleton().mainWebView()->platformView();
     Class pkCanvasViewClass = NSClassFromString(@"PKCanvasView");
     __block PKCanvasView *canvasView = nil;
-    forEachViewInHierarchy(webView.window, ^(UIView *subview, BOOL *stop) {
+    forEachViewInHierarchy(webView().window, ^(UIView *subview, BOOL *stop) {
         if (![subview isKindOfClass:pkCanvasViewClass])
             return;
 
@@ -1073,7 +1046,7 @@ static PKCanvasView *findEditableImageCanvas()
 }
 #endif
 
-void UIScriptController::drawSquareInEditableImage()
+void UIScriptControllerIOS::drawSquareInEditableImage()
 {
 #if HAVE(PENCILKIT)
     Class pkDrawingClass = NSClassFromString(@"PKDrawing");
@@ -1091,7 +1064,7 @@ void UIScriptController::drawSquareInEditableImage()
 #endif
 }
 
-long UIScriptController::numberOfStrokesInEditableImage()
+long UIScriptControllerIOS::numberOfStrokesInEditableImage()
 {
 #if HAVE(PENCILKIT)
     PKCanvasView *canvasView = findEditableImageCanvas();
@@ -1101,14 +1074,14 @@ long UIScriptController::numberOfStrokesInEditableImage()
 #endif
 }
 
-void UIScriptController::setKeyboardInputModeIdentifier(JSStringRef identifier)
+void UIScriptControllerIOS::setKeyboardInputModeIdentifier(JSStringRef identifier)
 {
     TestController::singleton().setKeyboardInputModeIdentifier(toWTFString(toWK(identifier)));
 }
 
 // FIXME: Write this in terms of HIDEventGenerator once we know how to reset caps lock state
 // on test completion to avoid it effecting subsequent tests.
-void UIScriptController::toggleCapsLock(JSValueRef callback)
+void UIScriptControllerIOS::toggleCapsLock(JSValueRef callback)
 {
     m_capsLockOn = !m_capsLockOn;
     auto *keyboardEvent = createUIPhysicalKeyboardEvent(@"capsLock", [NSString string], m_capsLockOn ? UIKeyModifierAlphaShift : 0,
@@ -1117,12 +1090,10 @@ void UIScriptController::toggleCapsLock(JSValueRef callback)
     doAsyncTask(callback);
 }
 
-JSObjectRef UIScriptController::attachmentInfo(JSStringRef jsAttachmentIdentifier)
+JSObjectRef UIScriptControllerIOS::attachmentInfo(JSStringRef jsAttachmentIdentifier)
 {
-    TestRunnerWKWebView *webView = TestController::singleton().mainWebView()->platformView();
-
     auto attachmentIdentifier = toWTFString(toWK(jsAttachmentIdentifier));
-    _WKAttachment *attachment = [webView _attachmentForIdentifier:attachmentIdentifier];
+    _WKAttachment *attachment = [webView() _attachmentForIdentifier:attachmentIdentifier];
     _WKAttachmentInfo *attachmentInfo = attachment.info;
 
     NSDictionary *attachmentInfoDictionary = @{
@@ -1136,25 +1107,29 @@ JSObjectRef UIScriptController::attachmentInfo(JSStringRef jsAttachmentIdentifie
     return JSValueToObject(m_context->jsContext(), [JSValue valueWithObject:attachmentInfoDictionary inContext:[JSContext contextWithJSGlobalContextRef:m_context->jsContext()]].JSValueRef, nullptr);
 }
 
-UIView *UIScriptController::platformContentView() const
+UIView *UIScriptControllerIOS::platformContentView() const
 {
-    return [TestController::singleton().mainWebView()->platformView() valueForKeyPath:@"_currentContentView"];
+    return [webView() valueForKeyPath:@"_currentContentView"];
 }
 
-JSObjectRef UIScriptController::calendarType() const
+JSObjectRef UIScriptControllerIOS::calendarType() const
 {
-    WKWebView *webView = TestController::singleton().mainWebView()->platformView();
-    UIView *contentView = [webView valueForKeyPath:@"_currentContentView"];
+    UIView *contentView = [webView() valueForKeyPath:@"_currentContentView"];
     NSString *calendarTypeString = [contentView valueForKeyPath:@"formInputControl.dateTimePickerCalendarType"];
     auto jsContext = m_context->jsContext();
     return JSValueToObject(jsContext, [JSValue valueWithObject:calendarTypeString inContext:[JSContext contextWithJSGlobalContextRef:jsContext]].JSValueRef, nullptr);
 }
 
-void UIScriptController::setHardwareKeyboardAttached(bool attached)
+void UIScriptControllerIOS::setHardwareKeyboardAttached(bool attached)
 {
     GSEventSetHardwareKeyboardAttached(attached, 0);
 }
 
+void UIScriptControllerIOS::setAllowsViewportShrinkToFit(bool allows)
+{
+    webView()._allowsViewportShrinkToFit = allows;
+}
+
 }
 
 #endif // PLATFORM(IOS_FAMILY)
diff --git a/Tools/WebKitTestRunner/mac/UIScriptControllerMac.h b/Tools/WebKitTestRunner/mac/UIScriptControllerMac.h
new file mode 100644 (file)
index 0000000..049d971
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2019 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#import "UIScriptControllerCocoa.h"
+
+OBJC_CLASS WKWebView;
+
+namespace WTR {
+
+class UIScriptControllerMac : public UIScriptControllerCocoa {
+public:
+    explicit UIScriptControllerMac(UIScriptContext& context)
+        : UIScriptControllerCocoa(context)
+    {
+    }
+
+    void replaceTextAtRange(JSStringRef, int, int) override;
+    void zoomToScale(double, JSValueRef) override;
+    double zoomScale() const override;
+    void simulateAccessibilitySettingsChangeNotification(JSValueRef) override;
+    bool isShowingDataListSuggestions() const override;
+    void beginBackSwipe(JSValueRef) override;
+    void completeBackSwipe(JSValueRef) override;
+    void playBackEventStream(JSStringRef, JSValueRef) override;
+    void firstResponderSuppressionForWebView(bool) override;
+    void makeWindowContentViewFirstResponder() override;
+    bool isWindowContentViewFirstResponder() const override;
+    void toggleCapsLock(JSValueRef) override;
+    NSView *platformContentView() const override;
+};
+
+} // namespace WTR
index acb26c2..68ef878 100644 (file)
@@ -24,7 +24,7 @@
  */
 
 #import "config.h"
-#import "UIScriptController.h"
+#import "UIScriptControllerMac.h"
 
 #import "EventSerializerMac.h"
 #import "PlatformWebView.h"
 
 namespace WTR {
 
-NSString *nsString(JSStringRef string)
+Ref<UIScriptController> UIScriptController::create(UIScriptContext& context)
 {
-    return CFBridgingRelease(JSStringCopyCFString(kCFAllocatorDefault, string));
-}
-
-void UIScriptController::doAfterPresentationUpdate(JSValueRef callback)
-{
-    return doAsyncTask(callback);
-}
-
-void UIScriptController::doAfterNextStablePresentationUpdate(JSValueRef callback)
-{
-    doAsyncTask(callback);
+    return adoptRef(*new UIScriptControllerMac(context));
 }
 
-void UIScriptController::ensurePositionInformationIsUpToDateAt(long, long, JSValueRef callback)
+static NSString *nsString(JSStringRef string)
 {
-    doAsyncTask(callback);
-}
-
-void UIScriptController::doAfterVisibleContentRectUpdate(JSValueRef callback)
-{
-    doAsyncTask(callback);
+    return CFBridgingRelease(JSStringCopyCFString(kCFAllocatorDefault, string));
 }
 
-void UIScriptController::replaceTextAtRange(JSStringRef text, int location, int length)
+void UIScriptControllerMac::replaceTextAtRange(JSStringRef text, int location, int length)
 {
-    auto* webView = TestController::singleton().mainWebView()->platformView();
-    [webView _insertText:nsString(text) replacementRange:NSMakeRange(location == -1 ? NSNotFound : location, length)];
+    [webView() _insertText:nsString(text) replacementRange:NSMakeRange(location == -1 ? NSNotFound : location, length)];
 }
 
-void UIScriptController::zoomToScale(double scale, JSValueRef callback)
+void UIScriptControllerMac::zoomToScale(double scale, JSValueRef callback)
 {
     unsigned callbackID = m_context->prepareForAsyncTask(callback, CallbackTypeNonPersistent);
 
-    auto* webView = TestController::singleton().mainWebView()->platformView();
+    auto* webView = this->webView();
     [webView _setPageScale:scale withOrigin:CGPointZero];
 
-    [webView _doAfterNextPresentationUpdate: ^ {
+    [webView _doAfterNextPresentationUpdate:^{
         if (!m_context)
             return;
         m_context->asyncTaskComplete(callbackID);
     }];
 }
 
-void UIScriptController::simulateAccessibilitySettingsChangeNotification(JSValueRef callback)
+double UIScriptControllerMac::zoomScale() const
+{
+    return webView().magnification;
+}
+
+void UIScriptControllerMac::simulateAccessibilitySettingsChangeNotification(JSValueRef callback)
 {
     unsigned callbackID = m_context->prepareForAsyncTask(callback, CallbackTypeNonPersistent);
 
-    auto* webView = TestController::singleton().mainWebView()->platformView();
+    auto* webView = this->webView();
     NSNotificationCenter *center = [[NSWorkspace sharedWorkspace] notificationCenter];
     [center postNotificationName:NSWorkspaceAccessibilityDisplayOptionsDidChangeNotification object:webView];
 
-    [webView _doAfterNextPresentationUpdate: ^{
+    [webView _doAfterNextPresentationUpdate:^{
         if (!m_context)
             return;
         m_context->asyncTaskComplete(callbackID);
     }];
 }
 
-void UIScriptController::simulateRotation(DeviceOrientation*, JSValueRef)
-{
-}
-
-void UIScriptController::simulateRotationLikeSafari(DeviceOrientation*, JSValueRef)
-{
-}
-
-bool UIScriptController::isShowingDataListSuggestions() const
+bool UIScriptControllerMac::isShowingDataListSuggestions() const
 {
-    TestRunnerWKWebView *webView = TestController::singleton().mainWebView()->platformView();
-    for (NSWindow *childWindow in webView.window.childWindows) {
+    for (NSWindow *childWindow in webView().window.childWindows) {
         if ([childWindow isKindOfClass:NSClassFromString(@"WKDataListSuggestionWindow")])
             return true;
     }
     return false;
 }
 
-static void playBackEvents(UIScriptContext *context, NSString *eventStream, JSValueRef callback)
+static void playBackEvents(WKWebView *webView, UIScriptContext *context, NSString *eventStream, JSValueRef callback)
 {
     NSError *error = nil;
     NSArray *eventDicts = [NSJSONSerialization JSONObjectWithData:[eventStream dataUsingEncoding:NSUTF8StringEncoding] options:0 error:&error];
@@ -133,52 +113,48 @@ static void playBackEvents(UIScriptContext *context, NSString *eventStream, JSVa
     }
 
     unsigned callbackID = context->prepareForAsyncTask(callback, CallbackTypeNonPersistent);
-
-    NSWindow *window = [TestController::singleton().mainWebView()->platformView() window];
-
-    [EventStreamPlayer playStream:eventDicts window:window completionHandler:^ {
+    [EventStreamPlayer playStream:eventDicts window:webView.window completionHandler:^{
         context->asyncTaskComplete(callbackID);
     }];
 }
 
-void UIScriptController::beginBackSwipe(JSValueRef callback)
+void UIScriptControllerMac::beginBackSwipe(JSValueRef callback)
 {
-    playBackEvents(m_context, beginSwipeBackEventStream(), callback);
+    playBackEvents(webView(), m_context, beginSwipeBackEventStream(), callback);
 }
 
-void UIScriptController::completeBackSwipe(JSValueRef callback)
+void UIScriptControllerMac::completeBackSwipe(JSValueRef callback)
 {
-    playBackEvents(m_context, completeSwipeBackEventStream(), callback);
+    playBackEvents(webView(), m_context, completeSwipeBackEventStream(), callback);
 }
 
-void UIScriptController::platformPlayBackEventStream(JSStringRef eventStream, JSValueRef callback)
+void UIScriptControllerMac::playBackEventStream(JSStringRef eventStream, JSValueRef callback)
 {
     RetainPtr<CFStringRef> stream = adoptCF(JSStringCopyCFString(kCFAllocatorDefault, eventStream));
-    playBackEvents(m_context, (__bridge NSString *)stream.get(), callback);
+    playBackEvents(webView(), m_context, (__bridge NSString *)stream.get(), callback);
 }
 
-void UIScriptController::firstResponderSuppressionForWebView(bool shouldSuppress)
+void UIScriptControllerMac::firstResponderSuppressionForWebView(bool shouldSuppress)
 {
-    auto* webView = TestController::singleton().mainWebView()->platformView();
-    [webView _setShouldSuppressFirstResponderChanges:shouldSuppress];
+    [webView() _setShouldSuppressFirstResponderChanges:shouldSuppress];
 }
 
-void UIScriptController::makeWindowContentViewFirstResponder()
+void UIScriptControllerMac::makeWindowContentViewFirstResponder()
 {
-    NSWindow *window = [TestController::singleton().mainWebView()->platformView() window];
+    NSWindow *window = [webView() window];
     [window makeFirstResponder:[window contentView]];
 }
 
-bool UIScriptController::isWindowContentViewFirstResponder() const
+bool UIScriptControllerMac::isWindowContentViewFirstResponder() const
 {
-    NSWindow *window = [TestController::singleton().mainWebView()->platformView() window];
+    NSWindow *window = [webView() window];
     return [window firstResponder] == [window contentView];
 }
 
-void UIScriptController::toggleCapsLock(JSValueRef callback)
+void UIScriptControllerMac::toggleCapsLock(JSValueRef callback)
 {
     m_capsLockOn = !m_capsLockOn;
-    NSWindow *window = [TestController::singleton().mainWebView()->platformView() window];
+    NSWindow *window = [webView() window];
     NSEvent *fakeEvent = [NSEvent keyEventWithType:NSEventTypeFlagsChanged
         location:NSZeroPoint
         modifierFlags:m_capsLockOn ? NSEventModifierFlagCapsLock : 0
@@ -193,14 +169,9 @@ void UIScriptController::toggleCapsLock(JSValueRef callback)
     doAsyncTask(callback);
 }
 
-NSView *UIScriptController::platformContentView() const
-{
-    return TestController::singleton().mainWebView()->platformView();
-}
-
-JSObjectRef UIScriptController::calendarType() const
+NSView *UIScriptControllerMac::platformContentView() const
 {
-    return nullptr;
+    return webView();
 }
 
 } // namespace WTR