[Extra zoom mode] 100vw is roughly half of the viewport width in extra zoom mode
authorwenson_hsieh@apple.com <wenson_hsieh@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 23 Apr 2018 19:40:26 +0000 (19:40 +0000)
committerwenson_hsieh@apple.com <wenson_hsieh@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 23 Apr 2018 19:40:26 +0000 (19:40 +0000)
https://bugs.webkit.org/show_bug.cgi?id=184871
<rdar://problem/39477595>

Reviewed by Andy Estes.

Source/WebCore:

Currently, when computing CSS viewport units, we use ViewportConfiguration::initialScaleIgnoringContentSize().
This method computes an initial scale from the layout width and height without relying on any information
derived from the current content size. This is done to ensure that the content size and viewport dimensions for
CSS viewport units should not be simultaneously dependent on each other.

Since shrink-to-fit heuristics depend on content size, we currently assume that shrink-to-fit is disabled when
computing initialScaleIgnoringContentSize, by always passing in `false` for `shouldIgnoreScalingConstraints`.
However, in extra zoom mode, the opposite is true: since we force both `m_canIgnoreScalingConstraints` and
`m_forceHorizontalShrinkToFit` to be `true` in this mode, we will always try to shrink-to-fit regardless of
content size.

Because of this shrink-to-fit disparity between `initialScale` and `initialScaleIgnoringContentSize`, viewport
units in extra zoom mode are currently computed assuming an initial scale set by the page, whereas the real
viewport is scaled to fit, which causes any lengths computed in terms of vw and vh to be incorrect. To fix this,
we introduce a version of shouldIgnoreScalingConstraints() that returns `true` iff scaling constraints are
always ignored, regardless of content size. We then use this in initialScaleIgnoringContentSize, instead of
always passing in `false` for `shouldIgnoreScalingConstraints`.

Test: fast/css/extrazoom/viewport-units-shrink-to-fit.html

* page/ViewportConfiguration.cpp:
(WebCore::ViewportConfiguration::shouldIgnoreScalingConstraintsRegardlessOfContentSize const):
(WebCore::ViewportConfiguration::initialScaleIgnoringContentSize const):
* page/ViewportConfiguration.h:

LayoutTests:

Add a new layout test to verify that shrink-to-fit works as intended in extra zoom mode:
1.  The large element should cause the entire viewport to shrink down to fit.
2.  Removing the large element should adjust the viewport, such that the smaller element now fits the entire
    viewport.
3.  The smaller element (at 100vw and 100vh) should be the same size as the window.

* TestExpectations:
* fast/css/extrazoom/viewport-units-shrink-to-fit-expected.txt: Added.
* fast/css/extrazoom/viewport-units-shrink-to-fit.html: Added.

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

LayoutTests/ChangeLog
LayoutTests/TestExpectations
LayoutTests/fast/css/extrazoom/viewport-units-shrink-to-fit-expected.txt [new file with mode: 0644]
LayoutTests/fast/css/extrazoom/viewport-units-shrink-to-fit.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/page/ViewportConfiguration.cpp
Source/WebCore/page/ViewportConfiguration.h

index 06a5799..d4c1e6f 100644 (file)
@@ -1,3 +1,21 @@
+2018-04-23  Wenson Hsieh  <wenson_hsieh@apple.com>
+
+        [Extra zoom mode] 100vw is roughly half of the viewport width in extra zoom mode
+        https://bugs.webkit.org/show_bug.cgi?id=184871
+        <rdar://problem/39477595>
+
+        Reviewed by Andy Estes.
+
+        Add a new layout test to verify that shrink-to-fit works as intended in extra zoom mode:
+        1.  The large element should cause the entire viewport to shrink down to fit.
+        2.  Removing the large element should adjust the viewport, such that the smaller element now fits the entire
+            viewport.
+        3.  The smaller element (at 100vw and 100vh) should be the same size as the window.
+
+        * TestExpectations:
+        * fast/css/extrazoom/viewport-units-shrink-to-fit-expected.txt: Added.
+        * fast/css/extrazoom/viewport-units-shrink-to-fit.html: Added.
+
 2018-04-22  Wenson Hsieh  <wenson_hsieh@apple.com>
 
         Add a layout test for r230785
