Commit 9d62f965 authored by aelias@chromium.org's avatar aelias@chromium.org

Base new scale on minimum-scale after orientation change.

The previous width-ratio based logic was complicated, and behaves badly
in a particular scenario where the contents overflows past the
webmaster's specified minimum scale.  Replace it with some much simpler
logic that just maintains distance from minimum scale.  (In most cases
this behaves the same as before, because minimum scale is usually based
on the ratio of viewport width to contents width.)

NOTRY=true
BUG=395503

Review URL: https://codereview.chromium.org/405263002

git-svn-id: svn://svn.chromium.org/blink/trunk@178608 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent af0e421b
...@@ -1643,15 +1643,13 @@ void WebViewImpl::resize(const WebSize& newSize) ...@@ -1643,15 +1643,13 @@ void WebViewImpl::resize(const WebSize& newSize)
if (!view) if (!view)
return; return;
WebSize oldSize = m_size; bool shouldAnchorAndRescaleViewport = settings()->mainFrameResizesAreOrientationChanges()
&& m_size.width && contentsSize().width() && newSize.width != m_size.width && !m_fullscreenController->isFullscreen();
float oldPageScaleFactor = pageScaleFactor(); float oldPageScaleFactor = pageScaleFactor();
int oldContentsWidth = contentsSize().width(); float oldMinimumPageScaleFactor = minimumPageScaleFactor();
m_size = newSize; m_size = newSize;
bool shouldAnchorAndRescaleViewport = settings()->mainFrameResizesAreOrientationChanges()
&& oldSize.width && oldContentsWidth && newSize.width != oldSize.width && !m_fullscreenController->isFullscreen();
ViewportAnchor viewportAnchor(&localFrameRootTemporary()->frame()->eventHandler()); ViewportAnchor viewportAnchor(&localFrameRootTemporary()->frame()->eventHandler());
if (shouldAnchorAndRescaleViewport) { if (shouldAnchorAndRescaleViewport) {
viewportAnchor.setAnchor(view->visibleContentRect(), viewportAnchor.setAnchor(view->visibleContentRect(),
...@@ -1674,20 +1672,10 @@ void WebViewImpl::resize(const WebSize& newSize) ...@@ -1674,20 +1672,10 @@ void WebViewImpl::resize(const WebSize& newSize)
view->layout(); view->layout();
if (shouldAnchorAndRescaleViewport) { if (shouldAnchorAndRescaleViewport) {
float viewportWidthRatio = static_cast<float>(newSize.width) / oldSize.width; float newPageScaleFactor = oldPageScaleFactor / oldMinimumPageScaleFactor * minimumPageScaleFactor();
float contentsWidthRatio = static_cast<float>(contentsSize().width()) / oldContentsWidth; IntSize scaledViewportSize = newSize;
float scaleMultiplier = viewportWidthRatio / contentsWidthRatio; scaledViewportSize.scale(1 / newPageScaleFactor);
setPageScaleFactor(newPageScaleFactor, viewportAnchor.computeOrigin(scaledViewportSize));
IntSize viewportSize = view->visibleContentRect().size();
if (scaleMultiplier != 1) {
float newPageScaleFactor = oldPageScaleFactor * scaleMultiplier;
viewportSize.scale(pageScaleFactor() / newPageScaleFactor);
IntPoint scrollOffsetAtNewScale = viewportAnchor.computeOrigin(viewportSize);
setPageScaleFactor(newPageScaleFactor, scrollOffsetAtNewScale);
} else {
IntPoint scrollOffsetAtNewScale = clampOffsetAtScale(viewportAnchor.computeOrigin(viewportSize), pageScaleFactor());
updateMainFrameScrollPosition(scrollOffsetAtNewScale, false);
}
} }
} }
......
...@@ -2042,6 +2042,22 @@ TEST_F(WebFrameResizeTest, ResizeYieldsCorrectScrollAndScaleForWidthEqualsDevice ...@@ -2042,6 +2042,22 @@ TEST_F(WebFrameResizeTest, ResizeYieldsCorrectScrollAndScaleForWidthEqualsDevice
url, initialPageScaleFactor, scrollOffset, viewportSize, shouldScaleRelativeToViewportWidth); url, initialPageScaleFactor, scrollOffset, viewportSize, shouldScaleRelativeToViewportWidth);
} }
TEST_F(WebFrameResizeTest, ResizeYieldsCorrectScrollAndScaleForMinimumScale)
{
// This tests a scenario where minimum-scale is set to 1.0, but some element
// on the page is slightly larger than the portrait width, so our "natural"
// minimum-scale would be lower. In that case, we should stick to 1.0 scale
// on rotation and not do anything strange.
const char* url = "resize_scroll_minimum_scale.html";
const float initialPageScaleFactor = 1;
const WebSize scrollOffset(0, 0);
const WebSize viewportSize(240, 320);
const bool shouldScaleRelativeToViewportWidth = false;
testResizeYieldsCorrectScrollAndScale(
url, initialPageScaleFactor, scrollOffset, viewportSize, shouldScaleRelativeToViewportWidth);
}
TEST_F(WebFrameResizeTest, ResizeYieldsCorrectScrollAndScaleForFixedWidth) TEST_F(WebFrameResizeTest, ResizeYieldsCorrectScrollAndScaleForFixedWidth)
{ {
// With a fixed width, pageScaleFactor scales by the relative change in viewport width. // With a fixed width, pageScaleFactor scales by the relative change in viewport width.
......
<html>
<head>
<meta name="viewport" content="width=device-width, minimum-scale=1">
</head>
<body style="margin:0px; padding:0px"><div style="width:280px; background-color:red">Wide div forcing page to widen only in portrait orientation (240x320px)</div></body>
</html>
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment