[iOS] Allow SPI clients to lay out at arbitrarily scaled sizes and scale to fit the...
authorwenson_hsieh@apple.com <wenson_hsieh@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 12 Oct 2018 23:13:37 +0000 (23:13 +0000)
committerwenson_hsieh@apple.com <wenson_hsieh@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 12 Oct 2018 23:13:37 +0000 (23:13 +0000)
https://bugs.webkit.org/show_bug.cgi?id=190504
<rdar://problem/45117760>

Reviewed by Tim Horton.

Source/WebCore:

Add support in ViewportConfiguration for applying a layout size scale factor to the viewport. See below for
more details.

Tests: fast/viewport/ios/constant-width-viewport-after-changing-view-scale.html
       fast/viewport/ios/device-width-viewport-after-changing-view-scale.html

* page/ViewportConfiguration.cpp:
(WebCore::ViewportConfiguration::setViewLayoutSize):

The viewport's layout size may now be changed alongside the layout size scale factor. If either of these two
variables change, we recompute our minimum layout size and viewport configuration parameters.

(WebCore::ViewportConfiguration::shouldIgnoreHorizontalScalingConstraints const):
(WebCore::ViewportConfiguration::nativeWebpageParameters):
(WebCore::ViewportConfiguration::testingParameters):
(WebCore::ViewportConfiguration::updateConfiguration):

Multiply the minimum scale, initial scale, and maximum scale by the layout size scale factor. This allows us to
keep the document well-proportioned within the viewport, while still laying out at a different layout size.

(WebCore::ViewportConfiguration::updateMinimumLayoutSize):

Compute the minimum layout size by scaling the default layout size derived from our view's size.

(WebCore::ViewportConfiguration::layoutWidth const):
(WebCore::ViewportConfiguration::layoutHeight const):
* page/ViewportConfiguration.h:

Maintain the original initial scale, unaffected by the layout size scale factor. This is used when computing
layout width and height to prevent scaling by the layout size scale factor twice when computing layout sizes.

(WebCore::ViewportConfiguration::description const):

Include the layout size scale factor in ViewportConfiguration's description string.

(WebCore::ViewportConfiguration::Parameters::operator== const):
(WebCore::operator<<):

Source/WebKit:

Add support for _setViewScale: and _viewScale on iOS. While similar in concept to macOS, changing this property
on iOS uses viewport configurations to change the minimum layout size of the document and apply view scaling.
Setting the view scale on iOS to a value `s` multiplies the minimium layout size by a factor `1 / s`, but also
multiplies the initial, minimum and maximum scales by a factor of `s`. The net effect of applying this scale
causes the page to lay out at a larger width and shrink (or a smaller width and expand) to fit the viewport.

* Shared/WebPageCreationParameters.cpp:
(WebKit::WebPageCreationParameters::encode const):
(WebKit::WebPageCreationParameters::decode):
* Shared/WebPageCreationParameters.h:

Send `viewportConfigurationLayoutSizeScaleFactor` alongside `viewportConfigurationViewLayoutSize`.

(-[WKWebView _dispatchSetViewLayoutSize:]):
(-[WKWebView _viewScale]):
(-[WKWebView _setViewScale:]):

Provide a different implementation of `_setViewScale:` on iOS, by scaling the effective minimum layout size.
(See above for more detail).

* UIProcess/API/Cocoa/WKWebViewPrivate.h:

Add missing API availability annotations for the _viewScale property.

* UIProcess/API/mac/WKView.mm:
(-[WKView _setViewScale:]):
* UIProcess/Cocoa/WebViewImpl.mm:

Both -[WKView _setViewScale:] and -[WKWebView _setViewScale:] throw Objective C exceptions upon receiving a bad
argument (e.g. scale <= 0). However, logic for throwing this exception is specific to iOS in WKWebView, and
handled in WebViewImpl on macOS. To make this less confusing, move the exception throwing code out of
!PLATFORM(MAC) in WKWebView, and move the path for raising this exception in WKView on macOS from WebViewImpl to
WKView.

* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::creationParameters):
* UIProcess/WebPageProxy.h:
(WebKit::WebPageProxy::layoutSizeScaleFactor const):

Tie the notion of "view scale" on iOS to `layoutSizeScaleFactor`. As its name suggests, this is a scale factor
by which we transform the layout size.

* UIProcess/ios/WebPageProxyIOS.mm:
(WebKit::WebPageProxy::setViewportConfigurationViewLayoutSize):
* WebProcess/WebPage/WebPage.cpp:
* WebProcess/WebPage/WebPage.h:
* WebProcess/WebPage/WebPage.messages.in:

Plumb the layout size scale factor over to the web process, along with the layout size.

* WebProcess/WebPage/ios/WebPageIOS.mm:
(WebKit::WebPage::setViewportConfigurationViewLayoutSize):

Tools:

Teach UIScriptController to set WKWebView's view scale via a new `setViewScale` method, supported in WebKit2 on
macOS and iOS.

* DumpRenderTree/ios/UIScriptControllerIOS.mm:
(WTR::UIScriptController::setViewScale):
* DumpRenderTree/mac/UIScriptControllerMac.mm:
(WTR::UIScriptController::setViewScale):
* TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl:
* TestRunnerShared/UIScriptContext/UIScriptController.cpp:
(WTR::UIScriptController::setViewScale):
* TestRunnerShared/UIScriptContext/UIScriptController.h:
* WebKitTestRunner/UIScriptControllerCocoa.mm: Added.

Add a new file for UIScriptController methods on Cocoa platforms.

(WTR::UIScriptController::setViewScale):
* WebKitTestRunner/WebKitTestRunner.xcodeproj/project.pbxproj:
* WebKitTestRunner/cocoa/TestControllerCocoa.mm:
(WTR::TestController::cocoaResetStateToConsistentValues):

Ensure that _viewScale is reset to 1 after running a layout test.

LayoutTests:

Add two new layout tests on iOS that change WKWebView's view scale, and measure the resulting window sizes and
lengths of viewport units.

* fast/viewport/ios/constant-width-viewport-after-changing-view-scale-expected.txt: Added.
* fast/viewport/ios/constant-width-viewport-after-changing-view-scale.html: Added.

Add a test page with a viewport meta tag that has a constant width and an explicit initial scale of 0.5.

* fast/viewport/ios/device-width-viewport-after-changing-view-scale-expected.txt: Added.
* fast/viewport/ios/device-width-viewport-after-changing-view-scale.html: Added.

Add a test page with a viewport meta tag at device-width, with initial scale 1.

* resources/ui-helper.js:
(window.UIHelper.setViewScale):

Add a convenience function that wraps a UI script invocation of `setViewScale` in a promise.

(window.UIHelper):

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

