| <!DOCTYPE html> |
| <style> |
| body, html { |
| width: 100%; |
| height: 100%; |
| margin: 0px; |
| } |
| |
| #root-scroller::-webkit-scrollbar { |
| width: 0px; |
| height: 0px; |
| } |
| |
| #root-scroller { |
| width: 100%; |
| height: 100%; |
| overflow: scroll; |
| position: absolute; |
| left: 0; |
| top: 0; |
| background-color: red; |
| scroll-snap-type: y mandatory; |
| } |
| |
| .spacer { |
| width: 100%; |
| height: 100%; |
| } |
| |
| #initial-snap-area { |
| width: 200px; |
| height: 50%; |
| background-color: blue; |
| scroll-snap-align: start; |
| } |
| |
| #snap-area { |
| width: 200px; |
| height: 50%; |
| background-color: blue; |
| scroll-snap-align: start; |
| } |
| </style> |
| |
| <script src="../../../resources/gesture-util.js"></script> |
| <script src="../../../resources/testharness.js"></script> |
| <script src="../../../resources/testharnessreport.js"></script> |
| |
| <div id="root-scroller"> |
| <div id="initial-snap-area"></div> |
| <div class="spacer" style="background-color: PaleGreen"></div> |
| <div class="spacer" style="background-color: PaleGreen"></div> |
| <div id="snap-area"></div> |
| </div> |
| |
| <script> |
| if (window.internals) { |
| internals.runtimeFlags.implicitRootScrollerEnabled = true; |
| // Jump directly to the snap position. Otherwise, we need to wait until X ms |
| // goes by without a change to the scroll position, which leads to either slow |
| // running tests or flakes when the test machines get bogged down. |
| internals.settings.setScrollAnimatorEnabled(false); |
| } |
| |
| const root_scroller = document.getElementById("root-scroller"); |
| const snap_area = document.getElementById("snap-area"); |
| const initial_area = document.getElementById("initial-snap-area"); |
| |
| async function arrowDown() { |
| // Click on the middle of the viewport. |
| const initial_scroll_position = { |
| x: visualViewport.width / 2, |
| y: visualViewport.height / 2 |
| } |
| await mouseClickOn(initial_scroll_position.x, initial_scroll_position.y); |
| await new Promise((resolve, reject) => { |
| if (window.eventSender) { |
| eventSender.keyDown("ArrowDown"); |
| resolve(); |
| } |
| else { |
| reject('This test requires window.eventSender'); |
| } |
| }); |
| } |
| |
| // Tests that the visual viewport is affected when scrolling the global root |
| // scroller with an arrow key. The snap area is located at the bottom of the layout |
| // viewport, so the layout viewport cannot align with the snap area. |
| // However, when it becomes the global root scroller we should be scrolling the |
| // visual viewport too to align with the snap area. |
| promise_test(async function () { |
| const scale_factor = 2; |
| internals.setPageScaleFactor(scale_factor); |
| internals.setVisualViewportOffset(0, 0); |
| |
| assert_equals(visualViewport.scale, 2); |
| assert_equals(visualViewport.offsetTop, 0); |
| |
| await waitForCompositorCommit(); |
| |
| assert_equals(window.internals.effectiveRootScroller(document), |
| root_scroller, |
| "#root-scroller must be the effective root scroller"); |
| // Should be snapped to the closer snap area (0,0) on the initial layout. |
| assert_equals(visualViewport.offsetTop + root_scroller.scrollTop, |
| initial_area.offsetTop); |
| |
| const scrollWatcher = waitForScrollEvent(root_scroller); |
| await arrowDown(); |
| await scrollWatcher; |
| |
| // The offset of the visual viewport and the layout viewport combined should |
| // be at the snap point. |
| assert_equals(visualViewport.offsetTop + root_scroller.scrollTop, |
| snap_area.offsetTop, "Visual viewport offset combined with the scroller's \ |
| scroll offset should add to the snap area's position."); |
| |
| }, "Snapping the root scroller after arrow key scrolling should affect the \ |
| visual viewport offset."); |
| </script> |