[Extra zoom mode] Add a mechanism to override default viewport behaviors in extra zoom mode
https://bugs.webkit.org/show_bug.cgi?id=185050
<rdar://problem/39624038>

Reviewed by Tim Horton.

Source/WebCore:

Currently, in extra zoom mode, there's no way for web pages to opt out of the default viewport behaviors
(namely, laying out at a larger width and shrinking to fit) when the web view is very tall and narrow. This
patch adds a new experimental viewport attribute, "min-device-width", that can be used to prevent WebKit from
automatically clamping the web view width to a greater value for the device width in this scenario.

Note that after this patch, logic that plumbs a minimumLayoutSize from WKWebView to the viewport configuration
will need to be renamed to reflect that this size is no longer the minimum layout size, but rather, the view
size that is used for viewport device dimensions by default. This refactoring will be done in a followup part.

See per-method comments below for more detail.

Test: fast/viewport/extrazoom/viewport-change-min-device-width.html

* dom/ViewportArguments.cpp:
(WebCore::setViewportFeature):
(WebCore::operator<<):
* dom/ViewportArguments.h:

Removes `m_forceHorizontalShrinkToFit` (more detail below).

* page/ViewportConfiguration.cpp:
(WebCore::computedMinDeviceWidth):
(WebCore::ViewportConfiguration::ViewportConfiguration):
(WebCore::ViewportConfiguration::setMinimumLayoutSize):

Instead of directly setting the minimum layout size, setMinimumLayoutSize now first sets the view size (i.e. the
size we use for `device-width` in the viewport meta tag), and then updates the minimum layout size.

(WebCore::ViewportConfiguration::shouldOverrideDeviceWidthWithMinDeviceWidth const):

Replaces `m_forceHorizontalShrinkToFit`. Whether or not we shrink to fit is now determined by whether the
min-device-width attribute is actively clamping the width of the view.

(WebCore::ViewportConfiguration::shouldIgnoreHorizontalScalingConstraints const):
(WebCore::ViewportConfiguration::shouldIgnoreScalingConstraintsRegardlessOfContentSize const):
(WebCore::ViewportConfiguration::updateMinimumLayoutSize):

Computes and sets the minimum layout size using the view size, taking the minimum device width into account if
needed.

(WebCore::ViewportConfiguration::description const):
(WebCore::ViewportConfiguration::setForceHorizontalShrinkToFit): Deleted.
* page/ViewportConfiguration.h:

Source/WebKit:

Remove the forceHorizontalViewportShrinkToFit and minimumAllowedLayoutWidth SPI hooks from WebKit, and
additionally remove all logic for plumbing viewSize to WebCore. See WebCore/ChangeLog for more information.

* Shared/VisibleContentRectUpdateInfo.cpp:
(WebKit::VisibleContentRectUpdateInfo::encode const):
(WebKit::VisibleContentRectUpdateInfo::decode):
(WebKit::operator<<):
* Shared/VisibleContentRectUpdateInfo.h:
(WebKit::VisibleContentRectUpdateInfo::VisibleContentRectUpdateInfo):
(WebKit::VisibleContentRectUpdateInfo::allowShrinkToFit const):
(WebKit::operator==):
(WebKit::VisibleContentRectUpdateInfo::forceHorizontalShrinkToFit const): Deleted.
* UIProcess/API/Cocoa/WKWebView.mm:
(-[WKWebView _initializeWithConfiguration:]):
(-[WKWebView activeMinimumLayoutSize:]):
(-[WKWebView _dispatchSetMinimumLayoutSize:]):
(-[WKWebView _frameOrBoundsChanged]):
(-[WKWebView _setMinimumLayoutSizeOverride:]):
(-[WKWebView _beginAnimatedResizeWithUpdates:]):
(-[WKWebView _endAnimatedResize]):
(-[WKWebView _minimumAllowedLayoutWidth]): Deleted.
(-[WKWebView _setMinimumAllowedLayoutWidth:]): Deleted.
(-[WKWebView activeMinimumLayoutSizes:]): Deleted.
(-[WKWebView _dispatchSetMinimumLayoutSize:viewSize:]): Deleted.
(-[WKWebView _setForceHorizontalViewportShrinkToFit:]): Deleted.
(-[WKWebView _forceHorizontalViewportShrinkToFit]): Deleted.
* UIProcess/API/Cocoa/WKWebViewPrivate.h:
* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::creationParameters):
* UIProcess/WebPageProxy.h:
* UIProcess/ios/WKContentView.mm:
(-[WKContentView didUpdateVisibleRect:unobscuredRect:unobscuredRectInScrollViewCoordinates:obscuredInsets:unobscuredSafeAreaInsets:inputViewBounds:scale:minimumScale:inStableState:isChangingObscuredInsetsInteractively:enclosedInScrollableAncestorView:]):
* UIProcess/ios/WebPageProxyIOS.mm:
(WebKit::WebPageProxy::dynamicViewportSizeUpdate):
(WebKit::WebPageProxy::setViewportConfigurationMinimumLayoutSize):
* WebProcess/WebPage/WebPage.cpp:
(WebKit::m_credentialsMessenger):
* WebProcess/WebPage/WebPage.h:
* WebProcess/WebPage/WebPage.messages.in:
* WebProcess/WebPage/ios/WebPageIOS.mm:
(WebKit::WebPage::setViewportConfigurationMinimumLayoutSize):
(WebKit::WebPage::dynamicViewportSizeUpdate):
(WebKit::WebPage::updateVisibleContentRects):

Tools:

Remove a test that's no longer useful, now that the SPI it was testing is gone. This functionality is now
tested by the layout test added in this patch.

* TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
* TestWebKitAPI/Tests/ios/ViewportSizingTests.mm: Removed.

LayoutTests:

Add a new layout test to check that:
• By default (with no `min-device-width` override), shrink-to-fit and expanded minimum layout sizes takes effect.
• `min-device-width` can be used to bail out of shrink-to-fit and viewport behaviors.
• A large `min-device-width` can be used to make extra zoom mode viewport heuristics even more aggressive.

* TestExpectations:
* fast/viewport/extrazoom/viewport-change-min-device-width.html: Added.
* resources/ui-helper.js:
(window.UIHelper.zoomScale):
(window.UIHelper):


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@231095 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index 288d28a..306a002 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,22 @@
+2018-04-27  Wenson Hsieh  <wenson_hsieh@apple.com>
+
+        [Extra zoom mode] Add a mechanism to override default viewport behaviors in extra zoom mode
+        https://bugs.webkit.org/show_bug.cgi?id=185050
+        <rdar://problem/39624038>
+
+        Reviewed by Tim Horton.
+
+        Add a new layout test to check that:
+        • By default (with no `min-device-width` override), shrink-to-fit and expanded minimum layout sizes takes effect.
+        • `min-device-width` can be used to bail out of shrink-to-fit and viewport behaviors.
+        • A large `min-device-width` can be used to make extra zoom mode viewport heuristics even more aggressive.
+
+        * TestExpectations:
+        * fast/viewport/extrazoom/viewport-change-min-device-width.html: Added.
+        * resources/ui-helper.js:
+        (window.UIHelper.zoomScale):
+        (window.UIHelper):
+
 2018-04-27  Claudio Saavedra  <csaavedra@igalia.com>
 
         [GTK] Mark a few new test failures
diff --git a/LayoutTests/TestExpectations b/LayoutTests/TestExpectations
index 0672638..cd42ce2 100644
--- a/LayoutTests/TestExpectations
+++ b/LayoutTests/TestExpectations
@@ -21,6 +21,7 @@
 fast/css/extrazoom [ Skip ]
 fast/dom/Window/extrazoom [ Skip ]
 fast/forms/extrazoom [ Skip ]
+fast/viewport/extrazoom [ Skip ]
 fast/visual-viewport/extrazoom [ Skip ]
 fast/visual-viewport/tiled-drawing [ Skip ]
 swipe [ Skip ]