32 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/viewport/ios/constant-width-viewport-after-changing-view-scale-expected.txt [new file with mode: 0644]
LayoutTests/fast/viewport/ios/constant-width-viewport-after-changing-view-scale.html [new file with mode: 0644]
LayoutTests/fast/viewport/ios/device-width-viewport-after-changing-view-scale-expected.txt [new file with mode: 0644]
LayoutTests/fast/viewport/ios/device-width-viewport-after-changing-view-scale.html [new file with mode: 0644]
LayoutTests/resources/ui-helper.js
Source/WebCore/ChangeLog
Source/WebCore/page/ViewportConfiguration.cpp
Source/WebCore/page/ViewportConfiguration.h
Source/WebKit/ChangeLog
Source/WebKit/Shared/WebPageCreationParameters.cpp
Source/WebKit/Shared/WebPageCreationParameters.h
Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm
Source/WebKit/UIProcess/API/Cocoa/WKWebViewPrivate.h
Source/WebKit/UIProcess/API/mac/WKView.mm
Source/WebKit/UIProcess/Cocoa/WebViewImpl.mm
Source/WebKit/UIProcess/WebPageProxy.cpp
Source/WebKit/UIProcess/WebPageProxy.h
Source/WebKit/UIProcess/ios/WebPageProxyIOS.mm
Source/WebKit/WebProcess/WebPage/WebPage.cpp
Source/WebKit/WebProcess/WebPage/WebPage.h
Source/WebKit/WebProcess/WebPage/WebPage.messages.in
Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm
Tools/ChangeLog
Tools/DumpRenderTree/ios/UIScriptControllerIOS.mm
Tools/DumpRenderTree/mac/UIScriptControllerMac.mm
Tools/TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl
Tools/TestRunnerShared/UIScriptContext/UIScriptController.cpp
Tools/TestRunnerShared/UIScriptContext/UIScriptController.h
Tools/WebKitTestRunner/UIScriptControllerCocoa.mm [new file with mode: 0644]
Tools/WebKitTestRunner/WebKitTestRunner.xcodeproj/project.pbxproj
Tools/WebKitTestRunner/cocoa/TestControllerCocoa.mm

index 8ecf730..3800278 100644 (file)
@@ -1,3 +1,31 @@
+2018-10-12  Wenson Hsieh  <wenson_hsieh@apple.com>
+
+        [iOS] Allow SPI clients to lay out at arbitrarily scaled sizes and scale to fit the view
+        https://bugs.webkit.org/show_bug.cgi?id=190504
+        <rdar://problem/45117760>
+
+        Reviewed by Tim Horton.
+
+        Add two new layout tests on iOS that change WKWebView's view scale, and measure the resulting window sizes and
+        lengths of viewport units.
+
+        * fast/viewport/ios/constant-width-viewport-after-changing-view-scale-expected.txt: Added.
+        * fast/viewport/ios/constant-width-viewport-after-changing-view-scale.html: Added.
+
+        Add a test page with a viewport meta tag that has a constant width and an explicit initial scale of 0.5.
+
+        * fast/viewport/ios/device-width-viewport-after-changing-view-scale-expected.txt: Added.
+        * fast/viewport/ios/device-width-viewport-after-changing-view-scale.html: Added.
+
+        Add a test page with a viewport meta tag at device-width, with initial scale 1.
+
+        * resources/ui-helper.js:
+        (window.UIHelper.setViewScale):
+
+        Add a convenience function that wraps a UI script invocation of `setViewScale` in a promise.
+
+        (window.UIHelper):
+
 2018-10-12  Dawei Fenton  <realdawei@apple.com>
 
         [Mojave Wk2] Layout Test http/tests/cache/disk-cache/disk-cache-validation-attachment.html is flaky
