Title: [290151] trunk
Revision
290151
Author
timothy_hor...@apple.com
Date
2022-02-18 12:21:56 -0800 (Fri, 18 Feb 2022)

Log Message

Client-set minimum effective device width is not respected if AllowViewportShrinkToFitContent is enabled
https://bugs.webkit.org/show_bug.cgi?id=236822

Reviewed by Wenson Hsieh.

Source/WebCore:

New test: fast/viewport/ios/shrink-to-fit-content-with-wider-minimum-device-width.html

Re-instate the functionality of -[WKWebView _setMinimumEffectiveDeviceWidth:]
after it was intentionally broken in favor of shrink-to-fit in r244849.

It turns out that clients sometimes need a larger manually-set minimum
than the one shrink-to-fit will choose, so instead of picking between
them, we just take the maximum of the two.

* page/ViewportConfiguration.cpp:
(WebCore::ViewportConfiguration::setViewLayoutSize):
Rename the client-set mEDW to `m_minimumEffectiveDeviceWidthForView`.

(WebCore::ViewportConfiguration::nativeWebpageParameters):
(WebCore::ViewportConfiguration::setMinimumEffectiveDeviceWidthForShrinkToFit):
Rename to shouldIgnoreMinimumEffectiveDeviceWidthForShrinkToFit to be clear that
it's only about ignoring the shrink-to-fit mEDW, not the client-set one.

Rename the shrink-to-fit-set mEDW to `m_minimumEffectiveDeviceWidthForShrinkToFit`.

(WebCore::ViewportConfiguration::description const):
(WebCore::ViewportConfiguration::setMinimumEffectiveDeviceWidth): Deleted.
* page/ViewportConfiguration.h:
(WebCore::ViewportConfiguration::minimumEffectiveDeviceWidth const):
The effective-mEDW now takes the client-set value into account in all cases,
taking the maximum-of-minimums as the effective value.

(WebCore::ViewportConfiguration::shouldIgnoreMinimumEffectiveDeviceWidthForShrinkToFit const):
(WebCore::ViewportConfiguration::shouldIgnoreMinimumEffectiveDeviceWidth const): Deleted.

Source/WebKit:

* WebProcess/WebPage/ios/WebPageIOS.mm:
(WebKit::WebPage::setViewportConfigurationViewLayoutSize):
Reset the separate shrink-to-fit mEDW if shrink-to-fit is not engaged.

(WebKit::WebPage::shrinkToFitContent):

Modified Paths

Added Paths

Diff

Added: trunk/LayoutTests/fast/viewport/ios/shrink-to-fit-content-with-wider-minimum-device-width-expected.txt (0 => 290151)


--- trunk/LayoutTests/fast/viewport/ios/shrink-to-fit-content-with-wider-minimum-device-width-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/viewport/ios/shrink-to-fit-content-with-wider-minimum-device-width-expected.txt	2022-02-18 20:21:56 UTC (rev 290151)
@@ -0,0 +1,11 @@
+This test verifies that a page with a large client-set minimum effective device width, no viewport, and content larger than the actual view width is scaled to fit the client-set minimum effective device width. To test manually, load the page and verify that the bar spans half the width of the page.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS minScale is expectedScale
+PASS innerWidth became 1500
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/fast/viewport/ios/shrink-to-fit-content-with-wider-minimum-device-width.html (0 => 290151)


--- trunk/LayoutTests/fast/viewport/ios/shrink-to-fit-content-with-wider-minimum-device-width.html	                        (rev 0)
+++ trunk/LayoutTests/fast/viewport/ios/shrink-to-fit-content-with-wider-minimum-device-width.html	2022-02-18 20:21:56 UTC (rev 290151)
@@ -0,0 +1,47 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ ShouldIgnoreMetaViewport=true ] -->
+<html>
+<head>
+<meta name="viewport">
+<style>
+body, html {
+    margin: 0;
+    width: 100%;
+    height: 100%;
+}
+
+#bar {
+    width: 1000px;
+    height: 100px;
+    background: linear-gradient(to right, red 0%, green 50%, blue 100%);
+}
+
+#description {
+    width: 300px;
+    overflow: scroll;
+}
+</style>
+<script src=""
+<script src=""
+<script>
+jsTestIsAsync = true;
+
+description("This test verifies that a page with a large client-set minimum effective device width, no viewport, and content larger than the actual view width is scaled to fit the client-set minimum effective device width. To test manually, load the page and verify that the bar spans half the width of the page.");
+
+addEventListener("load", async () => {
+    if (!window.testRunner)
+        return;
+
+    await UIHelper.setMinimumEffectiveWidth(1500);
+    await UIHelper.ensureVisibleContentRectUpdate();
+    minScale = (await UIHelper.minimumZoomScale()).toFixed(2);
+    expectedScale = (screen.width / 1500).toFixed(2);
+    shouldBe("minScale", "expectedScale");
+    shouldBecomeEqual("innerWidth", "1500", finishJSTest);
+});
+</script>
+</head>
+<body>
+<div id="bar"></div>
+<div id="description"></div>
+</body>
+</html>

