<!DOCTYPE html>
<script src="../../resources/gesture-util.js"></script>
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<style>
html {
scroll-snap-type: both proximity;
}
body {
overflow: scroll;
height: 300px;
width: 300px;
margin: 0px;
padding: 0px;
}
#container {
margin: 0px;
padding: 0px;
width: 600px;
height: 2000px;
}
#area {
position: relative;
left: 100px;
top: 700px;
width: 200px;
height: 200px;
scroll-snap-align: start;
}
</style>
<div id="container">
<div id="area"></div>
</div>
<script>
const SOURCE_TYPE = navigator.platform.indexOf('Mac') == 0
? GestureSourceType.MOUSE_INPUT
: GestureSourceType.TOUCH_INPUT
async function set_and_scroll_and_snap(
initial_position,
scroll_delta,
scroll_direction,
layout_viewport_y,
visual_viewport_y) {
const scale_factor = 2;
internals.setPageScaleFactor(scale_factor);
window.scrollTo(0, initial_position);
internals.setVisualViewportOffset(0, 0);
assert_equals(window.visualViewport.scale, 2);
assert_equals(window.scrollY, initial_position);
assert_equals(window.visualViewport.offsetTop, 0);
const x = 200;
const y = 200;
const scrollPromise = waitForScrollEvent(document);
await smoothScroll(scale_factor * scroll_delta,
x,
y,
SOURCE_TYPE,
scroll_direction,
SPEED_INSTANT);
await scrollPromise;
await waitForAnimationEndTimeBased(() => {
return window.scrollY + window.visualViewport.offsetTop;
});
assert_approx_equals(window.scrollY, layout_viewport_y, 1);
assert_approx_equals(window.visualViewport.offsetTop, visual_viewport_y, 1);
}
promise_test(t => {
// The starting scroll position is 1000.
// We scroll upwards 400 to land on 600.
// As the visual_viewport's position is 0 and has room of 300 to scroll
// downwards, the layout_viewport can stay at 600 and only the visual_viewport
// needs to scroll to 100.
return set_and_scroll_and_snap(1000, 400, 'up', 600, 100);
}, "Snap scrolls visual viewport when it's scrollable.");
promise_test(t => {
// The starting scroll position is 1000.
// We scroll upwards 200 to land on 800.
// As the visual_viewport's position is 0 and has no room to scroll upwards,
// the layout_viewport is scrolled to 700 to snap to #area.
return set_and_scroll_and_snap(1000, 200, 'up', 700, 0);
}, "Snap scrolls layout viewport when visual viewport has reached its scroll extent.");
promise_test(t => {
// The starting scroll position is 300.
// We scroll downwards 250 to bring visual_viewport to 250, while still keeping
// layout_viewport at 300. So the total offset is 550.
// As the visual_viewport's position is 250 and only has room of 50 to scroll
// downwards, the layout_viewport needs to scroll another 100 downwards to
// make the total offset as 700.
return set_and_scroll_and_snap(300, 250, 'down', 400, 300);
}, "Snap scrolls both layout and visual viewports when visual viewport is " +
"scrollable but does not has enough room to reach the snap position.");
</script>