diff --git a/LayoutTests/fast/viewport/ios/constant-width-viewport-after-changing-view-scale-expected.txt b/LayoutTests/fast/viewport/ios/constant-width-viewport-after-changing-view-scale-expected.txt
new file mode 100644 (file)
index 0000000..e40cc14
--- /dev/null
@@ -0,0 +1,46 @@
+setViewScale(0.50)
+window size: [1280, 2192]
+square size: [128, 219]
+zoom scale: 0.25
+
+setViewScale(0.75)
+window size: [853, 1461]
+square size: [85, 146]
+zoom scale: 0.38
+
+setViewScale(1.00)
+window size: [640, 1096]
+square size: [64, 110]
+zoom scale: 0.50
+
+setViewScale(1.25)
+window size: [512, 877]
+square size: [51, 88]
+zoom scale: 0.63
+
+setViewScale(1.50)
+window size: [427, 731]
+square size: [43, 73]
+zoom scale: 0.75
+
+setViewScale(1.25)
+window size: [512, 877]
+square size: [51, 88]
+zoom scale: 0.63
+
+setViewScale(1.00)
+window size: [640, 1096]
+square size: [64, 110]
+zoom scale: 0.50
+
+setViewScale(0.75)
+window size: [853, 1461]
+square size: [85, 146]
+zoom scale: 0.38
+
+setViewScale(0.50)
+window size: [1280, 2192]
+square size: [128, 219]
+zoom scale: 0.25
+
+
diff --git a/LayoutTests/fast/viewport/ios/constant-width-viewport-after-changing-view-scale.html b/LayoutTests/fast/viewport/ios/constant-width-viewport-after-changing-view-scale.html
new file mode 100644 (file)
index 0000000..20c243e
--- /dev/null
@@ -0,0 +1,59 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ useFlexibleViewport=true ] -->
+<html>
+<head>
+    <meta name="viewport" content="width=640, initial-scale=0.5">
+    <style>
+        #square {
+            position: absolute;
+            width: 10vw;
+            height: 10vh;
+            border: 2px solid black;
+        }
+
+        #output {
+            width: 100%;
+            height: 100%;
+            overflow: scroll;
+        }
+
+        body {
+            margin: 0;
+            width: 100%;
+            height: 100%;
+        }
+    </style>
+    <script src="../../../resources/ui-helper.js"></script>
+    <script>
+    if (window.testRunner) {
+        testRunner.dumpAsText();
+        testRunner.waitUntilDone();
+    }
+
+    async function runTest() {
+        const appendOutput = message => {
+            output.appendChild(document.createTextNode(message));
+            output.appendChild(document.createElement("br"));
+        };
+
+        for (let targetScale of [0.5, 0.75, 1, 1.25, 1.5, 1.25, 1, 0.75, 0.5]) {
+            appendOutput(`setViewScale(${targetScale.toFixed(2)})`);
+
+            await UIHelper.setViewScale(targetScale);
+            await Promise.all([UIHelper.ensureVisibleContentRectUpdate(), UIHelper.ensurePresentationUpdate()]);
+
+            appendOutput(`window size: [${innerWidth}, ${innerHeight}]`);
+            appendOutput(`square size: [${square.clientWidth}, ${square.clientHeight}]`);
+            appendOutput(`zoom scale: ${parseFloat(await UIHelper.zoomScale()).toFixed(2)}`);
+            appendOutput("");
+        }
+
+        testRunner.notifyDone();
+    }
+    </script>
+</head>
+
+<body onload="runTest()">
+    <div id="square"></div>
+    <pre id="output"></pre>
+</body>
+</html>
diff --git a/LayoutTests/fast/viewport/ios/device-width-viewport-after-changing-view-scale-expected.txt b/LayoutTests/fast/viewport/ios/device-width-viewport-after-changing-view-scale-expected.txt
new file mode 100644 (file)
index 0000000..a5dd466
--- /dev/null
@@ -0,0 +1,46 @@
+setViewScale(0.50)
+window size: [640, 1096]
+square size: [64, 110]
+zoom scale: 0.50
+
+setViewScale(0.75)
+window size: [427, 731]
+square size: [43, 73]
+zoom scale: 0.75
+
+setViewScale(1.00)
+window size: [320, 548]
+square size: [32, 55]
+zoom scale: 1.00
+
+setViewScale(1.25)
+window size: [256, 438]
+square size: [26, 44]
+zoom scale: 1.25
+
+setViewScale(1.50)
+window size: [213, 365]
+square size: [21, 37]
+zoom scale: 1.50
+
+setViewScale(1.25)
+window size: [256, 438]
+square size: [26, 44]
+zoom scale: 1.25
+
+setViewScale(1.00)
+window size: [320, 548]
+square size: [32, 55]
+zoom scale: 1.00
+
+setViewScale(0.75)
+window size: [427, 731]
+square size: [43, 73]
+zoom scale: 0.75
+
+setViewScale(0.50)
+window size: [640, 1096]
+square size: [64, 110]
+zoom scale: 0.50
+
+
diff --git a/LayoutTests/fast/viewport/ios/device-width-viewport-after-changing-view-scale.html b/LayoutTests/fast/viewport/ios/device-width-viewport-after-changing-view-scale.html
new file mode 100644 (file)
index 0000000..5598de9
--- /dev/null
@@ -0,0 +1,59 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ useFlexibleViewport=true ] -->
+<html>
+<head>
+    <meta name="viewport" content="width=device-width, initial-scale=1">
+    <style>
+        #square {
+            position: absolute;
+            width: 10vw;
+            height: 10vh;
+            border: 2px solid black;
+        }
+
+        #output {
+            width: 100%;
+            height: 100%;
+            overflow: scroll;
+        }
+
+        body {
+            margin: 0;
+            width: 100%;
+            height: 100%;
+        }
+    </style>
+    <script src="../../../resources/ui-helper.js"></script>
+    <script>
+    if (window.testRunner) {
+        testRunner.dumpAsText();
+        testRunner.waitUntilDone();
+    }
+
+    async function runTest() {
+        const appendOutput = message => {
+            output.appendChild(document.createTextNode(message));
+            output.appendChild(document.createElement("br"));
+        };
+
+        for (let targetScale of [0.5, 0.75, 1, 1.25, 1.5, 1.25, 1, 0.75, 0.5]) {
+            appendOutput(`setViewScale(${targetScale.toFixed(2)})`);
+
+            await UIHelper.setViewScale(targetScale);
+            await Promise.all([UIHelper.ensureVisibleContentRectUpdate(), UIHelper.ensurePresentationUpdate()]);
+
+            appendOutput(`window size: [${innerWidth}, ${innerHeight}]`);
+            appendOutput(`square size: [${square.clientWidth}, ${square.clientHeight}]`);
+            appendOutput(`zoom scale: ${parseFloat(await UIHelper.zoomScale()).toFixed(2)}`);
+            appendOutput("");
+        }
+
+        testRunner.notifyDone();
+    }
+    </script>
+</head>
+
+<body onload="runTest()">
+    <div id="square"></div>
+    <pre id="output"></pre>
+</body>
+</html>
index ce178b5..ff0c60c 100644 (file)
@@ -339,4 +339,12 @@ window.UIHelper = class UIHelper {
             });
         });
     }
+
+    static setViewScale(scale)
+    {
+        if (!this.isWebKit2())
+            return Promise.resolve();
+
+        return new Promise(resolve => testRunner.runUIScript(`uiController.setViewScale(${scale})`, resolve));
+    }
 }
index 7da6e2d..3fccc5d 100644 (file)
@@ -1,3 +1,49 @@
+2018-10-12  Wenson Hsieh  <wenson_hsieh@apple.com>
+
+        [iOS] Allow SPI clients to lay out at arbitrarily scaled sizes and scale to fit the view
+        https://bugs.webkit.org/show_bug.cgi?id=190504
+        <rdar://problem/45117760>
+
+        Reviewed by Tim Horton.
+
+        Add support in ViewportConfiguration for applying a layout size scale factor to the viewport. See below for
+        more details.
+
+        Tests: fast/viewport/ios/constant-width-viewport-after-changing-view-scale.html
+               fast/viewport/ios/device-width-viewport-after-changing-view-scale.html
+
+        * page/ViewportConfiguration.cpp:
+        (WebCore::ViewportConfiguration::setViewLayoutSize):
+
+        The viewport's layout size may now be changed alongside the layout size scale factor. If either of these two
+        variables change, we recompute our minimum layout size and viewport configuration parameters.
+
+        (WebCore::ViewportConfiguration::shouldIgnoreHorizontalScalingConstraints const):
+        (WebCore::ViewportConfiguration::nativeWebpageParameters):
+        (WebCore::ViewportConfiguration::testingParameters):
+        (WebCore::ViewportConfiguration::updateConfiguration):
+
+        Multiply the minimum scale, initial scale, and maximum scale by the layout size scale factor. This allows us to
+        keep the document well-proportioned within the viewport, while still laying out at a different layout size.
+
+        (WebCore::ViewportConfiguration::updateMinimumLayoutSize):
+
+        Compute the minimum layout size by scaling the default layout size derived from our view's size.
+
+        (WebCore::ViewportConfiguration::layoutWidth const):
+        (WebCore::ViewportConfiguration::layoutHeight const):
+        * page/ViewportConfiguration.h:
+
+        Maintain the original initial scale, unaffected by the layout size scale factor. This is used when computing
+        layout width and height to prevent scaling by the layout size scale factor twice when computing layout sizes.
+
+        (WebCore::ViewportConfiguration::description const):
+
+        Include the layout size scale factor in ViewportConfiguration's description string.
+
+        (WebCore::ViewportConfiguration::Parameters::operator== const):
+        (WebCore::operator<<):
+
 2018-10-12  Youenn Fablet  <youenn@apple.com>
 
         Use downcast for use of RealtimeMediaSource in LibWebRTCMediaEndpoint
index c033571..412c52b 100644 (file)
@@ -114,11 +114,13 @@ bool ViewportConfiguration::setContentsSize(const IntSize& contentSize)
     return true;
 }
 
-bool ViewportConfiguration::setViewLayoutSize(const FloatSize& viewLayoutSize)
+bool ViewportConfiguration::setViewLayoutSize(const FloatSize& viewLayoutSize, std::optional<double>&& scaleFactor)
 {
-    if (m_viewLayoutSize == viewLayoutSize)
+    double newScaleFactor = scaleFactor.value_or(m_layoutSizeScaleFactor);
+    if (m_viewLayoutSize == viewLayoutSize && m_layoutSizeScaleFactor == newScaleFactor)
         return false;
 
+    m_layoutSizeScaleFactor = newScaleFactor;
     m_viewLayoutSize = viewLayoutSize;
 
     updateMinimumLayoutSize();
@@ -191,7 +193,7 @@ bool ViewportConfiguration::shouldIgnoreHorizontalScalingConstraints() const
     if (m_viewportArguments.width == ViewportArguments::ValueDeviceWidth)
         return laidOutWiderThanViewport;
 
-    if (m_configuration.initialScaleIsSet && m_configuration.initialScale == 1)
+    if (m_configuration.initialScaleIsSet && m_configuration.initialScaleIgnoringLayoutScaleFactor == 1)
         return laidOutWiderThanViewport;
 
     return false;
@@ -299,6 +301,7 @@ ViewportConfiguration::Parameters ViewportConfiguration::nativeWebpageParameters
     parameters.minimumScale = 1;
     parameters.maximumScale = 5;
     parameters.initialScale = 1;
+    parameters.initialScaleIgnoringLayoutScaleFactor = 1;
     parameters.initialScaleIsSet = true;
     return parameters;
 }
@@ -357,6 +360,7 @@ ViewportConfiguration::Parameters ViewportConfiguration::testingParameters()
 {
     Parameters parameters;
     parameters.initialScale = 1;
+    parameters.initialScaleIgnoringLayoutScaleFactor = 1;
     parameters.initialScaleIsSet = true;
     parameters.allowsShrinkToFit = true;
     parameters.minimumScale = 1;
@@ -426,19 +430,23 @@ void ViewportConfiguration::updateConfiguration()
         m_configuration.allowsShrinkToFit = m_viewportArguments.shrinkToFit != 0.;
 
     m_configuration.avoidsUnsafeArea = m_viewportArguments.viewportFit != ViewportFit::Cover;
+    m_configuration.initialScaleIgnoringLayoutScaleFactor = m_configuration.initialScale;
+    m_configuration.initialScale *= m_layoutSizeScaleFactor;
+    m_configuration.minimumScale *= m_layoutSizeScaleFactor;
+    m_configuration.maximumScale *= m_layoutSizeScaleFactor;
 
     LOG_WITH_STREAM(Viewports, stream << "ViewportConfiguration " << this << " updateConfiguration " << *this << " gives initial scale " << initialScale() << " based on contentSize " << m_contentSize << " and layout size " << layoutWidth() << "x" << layoutHeight());
 }
 
 void ViewportConfiguration::updateMinimumLayoutSize()
 {
-    if (!shouldOverrideDeviceWidthAndShrinkToFit()) {
-        m_minimumLayoutSize = m_viewLayoutSize;
+    m_minimumLayoutSize = m_viewLayoutSize / m_layoutSizeScaleFactor;
+
+    if (!shouldOverrideDeviceWidthAndShrinkToFit())
         return;
-    }
 
     float minDeviceWidth = platformDeviceWidthOverride();
-    m_minimumLayoutSize = FloatSize(minDeviceWidth, std::roundf(m_viewLayoutSize.height() * (minDeviceWidth / m_viewLayoutSize.width())));
+    m_minimumLayoutSize = FloatSize(minDeviceWidth, std::roundf(m_minimumLayoutSize.height() * (minDeviceWidth / m_minimumLayoutSize.width())));
 }
 
 double ViewportConfiguration::viewportArgumentsLength(double length) const
@@ -469,17 +477,17 @@ int ViewportConfiguration::layoutWidth() const
         }
 
         // If not, make sure the viewport width and initial scale can co-exist.
-        double initialContentWidthInViewportCoordinate = m_configuration.width * m_configuration.initialScale;
+        double initialContentWidthInViewportCoordinate = m_configuration.width * m_configuration.initialScaleIgnoringLayoutScaleFactor;
         if (initialContentWidthInViewportCoordinate < minimumLayoutSize.width()) {
             // The specified width does not fit in viewport. Return the minimum width that satisfy the initialScale constraint.
-            return std::round(minimumLayoutSize.width() / m_configuration.initialScale);
+            return std::round(minimumLayoutSize.width() / m_configuration.initialScaleIgnoringLayoutScaleFactor);
         }
         return std::round(m_configuration.width);
     }
 
     // If the page has a real scale, then just return the minimum size over the initial scale.
     if (m_configuration.initialScaleIsSet && !m_configuration.heightIsSet)
-        return std::round(minimumLayoutSize.width() / m_configuration.initialScale);
+        return std::round(minimumLayoutSize.width() / m_configuration.initialScaleIgnoringLayoutScaleFactor);
 
     if (minimumLayoutSize.height() > 0)
         return std::round(minimumLayoutSize.width() * layoutHeight() / minimumLayoutSize.height());
@@ -505,17 +513,17 @@ int ViewportConfiguration::layoutHeight() const
         }
 
         // If not, make sure the viewport width and initial scale can co-exist.
-        double initialContentHeightInViewportCoordinate = m_configuration.height * m_configuration.initialScale;
+        double initialContentHeightInViewportCoordinate = m_configuration.height * m_configuration.initialScaleIgnoringLayoutScaleFactor;
         if (initialContentHeightInViewportCoordinate < minimumLayoutSize.height()) {
             // The specified width does not fit in viewport. Return the minimum height that satisfy the initialScale constraint.
-            return std::round(minimumLayoutSize.height() / m_configuration.initialScale);
+            return std::round(minimumLayoutSize.height() / m_configuration.initialScaleIgnoringLayoutScaleFactor);
         }
         return std::round(m_configuration.height);
     }
 
     // If the page has a real scale, then just return the minimum size over the initial scale.
     if (m_configuration.initialScaleIsSet && !m_configuration.widthIsSet)
-        return std::round(minimumLayoutSize.height() / m_configuration.initialScale);
+        return std::round(minimumLayoutSize.height() / m_configuration.initialScaleIgnoringLayoutScaleFactor);
 
     if (minimumLayoutSize.width() > 0)
         return std::round(minimumLayoutSize.height() * layoutWidth() / minimumLayoutSize.width());