Modified: trunk/Source/WebCore/ChangeLog (290150 => 290151)


--- trunk/Source/WebCore/ChangeLog	2022-02-18 20:17:45 UTC (rev 290150)
+++ trunk/Source/WebCore/ChangeLog	2022-02-18 20:21:56 UTC (rev 290151)
@@ -1,3 +1,40 @@
+2022-02-18  Tim Horton  <timothy_hor...@apple.com>
+
+        Client-set minimum effective device width is not respected if AllowViewportShrinkToFitContent is enabled
+        https://bugs.webkit.org/show_bug.cgi?id=236822
+
+        Reviewed by Wenson Hsieh.
+
+        New test: fast/viewport/ios/shrink-to-fit-content-with-wider-minimum-device-width.html
+
+        Re-instate the functionality of -[WKWebView _setMinimumEffectiveDeviceWidth:]
+        after it was intentionally broken in favor of shrink-to-fit in r244849.
+
+        It turns out that clients sometimes need a larger manually-set minimum
+        than the one shrink-to-fit will choose, so instead of picking between
+        them, we just take the maximum of the two.
+
+        * page/ViewportConfiguration.cpp:
+        (WebCore::ViewportConfiguration::setViewLayoutSize):
+        Rename the client-set mEDW to `m_minimumEffectiveDeviceWidthForView`.
+
+        (WebCore::ViewportConfiguration::nativeWebpageParameters):
+        (WebCore::ViewportConfiguration::setMinimumEffectiveDeviceWidthForShrinkToFit):
+        Rename to shouldIgnoreMinimumEffectiveDeviceWidthForShrinkToFit to be clear that
+        it's only about ignoring the shrink-to-fit mEDW, not the client-set one.
+
+        Rename the shrink-to-fit-set mEDW to `m_minimumEffectiveDeviceWidthForShrinkToFit`.
+
+        (WebCore::ViewportConfiguration::description const):
+        (WebCore::ViewportConfiguration::setMinimumEffectiveDeviceWidth): Deleted.
+        * page/ViewportConfiguration.h:
+        (WebCore::ViewportConfiguration::minimumEffectiveDeviceWidth const):
+        The effective-mEDW now takes the client-set value into account in all cases,
+        taking the maximum-of-minimums as the effective value.
+
+        (WebCore::ViewportConfiguration::shouldIgnoreMinimumEffectiveDeviceWidthForShrinkToFit const):
+        (WebCore::ViewportConfiguration::shouldIgnoreMinimumEffectiveDeviceWidth const): Deleted.
+
 2022-02-18  Zan Dobersek  <zdober...@igalia.com>
 
         [TextureMapper] Refactor TextureMapperPlatformLayerProxy into specializable implementations

Modified: trunk/Source/WebCore/page/ViewportConfiguration.cpp (290150 => 290151)


--- trunk/Source/WebCore/page/ViewportConfiguration.cpp	2022-02-18 20:17:45 UTC (rev 290150)
+++ trunk/Source/WebCore/page/ViewportConfiguration.cpp	2022-02-18 20:21:56 UTC (rev 290151)
@@ -123,16 +123,16 @@
     return true;
 }
 
