Cherry-pick: [Android WebView] In non-WideViewport mode, initial-scale < 1 must be ignored
Cherry-pick of chromium http://crrev.com/25353006
Bug: 10566410
Original description:
[Android WebView] In non-WideViewport mode, initial-scale < 1 must be ignored
From my experiments with the existing implementation, it turns out that in the
case when WideViewport is turned off, values of initial-scale < 1 are ignored in
most cases. The layout width is set to device-width (scaled according to
target-densitydpi). This also includes 'auto' initial-scale.
An exception from the rule is the case when width is set to device-width,
in which case the initial-scale is respected.
BUG=303189
Change-Id: I3d7139ce0fe24e0c8f3f45e2209a9fdba0de5555
diff --git a/Source/core/page/PageScaleConstraintsSet.cpp b/Source/core/page/PageScaleConstraintsSet.cpp
index 01ac14e..182c39e 100644
--- a/Source/core/page/PageScaleConstraintsSet.cpp
+++ b/Source/core/page/PageScaleConstraintsSet.cpp
@@ -151,10 +151,17 @@
}
if (wideViewportQuirkEnabled) {
- if (useWideViewport && arguments.width == -1 && arguments.zoom != 1.0f)
+ if (useWideViewport && arguments.width == -1 && arguments.zoom != 1.0f) {
adjustedLayoutSizeWidth = layoutFallbackWidth;
- else if (!useWideViewport)
- adjustedLayoutSizeWidth = getLayoutWidthForNonWideViewport(viewSize, initialScale) / targetDensityDPIFactor;
+ } else if (!useWideViewport) {
+ const float nonWideScale = arguments.zoom < 1 && arguments.width != ViewportArguments::ValueDeviceWidth ? -1 : initialScale;
+ adjustedLayoutSizeWidth = getLayoutWidthForNonWideViewport(viewSize, nonWideScale) / targetDensityDPIFactor;
+ if (arguments.zoom < 1) {
+ m_pageDefinedConstraints.initialScale = viewSize.width() / adjustedLayoutSizeWidth;
+ m_pageDefinedConstraints.minimumScale = std::min<float>(m_pageDefinedConstraints.minimumScale, m_pageDefinedConstraints.initialScale);
+ m_pageDefinedConstraints.maximumScale = std::max<float>(m_pageDefinedConstraints.maximumScale, m_pageDefinedConstraints.initialScale);
+ }
+ }
}
if (adjustedLayoutSizeWidth != m_pageDefinedConstraints.layoutSize.width()) {
diff --git a/Source/web/tests/WebFrameTest.cpp b/Source/web/tests/WebFrameTest.cpp
index bd58af4..0f7bbda 100644
--- a/Source/web/tests/WebFrameTest.cpp
+++ b/Source/web/tests/WebFrameTest.cpp
@@ -1222,6 +1222,51 @@
}
}
+TEST_F(WebFrameTest, NoWideViewportAndScaleLessThanOne) {
+ registerMockedHttpURLLoad("viewport-initial-scale-less-than-1.html");
+
+ FixedLayoutTestWebViewClient client;
+ client.m_screenInfo.deviceScaleFactor = 1.33f;
+ int viewportWidth = 640;
+ int viewportHeight = 480;
+
+ m_webView = FrameTestHelpers::createWebViewAndLoad(m_baseURL + "viewport-initial-scale-less-than-1.html", true, 0, &client);
+ m_webView->enableFixedLayoutMode(true);
+ m_webView->settings()->setViewportEnabled(true);
+ m_webView->settings()->setSupportDeprecatedTargetDensityDPI(true);
+ m_webView->settings()->setWideViewportQuirkEnabled(true);
+ m_webView->settings()->setUseWideViewport(true);
+ m_webView->resize(WebSize(viewportWidth, viewportHeight));
+ m_webView->layout();
+
+ EXPECT_NEAR(viewportWidth * client.m_screenInfo.deviceScaleFactor, m_webView->fixedLayoutSize().width, 1.0f);
+ EXPECT_NEAR(viewportHeight * client.m_screenInfo.deviceScaleFactor, m_webView->fixedLayoutSize().height, 1.0f);
+ EXPECT_NEAR(1.0f / client.m_screenInfo.deviceScaleFactor, m_webView->pageScaleFactor(), 0.01f);
+}
+
+TEST_F(WebFrameTest, NoWideViewportAndScaleLessThanOneWithDeviceWidth) {
+ registerMockedHttpURLLoad("viewport-initial-scale-less-than-1-device-width.html");
+
+ FixedLayoutTestWebViewClient client;
+ client.m_screenInfo.deviceScaleFactor = 1.33f;
+ int viewportWidth = 640;
+ int viewportHeight = 480;
+
+ m_webView = FrameTestHelpers::createWebViewAndLoad(m_baseURL + "viewport-initial-scale-less-than-1-device-width.html", true, 0, &client);
+ m_webView->enableFixedLayoutMode(true);
+ m_webView->settings()->setViewportEnabled(true);
+ m_webView->settings()->setSupportDeprecatedTargetDensityDPI(true);
+ m_webView->settings()->setWideViewportQuirkEnabled(true);
+ m_webView->settings()->setUseWideViewport(true);
+ m_webView->resize(WebSize(viewportWidth, viewportHeight));
+ m_webView->layout();
+
+ const float pageZoom = 0.25f;
+ EXPECT_NEAR(viewportWidth * client.m_screenInfo.deviceScaleFactor / pageZoom, m_webView->fixedLayoutSize().width, 1.0f);
+ EXPECT_NEAR(viewportHeight * client.m_screenInfo.deviceScaleFactor / pageZoom, m_webView->fixedLayoutSize().height, 1.0f);
+ EXPECT_NEAR(pageZoom * 1.0f / client.m_screenInfo.deviceScaleFactor, m_webView->pageScaleFactor(), 0.01f);
+}
+
class WebFrameResizeTest : public WebFrameTest {
protected:
diff --git a/Source/web/tests/data/viewport-initial-scale-less-than-1-device-width.html b/Source/web/tests/data/viewport-initial-scale-less-than-1-device-width.html
new file mode 100644
index 0000000..990d727
--- /dev/null
+++ b/Source/web/tests/data/viewport-initial-scale-less-than-1-device-width.html
@@ -0,0 +1,8 @@
+<html>
+ <head>
+ <meta name='viewport' content='width=device-width,target-densitydpi=device-dpi,initial-scale=0.25' />
+ </head>
+ <body>
+ A page with a viewport set to device-dpi and device width, scale < 1.
+ </body>
+</html>
diff --git a/Source/web/tests/data/viewport-initial-scale-less-than-1.html b/Source/web/tests/data/viewport-initial-scale-less-than-1.html
new file mode 100644
index 0000000..f4d4d50
--- /dev/null
+++ b/Source/web/tests/data/viewport-initial-scale-less-than-1.html
@@ -0,0 +1,8 @@
+<html>
+ <head>
+ <meta name='viewport' content='width=320,target-densitydpi=device-dpi,initial-scale=0.25' />
+ </head>
+ <body>
+ A page with a viewport set to device-dpi and fixed width, scale < 1.
+ </body>
+</html>