// Tests that scrolling the viewport when the layout viewport is // !userInputScrollable (as happens when overflow:hidden is set) works // correctly, that is, the visual viewport can scroll, but not the layout. TEST_F(RootFrameViewportTest, UserInputScrollable) { IntSize viewportSize(100, 150); RootFrameViewStub* layoutViewport = RootFrameViewStub::create(viewportSize, IntSize(200, 300)); VisualViewportStub* visualViewport = VisualViewportStub::create(viewportSize, viewportSize); ScrollableArea* rootFrameViewport = RootFrameViewport::create(*visualViewport, *layoutViewport); visualViewport->setScale(2); // Disable just the layout viewport's horizontal scrolling, the // RootFrameViewport should remain scrollable overall. layoutViewport->setUserInputScrollable(false, true); visualViewport->setUserInputScrollable(true, true); EXPECT_TRUE(rootFrameViewport->userInputScrollable(HorizontalScrollbar)); EXPECT_TRUE(rootFrameViewport->userInputScrollable(VerticalScrollbar)); // Layout viewport shouldn't scroll since it's not horizontally scrollable, // but visual viewport should. rootFrameViewport->userScroll(ScrollByPixel, FloatSize(300, 0)); EXPECT_SIZE_EQ(ScrollOffset(0, 0), layoutViewport->getScrollOffset()); EXPECT_SIZE_EQ(ScrollOffset(50, 0), visualViewport->getScrollOffset()); EXPECT_SIZE_EQ(ScrollOffset(50, 0), rootFrameViewport->getScrollOffset()); // Vertical scrolling should be unaffected. rootFrameViewport->userScroll(ScrollByPixel, FloatSize(0, 300)); EXPECT_SIZE_EQ(ScrollOffset(0, 150), layoutViewport->getScrollOffset()); EXPECT_SIZE_EQ(ScrollOffset(50, 75), visualViewport->getScrollOffset()); EXPECT_SIZE_EQ(ScrollOffset(50, 225), rootFrameViewport->getScrollOffset()); // Try the same checks as above but for the vertical direction. // =============================================== rootFrameViewport->setScrollOffset(ScrollOffset(), ProgrammaticScroll); // Disable just the layout viewport's vertical scrolling, the // RootFrameViewport should remain scrollable overall. layoutViewport->setUserInputScrollable(true, false); visualViewport->setUserInputScrollable(true, true); EXPECT_TRUE(rootFrameViewport->userInputScrollable(HorizontalScrollbar)); EXPECT_TRUE(rootFrameViewport->userInputScrollable(VerticalScrollbar)); // Layout viewport shouldn't scroll since it's not vertically scrollable, // but visual viewport should. rootFrameViewport->userScroll(ScrollByPixel, FloatSize(0, 300)); EXPECT_SIZE_EQ(ScrollOffset(0, 0), layoutViewport->getScrollOffset()); EXPECT_SIZE_EQ(ScrollOffset(0, 75), visualViewport->getScrollOffset()); EXPECT_SIZE_EQ(ScrollOffset(0, 75), rootFrameViewport->getScrollOffset()); // Horizontal scrolling should be unaffected. rootFrameViewport->userScroll(ScrollByPixel, FloatSize(300, 0)); EXPECT_SIZE_EQ(ScrollOffset(100, 0), layoutViewport->getScrollOffset()); EXPECT_SIZE_EQ(ScrollOffset(50, 75), visualViewport->getScrollOffset()); EXPECT_SIZE_EQ(ScrollOffset(150, 75), rootFrameViewport->getScrollOffset()); }
// Make sure scrolls using the scroll animator (scroll(), setScrollOffset()) // work correctly when one of the subviewports is explicitly scrolled without // using the // RootFrameViewport interface. TEST_F(RootFrameViewportTest, TestScrollAnimatorUpdatedBeforeScroll) { IntSize viewportSize(100, 150); RootFrameViewStub* layoutViewport = RootFrameViewStub::create(viewportSize, IntSize(200, 300)); VisualViewportStub* visualViewport = VisualViewportStub::create(viewportSize, viewportSize); ScrollableArea* rootFrameViewport = RootFrameViewport::create(*visualViewport, *layoutViewport); visualViewport->setScale(2); visualViewport->setScrollOffset(ScrollOffset(50, 75), ProgrammaticScroll); EXPECT_SIZE_EQ(ScrollOffset(50, 75), rootFrameViewport->getScrollOffset()); // If the scroll animator doesn't update, it will still think it's at (0, 0) // and so it may early exit. rootFrameViewport->setScrollOffset(ScrollOffset(0, 0), ProgrammaticScroll); EXPECT_SIZE_EQ(ScrollOffset(0, 0), rootFrameViewport->getScrollOffset()); EXPECT_SIZE_EQ(ScrollOffset(0, 0), visualViewport->getScrollOffset()); // Try again for userScroll() visualViewport->setScrollOffset(ScrollOffset(50, 75), ProgrammaticScroll); EXPECT_SIZE_EQ(ScrollOffset(50, 75), rootFrameViewport->getScrollOffset()); rootFrameViewport->userScroll(ScrollByPixel, FloatSize(-50, 0)); EXPECT_SIZE_EQ(ScrollOffset(0, 75), rootFrameViewport->getScrollOffset()); EXPECT_SIZE_EQ(ScrollOffset(0, 75), visualViewport->getScrollOffset()); // Make sure the layout viewport is also accounted for. rootFrameViewport->setScrollOffset(ScrollOffset(0, 0), ProgrammaticScroll); layoutViewport->setScrollOffset(ScrollOffset(100, 150), ProgrammaticScroll); EXPECT_SIZE_EQ(ScrollOffset(100, 150), rootFrameViewport->getScrollOffset()); rootFrameViewport->userScroll(ScrollByPixel, FloatSize(-100, 0)); EXPECT_SIZE_EQ(ScrollOffset(0, 150), rootFrameViewport->getScrollOffset()); EXPECT_SIZE_EQ(ScrollOffset(0, 150), layoutViewport->getScrollOffset()); }
// Test that the scrollIntoView correctly scrolls the main frame // and visual viewport such that the given rect is centered in the viewport. TEST_F(RootFrameViewportTest, ScrollIntoView) { IntSize viewportSize(100, 150); RootFrameViewStub* layoutViewport = RootFrameViewStub::create(viewportSize, IntSize(200, 300)); VisualViewportStub* visualViewport = VisualViewportStub::create(viewportSize, viewportSize); ScrollableArea* rootFrameViewport = RootFrameViewport::create(*visualViewport, *layoutViewport); // Test that the visual viewport is scrolled if the viewport has been // resized (as is the case when the ChromeOS keyboard comes up) but not // scaled. visualViewport->setViewportSize(IntSize(100, 100)); rootFrameViewport->scrollIntoView(LayoutRect(100, 250, 50, 50), ScrollAlignment::alignToEdgeIfNeeded, ScrollAlignment::alignToEdgeIfNeeded); EXPECT_SIZE_EQ(ScrollOffset(50, 150), layoutViewport->getScrollOffset()); EXPECT_SIZE_EQ(ScrollOffset(0, 50), visualViewport->getScrollOffset()); rootFrameViewport->scrollIntoView(LayoutRect(25, 75, 50, 50), ScrollAlignment::alignToEdgeIfNeeded, ScrollAlignment::alignToEdgeIfNeeded); EXPECT_SIZE_EQ(ScrollOffset(25, 75), layoutViewport->getScrollOffset()); EXPECT_SIZE_EQ(ScrollOffset(0, 0), visualViewport->getScrollOffset()); // Reset the visual viewport's size, scale the page, and repeat the test visualViewport->setViewportSize(IntSize(100, 150)); visualViewport->setScale(2); rootFrameViewport->setScrollOffset(ScrollOffset(), ProgrammaticScroll); rootFrameViewport->scrollIntoView(LayoutRect(50, 75, 50, 75), ScrollAlignment::alignToEdgeIfNeeded, ScrollAlignment::alignToEdgeIfNeeded); EXPECT_SIZE_EQ(ScrollOffset(0, 0), layoutViewport->getScrollOffset()); EXPECT_SIZE_EQ(ScrollOffset(50, 75), visualViewport->getScrollOffset()); rootFrameViewport->scrollIntoView(LayoutRect(190, 290, 10, 10), ScrollAlignment::alignToEdgeIfNeeded, ScrollAlignment::alignToEdgeIfNeeded); EXPECT_SIZE_EQ(ScrollOffset(100, 150), layoutViewport->getScrollOffset()); EXPECT_SIZE_EQ(ScrollOffset(50, 75), visualViewport->getScrollOffset()); // Scrolling into view the viewport rect itself should be a no-op. visualViewport->setViewportSize(IntSize(100, 100)); visualViewport->setScale(1.5f); visualViewport->setScrollOffset(ScrollOffset(0, 10), ProgrammaticScroll); layoutViewport->setScrollOffset(ScrollOffset(50, 50), ProgrammaticScroll); rootFrameViewport->setScrollOffset(rootFrameViewport->getScrollOffset(), ProgrammaticScroll); rootFrameViewport->scrollIntoView( LayoutRect(rootFrameViewport->visibleContentRect(ExcludeScrollbars)), ScrollAlignment::alignToEdgeIfNeeded, ScrollAlignment::alignToEdgeIfNeeded); EXPECT_SIZE_EQ(ScrollOffset(50, 50), layoutViewport->getScrollOffset()); EXPECT_SIZE_EQ(ScrollOffset(0, 10), visualViewport->getScrollOffset()); rootFrameViewport->scrollIntoView( LayoutRect(rootFrameViewport->visibleContentRect(ExcludeScrollbars)), ScrollAlignment::alignCenterAlways, ScrollAlignment::alignCenterAlways); EXPECT_SIZE_EQ(ScrollOffset(50, 50), layoutViewport->getScrollOffset()); EXPECT_SIZE_EQ(ScrollOffset(0, 10), visualViewport->getScrollOffset()); rootFrameViewport->scrollIntoView( LayoutRect(rootFrameViewport->visibleContentRect(ExcludeScrollbars)), ScrollAlignment::alignTopAlways, ScrollAlignment::alignTopAlways); EXPECT_SIZE_EQ(ScrollOffset(50, 50), layoutViewport->getScrollOffset()); EXPECT_SIZE_EQ(ScrollOffset(0, 10), visualViewport->getScrollOffset()); }