@@ -538,6 +546,7 @@ TextStream& operator<<(TextStream& ts, const ViewportConfiguration::Parameters&
     ts << "initialScale " << parameters.initialScale << ", set: " << (parameters.initialScaleIsSet ? "true" : "false");
     ts.endGroup();
 
+    ts.dumpProperty("initialScaleIgnoringLayoutScaleFactor", parameters.initialScaleIgnoringLayoutScaleFactor);
     ts.dumpProperty("minimumScale", parameters.minimumScale);
     ts.dumpProperty("maximumScale", parameters.maximumScale);
     ts.dumpProperty("allowsUserScaling", parameters.allowsUserScaling);
@@ -576,6 +585,7 @@ String ViewportConfiguration::description() const
 
     ts.dumpProperty("contentSize", m_contentSize);
     ts.dumpProperty("minimumLayoutSize", m_minimumLayoutSize);
+    ts.dumpProperty("layoutSizeScaleFactor", m_layoutSizeScaleFactor);
     ts.dumpProperty("computed initial scale", initialScale());
     ts.dumpProperty("computed minimum scale", minimumScale());
     ts.dumpProperty("computed layout size", layoutSize());
index 3fa6cdb..91a9ba1 100644 (file)
@@ -49,6 +49,7 @@ public:
         double width { 0 };
         double height { 0 };
         double initialScale { 0 };
+        double initialScaleIgnoringLayoutScaleFactor { 0 };
         double minimumScale { 0 };
         double maximumScale { 0 };
         bool allowsUserScaling { false };
@@ -62,7 +63,7 @@ public:
         bool operator==(const Parameters& other) const
         {
             return width == other.width && height == other.height
-                && initialScale == other.initialScale && minimumScale == other.minimumScale && maximumScale == other.maximumScale
+                && initialScale == other.initialScale && initialScaleIgnoringLayoutScaleFactor == other.initialScaleIgnoringLayoutScaleFactor && minimumScale == other.minimumScale && maximumScale == other.maximumScale
                 && allowsUserScaling == other.allowsUserScaling && allowsShrinkToFit == other.allowsShrinkToFit && avoidsUnsafeArea == other.avoidsUnsafeArea
                 && widthIsSet == other.widthIsSet && heightIsSet == other.heightIsSet && initialScaleIsSet == other.initialScaleIsSet;
         }
@@ -79,7 +80,7 @@ public:
     const FloatSize& viewLayoutSize() const { return m_viewLayoutSize; }
 
     const FloatSize& minimumLayoutSize() const { return m_minimumLayoutSize; }
-    WEBCORE_EXPORT bool setViewLayoutSize(const FloatSize&);
+    WEBCORE_EXPORT bool setViewLayoutSize(const FloatSize&, std::optional<double>&& scaleFactor = std::nullopt);
 
     const OptionSet<DisabledAdaptations>& disabledAdaptations() const { return m_disabledAdaptations; }
     WEBCORE_EXPORT bool setDisabledAdaptations(const OptionSet<DisabledAdaptations>&);
@@ -137,6 +138,7 @@ private:
     ViewportArguments m_viewportArguments;
     OptionSet<DisabledAdaptations> m_disabledAdaptations;
 
+    double m_layoutSizeScaleFactor { 1 };
     bool m_canIgnoreScalingConstraints;
     bool m_forceAlwaysUserScalable;
 };
index 42714ac..9ecdf21 100644 (file)
@@ -1,3 +1,64 @@
+2018-10-12  Wenson Hsieh  <wenson_hsieh@apple.com>
+
+        [iOS] Allow SPI clients to lay out at arbitrarily scaled sizes and scale to fit the view
+        https://bugs.webkit.org/show_bug.cgi?id=190504
+        <rdar://problem/45117760>
+
+        Reviewed by Tim Horton.
+
+        Add support for _setViewScale: and _viewScale on iOS. While similar in concept to macOS, changing this property
+        on iOS uses viewport configurations to change the minimum layout size of the document and apply view scaling.
+        Setting the view scale on iOS to a value `s` multiplies the minimium layout size by a factor `1 / s`, but also
+        multiplies the initial, minimum and maximum scales by a factor of `s`. The net effect of applying this scale
+        causes the page to lay out at a larger width and shrink (or a smaller width and expand) to fit the viewport.
+
+        * Shared/WebPageCreationParameters.cpp:
+        (WebKit::WebPageCreationParameters::encode const):
+        (WebKit::WebPageCreationParameters::decode):
+        * Shared/WebPageCreationParameters.h:
+
+        Send `viewportConfigurationLayoutSizeScaleFactor` alongside `viewportConfigurationViewLayoutSize`.
+
+        (-[WKWebView _dispatchSetViewLayoutSize:]):
+        (-[WKWebView _viewScale]):
+        (-[WKWebView _setViewScale:]):
+
+        Provide a different implementation of `_setViewScale:` on iOS, by scaling the effective minimum layout size.
+        (See above for more detail).
+
+        * UIProcess/API/Cocoa/WKWebViewPrivate.h:
+
+        Add missing API availability annotations for the _viewScale property.
+
+        * UIProcess/API/mac/WKView.mm:
+        (-[WKView _setViewScale:]):
+        * UIProcess/Cocoa/WebViewImpl.mm:
+
+        Both -[WKView _setViewScale:] and -[WKWebView _setViewScale:] throw Objective C exceptions upon receiving a bad
+        argument (e.g. scale <= 0). However, logic for throwing this exception is specific to iOS in WKWebView, and
+        handled in WebViewImpl on macOS. To make this less confusing, move the exception throwing code out of
+        !PLATFORM(MAC) in WKWebView, and move the path for raising this exception in WKView on macOS from WebViewImpl to
+        WKView.
+
+        * UIProcess/WebPageProxy.cpp:
+        (WebKit::WebPageProxy::creationParameters):
+        * UIProcess/WebPageProxy.h:
+        (WebKit::WebPageProxy::layoutSizeScaleFactor const):
+
+        Tie the notion of "view scale" on iOS to `layoutSizeScaleFactor`. As its name suggests, this is a scale factor
+        by which we transform the layout size.
+
+        * UIProcess/ios/WebPageProxyIOS.mm:
+        (WebKit::WebPageProxy::setViewportConfigurationViewLayoutSize):
+        * WebProcess/WebPage/WebPage.cpp:
+        * WebProcess/WebPage/WebPage.h:
+        * WebProcess/WebPage/WebPage.messages.in:
+
+        Plumb the layout size scale factor over to the web process, along with the layout size.
+
+        * WebProcess/WebPage/ios/WebPageIOS.mm:
+        (WebKit::WebPage::setViewportConfigurationViewLayoutSize):
+
 2018-10-12  Alex Christensen  <achristensen@webkit.org>
 
         Allow encoding of small enum classes
index b1fb4e5..ffc8c86 100644 (file)
@@ -90,6 +90,7 @@ void WebPageCreationParameters::encode(IPC::Encoder& encoder) const
     encoder << textAutosizingWidth;
     encoder << ignoresViewportScaleLimits;
     encoder << viewportConfigurationViewLayoutSize;
