diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 00:47:55 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 00:47:55 +0000 |
commit | 26a029d407be480d791972afb5975cf62c9360a6 (patch) | |
tree | f435a8308119effd964b339f76abb83a57c29483 /testing/web-platform/tests/css/css-scroll-snap-2/snapchanged | |
parent | Initial commit. (diff) | |
download | firefox-26a029d407be480d791972afb5975cf62c9360a6.tar.xz firefox-26a029d407be480d791972afb5975cf62c9360a6.zip |
Adding upstream version 124.0.1.upstream/124.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'testing/web-platform/tests/css/css-scroll-snap-2/snapchanged')
9 files changed, 1080 insertions, 0 deletions
diff --git a/testing/web-platform/tests/css/css-scroll-snap-2/snapchanged/snapchanged-after-layout-change.tentative.html b/testing/web-platform/tests/css/css-scroll-snap-2/snapchanged/snapchanged-after-layout-change.tentative.html new file mode 100644 index 0000000000..293400edda --- /dev/null +++ b/testing/web-platform/tests/css/css-scroll-snap-2/snapchanged/snapchanged-after-layout-change.tentative.html @@ -0,0 +1,145 @@ +<!DOCTYPE html> +<html> + +<head> + <link rel="help" href="https://drafts.csswg.org/css-scroll-snap-2/#snap-events" /> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> + <script src="/dom/events/scrolling/scroll_support.js"></script> + <script src="/css/css-scroll-snap-2/resources/common.js"></script> + <script src="/web-animations/testcommon.js"></script> +</head> + +<body> + <style> + #scroller { + overflow: scroll; + scroll-snap-type: y mandatory; + height: 200px; + width: 200px; + border: solid 1px; + position: absolute; + } + + .snap_area { + position: absolute; + width: 100px; + left: calc(50% - 50px); + } + + #outer_snap_area { + scroll-snap-align: start none; + height: 1000px; + background-color: blue; + } + + #inner_snap_area { + scroll-snap-align: start none; + height: 100px; + top: 100px; + background-color: yellow; + } + </style> + <div id="scroller"> + <div id="outer_snap_area" class="snap_area"></div> + <div id="inner_snap_area" class="snap_area"></div> + </div> + <script> + let scroller = document.getElementById("scroller"); + + async function reset(t) { + inner_snap_area.style.height = "100px"; + inner_snap_area.style.scrollSnapAlign = "start none"; + outer_snap_area.style.scrollSnapAlign = "start none"; + scroller.style.scrollSnapType = "y mandatory"; + await resetTargetScrollState(t, scroller); + } + + async function setup(t) { + checkSnapEventSupport("snapchanged"); + await reset(t); + await waitForCompositorCommit(); + assert_equals(scroller.scrollTop, 0, "test precondition: scroller " + + "is not scrolled."); + } + + promise_test(async (t) => { + await setup(t); + let target_snap_position = inner_snap_area.offsetTop + + inner_snap_area.offsetHeight; + // Scroll to an offset close to the bottom of the inner snap area and + // expect to snap to an offset just below this snap area. + let scrollend_promise = waitForScrollendEventNoTimeout(scroller); + scroller.scrollTo(0, target_snap_position - 10); + await scrollend_promise; + assert_equals(scroller.scrollTop, target_snap_position, + "scroller snaps to just below the inner snap area."); + // We are just below the inner snap area. Increase its height so that it + // is larger than the snapport and straddled by the snapport. Verify + // that we snap to its bottom. + let snapchanged_promise = waitForSnapChangedEvent(scroller); + inner_snap_area.style.height = + `${scroller.clientHeight + inner_snap_area.clientHeight - 10}px`; + const evt = await snapchanged_promise; + assertSnapEvent(evt, [outer_snap_area.id, inner_snap_area.id]); + target_snap_position = inner_snap_area.offsetTop + + inner_snap_area.offsetHeight - scroller.clientHeight; + assert_equals(scroller.scrollTop, target_snap_position, + "scroller snaps to the bottom of the smaller snap area (which is " + + "now covering)."); + }, "snapchanged fires after snap area is snapped to upon layout change."); + + promise_test(async (t) => { + await setup(t); + let target_snap_position = inner_snap_area.offsetTop + + inner_snap_area.offsetHeight; + // Scroll to an offset close to the bottom of the inner snap area and + // expect to snap to an offset just below this snap area. + let scrollend_promise = waitForScrollendEventNoTimeout(scroller); + scroller.scrollTo(0, target_snap_position - 10); + await scrollend_promise; + assert_equals(scroller.scrollTop, target_snap_position, + "scroller snaps to just below the inner snap area."); + // We are just below the inner snap area. Increase its height so that it + // is larger than the snapport making the current scroll position + // a valid covering position within the inner snap area. + let snapchanged_promise = waitForSnapChangedEvent(scroller, false); + inner_snap_area.style.height = + `${scroller.clientHeight + inner_snap_area.clientHeight + 10}px`; + const evt = await snapchanged_promise; + assertSnapEvent(evt, [outer_snap_area.id, inner_snap_area.id]); + assert_equals(scroller.scrollTop, target_snap_position, + "scroller maintains offset which is now covering within inner area"); + }, "snapchanged fires after snap area is snapped to upon layout change " + + "without scroll."); + + promise_test(async(t) => { + await setup(t); + await waitForCompositorCommit(); + let snapchanged_promise = waitForSnapChangedEvent(scroller, false); + scroller.style.scrollSnapType = "none"; + let evt = await snapchanged_promise; + assertSnapEvent(evt, []); + snapchanged_promise = waitForSnapChangedEvent(scroller, false); + scroller.style.scrollSnapType = "y mandatory"; + evt = await snapchanged_promise; + assertSnapEvent(evt, [outer_snap_area.id]); + }, "snapchanged fires when container stops snapping"); + + promise_test(async(t) => { + await setup(t); + await waitForCompositorCommit(); + let snapchanged_promise = waitForSnapChangedEvent(scroller, false); + inner_snap_area.style.scrollSnapAlign = "none"; + outer_snap_area.style.scrollSnapAlign = "none"; + let evt = await snapchanged_promise; + assertSnapEvent(evt, []); + snapchanged_promise = waitForSnapChangedEvent(scroller, false); + inner_snap_area.style.scrollSnapAlign = "start"; + outer_snap_area.style.scrollSnapAlign = "start"; + evt = await snapchanged_promise; + assertSnapEvent(evt, [outer_snap_area.id]); + }, "snapchanged fires when snap container no longer has snap areas"); + </script> +</body> +</html> diff --git a/testing/web-platform/tests/css/css-scroll-snap-2/snapchanged/snapchanged-ensures-dom-order.html b/testing/web-platform/tests/css/css-scroll-snap-2/snapchanged/snapchanged-ensures-dom-order.html new file mode 100644 index 0000000000..10bc73b622 --- /dev/null +++ b/testing/web-platform/tests/css/css-scroll-snap-2/snapchanged/snapchanged-ensures-dom-order.html @@ -0,0 +1,95 @@ +<!DOCTYPE html> +<html> + +<head> + <link rel="help" href="https://drafts.csswg.org/css-scroll-snap-2/#snap-events" /> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> + <script src="/dom/events/scrolling/scroll_support.js"></script> + <script src="/css/css-scroll-snap-2/resources/common.js"></script> + <script src="/web-animations/testcommon.js"></script> + <style> + #scroller { + overflow-y: scroll; + scroll-snap-type: y mandatory; + width: 500px; + height: 500px; + background-color: white; + position: relative; + } + .space_filler { + display: inline-block; + width: 40%; + height: 30%; + background-color: green; + } + .snap_area { + scroll-snap-align: start; + background-color: yellow; + position: absolute; + width: 40%; + height: 30%; + } + + #snap_point_1 { + left: 1px; + } + #snap_point_2 { + left: 80%; + } + #snap_point_3 { + left: 40%; + scroll-snap-align: start; + background-color: yellow; + position: absolute; + width: 40%; + height: 30%; + } + </style> +</head> +<body> + <div id="scroller"> + <div class="space_filler"></div> + <div class="space_filler"></div> + <div class="space_filler"></div> + <div class="space_filler"></div> + <div class="space_filler"></div> + <div class="space_filler"></div> + <div class="space_filler"></div> + <div class="space_filler"></div> + <div id="snap_point_1" class="snap_area"><h1>1</h1></div> + <div id="snap_point_2" class="snap_area"><h1>2</h1></div> + </div> + <script> + promise_test(async (t) => { + checkSnapEventSupport("snapchanged"); + await waitForCompositorCommit(); + const snapchanged_promise = waitForSnapChangedEvent(scroller, false); + const snap_point_3 = document.createElement("div"); + snap_point_3.id = "snap_point_3"; + t.add_cleanup(() => { + snap_point_3.remove(); + }); + scroller.insertBefore(snap_point_3, snap_point_2); + const evt_seen = await snapchanged_promise; + assertSnapEvent(evt_seen, + [snap_point_1.id, snap_point_3.id, snap_point_2.id]); + }, "snapchanged lists snapTargets in DOM order."); + + promise_test(async (t) => { + checkSnapEventSupport("snapchanged"); + await waitForCompositorCommit(); + const unreached_func = t.unreached_func("snapchanged shouldn't fire " + + "since the scroller is snapped to the same elements despite the " + + "dom order change."); + t.add_cleanup(() => { + scroller.removeEventListener("snapchanged", unreached_func); + }) + scroller.addEventListener("snapchanged", unreached_func); + scroller.insertBefore(snap_point_2, snap_point_1); + await waitForCompositorCommit(); + }, "DOM order change doesn't trigger snapchanged if snapped targets " + + "don't change."); + </script> +</body> +</html> diff --git a/testing/web-platform/tests/css/css-scroll-snap-2/snapchanged/snapchanged-on-interrupted-scroll.tentative.html b/testing/web-platform/tests/css/css-scroll-snap-2/snapchanged/snapchanged-on-interrupted-scroll.tentative.html new file mode 100644 index 0000000000..a1d5259451 --- /dev/null +++ b/testing/web-platform/tests/css/css-scroll-snap-2/snapchanged/snapchanged-on-interrupted-scroll.tentative.html @@ -0,0 +1,68 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title> CSS Scroll Snap 2 Test: snapchanged events</title> + <link rel="help" href="https://drafts.csswg.org/css-scroll-snap-2/#snap-events"> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> + <script src="/dom/events/scrolling/scroll_support.js"></script> + </head> + <body> + <style> + #container { + overflow-y: scroll; + height: 500px; + width: 300px; + border: solid 1px black; + position: absolute; + scroll-snap-type: y mandatory; + } + .snap_area { + scroll-snap-align: start; + height: 400px; + width: 200px; + left: 50px; + position: absolute; + } + #area1 { + background-color: blue; + } + #area2 { + top: 400px; + background-color: yellow; + } + #area3 { + top: 800px; + background-color: green; + } + </style> + <div id="container"> + <div id="area1" class="snap_area"></div> + <div id="area2" class="snap_area"></div> + <div id="area3" class="snap_area"></div> + </div> + <script> + promise_test(async (t) => { + await waitForCompositorCommit(); + + container.addEventListener("snapchanged", + t.unreached_func("snapchanged should not fire")); + let reset = () => { + container.scrollTo({ top: 0, behavior: "smooth"}); + container.removeEventListener("scroll", reset); + }; + container.addEventListener("scroll", reset); + + let scrollend_promise = waitForScrollendEventNoTimeout(container); + container.scrollTo({ top: 250, behavior: "smooth"}); + await scrollend_promise; + assert_equals(container.scrollTop, 0, "scroll position is reset"); + + // snapchanged should not fire since the scroll ended on the same snap + // target as the one it started on. + await waitForCompositorCommit(); + }, "snapchanged doesn't fire if interrupting scroll cancels snap"); + </script> + </body> +</html> diff --git a/testing/web-platform/tests/css/css-scroll-snap-2/snapchanged/snapchanged-on-programmatic-root-scroll.tentative.html b/testing/web-platform/tests/css/css-scroll-snap-2/snapchanged/snapchanged-on-programmatic-root-scroll.tentative.html new file mode 100644 index 0000000000..2e33c3c970 --- /dev/null +++ b/testing/web-platform/tests/css/css-scroll-snap-2/snapchanged/snapchanged-on-programmatic-root-scroll.tentative.html @@ -0,0 +1,122 @@ +<!DOCTYPE html> +<html> + +<head> + <meta charset="utf-8"> + <title> CSS Scroll Snap 2 Test: snapchanged event on the root/document</title> + <link rel="help" href="https://drafts.csswg.org/css-scroll-snap-2/#snap-events"> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> + <script src="/css/css-scroll-snap-2/resources/common.js"></script> + <script src="/dom/events/scrolling/scroll_support.js"></script> + <script src="/web-animations/testcommon.js"></script> +</head> + +<body> + <style> + :root { + margin: 0; + padding: 0; + scroll-snap-type: both mandatory; + } + + div { + position: absolute; + margin: 0px; + } + + #spacer { + width: 200vw; + height: 200vh; + } + + .snap_point { + width: 40vw; + height: 40vh; + scroll-snap-align: start; + } + + #snap_point_1 { + left: 0px; + top: 0px; + background-color: red; + } + + #snap_point_2 { + top: 40vh; + left: 40vw; + background-color: orange; + } + + #snap_point_3 { + left: 80vw; + top: 80vh; + background-color: blue; + } + </style> + <div id="spacer"></div> + <div id="snap_point_1" class="snap_point"></div> + <div id="snap_point_2" class="snap_point"></div> + <div id="snap_point_3" class="snap_point"></div> + + <script> + let scroller = document.scrollingElement; + + promise_test(async (t) => { + await waitForCompositorCommit(); + const test_data = { + scroller: scroller, + scrolling_function: () => { + scroller.scrollTo(snap_point_2.offsetLeft, snap_point_2.offsetTop); + }, + expected_snap_targets: [snap_point_2.id], + expected_scroll_offsets: { + x: snap_point_2.offsetLeft, + y: snap_point_2.offsetTop, + } + }; + await test_snapchanged(t, test_data); + }, "snapchanged event fires after snap target changes via scrollTo"); + + promise_test(async (t) => { + checkSnapEventSupport("snapchanged"); + await waitForScrollReset(t, scroller); + await waitForCompositorCommit(); + assert_equals(scroller.scrollTop, 0, + "scroller is initially not scrolled vertically"); + assert_equals(scroller.scrollLeft, 0, + "scroller is initially not scrolled horizontally"); + + let snapchanged_promise = waitForSnapChangedEvent(document, false); + // Set the scroll destination to just a little off (0, 0) so we snap + // back to the top box. + let scroll_top_target = 10; + let scroll_left_target = 10; + + scroller.scrollTo(scroll_left_target, scroll_top_target); + let evt = await snapchanged_promise; + assert_equals(evt, null, "no snapchanges since scroller is back to top"); + // scroller should snap back to (0,0) with no snapchanged event. + assert_equals(scroller.scrollTop, 0, + "scroller snaps back to the top"); + assert_equals(scroller.scrollLeft, 0, + "scroller snaps back to the left"); + + snapchanged_promise = waitForSnapChangedEvent(document); + scroll_top_target = snap_point_2.offsetTop + 10; + scroll_left_target = snap_point_2.offsetLeft + 10; + // This scroll should snap to snap_point_2, so snapchanged should be + // fired. + scroller.scrollTo(scroll_left_target, scroll_top_target); + + evt = await snapchanged_promise; + assertSnapEvent(evt, [snap_point_2.id]); + assert_approx_equals(scroller.scrollTop, snap_point_2.offsetTop, 1, + "scroller snaps to the top of snap_point_2"); + assert_approx_equals(scroller.scrollLeft, snap_point_2.offsetLeft, 1, + "scroller snaps to the left of snap_point_2"); + }, "snapchanged is not fired if snap target doesn't change on " + + "programmatic scroll"); + </script> +</body> +</html> diff --git a/testing/web-platform/tests/css/css-scroll-snap-2/snapchanged/snapchanged-on-programmatic-scroll.tentative.html b/testing/web-platform/tests/css/css-scroll-snap-2/snapchanged/snapchanged-on-programmatic-scroll.tentative.html new file mode 100644 index 0000000000..6082e09013 --- /dev/null +++ b/testing/web-platform/tests/css/css-scroll-snap-2/snapchanged/snapchanged-on-programmatic-scroll.tentative.html @@ -0,0 +1,128 @@ +<!DOCTYPE html> +<html> + +<head> + <meta charset="utf-8"> + <title> CSS Scroll Snap 2 Test: snapchanged events</title> + <link rel="help" href="https://drafts.csswg.org/css-scroll-snap-2/#snap-events"> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> + <script src="/css/css-scroll-snap-2/resources/common.js"></script> + <script src="/dom/events/scrolling/scroll_support.js"></script> + <script src="/web-animations/testcommon.js"></script> +</head> + +<body onload="runTests()"> + <style> + body { + margin: 0px; + } + + div { + position: absolute; + margin: 0px; + } + + #spacer { + width: 2000px; + height: 2000px; + } + + .scroller { + height: 400px; + width: 400px; + overflow: scroll; + scroll-snap-type: both mandatory; + } + + .snap_point { + width: 300px; + height: 300px; + scroll-snap-align: start; + } + + #snap_point_1 { + left: 0px; + top: 0px; + background-color: red; + } + + #snap_point_2 { + top: 300px; + left: 300px; + background-color: orange; + } + + #snap_point_3 { + left: 600px; + top: 600px; + background-color: blue; + } + </style> + <div id="scroller" class="scroller"> + <div id="spacer"></div> + <div id="snap_point_1" class="snap_point"></div> + <div id="snap_point_2" class="snap_point"></div> + <div id="snap_point_3" class="snap_point"></div> + </div> + <script> + function runTests () { + let scroller = document.getElementById("scroller"); + + promise_test(async (t) => { + await waitForCompositorCommit(); + const test_data = { + scroller: scroller, + scrolling_function: () => { + scroller.scrollTo(snap_point_2.offsetLeft, snap_point_2.offsetTop); + }, + expected_snap_targets: [snap_point_2.id], + expected_scroll_offsets: { + x: snap_point_2.offsetLeft, + y: snap_point_2.offsetTop, + } + }; + await test_snapchanged(t, test_data); + }, "snapchanged event fires after snap target changes via scrollTo"); + + promise_test(async (t) => { + checkSnapEventSupport("snapchanged"); + await waitForScrollReset(t, scroller); + await waitForCompositorCommit(); + assert_equals(scroller.scrollTop, 0, + "scroller is initially not scrolled vertically"); + assert_equals(scroller.scrollLeft, 0, + "scroller is initially not scrolled horizontally"); + + let snapchanged_promise = waitForSnapChangedEvent(scroller, false); + // Set the scroll destination to just a little off (0, 0) so we snap + // back to the top box. + let scroll_top_target = 10; + let scroll_left_target = 10; + + scroller.scrollTo(scroll_left_target, scroll_top_target); + let evt = await snapchanged_promise; + assert_equals(evt, null, "no snapchanges since scroller is back to top"); + // scroller should snap back to (0,0) with no snapchanged event. + assert_equals(scroller.scrollTop, 0, "scroller snaps back to the top"); + assert_equals(scroller.scrollLeft, 0, "scroller snaps back to the left"); + + snapchanged_promise = waitForSnapChangedEvent(scroller); + scroll_top_target = snap_point_2.offsetTop + 10; + scroll_left_target = snap_point_2.offsetLeft + 10; + // This scroll should snap to snap_point_2, so snapchanged should be + // fired. + scroller.scrollTo(scroll_left_target, scroll_top_target); + + evt = await snapchanged_promise; + assertSnapEvent(evt, [snap_point_2.id]); + assert_approx_equals(scroller.scrollTop, snap_point_2.offsetTop, 1, + "scroller snaps to the top of snap_point_2"); + assert_approx_equals(scroller.scrollLeft, snap_point_2.offsetLeft, 1, + "scroller snaps to the left of snap_point_2"); + }, "snapchanged is not fired if snap target doesn't change on " + + "programmatic scroll"); + } + </script> +</body> +</html> diff --git a/testing/web-platform/tests/css/css-scroll-snap-2/snapchanged/snapchanged-on-user-root-scroll.tentative.html b/testing/web-platform/tests/css/css-scroll-snap-2/snapchanged/snapchanged-on-user-root-scroll.tentative.html new file mode 100644 index 0000000000..5405d778bf --- /dev/null +++ b/testing/web-platform/tests/css/css-scroll-snap-2/snapchanged/snapchanged-on-user-root-scroll.tentative.html @@ -0,0 +1,166 @@ +<!DOCTYPE html> +<html> + +<head> + <meta charset="utf-8"> + <title> CSS Scroll Snap 2 Test: snapchanged events</title> + <link rel="help" href="https://drafts.csswg.org/css-scroll-snap-2/#snap-events"> + <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="/css/css-scroll-snap-2/resources/common.js"></script> + <script src="/css/css-scroll-snap-2/resources/user-scroll-common.js"></script> + <script src="/dom/events/scrolling/scroll_support.js"></script> + <script src="/web-animations/testcommon.js"></script> +</head> + +<body> + <style type='text/css'> + :root { + margin: 0px; + padding: 0px; + scroll-snap-type: both mandatory; + } + + div { + position: absolute; + margin: 0px; + } + + #spacer { + width: 200vw; + height: 200vh; + } + + .snap_point { + width: 40vw; + height: 40vh; + scroll-snap-align: start; + } + + #snap_point_1 { + left: 0px; + top: 0px; + background-color: red; + } + + #snap_point_2 { + top: 35vh; + left: 35vw; + background-color: orange; + } + + #snap_point_3 { + left: 70vw; + top: 70vh; + background-color: blue; + } + </style> + <div id="spacer"></div> + <div id="snap_point_1" class="snap_point"></div> + <div id="snap_point_2" class="snap_point"></div> + <div id="snap_point_3" class="snap_point"></div> + <script> + const scroller = document.scrollingElement; + const offset_to_snap_point_2 = { + x: snap_point_2.offsetLeft, + y: snap_point_2.offsetTop + }; + + // Touch scroll test. + promise_test(async (t) => { + await waitForCompositorCommit(); + const start_pos = { + x: scroller.clientWidth / 2, + y: scroller.clientHeight / 2, + }; + const end_pos = { x: 0, y: 0 }; + const test_data = { + scroller: scroller, + scrolling_function: async () => { + await snap_event_touch_scroll_helper(start_pos, end_pos); + }, + expected_snap_targets: [snap_point_2.id], + expected_scroll_offsets: { + x: offset_to_snap_point_2.x, + y: offset_to_snap_point_2.y, + } + }; + await test_snapchanged(t, test_data); + }, "snapchanged event fires after snap target changes on touch scroll"); + + // 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, + offset_to_snap_point_2.x, + offset_to_snap_point_2.y, + { origin: scroller }).send(); + }, + expected_snap_targets: [snap_point_2.id], + expected_scroll_offsets: { + x: offset_to_snap_point_2.x, + y: offset_to_snap_point_2.y, + } + }; + await test_snapchanged(t, test_data); + }, "snapchanged event fires after snap target changes on wheel scroll"); + + // 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; + if (scrollbar_width == 0) { + return; + } + const test_data = { + scroller: scroller, + scrolling_function: async () => { + const scrollbar_to_scroller_ratio = + getScrollbarToScrollerRatio(document.documentElement); + // Scroll by just over half of the top box's height. + const drag_amt = (offset_to_snap_point_2.y / 2 + 1) * + scrollbar_to_scroller_ratio; + await snap_event_scrollbar_drag_helper(scroller, scrollbar_width, + drag_amt); + }, + expected_snap_targets: [snap_point_1.id, snap_point_2.id], + expected_scroll_offsets: { + x: 0, + y: offset_to_snap_point_2.y, + } + }; + await test_snapchanged(t, test_data); + }, "snapchanged event fires after snap target changes on scrollbar drag"); + + // Keyboard test. + promise_test(async (t) => { + const test_data = { + scroller: scroller, + scrolling_function: async () => { + scroller.focus(); + window.test_driver.send_keys(document.documentElement, + '\ue015'/*ArrowDown*/); + }, + expected_snap_targets: [snap_point_1.id, snap_point_2.id], + expected_scroll_offsets: { + x: 0, + y: offset_to_snap_point_2.y, + } + }; + await test_snapchanged(t, test_data); + }, "snapchanged event fires after snap target changes on keydown press"); + + promise_test(async (t) => { + await test_no_snapchanged(t, scroller, /*delta*/10); + }, "snapchanged is not fired if snap target doesn't change on user scroll"); + </script> +</body> diff --git a/testing/web-platform/tests/css/css-scroll-snap-2/snapchanged/snapchanged-on-user-scroll.tentative.html b/testing/web-platform/tests/css/css-scroll-snap-2/snapchanged/snapchanged-on-user-scroll.tentative.html new file mode 100644 index 0000000000..4f36200722 --- /dev/null +++ b/testing/web-platform/tests/css/css-scroll-snap-2/snapchanged/snapchanged-on-user-scroll.tentative.html @@ -0,0 +1,170 @@ +<!DOCTYPE html> +<html> + +<head> + <meta charset="utf-8"> + <title> CSS Scroll Snap 2 Test: snapchanged events</title> + <link rel="help" href="https://drafts.csswg.org/css-scroll-snap-2/#snap-events"> + <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="/css/css-scroll-snap-2/resources/common.js"></script> + <script src="/css/css-scroll-snap-2/resources/user-scroll-common.js"></script> + <script src="/dom/events/scrolling/scroll_support.js"></script> + <script src="/web-animations/testcommon.js"></script> +</head> + +<body> + <style> + body { + margin: 0px; + } + + div { + position: absolute; + margin: 0px; + } + + #spacer { + width: 200vw; + height: 200vh; + } + + .scroller { + height: 400px; + width: 400px; + overflow: scroll; + scroll-snap-type: both mandatory; + } + + .snap_point { + width: 40%; + height: 40%; + scroll-snap-align: start; + } + + #snap_point_1 { + left: 0px; + top: 0px; + background-color: red; + } + + #snap_point_2 { + top: 35%; + left: 35%; + background-color: orange; + } + + #snap_point_3 { + top: 70%; + left: 70%; + background-color: blue; + } + </style> + <div id="scroller" class="scroller"> + <div id="spacer"></div> + <div id="snap_point_1" class="snap_point"></div> + <div id="snap_point_2" class="snap_point"></div> + <div id="snap_point_3" class="snap_point"></div> + </div> + <script> + const scroller = document.getElementById("scroller"); + const offset_to_snap_point_2 = { + x: snap_point_2.offsetLeft, + y: snap_point_2.offsetTop + }; + + // Touch scroll test. + promise_test(async (t) => { + await waitForCompositorCommit(); + const start_pos = { + x: scroller.clientWidth / 2, + y: scroller.clientHeight / 2, + }; + const end_pos = { x: 0, y: 0 }; + const test_data = { + scroller: scroller, + scrolling_function: async () => { + await snap_event_touch_scroll_helper(start_pos, end_pos); + }, + expected_snap_targets: [snap_point_2.id], + expected_scroll_offsets: { + x: offset_to_snap_point_2.x, + y: offset_to_snap_point_2.y, + } + }; + await test_snapchanged(t, test_data); + }, "snapchanged event fires after snap target changes on touch scroll"); + + // 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, + offset_to_snap_point_2.x, + offset_to_snap_point_2.y, + { origin: scroller }).send(); + }, + expected_snap_targets: [snap_point_2.id], + expected_scroll_offsets: { + x: offset_to_snap_point_2.x, + y: offset_to_snap_point_2.y, + } + }; + await test_snapchanged(t, test_data); + }, "snapchanged event fires after snap target changes on wheel scroll"); + + // 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 = scroller.offsetWidth - scroller.clientWidth; + if (scrollbar_width == 0) + return; + 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 = (offset_to_snap_point_2.y / 2 + 1) * + scrollbar_to_scroller_ratio; + await snap_event_scrollbar_drag_helper(scroller, scrollbar_width, drag_amt); + }, + expected_snap_targets: [snap_point_1.id, snap_point_2.id], + expected_scroll_offsets: { + x: 0, + y: offset_to_snap_point_2.y, + } + }; + await test_snapchanged(t, test_data); + }, "snapchanged event fires after snap target changes on scrollbar drag"); + + // Keyboard test. + promise_test(async (t) => { + await waitForCompositorCommit(); + const test_data = { + scroller: scroller, + scrolling_function: async () => { + scroller.focus(); + window.test_driver.send_keys(scroller, '\ue015'/*ArrowDown*/); + }, + expected_snap_targets: [snap_point_1.id, snap_point_2.id], + expected_scroll_offsets: { + x: 0, + y: offset_to_snap_point_2.y, + } + }; + await test_snapchanged(t, test_data); + }, "snapchanged event fires after snap target changes on keydown press"); + + promise_test(async (t) => { + await test_no_snapchanged(t, scroller, /*delta*/10); + }, "snapchanged is not fired if snap target doesn't change on user scroll"); + </script> +</body> diff --git a/testing/web-platform/tests/css/css-scroll-snap-2/snapchanged/snapchanged-same-targets-after-layout-changed.html b/testing/web-platform/tests/css/css-scroll-snap-2/snapchanged/snapchanged-same-targets-after-layout-changed.html new file mode 100644 index 0000000000..4d16bd80a3 --- /dev/null +++ b/testing/web-platform/tests/css/css-scroll-snap-2/snapchanged/snapchanged-same-targets-after-layout-changed.html @@ -0,0 +1,106 @@ +<!DOCTYPE html> +<html> + +<head> + <link rel="help" href="https://drafts.csswg.org/css-scroll-snap-2/#snap-events" /> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> + <script src="/dom/events/scrolling/scroll_support.js"></script> + <script src="/css/css-scroll-snap-2/resources/common.js"></script> + <style> + #scroller { + overflow-y: scroll; + scroll-snap-type: y mandatory; + width: 500px; + height: 500px; + background-color: white; + position: relative; + } + .large_space { + position: absolute; + height: 100vh; + width: 100vw; + } + .space_filler { + display: inline-block; + width: 40%; + height: 30%; + background-color: green; + } + .snap_area { + scroll-snap-align: start; + background-color: yellow; + position: absolute; + width: 40%; + height: 30%; + top: 500px; + } + + .left { + left: 1px; + } + .right { + left: 41%; + } + </style> +</head> +<body> + <div id="scroller"> + <div class="large_space"></div> + <div class="space_filler"></div> + <div class="space_filler"></div> + <div class="space_filler"></div> + <div class="space_filler"></div> + <div class="space_filler"></div> + <div class="space_filler"></div> + <div class="space_filler"></div> + <div class="space_filler"></div> + <div id="left" class="snap_area left"><h1>1</h1></div> + <div id="right" class="snap_area right"><h1>2</h1></div> + </div> + <script> + let unreached_func = null; + promise_test(async (t) => { + checkSnapEventSupport("snapchanged"); + await waitForCompositorCommit(); + unreached_func = t.unreached_func("snapchanged shouldn't fire " + + "since the scroller is snapped to the same elements."); + scroller.addEventListener("snapchanged", unreached_func); + t.add_cleanup(() => { + scroller.removeEventListener("snapchanged", unreached_func); + }); + assert_greater_than(right.offsetLeft, left.offsetLeft, + "boxes have switched positions."); + // Switch the boxes' horizontal positions. + right.style.left = "1px"; + left.style.left = "41%"; + await waitForCompositorCommit(); + assert_less_than(right.offsetLeft, left.offsetLeft, + "boxes have switched positions."); + await waitForCompositorCommit(); + }, "snapchanged doesn't fire after layout change if snapped to the same " + + "elements"); + + promise_test(async (t) => { + checkSnapEventSupport("snapchanged"); + await waitForCompositorCommit(); + unreached_func = t.unreached_func("snapchanged shouldn't fire " + + "since the scroller is snapped to the same elements."); + scroller.addEventListener("snapchanged", unreached_func); + t.add_cleanup(() => { + scroller.removeEventListener("snapchanged", unreached_func); + }); + const scrollend_promise = waitForScrollendEventNoTimeout(scroller); + // Move the boxes to the same vertical level. Both boxes should still be + // considered snapped to so snapchanged should not be triggerred. + right.style.top = `0px`; + left.style.top = `0px`; + await scrollend_promise; + assert_equals(scroller.scrollTop, 0); + await waitForCompositorCommit(); + }, "snapchanged doesn't fire after snap to the same targets after scroll. " + + "elements"); + + </script> +</body> +</html> diff --git a/testing/web-platform/tests/css/css-scroll-snap-2/snapchanged/snapchanged-with-proximity-strictness.tentative.html b/testing/web-platform/tests/css/css-scroll-snap-2/snapchanged/snapchanged-with-proximity-strictness.tentative.html new file mode 100644 index 0000000000..cb55054e6f --- /dev/null +++ b/testing/web-platform/tests/css/css-scroll-snap-2/snapchanged/snapchanged-with-proximity-strictness.tentative.html @@ -0,0 +1,80 @@ +<!DOCTYPE html> +<html> +<head> +<title> + <title> CSS Scroll Snap 2 Test: snapchanged events on proximity strictness container</title> + <link rel="help" href="https://drafts.csswg.org/css-scroll-snap-2/#snap-events"/> +</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/dom/events/scrolling/scroll_support.js"></script> +<script src="/css/css-scroll-snap-2/resources/common.js"></script> +<style> + div { + position: absolute; + margin: 0; + } + + #scroller { + height: 600px; + width: 600px; + overflow: hidden; + scroll-snap-type: y proximity; + } + + .snap { + width: 300px; + height: 300px; + background-color: green; + scroll-snap-align: start; + } + + .area { + width: 2000px; + height: 2000px; + } + </style> +</head> +<body> +<div id="scroller"> + <div class="area"></div> + <div id="target" class="snap" style="top: 0px;"></div> +</div> + +<script> + const target = document.getElementById("target"); + let resolve_func = null; + + promise_test(async (test) => { + checkSnapEventSupport("snapchanged"); + await waitForCompositorCommit(); + // The initial snap position is at (0, 0). + assert_equals(scroller.scrollTop, 0); + assert_equals(scroller.scrollLeft, 0); + + let snapchanged_promise = waitForSnapChangedEvent(scroller); + // Scroll to a position where it's outside of the scroll-snap proximity + // threshold, so that it won't trigger snapping. + scroller.scrollTo(0, 250); + + // snapchanged should fire as we've moved from within the proximity range + // to outside the proximity range and are no longer snapped. + let evt = await snapchanged_promise; + assert_equals(scroller.scrollTop, 250); + assertSnapEvent(evt, []); + evt = null; + + snapchanged_promise = waitForSnapChangedEvent(scroller); + // Scroll to a position within the scroll-snap proximity + // threshold, so that it triggers snapping. + scroller.scrollTo(0, 190); + + evt = await snapchanged_promise; + assert_equals(scroller.scrollTop, 0); + // snapchanged should fire as we've moved from outside the proximity range + // to inside the proximity range and are once again snapped. + assertSnapEvent(evt, [target.id]); + }, "Snapchanged fires when scrolling outside proximity range."); + </script> +</body> +</html> |