Source code

Revision control

Copy as Markdown

Other Tools

Test Info: Warnings

<!DOCTYPE html>
<html>
<head>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-actions.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<script src="/dom/events/scrolling/scroll_support.js"></script>
<script src="/css/css-scroll-snap-2/resources/common.js"></script>
<script src="/css/css-scroll-snap-2/resources/user-scroll-common.js"></script>
</head>
<body>
<style>
:root {
scroll-snap-type: y mandatory;
}
#scroller {
height: 400px;
width: 400px;
position: relative;
overflow: scroll;
scroll-snap-type: y mandatory;
border: solid 1px black;
}
.box {
position: absolute;
left: 150px;
height: 80vh;
width: 100px;
border: solid 1px white;
}
.snap {
scroll-snap-align: start;
}
.blue {
background-color: blue;
}
.green {
background-color: green;
}
.yellow {
background-color: yellow;
}
#snap_area_1 {
top: 0px;
}
#snap_area_2 {
top: calc(80vh + 2px); /* height of snap_area_1 + its borders. */
}
#snap_area_3 {
top: calc(160vh + 4px); /* heights of snap areas 1 & 2 + their borders */
}
.large_space {
height: 400vh;
width: 400vw;
position: absolute;
}
</style>
<div class="large_space"></div>
<div id="snap_area_1" class="blue snap box"></div>
<div id="snap_area_2" class="green snap box"></div>
<div id="snap_area_3" class="yellow snap box"></div>
<script>
const scroller = document.scrollingElement;
const snap_area_2 = document.getElementById("snap_area_2");
const snap_area_1 = document.getElementById("snap_area_1");
// Touch scroll test.
promise_test(async (t) => {
await waitForCompositorCommit();
const scroller_middle = Math.round(scroller.clientWidth / 2);
const test_data = {
scroller: scroller,
scrolling_function: async () => {
const start_pos = { x: scroller_middle, y: snap_area_2.offsetTop };
const end_pos = { x: scroller_middle, y: 0 };
await snap_event_touch_scroll_helper(start_pos, end_pos);
},
expected_snap_targets: { block: snap_area_2, inline: null },
expected_scroll_offsets: {
x: 0,
y: snap_area_2.offsetTop
}
};
await test_snap_event(t, test_data, "scrollsnapchanging");
}, "touch scrolling fires scrollsnapchanging.");
// Wheel scroll test.
promise_test(async (t) => {
await waitForCompositorCommit();
const test_data = {
scroller: scroller,
scrolling_function: async () => {
await new test_driver.Actions().scroll(0, 0, 0,
Math.round(snap_area_2.offsetTop / 2) + 1).send();
},
expected_snap_targets: { block: snap_area_2, inline: null },
expected_scroll_offsets: {
x: 0,
y: snap_area_2.offsetTop
}
};
await test_snap_event(t, test_data, "scrollsnapchanging");
}, "mouse wheel scroll triggers scrollsnapchanging.");
// Scrollbar drag test.
promise_test(async (t) => {
await waitForCompositorCommit();
// Skip test on platforms that do not have a visible scrollbar (e.g.
// overlay scrollbar).
const scrollbar_width = window.innerWidth -
document.documentElement.clientWidth;
const test_data = {
scroller: scroller,
scrolling_function: async () => {
const scrollbar_to_scroller_ratio =
getScrollbarToScrollerRatio(scroller);
// Scroll by just over half of the top box's height.
const drag_amt = (snap_area_2.offsetTop / 2 + 1) *
scrollbar_to_scroller_ratio;
await snap_event_scrollbar_drag_helper(scroller, scrollbar_width, drag_amt);
},
expected_snap_targets: { block: snap_area_2, inline: null },
expected_scroll_offsets: {
x: 0,
y: snap_area_2.offsetTop
}
};
await test_snap_event(t, test_data, "scrollsnapchanging");
}, "scrollbar dragging fires scrollsnapchanging.");
// Keyboard test.
promise_test(async (t) => {
await waitForCompositorCommit();
const test_data = {
scroller: scroller,
scrolling_function: async () => {
scroller.focus();
window.test_driver.send_keys(document.documentElement, '\ue015'/*ArrowDown*/);
},
expected_snap_targets: { block: snap_area_2, inline: null },
expected_scroll_offsets: {
x: 0,
y: snap_area_2.offsetTop
}
};
await test_snap_event(t, test_data, "scrollsnapchanging");
}, "keyboard scroll triggers scrollsnapchanging.");
// Touch scroll test (onscrollsnapchanging variant).
promise_test(async (t) => {
await waitForCompositorCommit();
const scroller_middle = Math.round(scroller.clientWidth / 2);
const test_data = {
scroller: scroller,
scrolling_function: async () => {
const start_pos = { x: scroller_middle, y: snap_area_2.offsetTop };
const end_pos = { x: scroller_middle, y: 0 };
await snap_event_touch_scroll_helper(start_pos, end_pos);
},
expected_snap_targets: { block: snap_area_2, inline: null },
expected_scroll_offsets: {
x: 0,
y: snap_area_2.offsetTop
}
};
await test_snap_event(t, test_data, "scrollsnapchanging",
/*use_onsnap_memeber*/true);
}, "touch scrolling fires Document.onscrollsnapchanging.");
// Touch scroll test: peek at snap_area_2 and then drag back to
// snap_area_1.
promise_test(async (t) => {
await waitForScrollReset(t, scroller);
await waitForCompositorCommit();
const pos_x = Math.round(scroller.clientWidth / 2);
const start_pos_y = Math.round(snap_area_2.offsetTop);
let evts_promise = waitForEventsUntil(document, "scrollsnapchanging",
waitForScrollendEventNoTimeout(document));
await new test_driver.Actions()
.addPointer("TestPointer", "touch")
.pointerMove(pos_x, start_pos_y)
.pointerDown()
.addTick()
.pause(200)
// Drag up to y=0, which should trigger a scrollsnapchanging event.
.pointerMove(pos_x, 0)
.addTick()
.pause(200)
// Drag down again to start position, which should trigger a
// scrollsnapchanging event.
.pointerMove(pos_x, start_pos_y)
.pointerUp()
.send();
let evts = await evts_promise;
assert_equals(evts.length, 2, "2 scrollsnapchanging events are seens");
assertSnapEvent(evts[0], { block: snap_area_2, inline: null });
assertSnapEvent(evts[1], { block: snap_area_1, inline: null });
}, "scrollsnapchanging fires as scroll moves through different snap targets.");
// scrollsnapchanging doesn't fire test.
promise_test(async (t) => {
test_no_scrollsnapchanging(t, scroller, 10);
}, "scrollsnapchanging doesn't fire if scroll doesn't reach different snap " +
"targets.");
</script>
</body>
</html>