+    encoder << viewportConfigurationLayoutSizeScaleFactor;
     encoder << viewportConfigurationViewSize;
     encoder << maximumUnobscuredSize;
 #endif
@@ -257,6 +258,8 @@ std::optional<WebPageCreationParameters> WebPageCreationParameters::decode(IPC::
         return std::nullopt;
     if (!decoder.decode(parameters.viewportConfigurationViewLayoutSize))
         return std::nullopt;
+    if (!decoder.decode(parameters.viewportConfigurationLayoutSizeScaleFactor))
+        return std::nullopt;
     if (!decoder.decode(parameters.viewportConfigurationViewSize))
         return std::nullopt;
     if (!decoder.decode(parameters.maximumUnobscuredSize))
index db4c07f..8d9fd8a 100644 (file)
@@ -147,6 +147,7 @@ struct WebPageCreationParameters {
     float textAutosizingWidth;
     bool ignoresViewportScaleLimits;
     WebCore::FloatSize viewportConfigurationViewLayoutSize;
+    double viewportConfigurationLayoutSizeScaleFactor;
     WebCore::FloatSize viewportConfigurationViewSize;
     WebCore::FloatSize maximumUnobscuredSize;
 #endif
index e6532d4..14a5c39 100644 (file)
@@ -2640,7 +2640,7 @@ static WebCore::FloatPoint constrainContentOffset(WebCore::FloatPoint contentOff
         return;
 
     LOG_WITH_STREAM(VisibleRects, stream << "-[WKWebView " << _page->pageID() << " _dispatchSetViewLayoutSize:] " << viewLayoutSize << " contentZoomScale " << contentZoomScale(self));
-    _page->setViewportConfigurationViewLayoutSize(viewLayoutSize);
+    _page->setViewportConfigurationViewLayoutSize(viewLayoutSize, _page->layoutSizeScaleFactor());
     _lastSentViewLayoutSize = viewLayoutSize;
 }
 
@@ -5150,18 +5150,25 @@ static inline WebKit::FindOptions toFindOptions(_WKFindOptions wkFindOptions)
 
 - (CGFloat)_viewScale
 {
+#if PLATFORM(MAC)
     return _page->viewScaleFactor();
+#else
+    return _page->layoutSizeScaleFactor();
+#endif
 }
 
 - (void)_setViewScale:(CGFloat)viewScale
 {
+    if (viewScale <= 0 || isnan(viewScale) || isinf(viewScale))
+        [NSException raise:NSInvalidArgumentException format:@"View scale should be a positive number"];
+
 #if PLATFORM(MAC)
     _impl->setViewScale(viewScale);
 #else
-    if (viewScale <= 0 || isnan(viewScale) || isinf(viewScale))
-        [NSException raise:NSInvalidArgumentException format:@"View scale should be a positive number"];
+    if (_page->layoutSizeScaleFactor() == viewScale)
+        return;
 
-    _page->scaleView(viewScale);
+    _page->setViewportConfigurationViewLayoutSize([self activeViewLayoutSize:self.bounds], viewScale);
 #endif
 }
 
index 7a4a3b2..4967316 100644 (file)
@@ -177,7 +177,7 @@ typedef NS_OPTIONS(NSUInteger, _WKRectEdge) {
 
 @property (nonatomic, setter=_setViewportSizeForCSSViewportUnits:) CGSize _viewportSizeForCSSViewportUnits WK_API_AVAILABLE(macosx(10.13), ios(11.0));
 
-@property (nonatomic, setter=_setViewScale:) CGFloat _viewScale;
+@property (nonatomic, setter=_setViewScale:) CGFloat _viewScale WK_API_AVAILABLE(macosx(10.11), ios(9.0));
 
 @property (nonatomic, setter=_setBackgroundExtendsBeyondPage:) BOOL _backgroundExtendsBeyondPage WK_API_AVAILABLE(macosx(10.13.4), ios(8.0));
 
index 83a7a78..081c4c6 100644 (file)
@@ -1430,6 +1430,9 @@ static WebCore::UserInterfaceLayoutDirection toUserInterfaceLayoutDirection(NSUs
 
 - (void)_setViewScale:(CGFloat)viewScale
 {
+    if (viewScale <= 0 || isnan(viewScale) || isinf(viewScale))
+        [NSException raise:NSInvalidArgumentException format:@"View scale should be a positive number"];
+
     _data->_impl->setViewScale(viewScale);
 }
 
index 52c12db..6c97771 100644 (file)
@@ -1886,9 +1886,6 @@ void WebViewImpl::setViewScale(CGFloat viewScale)
     if (!supportsArbitraryLayoutModes() && viewScale != 1)
         return;
 
-    if (viewScale <= 0 || isnan(viewScale) || isinf(viewScale))
-        [NSException raise:NSInvalidArgumentException format:@"View scale should be a positive number"];
-
     m_page->scaleView(viewScale);
     [m_layoutStrategy didChangeViewScale];
 }
index eacaf48..f9e882c 100644 (file)
@@ -6339,6 +6339,7 @@ WebPageCreationParameters WebPageProxy::creationParameters()
     parameters.mimeTypesWithCustomContentProviders = pageClient().mimeTypesWithCustomContentProviders();
     parameters.ignoresViewportScaleLimits = m_forceAlwaysUserScalable;
     parameters.viewportConfigurationViewLayoutSize = m_viewportConfigurationViewLayoutSize;
+    parameters.viewportConfigurationLayoutSizeScaleFactor = m_viewportConfigurationLayoutSizeScaleFactor;
     parameters.maximumUnobscuredSize = m_maximumUnobscuredSize;
 #endif
 
index 6f4d480..e3c327e 100644 (file)
@@ -585,7 +585,7 @@ public:
 
     void dynamicViewportSizeUpdate(const WebCore::FloatSize& viewLayoutSize, const WebCore::FloatSize& maximumUnobscuredSize, const WebCore::FloatRect& targetExposedContentRect, const WebCore::FloatRect& targetUnobscuredRect, const WebCore::FloatRect& targetUnobscuredRectInScrollViewCoordinates, const WebCore::FloatBoxExtent& unobscuredSafeAreaInsets, double targetScale, int32_t deviceOrientation, DynamicViewportSizeUpdateID);
 
-    void setViewportConfigurationViewLayoutSize(const WebCore::FloatSize&);
+    void setViewportConfigurationViewLayoutSize(const WebCore::FloatSize&, double scaleFactor);
     void setMaximumUnobscuredSize(const WebCore::FloatSize&);
     void setDeviceOrientation(int32_t);
     int32_t deviceOrientation() const { return m_deviceOrientation; }
@@ -637,6 +637,7 @@ public:
     void handleTwoFingerTapAtPoint(const WebCore::IntPoint&, uint64_t requestID);
     void setForceAlwaysUserScalable(bool);
     bool forceAlwaysUserScalable() const { return m_forceAlwaysUserScalable; }
+    double layoutSizeScaleFactor() const { return m_viewportConfigurationLayoutSizeScaleFactor; }
     void setIsScrollingOrZooming(bool);
     void requestRectsForGranularityWithSelectionOffset(WebCore::TextGranularity, uint32_t offset, WTF::Function<void(const Vector<WebCore::SelectionRect>&, CallbackBase::Error)>&&);
     void requestRectsAtSelectionOffsetWithText(int32_t offset, const String&, WTF::Function<void(const Vector<WebCore::SelectionRect>&, CallbackBase::Error)>&&);
@@ -2229,6 +2230,7 @@ private:
     std::unique_ptr<NodeAssistanceArguments> m_deferredNodeAssistanceArguments;
     bool m_forceAlwaysUserScalable { false };
     WebCore::FloatSize m_viewportConfigurationViewLayoutSize;
+    double m_viewportConfigurationLayoutSizeScaleFactor { 1 };
     WebCore::FloatSize m_maximumUnobscuredSize;
 #endif
 
index 394a565..196acc2 100644 (file)
@@ -318,12 +318,13 @@ void WebPageProxy::dynamicViewportSizeUpdate(const FloatSize& viewLayoutSize, co
         targetScale, deviceOrientation, dynamicViewportSizeUpdateID), m_pageID);
 }
 
-void WebPageProxy::setViewportConfigurationViewLayoutSize(const WebCore::FloatSize& size)
+void WebPageProxy::setViewportConfigurationViewLayoutSize(const WebCore::FloatSize& size, double scaleFactor)
 {
     m_viewportConfigurationViewLayoutSize = size;
+    m_viewportConfigurationLayoutSizeScaleFactor = scaleFactor;
 
     if (isValid())
-        m_process->send(Messages::WebPage::SetViewportConfigurationViewLayoutSize(size), m_pageID);
+        m_process->send(Messages::WebPage::SetViewportConfigurationViewLayoutSize(size, scaleFactor), m_pageID);
 }
 
 void WebPageProxy::setForceAlwaysUserScalable(bool userScalable)
index a4e46cb..f01059b 100644 (file)
@@ -623,7 +623,7 @@ WebPage::WebPage(uint64_t pageID, WebPageCreationParameters&& parameters)
 #endif
 
 #if PLATFORM(IOS)
-    setViewportConfigurationViewLayoutSize(parameters.viewportConfigurationViewLayoutSize);
+    setViewportConfigurationViewLayoutSize(parameters.viewportConfigurationViewLayoutSize, parameters.viewportConfigurationLayoutSizeScaleFactor);
     setMaximumUnobscuredSize(parameters.maximumUnobscuredSize);
 #endif
 }
index d01c9ae..16f6fd3 100644 (file)
@@ -893,7 +893,7 @@ public:
     void updateVisibilityState(bool isInitialState = false);
 
 #if PLATFORM(IOS)
-    void setViewportConfigurationViewLayoutSize(const WebCore::FloatSize&);
+    void setViewportConfigurationViewLayoutSize(const WebCore::FloatSize&, double scaleFactor);
     void setMaximumUnobscuredSize(const WebCore::FloatSize&);
     void setDeviceOrientation(int32_t);
     void setOverrideViewportArguments(const std::optional<WebCore::ViewportArguments>&);
index 6ddf8f4..bf25144 100644 (file)
@@ -45,7 +45,7 @@ messages -> WebPage LegacyReceiver {
     KeyEvent(WebKit::WebKeyboardEvent event)
     MouseEvent(WebKit::WebMouseEvent event)
 #if PLATFORM(IOS)
-    SetViewportConfigurationViewLayoutSize(WebCore::FloatSize size)
+    SetViewportConfigurationViewLayoutSize(WebCore::FloatSize size, double scaleFactor)
     SetMaximumUnobscuredSize(WebCore::FloatSize size)
     SetDeviceOrientation(int32_t deviceOrientation)
     SetOverrideViewportArguments(std::optional<WebCore::ViewportArguments> arguments)
index 4b082cb..ab81fdd 100644 (file)
@@ -2518,10 +2518,10 @@ void WebPage::autofillLoginCredentials(const String& username, const String& pas
     }
 }
 
-void WebPage::setViewportConfigurationViewLayoutSize(const FloatSize& size)
+void WebPage::setViewportConfigurationViewLayoutSize(const FloatSize& size, double scaleFactor)
 {
-    LOG_WITH_STREAM(VisibleRects, stream << "WebPage " << m_pageID << " setViewportConfigurationViewLayoutSize " << size);
-    if (m_viewportConfiguration.setViewLayoutSize(size))
+    LOG_WITH_STREAM(VisibleRects, stream << "WebPage " << m_pageID << " setViewportConfigurationViewLayoutSize " << size << " scaleFactor " << scaleFactor);
+    if (m_viewportConfiguration.setViewLayoutSize(size, scaleFactor))
         viewportConfigurationChanged();
 }
 
index 8e0190a..ea9508a 100644 (file)
@@ -1,3 +1,33 @@
+2018-10-12  Wenson Hsieh  <wenson_hsieh@apple.com>
+
+        [iOS] Allow SPI clients to lay out at arbitrarily scaled sizes and scale to fit the view
+        https://bugs.webkit.org/show_bug.cgi?id=190504
+        <rdar://problem/45117760>
+
+        Reviewed by Tim Horton.
+
+        Teach UIScriptController to set WKWebView's view scale via a new `setViewScale` method, supported in WebKit2 on
+        macOS and iOS.
+
+        * DumpRenderTree/ios/UIScriptControllerIOS.mm:
+        (WTR::UIScriptController::setViewScale):
+        * DumpRenderTree/mac/UIScriptControllerMac.mm:
+        (WTR::UIScriptController::setViewScale):
+        * TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl:
+        * TestRunnerShared/UIScriptContext/UIScriptController.cpp:
+        (WTR::UIScriptController::setViewScale):
+        * TestRunnerShared/UIScriptContext/UIScriptController.h:
+        * WebKitTestRunner/UIScriptControllerCocoa.mm: Added.
+
+        Add a new file for UIScriptController methods on Cocoa platforms.
+
+        (WTR::UIScriptController::setViewScale):
+        * WebKitTestRunner/WebKitTestRunner.xcodeproj/project.pbxproj:
+        * WebKitTestRunner/cocoa/TestControllerCocoa.mm:
+        (WTR::TestController::cocoaResetStateToConsistentValues):
+
+        Ensure that _viewScale is reset to 1 after running a layout test.
+
 2018-10-12  Aakash Jain  <aakash_jain@apple.com>
 
         [ews-build] Rename iOS-11-Simulator-Tests-EWS to iOS-11-Simulator-WK2-Tests-EWS
