Index: third_party/WebKit/Source/web/tests/VisualViewportTest.cpp |
diff --git a/third_party/WebKit/Source/web/tests/VisualViewportTest.cpp b/third_party/WebKit/Source/web/tests/VisualViewportTest.cpp |
index 26e906beb3ba2a789ed2a70caa29e0eef70d22cf..ae80af5d07e714e8c721fb4bc9527e35a6a457da 100644 |
--- a/third_party/WebKit/Source/web/tests/VisualViewportTest.cpp |
+++ b/third_party/WebKit/Source/web/tests/VisualViewportTest.cpp |
@@ -1111,6 +1111,64 @@ TEST_P(ParameterizedVisualViewportTest, TestClientNotifiedOfScrollEvents) |
webViewImpl()->mainFrameImpl()->setClient(oldClient); |
} |
+// Tests that calling scroll into view on a visible element doesn cause |
+// a scroll due to a fractional offset. Bug crbug.com/463356. |
+TEST_P(ParameterizedVisualViewportTest, ScrollIntoViewFractionalOffset) |
+{ |
+ initializeWithAndroidSettings(); |
+ |
+ webViewImpl()->resize(IntSize(1000, 1000)); |
+ |
+ registerMockedHttpURLLoad("scroll-into-view.html"); |
+ navigateTo(m_baseURL + "scroll-into-view.html"); |
+ |
+ FrameView& frameView = *webViewImpl()->mainFrameImpl()->frameView(); |
+ ScrollableArea* layoutViewportScrollableArea = frameView.layoutViewportScrollableArea(); |
+ VisualViewport& visualViewport = frame()->page()->frameHost().visualViewport(); |
+ Element* inputBox = frame()->document()->getElementById("box"); |
+ |
+ webViewImpl()->setPageScaleFactor(2); |
+ |
+ // The element is already in the view so the scrollIntoView shouldn't move |
+ // the viewport at all. |
+ webViewImpl()->setVisualViewportOffset(WebFloatPoint(250.25f, 100.25f)); |
+ layoutViewportScrollableArea->setScrollPosition(DoublePoint(0, 900.75), ProgrammaticScroll); |
+ inputBox->scrollIntoViewIfNeeded(false); |
+ |
+ EXPECT_POINT_EQ(DoublePoint(0, 900.75), layoutViewportScrollableArea->scrollPositionDouble()); |
+ EXPECT_POINT_EQ(FloatPoint(250.25f, 100.25f), visualViewport.location()); |
+ |
+ // Change the fractional part of the frameview to one that would round down. |
+ layoutViewportScrollableArea->setScrollPosition(DoublePoint(0, 900.125), ProgrammaticScroll); |
+ inputBox->scrollIntoViewIfNeeded(false); |
+ |
+ EXPECT_POINT_EQ(DoublePoint(0, 900.125), layoutViewportScrollableArea->scrollPositionDouble()); |
+ EXPECT_POINT_EQ(FloatPoint(250.25f, 100.25f), visualViewport.location()); |
+ |
+ // Repeat both tests above with the visual viewport at a high fractional. |
+ webViewImpl()->setVisualViewportOffset(WebFloatPoint(250.875f, 100.875f)); |
+ layoutViewportScrollableArea->setScrollPosition(DoublePoint(0, 900.75), ProgrammaticScroll); |
+ inputBox->scrollIntoViewIfNeeded(false); |
+ |
+ EXPECT_POINT_EQ(DoublePoint(0, 900.75), layoutViewportScrollableArea->scrollPositionDouble()); |
+ EXPECT_POINT_EQ(FloatPoint(250.875f, 100.875f), visualViewport.location()); |
+ |
+ // Change the fractional part of the frameview to one that would round down. |
+ layoutViewportScrollableArea->setScrollPosition(DoublePoint(0, 900.125), ProgrammaticScroll); |
+ inputBox->scrollIntoViewIfNeeded(false); |
+ |
+ EXPECT_POINT_EQ(DoublePoint(0, 900.125), layoutViewportScrollableArea->scrollPositionDouble()); |
+ EXPECT_POINT_EQ(FloatPoint(250.875f, 100.875f), visualViewport.location()); |
+ |
+ // Both viewports with a 0.5 fraction. |
+ webViewImpl()->setVisualViewportOffset(WebFloatPoint(250.5f, 100.5f)); |
+ layoutViewportScrollableArea->setScrollPosition(DoublePoint(0, 900.5), ProgrammaticScroll); |
+ inputBox->scrollIntoViewIfNeeded(false); |
+ |
+ EXPECT_POINT_EQ(DoublePoint(0, 900.5), layoutViewportScrollableArea->scrollPositionDouble()); |
+ EXPECT_POINT_EQ(FloatPoint(250.5f, 100.5f), visualViewport.location()); |
+} |
+ |
// Top controls can make an unscrollable page temporarily scrollable, causing |
// a scroll clamp when the page is resized. Make sure this bug is fixed. |
// crbug.com/437620 |
@@ -1407,6 +1465,84 @@ TEST_P(ParameterizedVisualViewportTest, ElementBoundsInViewportSpaceAccountsForV |
EXPECT_SIZE_EQ(expectedBounds.size(), boundsInViewport.size()); |
} |
+// Test that the various window.scroll and document.body.scroll properties and |
+// methods work unchanged from the pre-virtual viewport mode. |
+TEST_P(ParameterizedVisualViewportTest, bodyAndWindowScrollPropertiesAccountForViewport) |
+{ |
+ initializeWithAndroidSettings(); |
+ |
+ webViewImpl()->resize(IntSize(200, 300)); |
+ |
+ // Load page with no main frame scrolling. |
+ registerMockedHttpURLLoad("200-by-300-viewport.html"); |
+ navigateTo(m_baseURL + "200-by-300-viewport.html"); |
+ |
+ VisualViewport& visualViewport = frame()->page()->frameHost().visualViewport(); |
+ visualViewport.setScale(2); |
+ |
+ // Chrome's quirky behavior regarding viewport scrolling means we treat the |
+ // body element as the viewport and don't apply scrolling to the HTML |
+ // element. |
+ RuntimeEnabledFeatures::setScrollTopLeftInteropEnabled(false); |
+ |
+ LocalDOMWindow* window = webViewImpl()->mainFrameImpl()->frame()->localDOMWindow(); |
+ window->scrollTo(100, 150); |
+ EXPECT_EQ(100, window->scrollX()); |
+ EXPECT_EQ(150, window->scrollY()); |
+ EXPECT_FLOAT_POINT_EQ(FloatPoint(100, 150), visualViewport.location()); |
+ |
+ HTMLElement* body = toHTMLBodyElement(window->document()->body()); |
+ body->setScrollLeft(50); |
+ body->setScrollTop(130); |
+ EXPECT_EQ(50, body->scrollLeft()); |
+ EXPECT_EQ(130, body->scrollTop()); |
+ EXPECT_FLOAT_POINT_EQ(FloatPoint(50, 130), visualViewport.location()); |
+ |
+ HTMLElement* documentElement = toHTMLElement(window->document()->documentElement()); |
+ documentElement->setScrollLeft(40); |
+ documentElement->setScrollTop(50); |
+ EXPECT_EQ(0, documentElement->scrollLeft()); |
+ EXPECT_EQ(0, documentElement->scrollTop()); |
+ EXPECT_FLOAT_POINT_EQ(FloatPoint(50, 130), visualViewport.location()); |
+ |
+ visualViewport.setLocation(FloatPoint(10, 20)); |
+ EXPECT_EQ(10, body->scrollLeft()); |
+ EXPECT_EQ(20, body->scrollTop()); |
+ EXPECT_EQ(0, documentElement->scrollLeft()); |
+ EXPECT_EQ(0, documentElement->scrollTop()); |
+ EXPECT_EQ(10, window->scrollX()); |
+ EXPECT_EQ(20, window->scrollY()); |
+ |
+ // Turning on the standards-compliant viewport scrolling impl should make |
+ // the document element the viewport and not body. |
+ RuntimeEnabledFeatures::setScrollTopLeftInteropEnabled(true); |
+ |
+ window->scrollTo(100, 150); |
+ EXPECT_EQ(100, window->scrollX()); |
+ EXPECT_EQ(150, window->scrollY()); |
+ EXPECT_FLOAT_POINT_EQ(FloatPoint(100, 150), visualViewport.location()); |
+ |
+ body->setScrollLeft(50); |
+ body->setScrollTop(130); |
+ EXPECT_EQ(0, body->scrollLeft()); |
+ EXPECT_EQ(0, body->scrollTop()); |
+ EXPECT_FLOAT_POINT_EQ(FloatPoint(100, 150), visualViewport.location()); |
+ |
+ documentElement->setScrollLeft(40); |
+ documentElement->setScrollTop(50); |
+ EXPECT_EQ(40, documentElement->scrollLeft()); |
+ EXPECT_EQ(50, documentElement->scrollTop()); |
+ EXPECT_FLOAT_POINT_EQ(FloatPoint(40, 50), visualViewport.location()); |
+ |
+ visualViewport.setLocation(FloatPoint(10, 20)); |
+ EXPECT_EQ(0, body->scrollLeft()); |
+ EXPECT_EQ(0, body->scrollTop()); |
+ EXPECT_EQ(10, documentElement->scrollLeft()); |
+ EXPECT_EQ(20, documentElement->scrollTop()); |
+ EXPECT_EQ(10, window->scrollX()); |
+ EXPECT_EQ(20, window->scrollY()); |
+} |
+ |
// Tests that when a new frame is created, it is created with the intended |
// size (i.e. viewport at minimum scale, 100x200 / 0.5). |
TEST_P(ParameterizedVisualViewportTest, TestMainFrameInitializationSizing) |