index 34131eb..fc923dd 100644 (file)
@@ -18,6 +18,7 @@ editing/caret/ios [ Skip ]
 editing/pasteboard/gtk [ Skip ]
 editing/selection/ios [ Skip ]
 tiled-drawing [ Skip ]
+fast/css/extrazoom [ Skip ]
 fast/dom/Window/extrazoom [ Skip ]
 fast/forms/extrazoom [ Skip ]
 fast/visual-viewport/extrazoom [ Skip ]
diff --git a/LayoutTests/fast/css/extrazoom/viewport-units-shrink-to-fit-expected.txt b/LayoutTests/fast/css/extrazoom/viewport-units-shrink-to-fit-expected.txt
new file mode 100644 (file)
index 0000000..7fea310
--- /dev/null
@@ -0,0 +1,14 @@
+PASS innerWidthBeforeRemoval is 512
+PASS Math.round(largeElementRectBeforeRemoval.width) is 512
+PASS Math.round(largeElementRectBeforeRemoval.height) is innerHeightBeforeRemoval
+PASS Math.round(mediumElementRectBeforeRemoval.width) is 320
+
+After removing large container:
+
+PASS innerWidthAfterRemoval is 320
+PASS Math.round(mediumElementRectAfterRemoval.width) is 320
+PASS Math.round(mediumElementRectAfterRemoval.height) is innerHeightAfterRemoval
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/css/extrazoom/viewport-units-shrink-to-fit.html b/LayoutTests/fast/css/extrazoom/viewport-units-shrink-to-fit.html
new file mode 100644 (file)
index 0000000..ce3c5f0
--- /dev/null
@@ -0,0 +1,56 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ useFlexibleViewport=true ] -->
+<html>
+<meta name="viewport" content="width=device-width, initial-scale=1">
+<head>
+    <style>
+        html, body {
+            width: 100%;
+            height: 100%;
+            margin: 0;
+        }
+
+        #large, #medium {
+            position: absolute;
+            top: 0;
+            left: 0;
+        }
+    </style>
+    <script src="../../../resources/ui-helper.js"></script>
+    <script src="../../../resources/js-test.js"></script>
+    <script>
+        jsTestIsAsync = true;
+
+        async function runTest() {
+            await UIHelper.ensurePresentationUpdate();
+
+            largeElementRectBeforeRemoval = large.getBoundingClientRect();
+            mediumElementRectBeforeRemoval = medium.getBoundingClientRect();
+            innerWidthBeforeRemoval = innerWidth;
+            innerHeightBeforeRemoval = innerHeight;
+
+            large.remove();
+            await UIHelper.ensurePresentationUpdate();
+
+            mediumElementRectAfterRemoval = medium.getBoundingClientRect();
+            innerWidthAfterRemoval = innerWidth;
+            innerHeightAfterRemoval = innerHeight;
+
+            shouldBe("innerWidthBeforeRemoval", "512");
+            shouldBe("Math.round(largeElementRectBeforeRemoval.width)", "512");
+            shouldBe("Math.round(largeElementRectBeforeRemoval.height)", "innerHeightBeforeRemoval");
+            shouldBe("Math.round(mediumElementRectBeforeRemoval.width)", "320");
+            debug("\nAfter removing large container:\n");
+            shouldBe("innerWidthAfterRemoval", "320");
+            shouldBe("Math.round(mediumElementRectAfterRemoval.width)", "320");
+            shouldBe("Math.round(mediumElementRectAfterRemoval.height)", "innerHeightAfterRemoval");
+
+            finishJSTest();
+        }
+    </script>
+</head>
+
+<body onload="runTest()">
+    <div id="large" style="width: 160vw; height: 160vh; background-color: blue;"></div>
+    <div id="medium" style="width: 100vw; height: 100vh; background-color: green;"></div>
+</body>
+</html>
\ No newline at end of file
index 182e635..d196e99 100644 (file)
@@ -1,3 +1,36 @@
+2018-04-23  Wenson Hsieh  <wenson_hsieh@apple.com>
+
+        [Extra zoom mode] 100vw is roughly half of the viewport width in extra zoom mode
+        https://bugs.webkit.org/show_bug.cgi?id=184871
+        <rdar://problem/39477595>
+
+        Reviewed by Andy Estes.
+
+        Currently, when computing CSS viewport units, we use ViewportConfiguration::initialScaleIgnoringContentSize().
+        This method computes an initial scale from the layout width and height without relying on any information
+        derived from the current content size. This is done to ensure that the content size and viewport dimensions for
+        CSS viewport units should not be simultaneously dependent on each other.
+
+        Since shrink-to-fit heuristics depend on content size, we currently assume that shrink-to-fit is disabled when
+        computing initialScaleIgnoringContentSize, by always passing in `false` for `shouldIgnoreScalingConstraints`.
+        However, in extra zoom mode, the opposite is true: since we force both `m_canIgnoreScalingConstraints` and
+        `m_forceHorizontalShrinkToFit` to be `true` in this mode, we will always try to shrink-to-fit regardless of
+        content size.
+
+        Because of this shrink-to-fit disparity between `initialScale` and `initialScaleIgnoringContentSize`, viewport
+        units in extra zoom mode are currently computed assuming an initial scale set by the page, whereas the real
+        viewport is scaled to fit, which causes any lengths computed in terms of vw and vh to be incorrect. To fix this,
+        we introduce a version of shouldIgnoreScalingConstraints() that returns `true` iff scaling constraints are
+        always ignored, regardless of content size. We then use this in initialScaleIgnoringContentSize, instead of
+        always passing in `false` for `shouldIgnoreScalingConstraints`.
+
+        Test: fast/css/extrazoom/viewport-units-shrink-to-fit.html
+
+        * page/ViewportConfiguration.cpp:
+        (WebCore::ViewportConfiguration::shouldIgnoreScalingConstraintsRegardlessOfContentSize const):
+        (WebCore::ViewportConfiguration::initialScaleIgnoringContentSize const):
+        * page/ViewportConfiguration.h:
+
 2018-04-23  Zalan Bujtas  <zalan@apple.com>
 
         [Simple line layout] Generate inline boxtree using simple line layout runs.
index 7087d72..e4de76f 100644 (file)
@@ -171,6 +171,11 @@ bool ViewportConfiguration::shouldIgnoreScalingConstraints() const
     return shouldIgnoreHorizontalScalingConstraints() || shouldIgnoreVerticalScalingConstraints();
 }
 
+bool ViewportConfiguration::shouldIgnoreScalingConstraintsRegardlessOfContentSize() const
+{
+    return m_canIgnoreScalingConstraints && m_forceHorizontalShrinkToFit;
+}
+
 double ViewportConfiguration::initialScaleFromSize(double width, double height, bool shouldIgnoreScalingConstraints) const
 {
     ASSERT(!constraintsAreAllRelative(m_configuration));
@@ -200,7 +205,7 @@ double ViewportConfiguration::initialScale() const
 
 double ViewportConfiguration::initialScaleIgnoringContentSize() const
 {
-    return initialScaleFromSize(layoutWidth(), layoutHeight(), false);
+    return initialScaleFromSize(layoutWidth(), layoutHeight(), shouldIgnoreScalingConstraintsRegardlessOfContentSize());
 }
 
 double ViewportConfiguration::minimumScale() const
index 95db844..9ec6893 100644 (file)
@@ -116,6 +116,7 @@ private:
     int layoutWidth() const;
     int layoutHeight() const;
 
+    bool shouldIgnoreScalingConstraintsRegardlessOfContentSize() const;
     bool shouldIgnoreScalingConstraints() const;
     bool shouldIgnoreVerticalScalingConstraints() const;
     bool shouldIgnoreHorizontalScalingConstraints() const;