index 8f7000c..89e5cb5 100644 (file)
@@ -82,6 +82,10 @@ void UIScriptController::zoomToScale(double scale, JSValueRef callback)
     });
 }
 
+void UIScriptController::setViewScale(double)
+{
+}
+
 void UIScriptController::simulateAccessibilitySettingsChangeNotification(JSValueRef)
 {
 }
index 25453dd..f4a3343 100644 (file)
@@ -89,6 +89,10 @@ void UIScriptController::zoomToScale(double scale, JSValueRef callback)
     });
 }
 
+void UIScriptController::setViewScale(double)
+{
+}
+
 void UIScriptController::simulateAccessibilitySettingsChangeNotification(JSValueRef)
 {
 }
index 15225ca..32537d9 100644 (file)
@@ -216,6 +216,8 @@ interface UIScriptController {
 
     void zoomToScale(double scale, object callback);
 
+    void setViewScale(double scale);
+
     void scrollToOffset(long x, long y); // Initiate an animated scroll in the UI process.
     attribute object didEndScrollingCallback;
 
index 258b7c1..731b2cb 100644 (file)
@@ -210,6 +210,10 @@ void UIScriptController::zoomToScale(double, JSValueRef)
 {
 }
 
+void UIScriptController::setViewScale(double)
+{
+}
+
 void UIScriptController::simulateAccessibilitySettingsChangeNotification(JSValueRef)
 {
 }
index f88f76f..cfa3323 100644 (file)
@@ -66,6 +66,7 @@ public:
     void doAfterVisibleContentRectUpdate(JSValueRef callback);
 
     void zoomToScale(double scale, JSValueRef callback);
+    void setViewScale(double);
 
     void simulateAccessibilitySettingsChangeNotification(JSValueRef callback);
 
diff --git a/Tools/WebKitTestRunner/UIScriptControllerCocoa.mm b/Tools/WebKitTestRunner/UIScriptControllerCocoa.mm
new file mode 100644 (file)
index 0000000..208c748
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+
+#import "config.h"
+#import "UIScriptController.h"
+
+#import "PlatformWebView.h"
+#import "TestController.h"
+#import "TestRunnerWKWebView.h"
+#import <WebKit/WKWebViewPrivate.h>
+
+namespace WTR {
+
+void UIScriptController::setViewScale(double scale)
+{
+#if WK_API_ENABLED
+    TestController::singleton().mainWebView()->platformView()._viewScale = scale;
+#else
+    UNUSED_PARAM(scale);
+#endif
+}
+
+} // namespace WTR
index 6071ba5..23ac5ab 100644 (file)
                E132AA3D17CE776F00611DF0 /* WebKitTestRunnerEvent.mm in Sources */ = {isa = PBXBuildFile; fileRef = E132AA3B17CE776F00611DF0 /* WebKitTestRunnerEvent.mm */; };
                E1C642C317CBCC7300D66A3C /* PoseAsClass.mm in Sources */ = {isa = PBXBuildFile; fileRef = E1C642C117CBCC7300D66A3C /* PoseAsClass.mm */; };
                E1C642C617CBCD4C00D66A3C /* WebKitTestRunnerPasteboard.mm in Sources */ = {isa = PBXBuildFile; fileRef = E1C642C417CBCD4C00D66A3C /* WebKitTestRunnerPasteboard.mm */; };
+               F46240B1217013E500917B16 /* UIScriptControllerCocoa.mm in Sources */ = {isa = PBXBuildFile; fileRef = F46240AF2170128300917B16 /* UIScriptControllerCocoa.mm */; };
                F4C3578C20E8444600FA0748 /* LayoutTestSpellChecker.mm in Sources */ = {isa = PBXBuildFile; fileRef = F4C3578A20E8444000FA0748 /* LayoutTestSpellChecker.mm */; };
 /* End PBXBuildFile section */
 
                E1C642C217CBCC7300D66A3C /* PoseAsClass.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PoseAsClass.h; sourceTree = "<group>"; };
                E1C642C417CBCD4C00D66A3C /* WebKitTestRunnerPasteboard.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WebKitTestRunnerPasteboard.mm; sourceTree = "<group>"; };
                E1C642C517CBCD4C00D66A3C /* WebKitTestRunnerPasteboard.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebKitTestRunnerPasteboard.h; sourceTree = "<group>"; };
+               F46240AF2170128300917B16 /* UIScriptControllerCocoa.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = UIScriptControllerCocoa.mm; sourceTree = "<group>"; };
                F4C3578A20E8444000FA0748 /* LayoutTestSpellChecker.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = LayoutTestSpellChecker.mm; path = ../TestRunnerShared/cocoa/LayoutTestSpellChecker.mm; sourceTree = "<group>"; };
                F4C3578B20E8444000FA0748 /* LayoutTestSpellChecker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LayoutTestSpellChecker.h; path = ../TestRunnerShared/cocoa/LayoutTestSpellChecker.h; sourceTree = "<group>"; };
 /* End PBXFileReference section */
                                2DCE2CD11B84524500C7F832 /* TestControllerCocoa.mm */,
                                0F87B6141BACC4B9004EC572 /* TestRunnerWKWebView.h */,
                                0F87B6151BACC4B9004EC572 /* TestRunnerWKWebView.mm */,
+                               F46240AF2170128300917B16 /* UIScriptControllerCocoa.mm */,
                        );
                        name = cocoa;
                        sourceTree = "<group>";
                                0F87B6171BACC4C0004EC572 /* TestRunnerWKWebView.mm in Sources */,
                                0F18E6E51D6B9B9E0027E547 /* UIScriptContext.cpp in Sources */,
                                0F18E6E61D6B9BA20027E547 /* UIScriptController.cpp in Sources */,
+                               F46240B1217013E500917B16 /* UIScriptControllerCocoa.mm in Sources */,
                                0F73B55C1BA89042004B3EF4 /* UIScriptControllerIOS.mm in Sources */,
                                A18510431B9AE14500744AEB /* WebNotificationProvider.cpp in Sources */,
                                A18510441B9AE14A00744AEB /* WorkQueueManager.cpp in Sources */,
index aacd9c4..02b5329 100644 (file)
@@ -215,8 +215,11 @@ void TestController::cocoaResetStateToConsistentValues()
     platformRunUntil(doneRemoving, noTimeout);
     [[_WKUserContentExtensionStore defaultStore] _removeAllContentExtensions];
 
-    if (PlatformWebView* webView = mainWebView())
-        [webView->platformView().configuration.userContentController _removeAllUserContentFilters];
+    if (auto* webView = mainWebView()) {
+        TestRunnerWKWebView *platformView = webView->platformView();
+        [platformView.configuration.userContentController _removeAllUserContentFilters];
+        platformView._viewScale = 1;
+    }
 #endif
 }