diff --git a/LayoutTests/fast/viewport/extrazoom/viewport-change-min-device-width.html b/LayoutTests/fast/viewport/extrazoom/viewport-change-min-device-width.html
new file mode 100644
index 0000000..1531a92
--- /dev/null
+++ b/LayoutTests/fast/viewport/extrazoom/viewport-change-min-device-width.html
@@ -0,0 +1,60 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ useFlexibleViewport=true ] -->
+<html>
+<meta name="viewport" id="meta">
+<head>
+    <script src="../../../resources/js-test.js"></script>
+    <script src="../../../resources/ui-helper.js"></script>
+    <style>
+        body, html {
+            margin: 0;
+            width: 100%;
+            height: 100%;
+        }
+    </style>
+    <script>
+        jsTestIsAsync = true;
+
+        function logWindowDimensionsAfterSettingViewportContent(content) {
+            return new Promise(async resolve => {
+                meta.setAttribute("content", content);
+                await UIHelper.ensurePresentationUpdate();
+                debug(`[${meta.getAttribute("content")}] (${innerWidth}, ${innerHeight})`);
+                resolve();
+            });
+        }
+
+        async function runTest() {
+            if (!window.testRunner) {
+                description("Please use WebKitTestRunner to run this test.");
+                return;
+            }
+
+            debug("1. Initial min-device-width");
+            await logWindowDimensionsAfterSettingViewportContent("width=150");
+            await logWindowDimensionsAfterSettingViewportContent("width=device-width");
+            scaleAtDeviceWidthForInitialMinDeviceWidth = parseFloat(await UIHelper.zoomScale()).toFixed(3);
+            await logWindowDimensionsAfterSettingViewportContent("width=600");
+
+            debug("\n2. min-device-width=0");
+            await logWindowDimensionsAfterSettingViewportContent("width=150, min-device-width=0");
+            await logWindowDimensionsAfterSettingViewportContent("width=device-width, min-device-width=0");
+            scaleAtDeviceWidthForMinDeviceWidth0 = parseFloat(await UIHelper.zoomScale()).toFixed(3);
+            await logWindowDimensionsAfterSettingViewportContent("width=600, min-device-width=0");
+
+            debug("\n3. min-device-width=500");
+            await logWindowDimensionsAfterSettingViewportContent("width=150, min-device-width=500");
+            await logWindowDimensionsAfterSettingViewportContent("width=device-width, min-device-width=500");
+            scaleAtDeviceWidthForMinDeviceWidth500 = parseFloat(await UIHelper.zoomScale()).toFixed(3);
+            await logWindowDimensionsAfterSettingViewportContent("width=600, min-device-width=500");
+
+            shouldBe("scaleAtDeviceWidthForInitialMinDeviceWidth", "'0.488'");
+            shouldBe("scaleAtDeviceWidthForMinDeviceWidth0", "'1.000'");
+            shouldBe("scaleAtDeviceWidthForMinDeviceWidth500", "'0.312'");
+
+            finishJSTest();
+        }
+    </script>
+</head>
+<body onload="runTest()">
+</body>
+</html>
diff --git a/LayoutTests/resources/ui-helper.js b/LayoutTests/resources/ui-helper.js
index 4463567..41579b1 100644
--- a/LayoutTests/resources/ui-helper.js
+++ b/LayoutTests/resources/ui-helper.js
@@ -208,4 +208,13 @@
             })()`, resolve);
         });
     }
+
+    static zoomScale()
+    {
+        return new Promise(resolve => {
+            testRunner.runUIScript(`(() => {
+                uiController.uiScriptComplete(uiController.zoomScale);
+            })()`, resolve);
+        });
+    }
 }
diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog
index 803047a..1d57f4a 100644
--- a/Source/WebCore/ChangeLog
+++ b/Source/WebCore/ChangeLog
@@ -1,3 +1,55 @@
+2018-04-27  Wenson Hsieh  <wenson_hsieh@apple.com>
+
+        [Extra zoom mode] Add a mechanism to override default viewport behaviors in extra zoom mode
+        https://bugs.webkit.org/show_bug.cgi?id=185050
+        <rdar://problem/39624038>
+
+        Reviewed by Tim Horton.
+
+        Currently, in extra zoom mode, there's no way for web pages to opt out of the default viewport behaviors
+        (namely, laying out at a larger width and shrinking to fit) when the web view is very tall and narrow. This
+        patch adds a new experimental viewport attribute, "min-device-width", that can be used to prevent WebKit from
+        automatically clamping the web view width to a greater value for the device width in this scenario.
+
+        Note that after this patch, logic that plumbs a minimumLayoutSize from WKWebView to the viewport configuration
+        will need to be renamed to reflect that this size is no longer the minimum layout size, but rather, the view
+        size that is used for viewport device dimensions by default. This refactoring will be done in a followup part.
+
+        See per-method comments below for more detail.
+
+        Test: fast/viewport/extrazoom/viewport-change-min-device-width.html
+
+        * dom/ViewportArguments.cpp:
+        (WebCore::setViewportFeature):
+        (WebCore::operator<<):
+        * dom/ViewportArguments.h:
+
+        Removes `m_forceHorizontalShrinkToFit` (more detail below).
+
+        * page/ViewportConfiguration.cpp:
+        (WebCore::computedMinDeviceWidth):
+        (WebCore::ViewportConfiguration::ViewportConfiguration):
+        (WebCore::ViewportConfiguration::setMinimumLayoutSize):
+
+        Instead of directly setting the minimum layout size, setMinimumLayoutSize now first sets the view size (i.e. the
+        size we use for `device-width` in the viewport meta tag), and then updates the minimum layout size.
+
+        (WebCore::ViewportConfiguration::shouldOverrideDeviceWidthWithMinDeviceWidth const):
+
+        Replaces `m_forceHorizontalShrinkToFit`. Whether or not we shrink to fit is now determined by whether the
+        min-device-width attribute is actively clamping the width of the view.
+
+        (WebCore::ViewportConfiguration::shouldIgnoreHorizontalScalingConstraints const):
+        (WebCore::ViewportConfiguration::shouldIgnoreScalingConstraintsRegardlessOfContentSize const):
+        (WebCore::ViewportConfiguration::updateMinimumLayoutSize):
+
+        Computes and sets the minimum layout size using the view size, taking the minimum device width into account if
+        needed.
+
+        (WebCore::ViewportConfiguration::description const):
+        (WebCore::ViewportConfiguration::setForceHorizontalShrinkToFit): Deleted.
+        * page/ViewportConfiguration.h:
+
 2018-04-27  Zalan Bujtas  <zalan@apple.com>
 
         [LFC] Formatting contexts should take const Box&
diff --git a/Source/WebCore/dom/ViewportArguments.cpp b/Source/WebCore/dom/ViewportArguments.cpp
index ee327e5..71a3c5d 100644
--- a/Source/WebCore/dom/ViewportArguments.cpp
+++ b/Source/WebCore/dom/ViewportArguments.cpp
@@ -420,6 +420,8 @@
         arguments.shrinkToFit = findBooleanValue(document, key, value);
     else if (equalLettersIgnoringASCIICase(key, "viewport-fit") && document.settings().viewportFitEnabled())
         arguments.viewportFit = parseViewportFitValue(document, key, value);
+    else if (equalLettersIgnoringASCIICase(key, "min-device-width"))
+        arguments.minDeviceWidth = numericPrefix(document, key, value);
     else
         reportViewportWarning(document, UnrecognizedViewportArgumentKeyError, key);
 }
@@ -475,7 +477,7 @@
 {
     TextStream::IndentScope indentScope(ts);
 
-    ts << "\n" << indent << "(width " << viewportArguments.width << ", minWidth " << viewportArguments.minWidth << ", maxWidth " << viewportArguments.maxWidth << ")";
+    ts << "\n" << indent << "(width " << viewportArguments.width << ", minWidth " << viewportArguments.minWidth << ", maxWidth " << viewportArguments.maxWidth << ", minDeviceWidth " << viewportArguments.minDeviceWidth << ")";
     ts << "\n" << indent << "(height " << viewportArguments.height << ", minHeight " << viewportArguments.minHeight << ", maxHeight " << viewportArguments.maxHeight << ")";
     ts << "\n" << indent << "(zoom " << viewportArguments.zoom << ", minZoom " << viewportArguments.minZoom << ", maxZoom " << viewportArguments.maxZoom << ")";
 
diff --git a/Source/WebCore/dom/ViewportArguments.h b/Source/WebCore/dom/ViewportArguments.h
index 4f1afea..4a8e8cb 100644
--- a/Source/WebCore/dom/ViewportArguments.h
+++ b/Source/WebCore/dom/ViewportArguments.h
@@ -93,6 +93,7 @@
     float width { ValueAuto };
     float minWidth { ValueAuto };
     float maxWidth { ValueAuto };
+    float minDeviceWidth { ValueAuto };
     float height { ValueAuto };
     float minHeight { ValueAuto };
     float maxHeight { ValueAuto };
diff --git a/Source/WebCore/page/ViewportConfiguration.cpp b/Source/WebCore/page/ViewportConfiguration.cpp
index e4de76f..adc681d 100644
--- a/Source/WebCore/page/ViewportConfiguration.cpp
+++ b/Source/WebCore/page/ViewportConfiguration.cpp
@@ -45,11 +45,23 @@
 }
 #endif
 
+static float computedMinDeviceWidth(float minDeviceWidth)
+{
+    if (minDeviceWidth != ViewportArguments::ValueAuto)
+        return minDeviceWidth;
+
+#if ENABLE(EXTRA_ZOOM_MODE)
+    return 320;
+#else
+    return 0;
+#endif
+}
+
 ViewportConfiguration::ViewportConfiguration()
     : m_minimumLayoutSize(1024, 768)
+    , m_viewSize(1024, 768)
     , m_canIgnoreScalingConstraints(false)
     , m_forceAlwaysUserScalable(false)
-    , m_forceHorizontalShrinkToFit(false)
 {
     // Setup a reasonable default configuration to avoid computing infinite scale/sizes.
     // Those are the original iPhone configuration.
@@ -83,14 +95,16 @@
     return true;
 }
 
-bool ViewportConfiguration::setMinimumLayoutSize(const FloatSize& minimumLayoutSize, const FloatSize& viewSize)
+// FIXME: ViewportConfiguration::setMinimumLayoutSize is no longer an accurate name, since the minimum layout size
+// is not necessarily the size of the view.
+bool ViewportConfiguration::setMinimumLayoutSize(const FloatSize& minimumLayoutSize)
 {
-    if (m_minimumLayoutSize == minimumLayoutSize && m_viewSize == viewSize)
+    if (m_viewSize == minimumLayoutSize)
         return false;
 
-    m_minimumLayoutSize = minimumLayoutSize;
-    m_viewSize = viewSize;
+    m_viewSize = minimumLayoutSize;
 
+    updateMinimumLayoutSize();
     updateConfiguration();
     return true;
 }
@@ -102,19 +116,12 @@
 
     LOG_WITH_STREAM(Viewports, stream << "ViewportConfiguration::setViewportArguments " << viewportArguments);
     m_viewportArguments = viewportArguments;
+
+    updateMinimumLayoutSize();
     updateConfiguration();
     return true;
 }
 
-bool ViewportConfiguration::setForceHorizontalShrinkToFit(bool forceHorizontalShrinkToFit)
-{
-    if (m_forceHorizontalShrinkToFit == forceHorizontalShrinkToFit)
-        return false;
-
-    m_forceHorizontalShrinkToFit = forceHorizontalShrinkToFit;
-    return true;
-}
-
 bool ViewportConfiguration::setCanIgnoreScalingConstraints(bool canIgnoreScalingConstraints)
 {
     if (canIgnoreScalingConstraints == m_canIgnoreScalingConstraints)
@@ -130,12 +137,17 @@
     return IntSize(layoutWidth(), layoutHeight());
 }
 
+bool ViewportConfiguration::shouldOverrideDeviceWidthWithMinDeviceWidth() const
+{
+    return m_viewSize.width() < computedMinDeviceWidth(m_viewportArguments.minDeviceWidth);
+}
+
 bool ViewportConfiguration::shouldIgnoreHorizontalScalingConstraints() const
 {
     if (!m_canIgnoreScalingConstraints)
         return false;
 
-    if (m_forceHorizontalShrinkToFit)
+    if (shouldOverrideDeviceWidthWithMinDeviceWidth())
         return true;
 
     if (!m_configuration.allowsShrinkToFit)
@@ -173,7 +185,7 @@
 
 bool ViewportConfiguration::shouldIgnoreScalingConstraintsRegardlessOfContentSize() const
 {
-    return m_canIgnoreScalingConstraints && m_forceHorizontalShrinkToFit;
+    return m_canIgnoreScalingConstraints && shouldOverrideDeviceWidthWithMinDeviceWidth();
 }
 
 double ViewportConfiguration::initialScaleFromSize(double width, double height, bool shouldIgnoreScalingConstraints) const
@@ -361,13 +373,24 @@
         m_configuration.allowsUserScaling = m_viewportArguments.userZoom != 0.;
 
     if (booleanViewportArgumentIsSet(m_viewportArguments.shrinkToFit))
-        m_configuration.allowsShrinkToFit = m_viewportArguments.shrinkToFit != 0.;
+        m_configuration.allowsShrinkToFit = shouldOverrideDeviceWidthWithMinDeviceWidth() || m_viewportArguments.shrinkToFit != 0.;
 
     m_configuration.avoidsUnsafeArea = m_viewportArguments.viewportFit != ViewportFit::Cover;
 
     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 (!m_viewSize.width() || !shouldOverrideDeviceWidthWithMinDeviceWidth()) {
+        m_minimumLayoutSize = m_viewSize;
+        return;
+    }
+
+    auto minDeviceWidth = computedMinDeviceWidth(m_viewportArguments.minDeviceWidth);
+    m_minimumLayoutSize = FloatSize(minDeviceWidth, std::roundf(m_viewSize.height() * (minDeviceWidth / m_viewSize.width())));
+}
+
 double ViewportConfiguration::viewportArgumentsLength(double length) const
 {
     if (length == ViewportArguments::ValueDeviceWidth)
@@ -509,7 +532,6 @@
     ts.dumpProperty("ignoring horizontal scaling constraints", shouldIgnoreHorizontalScalingConstraints() ? "true" : "false");
     ts.dumpProperty("ignoring vertical scaling constraints", shouldIgnoreVerticalScalingConstraints() ? "true" : "false");
     ts.dumpProperty("avoids unsafe area", avoidsUnsafeArea() ? "true" : "false");
-    ts.dumpProperty("force horizontal shrink to fit", m_forceHorizontalShrinkToFit ? "true" : "false");
     
     ts.endGroup();
 
diff --git a/Source/WebCore/page/ViewportConfiguration.h b/Source/WebCore/page/ViewportConfiguration.h
index 9ec6893..d6a50ca 100644
--- a/Source/WebCore/page/ViewportConfiguration.h
+++ b/Source/WebCore/page/ViewportConfiguration.h
@@ -77,12 +77,12 @@
     FloatSize viewSize() const { return m_viewSize; }
 
     const FloatSize& minimumLayoutSize() const { return m_minimumLayoutSize; }
-    WEBCORE_EXPORT bool setMinimumLayoutSize(const FloatSize&, const FloatSize& viewSize);
+    WEBCORE_EXPORT bool setMinimumLayoutSize(const FloatSize&);
 
     const ViewportArguments& viewportArguments() const { return m_viewportArguments; }
     WEBCORE_EXPORT bool setViewportArguments(const ViewportArguments&);
 
-    WEBCORE_EXPORT bool setForceHorizontalShrinkToFit(bool);
+    bool shouldOverrideDeviceWidthWithMinDeviceWidth() const;
 
     WEBCORE_EXPORT bool setCanIgnoreScalingConstraints(bool);
     void setForceAlwaysUserScalable(bool forceAlwaysUserScalable) { m_forceAlwaysUserScalable = forceAlwaysUserScalable; }
@@ -121,6 +121,8 @@
     bool shouldIgnoreVerticalScalingConstraints() const;
     bool shouldIgnoreHorizontalScalingConstraints() const;
 
+    void updateMinimumLayoutSize();
+
     Parameters m_configuration;
     Parameters m_defaultConfiguration;
     IntSize m_contentSize;
@@ -130,7 +132,6 @@
 
     bool m_canIgnoreScalingConstraints;
     bool m_forceAlwaysUserScalable;
-    bool m_forceHorizontalShrinkToFit;
 };
 
 WTF::TextStream& operator<<(WTF::TextStream&, const ViewportConfiguration::Parameters&);
diff --git a/Source/WebKit/ChangeLog b/Source/WebKit/ChangeLog
index 6b34979..8a721e4 100644
--- a/Source/WebKit/ChangeLog
+++ b/Source/WebKit/ChangeLog
@@ -1,3 +1,55 @@
+2018-04-27  Wenson Hsieh  <wenson_hsieh@apple.com>
+
+        [Extra zoom mode] Add a mechanism to override default viewport behaviors in extra zoom mode
+        https://bugs.webkit.org/show_bug.cgi?id=185050
+        <rdar://problem/39624038>
+
+        Reviewed by Tim Horton.
+
+        Remove the forceHorizontalViewportShrinkToFit and minimumAllowedLayoutWidth SPI hooks from WebKit, and
+        additionally remove all logic for plumbing viewSize to WebCore. See WebCore/ChangeLog for more information.
+
+        * Shared/VisibleContentRectUpdateInfo.cpp:
+        (WebKit::VisibleContentRectUpdateInfo::encode const):
+        (WebKit::VisibleContentRectUpdateInfo::decode):
+        (WebKit::operator<<):
+        * Shared/VisibleContentRectUpdateInfo.h:
+        (WebKit::VisibleContentRectUpdateInfo::VisibleContentRectUpdateInfo):
+        (WebKit::VisibleContentRectUpdateInfo::allowShrinkToFit const):
+        (WebKit::operator==):
+        (WebKit::VisibleContentRectUpdateInfo::forceHorizontalShrinkToFit const): Deleted.
+        * UIProcess/API/Cocoa/WKWebView.mm:
+        (-[WKWebView _initializeWithConfiguration:]):
+        (-[WKWebView activeMinimumLayoutSize:]):
+        (-[WKWebView _dispatchSetMinimumLayoutSize:]):
+        (-[WKWebView _frameOrBoundsChanged]):
+        (-[WKWebView _setMinimumLayoutSizeOverride:]):
+        (-[WKWebView _beginAnimatedResizeWithUpdates:]):
+        (-[WKWebView _endAnimatedResize]):
+        (-[WKWebView _minimumAllowedLayoutWidth]): Deleted.
+        (-[WKWebView _setMinimumAllowedLayoutWidth:]): Deleted.
+        (-[WKWebView activeMinimumLayoutSizes:]): Deleted.
+        (-[WKWebView _dispatchSetMinimumLayoutSize:viewSize:]): Deleted.
+        (-[WKWebView _setForceHorizontalViewportShrinkToFit:]): Deleted.
+        (-[WKWebView _forceHorizontalViewportShrinkToFit]): Deleted.
+        * UIProcess/API/Cocoa/WKWebViewPrivate.h:
+        * UIProcess/WebPageProxy.cpp:
+        (WebKit::WebPageProxy::creationParameters):
+        * UIProcess/WebPageProxy.h:
+        * UIProcess/ios/WKContentView.mm:
+        (-[WKContentView didUpdateVisibleRect:unobscuredRect:unobscuredRectInScrollViewCoordinates:obscuredInsets:unobscuredSafeAreaInsets:inputViewBounds:scale:minimumScale:inStableState:isChangingObscuredInsetsInteractively:enclosedInScrollableAncestorView:]):
+        * UIProcess/ios/WebPageProxyIOS.mm:
+        (WebKit::WebPageProxy::dynamicViewportSizeUpdate):
+        (WebKit::WebPageProxy::setViewportConfigurationMinimumLayoutSize):
+        * WebProcess/WebPage/WebPage.cpp:
+        (WebKit::m_credentialsMessenger):
+        * WebProcess/WebPage/WebPage.h:
+        * WebProcess/WebPage/WebPage.messages.in:
+        * WebProcess/WebPage/ios/WebPageIOS.mm:
+        (WebKit::WebPage::setViewportConfigurationMinimumLayoutSize):
+        (WebKit::WebPage::dynamicViewportSizeUpdate):
+        (WebKit::WebPage::updateVisibleContentRects):
+
 2018-04-27  Carlos Garcia Campos  <cgarcia@igalia.com>
 
         REGRESSION(r230812): [WPE][GTK] WebKitWebViewSessionState.cpp throws away encoded BackForwardList identifier
diff --git a/Source/WebKit/Shared/VisibleContentRectUpdateInfo.cpp b/Source/WebKit/Shared/VisibleContentRectUpdateInfo.cpp
index 8185bca..04150c1 100644
--- a/Source/WebKit/Shared/VisibleContentRectUpdateInfo.cpp
+++ b/Source/WebKit/Shared/VisibleContentRectUpdateInfo.cpp
@@ -53,7 +53,6 @@
     encoder << m_isFirstUpdateForNewViewSize;
     encoder << m_isChangingObscuredInsetsInteractively;
     encoder << m_allowShrinkToFit;
-    encoder << m_forceHorizontalShrinkToFit;
     encoder << m_enclosedInScrollableAncestorView;
 }
 
@@ -93,8 +92,6 @@
         return false;
     if (!decoder.decode(result.m_allowShrinkToFit))
         return false;
-    if (!decoder.decode(result.m_forceHorizontalShrinkToFit))
-        return false;
     if (!decoder.decode(result.m_enclosedInScrollableAncestorView))
         return false;
 
@@ -134,7 +131,6 @@
 
     ts.dumpProperty("timestamp", info.timestamp().secondsSinceEpoch().value());
     ts.dumpProperty("allowShrinkToFit", info.allowShrinkToFit());
-    ts.dumpProperty("forceHorizontalShrinkToFit", info.forceHorizontalShrinkToFit());
     if (info.horizontalVelocity())
         ts.dumpProperty("horizontalVelocity", info.horizontalVelocity());
     if (info.verticalVelocity())
diff --git a/Source/WebKit/Shared/VisibleContentRectUpdateInfo.h b/Source/WebKit/Shared/VisibleContentRectUpdateInfo.h
index d22abaa..5f07c2b 100644
--- a/Source/WebKit/Shared/VisibleContentRectUpdateInfo.h
+++ b/Source/WebKit/Shared/VisibleContentRectUpdateInfo.h
@@ -45,7 +45,7 @@
 public:
     VisibleContentRectUpdateInfo() = default;
 
-    VisibleContentRectUpdateInfo(const WebCore::FloatRect& exposedContentRect, const WebCore::FloatRect& unobscuredContentRect, const WebCore::FloatRect& unobscuredRectInScrollViewCoordinates, const WebCore::FloatRect& unobscuredContentRectRespectingInputViewBounds, const WebCore::FloatRect& customFixedPositionRect, const WebCore::FloatBoxExtent& obscuredInsets, const WebCore::FloatBoxExtent& unobscuredSafeAreaInsets, double scale, bool inStableState, bool isFirstUpdateForNewViewSize, bool isChangingObscuredInsetsInteractively, bool allowShrinkToFit, bool forceHorizontalShrinkToFit, bool enclosedInScrollableAncestorView, MonotonicTime timestamp, double horizontalVelocity, double verticalVelocity, double scaleChangeRate, uint64_t lastLayerTreeTransactionId)
+    VisibleContentRectUpdateInfo(const WebCore::FloatRect& exposedContentRect, const WebCore::FloatRect& unobscuredContentRect, const WebCore::FloatRect& unobscuredRectInScrollViewCoordinates, const WebCore::FloatRect& unobscuredContentRectRespectingInputViewBounds, const WebCore::FloatRect& customFixedPositionRect, const WebCore::FloatBoxExtent& obscuredInsets, const WebCore::FloatBoxExtent& unobscuredSafeAreaInsets, double scale, bool inStableState, bool isFirstUpdateForNewViewSize, bool isChangingObscuredInsetsInteractively, bool allowShrinkToFit, bool enclosedInScrollableAncestorView, MonotonicTime timestamp, double horizontalVelocity, double verticalVelocity, double scaleChangeRate, uint64_t lastLayerTreeTransactionId)
         : m_exposedContentRect(exposedContentRect)
         , m_unobscuredContentRect(unobscuredContentRect)
         , m_unobscuredContentRectRespectingInputViewBounds(unobscuredContentRectRespectingInputViewBounds)
@@ -63,7 +63,6 @@
         , m_isFirstUpdateForNewViewSize(isFirstUpdateForNewViewSize)
         , m_isChangingObscuredInsetsInteractively(isChangingObscuredInsetsInteractively)
         , m_allowShrinkToFit(allowShrinkToFit)
-        , m_forceHorizontalShrinkToFit(forceHorizontalShrinkToFit)
         , m_enclosedInScrollableAncestorView(enclosedInScrollableAncestorView)
     {
     }
@@ -81,7 +80,6 @@
     bool isFirstUpdateForNewViewSize() const { return m_isFirstUpdateForNewViewSize; }
     bool isChangingObscuredInsetsInteractively() const { return m_isChangingObscuredInsetsInteractively; }
     bool allowShrinkToFit() const { return m_allowShrinkToFit; }
-    bool forceHorizontalShrinkToFit() const { return m_forceHorizontalShrinkToFit; }
     bool enclosedInScrollableAncestorView() const { return m_enclosedInScrollableAncestorView; }
 
     MonotonicTime timestamp() const { return m_timestamp; }
@@ -114,7 +112,6 @@
     bool m_isFirstUpdateForNewViewSize { false };
     bool m_isChangingObscuredInsetsInteractively { false };
     bool m_allowShrinkToFit { false };
-    bool m_forceHorizontalShrinkToFit { false };
     bool m_enclosedInScrollableAncestorView { false };
 };
 
@@ -133,7 +130,6 @@
         && a.inStableState() == b.inStableState()
         && a.isFirstUpdateForNewViewSize() == b.isFirstUpdateForNewViewSize()
         && a.allowShrinkToFit() == b.allowShrinkToFit()
-        && a.forceHorizontalShrinkToFit() == b.forceHorizontalShrinkToFit()
         && a.enclosedInScrollableAncestorView() == b.enclosedInScrollableAncestorView();
 }
 
diff --git a/Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm b/Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm
index 8ea437f..4a16e6d 100644
--- a/Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm
+++ b/Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm
@@ -181,11 +181,6 @@
     ResizingWithDocumentHidden,
 };
 
-struct ActiveViewportLayoutSizes {
-    WebCore::FloatSize minimumLayoutSize;
-    WebCore::FloatSize viewSize;
-};
-
 #endif // PLATFORM(IOS)
 
 #if PLATFORM(IOS)
@@ -311,8 +306,6 @@
     std::optional<int32_t> _lastSentDeviceOrientation;
 
     BOOL _allowsViewportShrinkToFit;
-    BOOL _forceHorizontalViewportShrinkToFit;
-    CGFloat _minimumAllowedLayoutWidth;
 
     BOOL _hasCommittedLoadForMainFrame;
     BOOL _needsResetViewStateAfterCommitLoadForMainFrame;
@@ -734,13 +727,9 @@
 #if PLATFORM(IOS)
     _dragInteractionPolicy = _WKDragInteractionPolicyDefault;
 #if ENABLE(EXTRA_ZOOM_MODE)
-    _minimumAllowedLayoutWidth = 320;
     _allowsViewportShrinkToFit = YES;
-    _forceHorizontalViewportShrinkToFit = YES;
 #else
-    _minimumAllowedLayoutWidth = 0;
     _allowsViewportShrinkToFit = NO;
-    _forceHorizontalViewportShrinkToFit = NO;
 #endif
 #endif // PLATFORM(IOS)
 }
@@ -2575,46 +2564,25 @@
     return UIEdgeInsetsAdd([_scrollView _contentScrollInset], self.safeAreaInsets, [_scrollView _edgesApplyingSafeAreaInsetsToContentInset]);
 }
 
-- (CGFloat)_minimumAllowedLayoutWidth
-{
-    return _minimumAllowedLayoutWidth;
-}
-
-- (void)_setMinimumAllowedLayoutWidth:(CGFloat)minimumAllowedLayoutWidth
-{
-    if (_minimumAllowedLayoutWidth == minimumAllowedLayoutWidth)
-        return;
-
-    _minimumAllowedLayoutWidth = minimumAllowedLayoutWidth;
-
-    auto sizes = [self activeMinimumLayoutSizes:self.bounds];
-    [self _dispatchSetMinimumLayoutSize:sizes.minimumLayoutSize viewSize:sizes.viewSize];
-}
-
-- (ActiveViewportLayoutSizes)activeMinimumLayoutSizes:(const CGRect&)bounds
+- (WebCore::FloatSize)activeMinimumLayoutSize:(const CGRect&)bounds
 {
     if (_overridesMinimumLayoutSize)
-        return { WebCore::FloatSize(_minimumLayoutSizeOverride), WebCore::FloatSize(_minimumLayoutSizeOverride) };
+        return WebCore::FloatSize(_minimumLayoutSizeOverride);
 
-    ActiveViewportLayoutSizes sizes;
 #if __IPHONE_OS_VERSION_MIN_REQUIRED >= 110000
-    sizes.viewSize = WebCore::FloatSize(UIEdgeInsetsInsetRect(CGRectMake(0, 0, bounds.size.width, bounds.size.height), self._scrollViewSystemContentInset).size);
+    return WebCore::FloatSize(UIEdgeInsetsInsetRect(CGRectMake(0, 0, bounds.size.width, bounds.size.height), self._scrollViewSystemContentInset).size);
 #else
-    sizes.viewSize = WebCore::FloatSize { bounds.size };
+    return WebCore::FloatSize { bounds.size };
 #endif
-
-    auto layoutWidth = std::max<float>(sizes.viewSize.width(), self._minimumAllowedLayoutWidth);
-    sizes.minimumLayoutSize = { layoutWidth, sizes.viewSize.height() * (layoutWidth / sizes.viewSize.width()) };
-    return sizes;
 }
 
-- (void)_dispatchSetMinimumLayoutSize:(WebCore::FloatSize)minimumLayoutSize viewSize:(WebCore::FloatSize)viewSize
+- (void)_dispatchSetMinimumLayoutSize:(WebCore::FloatSize)minimumLayoutSize
 {
     if (_lastSentMinimumLayoutSize && CGSizeEqualToSize(_lastSentMinimumLayoutSize.value(), minimumLayoutSize))
         return;
 
-    LOG_WITH_STREAM(VisibleRects, stream << "-[WKWebView " << _page->pageID() << " _dispatchSetMinimumLayoutSize:] " << minimumLayoutSize << " viewSize " << viewSize << " contentZoomScale " << contentZoomScale(self));
-    _page->setViewportConfigurationMinimumLayoutSize(minimumLayoutSize, viewSize);
+    LOG_WITH_STREAM(VisibleRects, stream << "-[WKWebView " << _page->pageID() << " _dispatchSetMinimumLayoutSize:] " << minimumLayoutSize << " contentZoomScale " << contentZoomScale(self));
+    _page->setViewportConfigurationMinimumLayoutSize(minimumLayoutSize);
     _lastSentMinimumLayoutSize = minimumLayoutSize;
 }
 
@@ -2642,10 +2610,8 @@
     [_scrollView setFrame:bounds];
 
     if (_dynamicViewportUpdateMode == DynamicViewportUpdateMode::NotResizing) {
-        if (!_overridesMinimumLayoutSize) {
-            auto sizes = [self activeMinimumLayoutSizes:self.bounds];
-            [self _dispatchSetMinimumLayoutSize:sizes.minimumLayoutSize viewSize:sizes.viewSize];
-        }
+        if (!_overridesMinimumLayoutSize)
+            [self _dispatchSetMinimumLayoutSize:[self activeMinimumLayoutSize:self.bounds]];
         if (!_overridesMaximumUnobscuredSize)
             [self _dispatchSetMaximumUnobscuredSize:WebCore::FloatSize(bounds.size)];
 
@@ -5031,7 +4997,7 @@
     _minimumLayoutSizeOverride = minimumLayoutSizeOverride;
 
     if (_dynamicViewportUpdateMode == DynamicViewportUpdateMode::NotResizing)
-        [self _dispatchSetMinimumLayoutSize:WebCore::FloatSize(minimumLayoutSizeOverride) viewSize:WebCore::FloatSize(minimumLayoutSizeOverride)];
+        [self _dispatchSetMinimumLayoutSize:WebCore::FloatSize(minimumLayoutSizeOverride)];
 
 }
 
@@ -5138,20 +5104,6 @@
         [self _dispatchSetMaximumUnobscuredSize:WebCore::FloatSize(size)];
 }
 
-- (void)_setForceHorizontalViewportShrinkToFit:(BOOL)forceHorizontalViewportShrinkToFit
-{
-    if (_forceHorizontalViewportShrinkToFit == forceHorizontalViewportShrinkToFit)
-        return;
-
-    _forceHorizontalViewportShrinkToFit = forceHorizontalViewportShrinkToFit;
-    [self _scheduleVisibleContentRectUpdate];
-}
-
-- (BOOL)_forceHorizontalViewportShrinkToFit
-{
-    return _forceHorizontalViewportShrinkToFit;
-}
-
 - (void)_setAllowsViewportShrinkToFit:(BOOL)allowShrinkToFit
 {
     _allowsViewportShrinkToFit = allowShrinkToFit;
@@ -5193,7 +5145,7 @@
 
     _dynamicViewportUpdateMode = DynamicViewportUpdateMode::ResizingWithAnimation;
 
-    auto oldSizes = [self activeMinimumLayoutSizes:self.bounds];
+    auto oldMinimumLayoutSize = [self activeMinimumLayoutSize:self.bounds];
     auto oldMaximumUnobscuredSize = activeMaximumUnobscuredSize(self, oldBounds);
     int32_t oldOrientation = activeOrientation(self);
     UIEdgeInsets oldObscuredInsets = _obscuredInsets;
@@ -5201,19 +5153,19 @@
     updateBlock();
 
     CGRect newBounds = self.bounds;
-    auto newSizes = [self activeMinimumLayoutSizes:newBounds];
+    auto newMinimumLayoutSize = [self activeMinimumLayoutSize:newBounds];
     auto newMaximumUnobscuredSize = activeMaximumUnobscuredSize(self, newBounds);
     int32_t newOrientation = activeOrientation(self);
     UIEdgeInsets newObscuredInsets = _obscuredInsets;
     CGRect futureUnobscuredRectInSelfCoordinates = UIEdgeInsetsInsetRect(newBounds, _obscuredInsets);
     CGRect contentViewBounds = [_contentView bounds];
 
-    ASSERT_WITH_MESSAGE(!(_overridesMinimumLayoutSize && newSizes.minimumLayoutSize.isEmpty()), "Clients controlling the layout size should maintain a valid layout size to minimize layouts.");
-    if (CGRectIsEmpty(newBounds) || newSizes.minimumLayoutSize.isEmpty() || CGRectIsEmpty(futureUnobscuredRectInSelfCoordinates) || CGRectIsEmpty(contentViewBounds)) {
+    ASSERT_WITH_MESSAGE(!(_overridesMinimumLayoutSize && newMinimumLayoutSize.isEmpty()), "Clients controlling the layout size should maintain a valid layout size to minimize layouts.");
+    if (CGRectIsEmpty(newBounds) || newMinimumLayoutSize.isEmpty() || CGRectIsEmpty(futureUnobscuredRectInSelfCoordinates) || CGRectIsEmpty(contentViewBounds)) {
         _dynamicViewportUpdateMode = DynamicViewportUpdateMode::NotResizing;
         [self _frameOrBoundsChanged];
         if (_overridesMinimumLayoutSize)
-            [self _dispatchSetMinimumLayoutSize:newSizes.minimumLayoutSize viewSize:newSizes.viewSize];
+            [self _dispatchSetMinimumLayoutSize:newMinimumLayoutSize];
         if (_overridesMaximumUnobscuredSize)
             [self _dispatchSetMaximumUnobscuredSize:WebCore::FloatSize(newMaximumUnobscuredSize)];
         if (_overridesInterfaceOrientation)
@@ -5224,7 +5176,7 @@
     }
 
     if (CGRectEqualToRect(oldBounds, newBounds)
-        && oldSizes.minimumLayoutSize == newSizes.minimumLayoutSize
+        && oldMinimumLayoutSize == newMinimumLayoutSize
         && oldMaximumUnobscuredSize == newMaximumUnobscuredSize
         && oldOrientation == newOrientation
         && UIEdgeInsetsEqualToEdgeInsets(oldObscuredInsets, newObscuredInsets)) {
@@ -5244,13 +5196,13 @@
     [_resizeAnimationView addSubview:[_contentView unscaledView]];
 
     CGSize contentSizeInContentViewCoordinates = contentViewBounds.size;
-    [_scrollView setMinimumZoomScale:std::min(newSizes.minimumLayoutSize.width() / contentSizeInContentViewCoordinates.width, [_scrollView minimumZoomScale])];
-    [_scrollView setMaximumZoomScale:std::max(newSizes.minimumLayoutSize.width() / contentSizeInContentViewCoordinates.width, [_scrollView maximumZoomScale])];
+    [_scrollView setMinimumZoomScale:std::min(newMinimumLayoutSize.width() / contentSizeInContentViewCoordinates.width, [_scrollView minimumZoomScale])];
+    [_scrollView setMaximumZoomScale:std::max(newMinimumLayoutSize.width() / contentSizeInContentViewCoordinates.width, [_scrollView maximumZoomScale])];
 
     // Compute the new scale to keep the current content width in the scrollview.
     CGFloat oldWebViewWidthInContentViewCoordinates = oldUnobscuredContentRect.width();
     CGFloat visibleContentViewWidthInContentCoordinates = std::min(contentSizeInContentViewCoordinates.width, oldWebViewWidthInContentViewCoordinates);
-    CGFloat targetScale = newSizes.minimumLayoutSize.width() / visibleContentViewWidthInContentCoordinates;
+    CGFloat targetScale = newMinimumLayoutSize.width() / visibleContentViewWidthInContentCoordinates;
     CGFloat resizeAnimationViewAnimationScale = targetScale / contentZoomScale(self);
     [_resizeAnimationView setTransform:CGAffineTransformMakeScale(resizeAnimationViewAnimationScale, resizeAnimationViewAnimationScale)];
 
@@ -5290,11 +5242,11 @@
     UIEdgeInsets unobscuredSafeAreaInsets = [self _computedUnobscuredSafeAreaInset];
     WebCore::FloatBoxExtent unobscuredSafeAreaInsetsExtent(unobscuredSafeAreaInsets.top, unobscuredSafeAreaInsets.right, unobscuredSafeAreaInsets.bottom, unobscuredSafeAreaInsets.left);
 
-    _lastSentMinimumLayoutSize = newSizes.minimumLayoutSize;
+    _lastSentMinimumLayoutSize = newMinimumLayoutSize;
     _lastSentMaximumUnobscuredSize = newMaximumUnobscuredSize;
     _lastSentDeviceOrientation = newOrientation;
 
-    _page->dynamicViewportSizeUpdate(newSizes.minimumLayoutSize, newSizes.viewSize, newMaximumUnobscuredSize, visibleRectInContentCoordinates, unobscuredRectInContentCoordinates, futureUnobscuredRectInSelfCoordinates, unobscuredSafeAreaInsetsExtent, targetScale, newOrientation);
+    _page->dynamicViewportSizeUpdate(newMinimumLayoutSize, newMaximumUnobscuredSize, visibleRectInContentCoordinates, unobscuredRectInContentCoordinates, futureUnobscuredRectInSelfCoordinates, unobscuredSafeAreaInsetsExtent, targetScale, newOrientation);
     if (WebKit::DrawingAreaProxy* drawingArea = _page->drawingArea())
         drawingArea->setSize(WebCore::IntSize(newBounds.size));
 }
@@ -5359,12 +5311,12 @@
     [self _scheduleVisibleContentRectUpdate];
 
     CGRect newBounds = self.bounds;
-    auto newSizes = [self activeMinimumLayoutSizes:newBounds];
+    auto newMinimumLayoutSize = [self activeMinimumLayoutSize:newBounds];
     auto newMaximumUnobscuredSize = activeMaximumUnobscuredSize(self, newBounds);
     int32_t newOrientation = activeOrientation(self);
 
-    if (!_lastSentMinimumLayoutSize || newSizes.minimumLayoutSize != _lastSentMinimumLayoutSize.value())
-        [self _dispatchSetMinimumLayoutSize:newSizes.minimumLayoutSize viewSize:newSizes.viewSize];
+    if (!_lastSentMinimumLayoutSize || newMinimumLayoutSize != _lastSentMinimumLayoutSize.value())
+        [self _dispatchSetMinimumLayoutSize:newMinimumLayoutSize];
     if (!_lastSentMaximumUnobscuredSize || newMaximumUnobscuredSize != _lastSentMaximumUnobscuredSize.value())
         [self _dispatchSetMaximumUnobscuredSize:WebCore::FloatSize(newMaximumUnobscuredSize)];
     if (!_lastSentDeviceOrientation || newOrientation != _lastSentDeviceOrientation.value())
diff --git a/Source/WebKit/UIProcess/API/Cocoa/WKWebViewPrivate.h b/Source/WebKit/UIProcess/API/Cocoa/WKWebViewPrivate.h
index 8f293f8..707df92 100644
--- a/Source/WebKit/UIProcess/API/Cocoa/WKWebViewPrivate.h
+++ b/Source/WebKit/UIProcess/API/Cocoa/WKWebViewPrivate.h
@@ -204,8 +204,6 @@
 @property (nonatomic, setter=_setInterfaceOrientationOverride:) UIInterfaceOrientation _interfaceOrientationOverride;
 
 @property (nonatomic, setter=_setAllowsViewportShrinkToFit:) BOOL _allowsViewportShrinkToFit;
-@property (nonatomic, setter=_setForceHorizontalViewportShrinkToFit:) BOOL _forceHorizontalViewportShrinkToFit WK_API_AVAILABLE(ios(WK_IOS_TBA));
-@property (nonatomic, setter=_setMinimumAllowedLayoutWidth:) CGFloat _minimumAllowedLayoutWidth WK_API_AVAILABLE(ios(WK_IOS_TBA));
 
 // FIXME: Remove these three properties once we expose WKWebViewContentProvider as API.
 @property (nonatomic, readonly, getter=_isDisplayingPDF) BOOL _displayingPDF;
diff --git a/Source/WebKit/UIProcess/WebPageProxy.cpp b/Source/WebKit/UIProcess/WebPageProxy.cpp
index 37a0685..6accce0 100644
--- a/Source/WebKit/UIProcess/WebPageProxy.cpp
+++ b/Source/WebKit/UIProcess/WebPageProxy.cpp
@@ -6060,7 +6060,6 @@
     parameters.mimeTypesWithCustomContentProviders = m_pageClient.mimeTypesWithCustomContentProviders();
     parameters.ignoresViewportScaleLimits = m_forceAlwaysUserScalable;
     parameters.viewportConfigurationMinimumLayoutSize = m_viewportConfigurationMinimumLayoutSize;
-    parameters.viewportConfigurationViewSize = m_viewportConfigurationViewSize;
     parameters.maximumUnobscuredSize = m_maximumUnobscuredSize;
 #endif
 
diff --git a/Source/WebKit/UIProcess/WebPageProxy.h b/Source/WebKit/UIProcess/WebPageProxy.h
index 14f91ad..911210e 100644
--- a/Source/WebKit/UIProcess/WebPageProxy.h
+++ b/Source/WebKit/UIProcess/WebPageProxy.h
@@ -545,10 +545,10 @@
     void overflowScrollWillStartScroll();
     void overflowScrollDidEndScroll();
 
-    void dynamicViewportSizeUpdate(const WebCore::FloatSize& minimumLayoutSize, const WebCore::FloatSize& viewSize, 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);
+    void dynamicViewportSizeUpdate(const WebCore::FloatSize& minimumLayoutSize, 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);
     void synchronizeDynamicViewportUpdate();
 
-    void setViewportConfigurationMinimumLayoutSize(const WebCore::FloatSize&, const WebCore::FloatSize& viewSize);
+    void setViewportConfigurationMinimumLayoutSize(const WebCore::FloatSize&);
     void setMaximumUnobscuredSize(const WebCore::FloatSize&);
     void setDeviceOrientation(int32_t);
     int32_t deviceOrientation() const { return m_deviceOrientation; }
@@ -2135,7 +2135,6 @@
     std::unique_ptr<NodeAssistanceArguments> m_deferredNodeAssistanceArguments;
     bool m_forceAlwaysUserScalable { false };
     WebCore::FloatSize m_viewportConfigurationMinimumLayoutSize;
-    WebCore::FloatSize m_viewportConfigurationViewSize;
     WebCore::FloatSize m_maximumUnobscuredSize;
 #endif
 
diff --git a/Source/WebKit/UIProcess/ios/WKContentView.mm b/Source/WebKit/UIProcess/ios/WKContentView.mm
index 0fa0788..d0cbde1 100644
--- a/Source/WebKit/UIProcess/ios/WKContentView.mm
+++ b/Source/WebKit/UIProcess/ios/WKContentView.mm
@@ -402,7 +402,6 @@
         _sizeChangedSinceLastVisibleContentRectUpdate,
         isChangingObscuredInsetsInteractively,
         _webView._allowsViewportShrinkToFit,
-        _webView._forceHorizontalViewportShrinkToFit,
         enclosedInScrollableAncestorView,
         timestamp,
         velocityData.horizontalVelocity,
diff --git a/Source/WebKit/UIProcess/ios/WebPageProxyIOS.mm b/Source/WebKit/UIProcess/ios/WebPageProxyIOS.mm
index 49e7c43..f50ab2c 100644
--- a/Source/WebKit/UIProcess/ios/WebPageProxyIOS.mm
+++ b/Source/WebKit/UIProcess/ios/WebPageProxyIOS.mm
@@ -305,7 +305,7 @@
     m_pageClient.overflowScrollDidEndScroll();
 }
 
-void WebPageProxy::dynamicViewportSizeUpdate(const FloatSize& minimumLayoutSize, const FloatSize& viewSize, const WebCore::FloatSize& maximumUnobscuredSize, const FloatRect& targetExposedContentRect, const FloatRect& targetUnobscuredRect, const FloatRect& targetUnobscuredRectInScrollViewCoordinates, const WebCore::FloatBoxExtent& unobscuredSafeAreaInsets, double targetScale, int32_t deviceOrientation)
+void WebPageProxy::dynamicViewportSizeUpdate(const FloatSize& minimumLayoutSize, const WebCore::FloatSize& maximumUnobscuredSize, const FloatRect& targetExposedContentRect, const FloatRect& targetUnobscuredRect, const FloatRect& targetUnobscuredRectInScrollViewCoordinates, const WebCore::FloatBoxExtent& unobscuredSafeAreaInsets, double targetScale, int32_t deviceOrientation)
 {
     if (!isValid())
         return;
@@ -314,7 +314,7 @@
 
     m_dynamicViewportSizeUpdateWaitingForTarget = true;
     m_dynamicViewportSizeUpdateWaitingForLayerTreeCommit = true;
-    m_process->send(Messages::WebPage::DynamicViewportSizeUpdate(minimumLayoutSize, viewSize, maximumUnobscuredSize, targetExposedContentRect, targetUnobscuredRect, targetUnobscuredRectInScrollViewCoordinates, unobscuredSafeAreaInsets, targetScale, deviceOrientation, ++m_currentDynamicViewportSizeUpdateID), m_pageID);
+    m_process->send(Messages::WebPage::DynamicViewportSizeUpdate(minimumLayoutSize, maximumUnobscuredSize, targetExposedContentRect, targetUnobscuredRect, targetUnobscuredRectInScrollViewCoordinates, unobscuredSafeAreaInsets, targetScale, deviceOrientation, ++m_currentDynamicViewportSizeUpdateID), m_pageID);
 }
 
 void WebPageProxy::synchronizeDynamicViewportUpdate()
@@ -354,13 +354,12 @@
     m_dynamicViewportSizeUpdateWaitingForLayerTreeCommit = false;
 }
 
-void WebPageProxy::setViewportConfigurationMinimumLayoutSize(const WebCore::FloatSize& size, const WebCore::FloatSize& viewSize)
+void WebPageProxy::setViewportConfigurationMinimumLayoutSize(const WebCore::FloatSize& size)
 {
     m_viewportConfigurationMinimumLayoutSize = size;
-    m_viewportConfigurationViewSize = viewSize;
 
     if (isValid())
-        m_process->send(Messages::WebPage::SetViewportConfigurationMinimumLayoutSize(size, viewSize), m_pageID);
+        m_process->send(Messages::WebPage::SetViewportConfigurationMinimumLayoutSize(size), m_pageID);
 }
 
 void WebPageProxy::setForceAlwaysUserScalable(bool userScalable)
diff --git a/Source/WebKit/WebProcess/WebPage/WebPage.cpp b/Source/WebKit/WebProcess/WebPage/WebPage.cpp
index cc1c601..0ebc215 100644
--- a/Source/WebKit/WebProcess/WebPage/WebPage.cpp
+++ b/Source/WebKit/WebProcess/WebPage/WebPage.cpp
@@ -612,7 +612,7 @@
 #endif
 
 #if PLATFORM(IOS)
-    setViewportConfigurationMinimumLayoutSize(parameters.viewportConfigurationMinimumLayoutSize, parameters.viewportConfigurationViewSize);
+    setViewportConfigurationMinimumLayoutSize(parameters.viewportConfigurationMinimumLayoutSize);
     setMaximumUnobscuredSize(parameters.maximumUnobscuredSize);
 #endif
 }
diff --git a/Source/WebKit/WebProcess/WebPage/WebPage.h b/Source/WebKit/WebProcess/WebPage/WebPage.h
index bf5f68c..ea652ff 100644
--- a/Source/WebKit/WebProcess/WebPage/WebPage.h
+++ b/Source/WebKit/WebProcess/WebPage/WebPage.h
@@ -875,10 +875,10 @@
     void updateVisibilityState(bool isInitialState = false);
 
 #if PLATFORM(IOS)
-    void setViewportConfigurationMinimumLayoutSize(const WebCore::FloatSize&, const WebCore::FloatSize& viewSize);
+    void setViewportConfigurationMinimumLayoutSize(const WebCore::FloatSize&);
     void setMaximumUnobscuredSize(const WebCore::FloatSize&);
     void setDeviceOrientation(int32_t);
-    void dynamicViewportSizeUpdate(const WebCore::FloatSize& minimumLayoutSize, const WebCore::FloatSize& viewSize, const WebCore::FloatSize& maximumUnobscuredSize, const WebCore::FloatRect& targetExposedContentRect, const WebCore::FloatRect& targetUnobscuredRect, const WebCore::FloatRect& targetUnobscuredRectInScrollViewCoordinates, const WebCore::FloatBoxExtent& targetUnobscuredSafeAreaInsets, double scale, int32_t deviceOrientation, uint64_t dynamicViewportSizeUpdateID);
+    void dynamicViewportSizeUpdate(const WebCore::FloatSize& minimumLayoutSize, const WebCore::FloatSize& maximumUnobscuredSize, const WebCore::FloatRect& targetExposedContentRect, const WebCore::FloatRect& targetUnobscuredRect, const WebCore::FloatRect& targetUnobscuredRectInScrollViewCoordinates, const WebCore::FloatBoxExtent& targetUnobscuredSafeAreaInsets, double scale, int32_t deviceOrientation, uint64_t dynamicViewportSizeUpdateID);
     void synchronizeDynamicViewportUpdate(double& newTargetScale, WebCore::FloatPoint& newScrollPosition, uint64_t& nextValidLayerTreeTransactionID);
     std::optional<float> scaleFromUIProcess(const VisibleContentRectUpdateInfo&) const;
     void updateVisibleContentRects(const VisibleContentRectUpdateInfo&, MonotonicTime oldestTimestamp);
diff --git a/Source/WebKit/WebProcess/WebPage/WebPage.messages.in b/Source/WebKit/WebProcess/WebPage/WebPage.messages.in
index 6def3b0..d2c684d 100644
--- a/Source/WebKit/WebProcess/WebPage/WebPage.messages.in
+++ b/Source/WebKit/WebProcess/WebPage/WebPage.messages.in
@@ -41,10 +41,10 @@
     KeyEvent(WebKit::WebKeyboardEvent event)
     MouseEvent(WebKit::WebMouseEvent event)
 #if PLATFORM(IOS)
-    SetViewportConfigurationMinimumLayoutSize(WebCore::FloatSize size, WebCore::FloatSize viewSize)
+    SetViewportConfigurationMinimumLayoutSize(WebCore::FloatSize size)
     SetMaximumUnobscuredSize(WebCore::FloatSize size)
     SetDeviceOrientation(int32_t deviceOrientation)
-    DynamicViewportSizeUpdate(WebCore::FloatSize minimumLayoutSize, WebCore::FloatSize viewSize, WebCore::FloatSize maximumUnobscuredSize, WebCore::FloatRect targetExposedContentRect, WebCore::FloatRect targetUnobscuredRect, WebCore::FloatRect targetUnobscuredRectInScrollViewCoordinates, WebCore::RectEdges<float> targetUnobscuredSafeAreaInsets, double scale, int32_t deviceOrientation, uint64_t dynamicViewportSizeUpdateID)
+    DynamicViewportSizeUpdate(WebCore::FloatSize minimumLayoutSize, WebCore::FloatSize maximumUnobscuredSize, WebCore::FloatRect targetExposedContentRect, WebCore::FloatRect targetUnobscuredRect, WebCore::FloatRect targetUnobscuredRectInScrollViewCoordinates, WebCore::RectEdges<float> targetUnobscuredSafeAreaInsets, double scale, int32_t deviceOrientation, uint64_t dynamicViewportSizeUpdateID)
     SynchronizeDynamicViewportUpdate() -> (double newTargetScale, WebCore::FloatPoint newScrollPosition, uint64_t nextValidLayerTreeTransactionID)
 
     HandleTap(WebCore::IntPoint point, uint64_t lastLayerTreeTransactionId)
diff --git a/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm b/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm
index 5ced48b..e47584d 100644
--- a/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm
+++ b/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm
@@ -2454,10 +2454,10 @@
     }
 }
 
-void WebPage::setViewportConfigurationMinimumLayoutSize(const FloatSize& size, const FloatSize& viewSize)
+void WebPage::setViewportConfigurationMinimumLayoutSize(const FloatSize& size)
 {
-    LOG_WITH_STREAM(VisibleRects, stream << "WebPage " << m_pageID << " setViewportConfigurationMinimumLayoutSize " << size << " viewSize " << viewSize);
-    if (m_viewportConfiguration.setMinimumLayoutSize(size, viewSize))
+    LOG_WITH_STREAM(VisibleRects, stream << "WebPage " << m_pageID << " setViewportConfigurationMinimumLayoutSize " << size);
+    if (m_viewportConfiguration.setMinimumLayoutSize(size))
         viewportConfigurationChanged();
 }
 
@@ -2492,12 +2492,12 @@
     }
 }
 
-void WebPage::dynamicViewportSizeUpdate(const FloatSize& minimumLayoutSize, const FloatSize& viewSize, const WebCore::FloatSize& maximumUnobscuredSize, const FloatRect& targetExposedContentRect, const FloatRect& targetUnobscuredRect, const WebCore::FloatRect& targetUnobscuredRectInScrollViewCoordinates, const WebCore::FloatBoxExtent& targetUnobscuredSafeAreaInsets, double targetScale, int32_t deviceOrientation, uint64_t dynamicViewportSizeUpdateID)
+void WebPage::dynamicViewportSizeUpdate(const FloatSize& minimumLayoutSize, const WebCore::FloatSize& maximumUnobscuredSize, const FloatRect& targetExposedContentRect, const FloatRect& targetUnobscuredRect, const WebCore::FloatRect& targetUnobscuredRectInScrollViewCoordinates, const WebCore::FloatBoxExtent& targetUnobscuredSafeAreaInsets, double targetScale, int32_t deviceOrientation, uint64_t dynamicViewportSizeUpdateID)
 {
     SetForScope<bool> dynamicSizeUpdateGuard(m_inDynamicSizeUpdate, true);
     // FIXME: this does not handle the cases where the content would change the content size or scroll position from JavaScript.
     // To handle those cases, we would need to redo this computation on every change until the next visible content rect update.
-    LOG_WITH_STREAM(VisibleRects, stream << "\nWebPage::dynamicViewportSizeUpdate - minimumLayoutSize " << minimumLayoutSize << " viewSize " << viewSize << " targetUnobscuredRect " << targetUnobscuredRect << " targetExposedContentRect " << targetExposedContentRect << " targetScale " << targetScale);
+    LOG_WITH_STREAM(VisibleRects, stream << "\nWebPage::dynamicViewportSizeUpdate - minimumLayoutSize " << minimumLayoutSize << " targetUnobscuredRect " << targetUnobscuredRect << " targetExposedContentRect " << targetExposedContentRect << " targetScale " << targetScale);
 
     FrameView& frameView = *m_page->mainFrame().view();
     IntSize oldContentSize = frameView.contentsSize();
@@ -2530,7 +2530,7 @@
     }
 
     LOG_WITH_STREAM(VisibleRects, stream << "WebPage::dynamicViewportSizeUpdate setting minimum layout size to " << minimumLayoutSize);
-    m_viewportConfiguration.setMinimumLayoutSize(minimumLayoutSize, viewSize);
+    m_viewportConfiguration.setMinimumLayoutSize(minimumLayoutSize);
     IntSize newLayoutSize = m_viewportConfiguration.layoutSize();
 
     if (setFixedLayoutSize(newLayoutSize))
@@ -2912,9 +2912,7 @@
     if (scrollPosition != frameView.scrollPosition())
         m_dynamicSizeUpdateHistory.clear();
 
-    bool didUpdateForceHorizontalShrinkToFit = m_viewportConfiguration.setForceHorizontalShrinkToFit(visibleContentRectUpdateInfo.forceHorizontalShrinkToFit());
-    bool didUpdateCanIgnoreViewportScalingConstraints = m_viewportConfiguration.setCanIgnoreScalingConstraints(m_ignoreViewportScalingConstraints && visibleContentRectUpdateInfo.allowShrinkToFit());
-    if (didUpdateForceHorizontalShrinkToFit || didUpdateCanIgnoreViewportScalingConstraints)
+    if (m_viewportConfiguration.setCanIgnoreScalingConstraints(m_ignoreViewportScalingConstraints && visibleContentRectUpdateInfo.allowShrinkToFit()))
         viewportConfigurationChanged();
 
     frameView.setUnobscuredContentSize(visibleContentRectUpdateInfo.unobscuredContentRect().size());
diff --git a/Tools/ChangeLog b/Tools/ChangeLog
index 3018a41..7dc32fb 100644
--- a/Tools/ChangeLog
+++ b/Tools/ChangeLog
@@ -1,3 +1,17 @@
+2018-04-27  Wenson Hsieh  <wenson_hsieh@apple.com>
+
+        [Extra zoom mode] Add a mechanism to override default viewport behaviors in extra zoom mode
+        https://bugs.webkit.org/show_bug.cgi?id=185050
+        <rdar://problem/39624038>
+
+        Reviewed by Tim Horton.
+
+        Remove a test that's no longer useful, now that the SPI it was testing is gone. This functionality is now
+        tested by the layout test added in this patch.
+
+        * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
+        * TestWebKitAPI/Tests/ios/ViewportSizingTests.mm: Removed.
+
 2018-04-26  Ryan Haddad  <ryanhaddad@apple.com>
 
         REGRESSION (r231039): RunUnitTests step reports disabled tests as failures
diff --git a/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj b/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj
index c32c265..f1993fd 100644
--- a/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj
+++ b/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj
@@ -94,7 +94,6 @@
 		2E14A5291D3FE96B0010F35B /* autoplaying-video-with-audio.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 2E14A5281D3FE8B80010F35B /* autoplaying-video-with-audio.html */; };
 		2E1B7B001D41ABA7007558B4 /* large-video-seek-after-ending.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 2E1B7AFF1D41A95F007558B4 /* large-video-seek-after-ending.html */; };
 		2E1B7B021D41B1B9007558B4 /* large-video-hides-controls-after-seek-to-end.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 2E1B7B011D41B1B3007558B4 /* large-video-hides-controls-after-seek-to-end.html */; };
-		2E1B881F2040EE5300FFF6A9 /* ViewportSizingTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2E1B881E2040EE5300FFF6A9 /* ViewportSizingTests.mm */; };
 		2E1DFDED1D42A51100714A00 /* large-videos-with-audio.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 2E1DFDEC1D42A41C00714A00 /* large-videos-with-audio.html */; };
 		2E1DFDEF1D42A6F200714A00 /* large-videos-with-audio-autoplay.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 2E1DFDEE1D42A6EB00714A00 /* large-videos-with-audio-autoplay.html */; };
 		2E1DFDF11D42E1E400714A00 /* large-video-seek-to-beginning-and-play-after-ending.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 2E1DFDF01D42E14400714A00 /* large-video-seek-to-beginning-and-play-after-ending.html */; };
@@ -1256,7 +1255,6 @@
 		2E14A5281D3FE8B80010F35B /* autoplaying-video-with-audio.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "autoplaying-video-with-audio.html"; sourceTree = "<group>"; };
 		2E1B7AFF1D41A95F007558B4 /* large-video-seek-after-ending.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "large-video-seek-after-ending.html"; sourceTree = "<group>"; };
 		2E1B7B011D41B1B3007558B4 /* large-video-hides-controls-after-seek-to-end.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "large-video-hides-controls-after-seek-to-end.html"; sourceTree = "<group>"; };
-		2E1B881E2040EE5300FFF6A9 /* ViewportSizingTests.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = ViewportSizingTests.mm; sourceTree = "<group>"; };
 		2E1DFDEC1D42A41C00714A00 /* large-videos-with-audio.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "large-videos-with-audio.html"; sourceTree = "<group>"; };
 		2E1DFDEE1D42A6EB00714A00 /* large-videos-with-audio-autoplay.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "large-videos-with-audio-autoplay.html"; sourceTree = "<group>"; };
 		2E1DFDF01D42E14400714A00 /* large-video-seek-to-beginning-and-play-after-ending.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "large-video-seek-to-beginning-and-play-after-ending.html"; sourceTree = "<group>"; };
@@ -2379,7 +2377,6 @@
 				4433A395208044130091ED57 /* SynchronousTimeoutTests.mm */,
 				F45033F4206BEC95009351CE /* TextAutosizingBoost.mm */,
 				F46849BD1EEF58E400B937FE /* UIPasteboardTests.mm */,
-				2E1B881E2040EE5300FFF6A9 /* ViewportSizingTests.mm */,
 				514958BD1F7427AC00E87BAD /* WKWebViewAutofillTests.mm */,
 			);
 			path = ios;
@@ -3768,7 +3765,6 @@
 				7C83E03A1D0A602700FEBCF3 /* UtilitiesCocoa.mm in Sources */,
 				7C83E0C61D0A654E00FEBCF3 /* VideoControlsManager.mm in Sources */,
 				115EB3431EE0BA03003C2C0A /* ViewportSizeForViewportUnits.mm in Sources */,
-				2E1B881F2040EE5300FFF6A9 /* ViewportSizingTests.mm in Sources */,
 				6356FB221EC4E0BA0044BF18 /* VisibleContentRect.mm in Sources */,
 				83779C381F82FECE007CDA8A /* VisitedLinkStore.mm in Sources */,
 				0F139E771A423A5B00F590F5 /* WeakObjCPtr.mm in Sources */,
diff --git a/Tools/TestWebKitAPI/Tests/ios/ViewportSizingTests.mm b/Tools/TestWebKitAPI/Tests/ios/ViewportSizingTests.mm
deleted file mode 100644
index 9800d37..0000000
--- a/Tools/TestWebKitAPI/Tests/ios/ViewportSizingTests.mm
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * 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"
-
-#if WK_API_ENABLED && PLATFORM(IOS)
-
-#import "PlatformUtilities.h"
-#import "TestWKWebView.h"
-#import <WebKit/WKWebViewPrivate.h>
-
-using namespace TestWebKitAPI;
-
-@implementation TestWKWebView (ViewportTestingHelpers)
-
-- (BOOL)scaleIsApproximately:(CGFloat)expectedScale
-{
-    static const double maximumExpectedScaleDifference = 0.001;
-    return ABS(self.scrollView.zoomScale - expectedScale) < maximumExpectedScaleDifference;
-}
-
-- (void)expectScaleToBecome:(CGFloat)expectedScale
-{
-    while (![self scaleIsApproximately:expectedScale])
-        [self waitForNextPresentationUpdate];
-}
-
-@end
-
-static NSString *viewportTestPageMarkup(NSString *viewportMetaContent, int contentWidth, int contentHeight)
-{
-    return [NSString stringWithFormat:@"<meta name='viewport' content='%@'><body style='margin: 0'><div style='width: %dpx; height: %dpx; background-color: red'></div>", viewportMetaContent, contentWidth, contentHeight];
-}
-
-namespace TestWebKitAPI {
-
-TEST(ViewportSizingTests, ForceShrinkToFitViewportOverridesViewportParameters)
-{
-    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 400, 400)]);
-    [webView _setAllowsViewportShrinkToFit:YES];
-    [webView _setForceHorizontalViewportShrinkToFit:NO];
-    [webView synchronouslyLoadHTMLString:viewportTestPageMarkup(@"width=device-width, shrink-to-fit=no", 600, 100)];
-    [webView expectScaleToBecome:1];
-
-    [webView _setForceHorizontalViewportShrinkToFit:YES];
-    [webView expectScaleToBecome:0.667];
-
-    [webView _setForceHorizontalViewportShrinkToFit:NO];
-    [webView expectScaleToBecome:1];
-}
-
-TEST(ViewportSizingTests, ShrinkToFitViewportWithMinimumAllowedLayoutWidth)
-{
-    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 200, 200)]);
-    [webView _setAllowsViewportShrinkToFit:YES];
-    [webView _setForceHorizontalViewportShrinkToFit:YES];
-    [webView _setMinimumAllowedLayoutWidth:0];
-    [webView synchronouslyLoadHTMLString:viewportTestPageMarkup(@"width=device-width, initial-scale=1", 400, 100)];
-    [webView expectScaleToBecome:0.5];
-    EXPECT_WK_STREQ("200", [webView stringByEvaluatingJavaScript:@"document.body.clientWidth"]);
-
-    [webView _setMinimumAllowedLayoutWidth:400];
-    [webView waitForNextPresentationUpdate];
-    EXPECT_WK_STREQ("400", [webView stringByEvaluatingJavaScript:@"document.body.clientWidth"]);
-    EXPECT_TRUE([webView scaleIsApproximately:0.5]);
-
-    [webView _setMinimumAllowedLayoutWidth:100];
-    [webView waitForNextPresentationUpdate];
-    EXPECT_WK_STREQ("200", [webView stringByEvaluatingJavaScript:@"document.body.clientWidth"]);
-    EXPECT_TRUE([webView scaleIsApproximately:0.5]);
-}
-
-} // namespace TestWebKitAPI
-
-#endif // WK_API_ENABLED && PLATFORM(IOS)