-bool ViewportConfiguration::setViewLayoutSize(const FloatSize& viewLayoutSize, std::optional<double>&& scaleFactor, std::optional<double>&& minimumEffectiveDeviceWidth)
+bool ViewportConfiguration::setViewLayoutSize(const FloatSize& viewLayoutSize, std::optional<double>&& scaleFactor, std::optional<double>&& minimumEffectiveDeviceWidthFromClient)
 {
     double newScaleFactor = scaleFactor.value_or(m_layoutSizeScaleFactor);
-    double newEffectiveWidth = minimumEffectiveDeviceWidth.value_or(m_minimumEffectiveDeviceWidth);
-    if (m_viewLayoutSize == viewLayoutSize && m_layoutSizeScaleFactor == newScaleFactor && newEffectiveWidth == m_minimumEffectiveDeviceWidth)
+    double newEffectiveWidth = minimumEffectiveDeviceWidthFromClient.value_or(m_minimumEffectiveDeviceWidthForView);
+    if (m_viewLayoutSize == viewLayoutSize && m_layoutSizeScaleFactor == newScaleFactor && newEffectiveWidth == m_minimumEffectiveDeviceWidthForView)
         return false;
 
     m_layoutSizeScaleFactor = newScaleFactor;
     m_viewLayoutSize = viewLayoutSize;
-    m_minimumEffectiveDeviceWidth = newEffectiveWidth;
+    m_minimumEffectiveDeviceWidthForView = newEffectiveWidth;
 
     updateMinimumLayoutSize();
     updateConfiguration();
@@ -356,7 +356,7 @@
 
 ViewportConfiguration::Parameters ViewportConfiguration::nativeWebpageParameters()
 {
-    if (m_canIgnoreScalingConstraints || !shouldIgnoreMinimumEffectiveDeviceWidth())
+    if (m_canIgnoreScalingConstraints || !shouldIgnoreMinimumEffectiveDeviceWidthForShrinkToFit())
         return ViewportConfiguration::nativeWebpageParametersWithShrinkToFit();
 
     return ViewportConfiguration::nativeWebpageParametersWithoutShrinkToFit();
@@ -618,14 +618,14 @@
     return minimumLayoutSize.height();
 }
 
-bool ViewportConfiguration::setMinimumEffectiveDeviceWidth(double width)
+bool ViewportConfiguration::setMinimumEffectiveDeviceWidthForShrinkToFit(double width)
 {
-    if (WTF::areEssentiallyEqual(m_minimumEffectiveDeviceWidth, width))
+    if (WTF::areEssentiallyEqual(m_minimumEffectiveDeviceWidthForShrinkToFit, width))
         return false;
 
-    m_minimumEffectiveDeviceWidth = width;
+    m_minimumEffectiveDeviceWidthForShrinkToFit = width;
 
-    if (shouldIgnoreMinimumEffectiveDeviceWidth())
+    if (shouldIgnoreMinimumEffectiveDeviceWidthForShrinkToFit())
         return false;
 
     updateMinimumLayoutSize();
@@ -721,7 +721,8 @@
     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("minimum effective device width", m_minimumEffectiveDeviceWidth);
+    ts.dumpProperty("minimum effective device width (for view)", m_minimumEffectiveDeviceWidthForView);
+    ts.dumpProperty("minimum effective device width (for shrink-to-fit)", m_minimumEffectiveDeviceWidthForShrinkToFit);
     ts.dumpProperty("known to lay out wider than viewport", m_isKnownToLayOutWiderThanViewport ? "true" : "false");
     
     ts.endGroup();

Modified: trunk/Source/WebCore/page/ViewportConfiguration.h (290150 => 290151)


--- trunk/Source/WebCore/page/ViewportConfiguration.h	2022-02-18 20:17:45 UTC (rev 290150)
+++ trunk/Source/WebCore/page/ViewportConfiguration.h	2022-02-18 20:21:56 UTC (rev 290151)
@@ -89,18 +89,21 @@
     constexpr bool canIgnoreScalingConstraints() const { return m_canIgnoreScalingConstraints; }
 
     WEBCORE_EXPORT bool setMinimumEffectiveDeviceWidthWhenIgnoringScalingConstraints(double);
-    WEBCORE_EXPORT bool setMinimumEffectiveDeviceWidth(double);
+    WEBCORE_EXPORT bool setMinimumEffectiveDeviceWidthForShrinkToFit(double);
     constexpr double minimumEffectiveDeviceWidth() const
     {
-        if (shouldIgnoreMinimumEffectiveDeviceWidth())
-            return 0;
-        return m_canIgnoreScalingConstraints ? m_minimumEffectiveDeviceWidthWhenIgnoringScalingConstraints : m_minimumEffectiveDeviceWidth;
+        double minimumEffectiveDeviceWidth = m_minimumEffectiveDeviceWidthForView;
+
+        if (!shouldIgnoreMinimumEffectiveDeviceWidthForShrinkToFit())
+            minimumEffectiveDeviceWidth = std::max(minimumEffectiveDeviceWidth, m_canIgnoreScalingConstraints ? m_minimumEffectiveDeviceWidthWhenIgnoringScalingConstraints : m_minimumEffectiveDeviceWidthForShrinkToFit);
+
+        return minimumEffectiveDeviceWidth;
     }
 
     constexpr bool isKnownToLayOutWiderThanViewport() const { return m_isKnownToLayOutWiderThanViewport; }
     WEBCORE_EXPORT bool setIsKnownToLayOutWiderThanViewport(bool value);
 
-    constexpr bool shouldIgnoreMinimumEffectiveDeviceWidth() const
+    constexpr bool shouldIgnoreMinimumEffectiveDeviceWidthForShrinkToFit() const
     {
         if (shouldShrinkToFitMinimumEffectiveDeviceWidthWhenIgnoringScalingConstraints())
             return false;
@@ -200,7 +203,8 @@
     OptionSet<DisabledAdaptations> m_disabledAdaptations;
 
     double m_layoutSizeScaleFactor { 1 };
-    double m_minimumEffectiveDeviceWidth { 0 };
+    double m_minimumEffectiveDeviceWidthForView { 0 };
+    double m_minimumEffectiveDeviceWidthForShrinkToFit { 0 };
     double m_minimumEffectiveDeviceWidthWhenIgnoringScalingConstraints { 0 };
     bool m_canIgnoreScalingConstraints;
     bool m_forceAlwaysUserScalable;

Modified: trunk/Source/WebKit/ChangeLog (290150 => 290151)


--- trunk/Source/WebKit/ChangeLog	2022-02-18 20:17:45 UTC (rev 290150)
+++ trunk/Source/WebKit/ChangeLog	2022-02-18 20:21:56 UTC (rev 290151)
@@ -1,3 +1,16 @@
+2022-02-18  Tim Horton  <timothy_hor...@apple.com>
+
+        Client-set minimum effective device width is not respected if AllowViewportShrinkToFitContent is enabled
+        https://bugs.webkit.org/show_bug.cgi?id=236822
+
+        Reviewed by Wenson Hsieh.
+
+        * WebProcess/WebPage/ios/WebPageIOS.mm:
+        (WebKit::WebPage::setViewportConfigurationViewLayoutSize):
+        Reset the separate shrink-to-fit mEDW if shrink-to-fit is not engaged.
+
+        (WebKit::WebPage::shrinkToFitContent):
+
 2022-02-18  Brandon Stewart  <brandonstew...@apple.com>
 
         Generate compile_commands.json on macOS Builds

Modified: trunk/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm (290150 => 290151)


--- trunk/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm	2022-02-18 20:17:45 UTC (rev 290150)
+++ trunk/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm	2022-02-18 20:21:56 UTC (rev 290151)
@@ -3543,9 +3543,11 @@
 {
     LOG_WITH_STREAM(VisibleRects, stream << "WebPage " << m_identifier << " setViewportConfigurationViewLayoutSize " << size << " scaleFactor " << scaleFactor << " minimumEffectiveDeviceWidth " << minimumEffectiveDeviceWidth);
 
+    if (!m_viewportConfiguration.isKnownToLayOutWiderThanViewport())
+        m_viewportConfiguration.setMinimumEffectiveDeviceWidthForShrinkToFit(0);
+
     auto previousLayoutSizeScaleFactor = m_viewportConfiguration.layoutSizeScaleFactor();
-    auto clampedMinimumEffectiveDevice = m_viewportConfiguration.isKnownToLayOutWiderThanViewport() ? std::nullopt : std::optional<double>(minimumEffectiveDeviceWidth);
-    if (!m_viewportConfiguration.setViewLayoutSize(size, scaleFactor, WTFMove(clampedMinimumEffectiveDevice)))
+    if (!m_viewportConfiguration.setViewLayoutSize(size, scaleFactor, minimumEffectiveDeviceWidth))
         return;
 
     auto zoomToInitialScale = ZoomToInitialScale::No;
@@ -3897,7 +3899,7 @@
         return;
 
     auto changeMinimumEffectiveDeviceWidth = [this, mainDocument] (int targetLayoutWidth) -> bool {
-        if (m_viewportConfiguration.setMinimumEffectiveDeviceWidth(targetLayoutWidth)) {
+        if (m_viewportConfiguration.setMinimumEffectiveDeviceWidthForShrinkToFit(targetLayoutWidth)) {
             viewportConfigurationChanged();
             mainDocument->updateLayout();
             return true;
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to