diff options
Diffstat (limited to 'testing/web-platform/tests/css/css-scroll-snap-2/scroll-start-target')
17 files changed, 1341 insertions, 0 deletions
diff --git a/testing/web-platform/tests/css/css-scroll-snap-2/scroll-start-target/scroll-start-target-aligns-with-snap-align.tentative.html b/testing/web-platform/tests/css/css-scroll-snap-2/scroll-start-target/scroll-start-target-aligns-with-snap-align.tentative.html new file mode 100644 index 0000000000..6b133dea7d --- /dev/null +++ b/testing/web-platform/tests/css/css-scroll-snap-2/scroll-start-target/scroll-start-target-aligns-with-snap-align.tentative.html @@ -0,0 +1,74 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title> CSS Scroll Snap 2 Test: scroll-start-target*</title> + <link rel="help" href="https://drafts.csswg.org/css-scroll-snap-2/#scroll-start-target"> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> + <script src="/dom/events/scrolling/scroll_support.js"></script> + </head> + <body> + <style> + #space { + width: 1000px; + height: 1000px; + border: solid 1px red; + } + #scroller { + width: 400px; + height: 400px; + overflow: hidden; + border: solid 1px blue; + position: absolute; + } + #target { + width: 100px; + height: 100px; + background-color: pink; + scroll-start-target: auto auto; + position: absolute; + top: 400px; + left: 400px; + } + </style> + <div id="scroller"> + <div id="space"></div> + <div id="target"></div> + </div> + <script> + promise_test(async (t) => { + await waitForCompositorCommit(); + + assert_equals(scroller.scrollTop, 400, + "scroller is vertically scrolled to target"); + assert_equals(scroller.scrollLeft, 400, + "scroller is horizontally scrolled to target"); + + target.style.scrollSnapAlign = "center"; + await waitForCompositorCommit(); + + assert_equals(scroller.scrollTop, 250, + "scroller is vertically aligned to target's center"); + assert_equals(scroller.scrollLeft, 250, + "scroller is horizontally aligned to target's center"); + + target.style.scrollSnapAlign = "end"; + await waitForCompositorCommit(); + + assert_equals(scroller.scrollTop, 100, + "scroller is vertically aligned to target's bottom"); + assert_equals(scroller.scrollLeft, 100, + "scroller is horizontally aligned to target's right"); + + target.style.scrollSnapAlign = "start"; + await waitForCompositorCommit(); + + assert_equals(scroller.scrollTop, 400, + "scroller is vertically aligned to target's top"); + assert_equals(scroller.scrollLeft, 400, + "scroller is horizontally aligned to target's left"); + }, "scroll-start-target aligns with scroll-snap-align"); + </script> + </body> +</html> diff --git a/testing/web-platform/tests/css/css-scroll-snap-2/scroll-start-target/scroll-start-target-display-toggled.tentative.html b/testing/web-platform/tests/css/css-scroll-snap-2/scroll-start-target/scroll-start-target-display-toggled.tentative.html new file mode 100644 index 0000000000..527d750267 --- /dev/null +++ b/testing/web-platform/tests/css/css-scroll-snap-2/scroll-start-target/scroll-start-target-display-toggled.tentative.html @@ -0,0 +1,125 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title> CSS Scroll Snap 2 Test: scroll-start-target*</title> + <link rel="help" href="https://drafts.csswg.org/css-scroll-snap-2/#scroll-start-target"> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> + </head> + <body> + <style> + #space-filler { + width: 500px; + height: 500px; + border: solid 1px red; + } + #outer-container { + width: 400px; + height: 400px; + overflow: scroll; + border: solid 2px blue; + } + #inner-container { + top: 20px; + left: 20px; + width: 300px; + height: 300px; + overflow: scroll; + position: relative; + border: solid 2px black; + } + #target { + width: 100px; + height: 100px; + background-color: pink; + scroll-start-target: auto auto; + } + </style> + <div id="outer-container"> + <div id="inner-container"> + <div id="space-filler"></div> + <div id="target"> + </div> + </div> + </div> + <script> + let outer_scroller = document.getElementById("outer-container"); + let inner_scroller = document.getElementById("inner-container"); + let space_filler = document.getElementById("space-filler"); + let target = document.getElementById("target"); + + const target_height = target.getBoundingClientRect().height; + const space_filler_height = space_filler.getBoundingClientRect().height; + const total_content_height = target_height + space_filler_height; + + async function resetDisplay() { + return new Promise((resolve) => { + if (getComputedStyle(outer_scroller).display == "block" && + getComputedStyle(inner_scroller).display == "block" && + getComputedStyle(target).display == "block") { + resolve(); + } else { + outer_scroller.style.display = "block"; + inner_scroller.style.display = "block"; + target.style.display = "block"; + requestAnimationFrame(async () => { + await resetDisplay(); + resolve(); + }); + } + }); + } + + async function waitForDisplay(element, display) { + return new Promise((resolve) => { + if (getComputedStyle(element).display == display) { + resolve(); + } else { + requestAnimationFrame(async () => { + await waitForDisplay(element, display); + resolve(); + }) + } + }); + } + + promise_test(async (t) => { + await resetDisplay(); + let initial_expected_scroll_top = + total_content_height - inner_scroller.clientHeight; + assert_equals(inner_scroller.scrollTop, initial_expected_scroll_top, + "inner-scroller is scrolled to scroll-start-target"); + + let display_promise = waitForDisplay(target, "none"); + target.style.display = "none"; + await display_promise; + + let final_expected_scroll_top = initial_expected_scroll_top - target_height; + assert_equals(inner_scroller.scrollTop, final_expected_scroll_top, + "inner scroller is clamped to updated scroll range"); + }, "display:block scroll-start-target becomes display: none"); + + promise_test(async (t) => { + await resetDisplay(); + let initial_expected_scroll_top = + total_content_height - inner_scroller.clientHeight; + assert_equals(inner_scroller.scrollTop, initial_expected_scroll_top, + "inner-scroller is scrolled to scroll-start-target"); + + let display_promise = waitForDisplay(target, "none"); + target.style.display = "none"; + await display_promise; + assert_equals(inner_scroller.scrollTop, + initial_expected_scroll_top - target_height, + "inner scroller is clamped to updated scroll range"); + + display_promise = waitForDisplay(target, "block"); + target.style.display = "block"; + await display_promise; + assert_equals(inner_scroller.scrollTop, initial_expected_scroll_top, + "inner scroller is updated as scroll-start-target reappears"); + }, "display:none scroll-start-target becomes display: block"); + </script> + </body> +</html> diff --git a/testing/web-platform/tests/css/css-scroll-snap-2/scroll-start-target/scroll-start-target-nested-container.tentative.html b/testing/web-platform/tests/css/css-scroll-snap-2/scroll-start-target/scroll-start-target-nested-container.tentative.html new file mode 100644 index 0000000000..b84803c941 --- /dev/null +++ b/testing/web-platform/tests/css/css-scroll-snap-2/scroll-start-target/scroll-start-target-nested-container.tentative.html @@ -0,0 +1,230 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title> CSS Scroll Snap 2 Test: scroll-start-target*</title> + <link rel="help" href="https://drafts.csswg.org/css-scroll-snap-2/#scroll-start-target"> + <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> + </head> + <body> + <style> + #space-filler { + width: 500px; + height: 500px; + background-color: green; + } + #outer-container { + width: 400px; + height: 400px; + overflow: scroll; + background-color: yellow; + } + #inner-container { + top: 20px; + left: 20px; + width: 300px; + height: 300px; + overflow: visible; + position: relative; + background-color: blue; + } + #target { + width: 100px; + height: 100px; + background-color: pink; + scroll-start-target: auto auto; + } + </style> + <div id="outer-container"> + <div id="space-filler"></div> + <div id="inner-container"> + <div id="space-filler"></div> + <div id="target"> + </div> + </div> + </div> + <script> + let outer_container = document.getElementById("outer-container"); + let inner_container = document.getElementById("inner-container"); + let space_filler = document.getElementById("space-filler"); + let target = document.getElementById("target"); + + const inner_scroller_top_offset = 20; + const target_height = target.getBoundingClientRect().height; + const space_filler_height = space_filler.getBoundingClientRect().height; + const inner_content_height = target_height + space_filler_height; + const inner_container_height = inner_container.getBoundingClientRect().height; + + async function resetDisplay() { + return new Promise((resolve) => { + if (getComputedStyle(outer_container).display == "block" && + getComputedStyle(inner_container).display == "block" && + getComputedStyle(target).display == "block") { + resolve(); + } else { + outer_container.style.display = "block"; + inner_container.style.display = "block"; + target.style.display = "block"; + requestAnimationFrame(async () => { + await resetDisplay(); + resolve(); + }); + } + }); + } + + async function waitForCSSProperty(element, property, value) { + return new Promise((resolve) => { + if (getComputedStyle(element)[property] == value) { + resolve(); + } else { + requestAnimationFrame(async () => { + await waitForCSSProperty(element, property, value); + resolve(); + }) + } + }); + } + + async function waitForDisplay(element, value) { + return waitForCSSProperty(element, "display", value); + } + + async function waitForOverflow(element, value) { + return waitForCSSProperty(element, "overflow", value); + } + + let initial_expected_scroll_top = space_filler_height + + inner_scroller_top_offset + inner_content_height - + outer_container.clientHeight; + promise_test(async (t) => { + await resetDisplay(); + assert_equals(outer_container.scrollTop, initial_expected_scroll_top, + "outer-container is scrolled to scroll-start-target"); + + inner_container.style.display = "none"; + await waitForDisplay(inner_container, "none"); + + assert_equals(outer_container.scrollTop, + space_filler_height - outer_container.clientHeight, + "outer-container has no content to scroll"); + + inner_container.style.display = "block"; + await waitForDisplay(inner_container, "block"); + + assert_equals(outer_container.scrollTop, initial_expected_scroll_top, + "outer-scroller is updated as scroll-start-target reappears"); + }, "display:none scroll-start-target becomes display:block"); + + promise_test(async (t) => { + await waitForCompositorCommit(); + await resetDisplay(); + assert_equals(outer_container.scrollTop, initial_expected_scroll_top, + "outer-container is scrolled to scroll-start-target"); + + inner_container.style.overflow = "scroll"; + await waitForOverflow(inner_container, "scroll"); + + // inner-container has become a scroller and should be scrolled to + // scroll-start-target. + assert_equals(inner_container.scrollTop, + inner_content_height - inner_container.clientHeight, + "inner-container is fully scrolled to target"); + // outer-container should be adjusted to its new max scroll offset. + const scrollbar_width = outer_container.offsetHeight - + outer_container.clientHeight; + assert_equals(outer_container.scrollTop, + space_filler_height + inner_scroller_top_offset + + inner_container_height - outer_container.clientHeight, + "outer-container's overflowing content is only its direct " + + "children"); + + inner_container.style.overflow = "visible"; + await waitForOverflow(inner_container, "visible"); + + assert_equals(inner_container.scrollTop, 0, + "inner-container is no longer a scroll container"); + assert_equals(outer_container.scrollTop, initial_expected_scroll_top, + "outer-scroller is the scroll container for target once again"); + }, "intermediate overflow:visible container becomes overflow:scroll"); + + promise_test(async (t) => { + // This test verifies that: + // 1. when both the child and grandchild are scroll-start-targets, the + // grandchild wins/is scrolled to. + // 2. if/when the grandchild stops being a scroll-start-target, the + // child (inner container) is scrolled to. + await waitForCompositorCommit(); + await resetDisplay(); + t.add_cleanup(async () => { + target.style.scrollStartTarget = "auto auto"; + await waitForCSSProperty(target, "scroll-start-target", "auto"); + }); + + assert_equals(outer_container.scrollTop, initial_expected_scroll_top, + "outer-container is scrolled to scroll-start-target"); + // Make the inner container a scroll-start-target. + inner_container.style.scrollStartTarget = "auto auto"; + await waitForCSSProperty(inner_container, "scroll-start-target", "auto"); + + // The inner container has overflow: visible, so it's not the scroll + // container of target. + assert_equals(outer_container.scrollTop, initial_expected_scroll_top, + "outer-container is still scrolled to inner scroll-start-target"); + + // Make target no longer a scroll-start-target. The outer container's + // scroll-start-target should now be the inner container. + target.style.scrollStartTarget = "none none"; + await waitForCSSProperty(target, "scroll-start-target", "none"); + assert_equals(outer_container.scrollTop, + space_filler_height + inner_scroller_top_offset, + "outer-container is scrolled to inner-container"); + }, "inner scroll-start-target takes precedence over outer"); + + promise_test(async (t) => { + // This test verifies that a child which is a scroller, is a + // scroll-start-target, and has a scroll-start-target is scrolled to by + // its scrolling container, and also scrolls to its own + // scroll-start-target. + await waitForCompositorCommit(); + await resetDisplay(); + t.add_cleanup(async () => { + inner_container.style.overflow = "visible"; + inner_container.style.scrollStartTarget = "none none"; + await waitForCSSProperty(inner_container, "overflow", + "visible"); + await waitForCSSProperty(inner_container, "scroll-start-target", + "none"); + }); + + assert_equals(outer_container.scrollTop, initial_expected_scroll_top, + "outer-container is scrolled to scroll-start-target"); + + // Make the inner container a scroll-start-target. + inner_container.style.scrollStartTarget = "auto auto"; + await waitForCSSProperty(inner_container, "scroll-start-target", "auto"); + + assert_equals(outer_container.scrollTop, initial_expected_scroll_top, + "outer-container is still scrolled to inner scroll-start-target"); + + // Make the inner container a scroller. + inner_container.style.overflow = "scroll"; + await waitForOverflow(inner_container, "scroll"); + + assert_equals(outer_container.scrollTop, + space_filler_height + inner_scroller_top_offset + + inner_container.offsetHeight - outer_container.clientHeight, + "outer-container is scrolled to the inner container"); + assert_equals(inner_container.scrollTop, + space_filler_height + target.offsetHeight - + inner_container.clientHeight, + "inner-container is scrolled to target"); + }, "scroll containers can also be scroll-start-targets"); + </script> + </body> +</html> diff --git a/testing/web-platform/tests/css/css-scroll-snap-2/scroll-start-target/scroll-start-target-root.tentative.html b/testing/web-platform/tests/css/css-scroll-snap-2/scroll-start-target/scroll-start-target-root.tentative.html new file mode 100644 index 0000000000..f2af38bbab --- /dev/null +++ b/testing/web-platform/tests/css/css-scroll-snap-2/scroll-start-target/scroll-start-target-root.tentative.html @@ -0,0 +1,63 @@ +<!DOCTYPE html> +<html> + +<head> + <meta charset="utf-8"> + <title> CSS Scroll Snap 2 Test: scroll-start-target*</title> + <link rel="help" href="https://drafts.csswg.org/css-scroll-snap-2/#scroll-start-target"> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> +</head> + +<body> + <style> + .spacer { + width: 200vw; + height: 200vh; + } + + .box { + position: absolute; + width: 60vw; + height: 60vh; + } + + .top_left { + top: 0px; + left: 0px; + background-color: red; + } + + .center { + top: 60vh; + left: 60vw; + background-color: purple; + scroll-start-target: auto auto; + } + + .bottom_right { + top: 120vh; + left: 120vw; + background-color: yellow; + } + </style> + <div class="spacer"></div> + <div class="top_left box" id="top_left_box"></div> + <div class="center box" id="centerbox"></div> + <div class="bottom_right box"></div> + <script> + test((t) => { + let scroller = document.scrollingElement; + let top_left_box = document.getElementById("top_left_box"); + + const expected_scroll_top = top_left_box.getBoundingClientRect().height; + const expected_scroll_left = top_left_box.getBoundingClientRect().width; + + assert_approx_equals(scroller.scrollTop, expected_scroll_top, 1, + "scroll-start-target sets initial vertical scroll position"); + assert_approx_equals(scroller.scrollLeft, expected_scroll_left, 1, + "scroll-start-target sets initial horizontal scroll position"); + }); + </script> +</body> + diff --git a/testing/web-platform/tests/css/css-scroll-snap-2/scroll-start-target/scroll-start-target-rtl.tentative.html b/testing/web-platform/tests/css/css-scroll-snap-2/scroll-start-target/scroll-start-target-rtl.tentative.html new file mode 100644 index 0000000000..5a2fa0a93c --- /dev/null +++ b/testing/web-platform/tests/css/css-scroll-snap-2/scroll-start-target/scroll-start-target-rtl.tentative.html @@ -0,0 +1,63 @@ +<!DOCTYPE html> +<html> + +<head> + <meta charset="utf-8"> + <title> CSS Scroll Snap 2 Test: scroll-start-target*</title> + <link rel="help" href="https://drafts.csswg.org/css-scroll-snap-2/#scroll-start-target"> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> +</head> + +<body> + <style> + #scroller { + height: 500px; + width: 500px; + display: block; + overflow: scroll; + writing-mode: vertical-rl; + } + + .box { + position: relative; + width: 60%; + height: 60%; + } + + .top_right { + top: 0px; + left: 0px; + background-color: red; + } + + .center { + top: 60%; + background-color: purple; + scroll-start-target: auto auto; + } + + .bottom_left { + top: 120%; + background-color: yellow; + } + </style> + <div id="scroller"> + <div class="top_right box" id="box1"></div> + <div class="center box" id="box2"></div> + <div class="bottom_left box" id="box3"></div> + </div> + <script> + let initial_expected_scroll_top = box1.getBoundingClientRect().height; + let initial_expected_scroll_left = -box1.getBoundingClientRect().width; + + test((t) => { + assert_equals(scroller.scrollTop, initial_expected_scroll_top, + "scroller is vertically scrolled to scroll-start-target"); + assert_equals(scroller.scrollLeft, initial_expected_scroll_left, + "scroller is horizontally scrolled to scroll-start-target"); + }, "scroll-start-target reflects vertical rtl writing mode."); + </script> +</body> + +</html>
\ No newline at end of file diff --git a/testing/web-platform/tests/css/css-scroll-snap-2/scroll-start-target/scroll-start-target-with-anchor-navigation-inner-frame.html b/testing/web-platform/tests/css/css-scroll-snap-2/scroll-start-target/scroll-start-target-with-anchor-navigation-inner-frame.html new file mode 100644 index 0000000000..bea0525ecd --- /dev/null +++ b/testing/web-platform/tests/css/css-scroll-snap-2/scroll-start-target/scroll-start-target-with-anchor-navigation-inner-frame.html @@ -0,0 +1,42 @@ +<!DOCTYPE html> +<html> + +<head> +</head> + +<body> + <style> + :root, body { + margin: 0px; + } + + #spacer { + height: 100vh; + width: 100px; + } + + #top_box { + width: 100px; + height: 60vh; + background-color: red; + } + #middle_box { + width: 100px; + height: 60vh; + scroll-start-target: auto auto; + background-color: purple; + } + #bottom_box { + width: 100px; + height: 60vh; + background-color: yellow; + } + </style> + <div id="top_box"><a id="anchor_target_link" href="#anchor_target">Anchor Link</a></div> + <div id="middle_box"></div> + <div id="bottom_box"></div> + <div id="spacer"></div> + <div id="anchor_target">Anchor Target</div> +</body> + +</html> diff --git a/testing/web-platform/tests/css/css-scroll-snap-2/scroll-start-target/scroll-start-target-with-anchor-navigation.tentative.html b/testing/web-platform/tests/css/css-scroll-snap-2/scroll-start-target/scroll-start-target-with-anchor-navigation.tentative.html new file mode 100644 index 0000000000..bc5b75f75f --- /dev/null +++ b/testing/web-platform/tests/css/css-scroll-snap-2/scroll-start-target/scroll-start-target-with-anchor-navigation.tentative.html @@ -0,0 +1,60 @@ +<!DOCTYPE html> +<html> + +<head> + <meta charset="utf-8"> + <title> CSS Scroll Snap 2 Test: scroll-start-target interaction with anchor navigation</title> + <link rel="help" href="https://drafts.csswg.org/css-scroll-snap-2/#scroll-start-target"> + <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="/html/browsers/browsing-the-web/resources/helpers.js"></script> + <script src="/dom/events/scrolling/scroll_support.js"></script> +</head> + +<body> + <iframe id="frame" src="scroll-start-target-with-anchor-navigation-inner-frame.html" onload="runTest()"></iframe> + <script> + function runTest() { + promise_test(async (t) => { + await waitForCompositorCommit(); + let scroller = frame.contentDocument.scrollingElement; + // anchor_target is at the bottom of the frame so the frame should be + // fully scrolled down to bring it into view. + let anchor_target_scrolltop = scroller.scrollHeight - scroller.clientHeight; + let anchor_target_link = frame.contentDocument.getElementById("anchor_target_link"); + + // Expect scroll offset of 100px per scroll-start. + const scroll_start_target_top = 0.6 * frame.contentWindow.innerHeight; + assert_equals(scroller.scrollTop, scroll_start_target_top, + "scroll-start-target sets initial scroll offset"); + + // Scroll away from start position. + scroller.scrollTop = 200; + assert_equals(scroller.scrollTop, 200, + "scrolled away from scroll-start-target"); + + anchor_target_link.click(); + await waitForHashchange(frame.contentWindow); + assert_equals(frame.contentWindow.location.hash, "#anchor_target", + "clicking anchor link navigates to target"); + + // Expect page to be fully scrolled as anchor_target is at the bottom of + // the document. + assert_equals(scroller.scrollTop, anchor_target_scrolltop, + "anchor navigation sets scroll offset"); + + frame.contentWindow.history.back(); + await waitForHashchange(frame.contentWindow); + assert_equals(frame.contentWindow.location.hash, ""); + + assert_equals(scroller.scrollTop, 200, + "scroller returns to previous scroll position, not " + + "scroll-start-target"); + }, "scroll-start-target does not override anchor navigation."); + } + </script> +</body> + diff --git a/testing/web-platform/tests/css/css-scroll-snap-2/scroll-start-target/scroll-start-target-with-hash-fragment-navigation-inner-frame.html b/testing/web-platform/tests/css/css-scroll-snap-2/scroll-start-target/scroll-start-target-with-hash-fragment-navigation-inner-frame.html new file mode 100644 index 0000000000..9bf77363d3 --- /dev/null +++ b/testing/web-platform/tests/css/css-scroll-snap-2/scroll-start-target/scroll-start-target-with-hash-fragment-navigation-inner-frame.html @@ -0,0 +1,48 @@ +<!DOCTYPE html> +<html> + +<head> +</head> + +<body> + <style> + :root { + margin: 0px; + } + + #spacer { + height: 100vh; + width: 100px; + } + + #top_box { + width: 100px; + height: 60vh; + background-color: blue; + } + #middle_box { + width: 100px; + height: 60vh; + scroll-start-target: auto auto; + background-color: purple; + } + #bottom_box { + width: 100px; + height: 60vh; + background-color: yellow; + } + + #fragment_target { + width: 100px; + height: 100px; + background-color: red; + } + </style> + <div id="top_box"></div> + <div id="middle_box"></div> + <div id="bottom_box"></div> + <div id="spacer"></div> + <div id="fragment_target">Fragment Target</div> +</body> + +</html> diff --git a/testing/web-platform/tests/css/css-scroll-snap-2/scroll-start-target/scroll-start-target-with-hash-fragment-navigation.tentative.html b/testing/web-platform/tests/css/css-scroll-snap-2/scroll-start-target/scroll-start-target-with-hash-fragment-navigation.tentative.html new file mode 100644 index 0000000000..2d291c2ef9 --- /dev/null +++ b/testing/web-platform/tests/css/css-scroll-snap-2/scroll-start-target/scroll-start-target-with-hash-fragment-navigation.tentative.html @@ -0,0 +1,34 @@ +<!DOCTYPE html> +<html> + +<head> + <meta charset="utf-8"> + <title> CSS Scroll Snap 2 Test: scroll-start-target interaction with fragment-navigation</title> + <link rel="help" href="https://drafts.csswg.org/css-scroll-snap-2/#scroll-start-target"> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> +</head> + +<body> + <iframe id="frame" src="scroll-start-target-with-fragment-navigation-inner-frame.html#fragment_target" + onload="runTest()"></iframe> + <script> + function runTest() { + test((t) => { + let scroller = frame.contentDocument.scrollingElement; + // fragment_target is at the bottom of the frame so the frame should be + // fully scrolled down to bring it into view (despite middle_box being + // the scroll-start-target). + let expected_scroll_top = scroller.scrollHeight - scroller.clientHeight; + // The scroll-start-target is just below top_box which has a height of + // 60vh. + const scroll_start_target_top = 0.6 * frame.contentWindow.innerHeight; + + assert_equals(frame.contentWindow.location.hash, "#fragment_target"); + assert_not_equals(scroll_start_target_top, expected_scroll_top); + assert_equals(frame.contentDocument.scrollingElement.scrollTop, + expected_scroll_top); + }, "scroll-start-target does not override hash fragment navigation"); + } + </script> +</body>
\ No newline at end of file diff --git a/testing/web-platform/tests/css/css-scroll-snap-2/scroll-start-target/scroll-start-target-with-scroll-snap.tentative.html b/testing/web-platform/tests/css/css-scroll-snap-2/scroll-start-target/scroll-start-target-with-scroll-snap.tentative.html new file mode 100644 index 0000000000..9cb66c01fc --- /dev/null +++ b/testing/web-platform/tests/css/css-scroll-snap-2/scroll-start-target/scroll-start-target-with-scroll-snap.tentative.html @@ -0,0 +1,79 @@ +<!DOCTYPE html> +<html> + +<head> + <meta charset="utf-8"> + <title> CSS Scroll Snap 2 Test: scroll-start-target*</title> + <link rel="help" href="https://drafts.csswg.org/css-scroll-snap-2/#scroll-start-target"> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> +</head> + +<body> + <style> + .spacer { + width: 1000px; + height: 1000px; + } + + .scroller { + width: 300px; + height: 300px; + border: solid 1px black; + overflow: scroll; + margin: 0px; + position: absolute; + scroll-snap-type: y mandatory; + } + + .box { + position: absolute; + width: 200px; + height: 200px; + } + + .top_left { + top: 0px; + left: 0px; + background-color: red; + } + + .center { + top: 200px; + left: 200px; + background-color: purple; + scroll-start-target: auto auto; + } + + .bottom_right { + top: 400px; + left: 400px; + background-color: yellow; + /* Expect scroller to snap to the top and left border of the bottom right div. */ + scroll-snap-align: start start; + } + </style> + <div class="scroller" id="scroller"> + <div class="spacer"></div> + <div class="top_left box" id="top_left_box"></div> + <div class="center box" id="centerbox"></div> + <div class="bottom_right box"></div> + </div> + <script> + test((t) => { + let scroller = document.getElementById("scroller"); + let top_left_box = document.getElementById("top_left_box"); + let center_box = document.getElementById("center_box"); + + const expected_scroll_top = top_left_box.getBoundingClientRect().height + + centerbox.getBoundingClientRect().height; + const expected_scroll_left = top_left_box.getBoundingClientRect().width; + centerbox.getBoundingClientRect().width; + + assert_approx_equals(scroller.scrollTop, expected_scroll_top, 1, + "scroll-start-target sets initial vertical scroll position"); + assert_approx_equals(scroller.scrollLeft, expected_scroll_left, 1, + "scroll-start-target sets initial horizontal scroll position"); + }); + </script> +</body>
\ No newline at end of file diff --git a/testing/web-platform/tests/css/css-scroll-snap-2/scroll-start-target/scroll-start-target-with-scroll-start-root.tentative.html b/testing/web-platform/tests/css/css-scroll-snap-2/scroll-start-target/scroll-start-target-with-scroll-start-root.tentative.html new file mode 100644 index 0000000000..af99595f25 --- /dev/null +++ b/testing/web-platform/tests/css/css-scroll-snap-2/scroll-start-target/scroll-start-target-with-scroll-start-root.tentative.html @@ -0,0 +1,66 @@ +<!DOCTYPE html> +<html> + +<head> + <meta charset="utf-8"> + <title> CSS Scroll Snap 2 Test: scroll-start-target*</title> + <link rel="help" href="https://drafts.csswg.org/css-scroll-snap-2/#scroll-start-target"> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> +</head> + +<body> + <style> + :root { + scroll-start: end end; + } + + .spacer { + width: 200vw; + height: 200vh; + } + + .box { + position: absolute; + width: 60vw; + height: 60vh; + } + + .top_left { + top: 0px; + left: 0px; + background-color: red; + } + + .center { + top: 60vh; + left: 60vw; + background-color: purple; + scroll-start-target: auto auto; + } + + .bottom_right { + top: 120vh; + left: 120vw; + background-color: yellow; + } + </style> + <div class="spacer"></div> + <div class="top_left box" id="top_left_box"></div> + <div class="center box" id="centerbox"></div> + <div class="bottom_right box"></div> + <script> + test((t) => { + let scroller = document.scrollingElement; + let top_left_box = document.getElementById("top_left_box"); + + const expected_scroll_top = top_left_box.getBoundingClientRect().height; + const expected_scroll_left = top_left_box.getBoundingClientRect().width; + + assert_approx_equals(scroller.scrollTop, expected_scroll_top, 1, + "scroll-start-target sets initial vertical scroll position"); + assert_approx_equals(scroller.scrollLeft, expected_scroll_left, 1, + "scroll-start-target sets initial horizontal scroll position"); + }); + </script> +</body>
\ No newline at end of file diff --git a/testing/web-platform/tests/css/css-scroll-snap-2/scroll-start-target/scroll-start-target-with-scroll-start.tentative.html b/testing/web-platform/tests/css/css-scroll-snap-2/scroll-start-target/scroll-start-target-with-scroll-start.tentative.html new file mode 100644 index 0000000000..a37c831288 --- /dev/null +++ b/testing/web-platform/tests/css/css-scroll-snap-2/scroll-start-target/scroll-start-target-with-scroll-start.tentative.html @@ -0,0 +1,75 @@ +<!DOCTYPE html> +<html> + +<head> + <meta charset="utf-8"> + <title> CSS Scroll Snap 2 Test: scroll-start-target*</title> + <link rel="help" href="https://drafts.csswg.org/css-scroll-snap-2/#scroll-start-target"> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> +</head> + +<body> + <style> + .spacer { + width: 1000px; + height: 1000px; + } + + .scroller { + width: 300px; + height: 300px; + border: solid 1px black; + overflow: scroll; + margin: 0px; + position: absolute; + scroll-start: end end; + /* This should be overriden by scroll-start-target. */ + } + + .box { + position: absolute; + width: 200px; + height: 200px; + } + + .top_left { + top: 0px; + left: 0px; + background-color: red; + } + + .center { + top: 200px; + left: 200px; + background-color: purple; + scroll-start-target: auto auto; + } + + .bottom_right { + top: 400px; + left: 400px; + background-color: yellow; + } + </style> + <div class="scroller" id="scroller"> + <div class="spacer"></div> + <div class="top_left box" id="top_left_box"></div> + <div class="center box" id="centerbox"></div> + <div class="bottom_right box"></div> + </div> + <script> + test((t) => { + let scroller = document.getElementById("scroller"); + let top_left_box = document.getElementById("top_left_box"); + + const expected_scroll_top = top_left_box.getBoundingClientRect().height; + const expected_scroll_left = top_left_box.getBoundingClientRect().width; + + assert_approx_equals(scroller.scrollTop, expected_scroll_top, 1, + "scroll-start-target sets initial vertical scroll position"); + assert_approx_equals(scroller.scrollLeft, expected_scroll_left, 1, + "scroll-start-target sets initial horizontal scroll position"); + }); + </script> +</body>
\ No newline at end of file diff --git a/testing/web-platform/tests/css/css-scroll-snap-2/scroll-start-target/scroll-start-target-with-text-fragment-navigation-target.html b/testing/web-platform/tests/css/css-scroll-snap-2/scroll-start-target/scroll-start-target-with-text-fragment-navigation-target.html new file mode 100644 index 0000000000..da53e7a566 --- /dev/null +++ b/testing/web-platform/tests/css/css-scroll-snap-2/scroll-start-target/scroll-start-target-with-text-fragment-navigation-target.html @@ -0,0 +1,83 @@ +<!DOCTYPE html> +<html> + +<body> + <style> + :root { + margin: 0px; + } + + #spacer { + height: 100vh; + width: 100px; + } + + #top_box { + width: 100px; + height: 60vh; + background-color: blue; + } + #middle_box { + width: 100px; + height: 60vh; + scroll-start-target: auto auto; + background-color: purple; + } + #bottom_box { + width: 100px; + height: 60vh; + background-color: yellow; + } + + #fragment_target { + width: 100px; + height: 100px; + background-color: red; + } + </style> + <div id="top_box"></div> + <div id="middle_box"></div> + <div id="bottom_box"></div> + <div id="spacer"></div> + <div id="fragment_target">Target</div> + <script> + function stashResult(key, results) { + fetch(`/css/css-scroll-snap-2/scroll-start-target/stash.py?key=${key}`, { + method: "POST", + body: JSON.stringify(results) + }).then(() => { + window.close(); + }); + } + function record() { + let scroll_position = "UNKNOWN"; + // Expect page is scrolled all the way down as the text is at the bottom of + // the page. + const expected_scroll_top = document.scrollingElement.scrollHeight - + document.scrollingElement.clientHeight; + + const scroll_start_target_top = top_box.getBoundingClientRect().height; + + if (document.scrollingElement.scrollTop == scroll_start_target_top) { + scroll_position = "AT_SCROLL_START_TARGET"; + } else if (document.scrollingElement.scrollTop == expected_scroll_top) { + scroll_position = "AT_TEXT_FRAGMENT"; + } + + const result = { + scroll_position: scroll_position + }; + + let key = (new URL(document.location)).searchParams.get("key"); + stashResult(key, result); + } + + window.onload = () => { + window.requestAnimationFrame(function () { + window.requestAnimationFrame(record); + }) + } + </script> +</body> + +</html>
\ No newline at end of file diff --git a/testing/web-platform/tests/css/css-scroll-snap-2/scroll-start-target/scroll-start-target-with-text-fragment-navigation.tentative.html b/testing/web-platform/tests/css/css-scroll-snap-2/scroll-start-target/scroll-start-target-with-text-fragment-navigation.tentative.html new file mode 100644 index 0000000000..f83ea1a036 --- /dev/null +++ b/testing/web-platform/tests/css/css-scroll-snap-2/scroll-start-target/scroll-start-target-with-text-fragment-navigation.tentative.html @@ -0,0 +1,49 @@ +<!DOCTYPE html> +<html> + +<head> + <meta charset="utf-8"> + <title> CSS Scroll Snap 2 Test: scroll-start-target interaction with text-fragment navigation</title> + <link rel="help" href="https://drafts.csswg.org/css-scroll-snap-2/#scroll-start-target"> + <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="/common/utils.js"></script> +</head> + +<body onload="runTest()"> + <script> + function fetchResult(key, resolve, reject) { + fetch(`/css/css-scroll-snap-2/scroll-start-target/stash.py?key=${key}`).then(response => { + return response.text(); + }).then(text => { + if (text) { + try { + let result = JSON.parse(text); + resolve(result); + } catch (e) { + reject(); + } + } else { + fetchResult(key, resolve, reject); + } + }); + } + + function runTest() { + promise_test(t => new Promise(async (resolve, reject) => { + let key = token(); + + test_driver.bless("Open a URL with a text fragment directive", () => { + window.open(`scroll-start-target-with-text-fragment-navigation-target.html?key=${key}#:~:text=Target`, "_blank", "noopener"); + }); + + fetchResult(key, resolve, reject); + }).then(result => { + assert_equals(result.scroll_position, "AT_TEXT_FRAGMENT"); + }), "scroll-start doesn't override text fragment navigation"); + } + </script> +</body> diff --git a/testing/web-platform/tests/css/css-scroll-snap-2/scroll-start-target/scroll-start-target-with-user-programmatic-scroll.tentative.html b/testing/web-platform/tests/css/css-scroll-snap-2/scroll-start-target/scroll-start-target-with-user-programmatic-scroll.tentative.html new file mode 100644 index 0000000000..2d487e9b85 --- /dev/null +++ b/testing/web-platform/tests/css/css-scroll-snap-2/scroll-start-target/scroll-start-target-with-user-programmatic-scroll.tentative.html @@ -0,0 +1,125 @@ +<!DOCTYPE html> +<html> + +<head> + <meta charset="utf-8"> + <title> CSS Scroll Snap 2 Test: scroll-start-target*</title> + <link rel="help" href="https://drafts.csswg.org/css-scroll-snap-2/#scroll-start-target"> + <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> +</head> + +<body> + <style> + .spacer { + width: 1000px; + height: 1000px; + } + + .scroller { + width: 300px; + height: 300px; + border: solid 1px black; + overflow: scroll; + margin: 0px; + position: absolute; + } + + .box { + position: absolute; + width: 200px; + height: 200px; + } + + .top_left { + top: 0px; + left: 0px; + background-color: red; + } + + .center { + top: 200px; + left: 200px; + background-color: purple; + scroll-start-target: auto auto; + } + + .bottom_right { + top: 400px; + left: 400px; + background-color: yellow; + } + </style> + <div class="scroller" id="user_scroller"> + <div class="spacer"></div> + <div class="top_left box" id="user_top_left_box"></div> + <div class="center box"></div> + <div class="bottom_right box"></div> + </div> + <div class="scroller" id="programmatic_scroller" style="left: 500px"> + <div class="spacer"></div> + <div class="top_left box" id="programmatic_top_left_box"></div> + <div class="center box"></div> + <div class="bottom_right box"></div> + </div> + <script> + async function user_scroll(scroller, current_offset, target_offset) { + return new test_driver.Actions().scroll(0, 0, + target_offset.x - current_offset.x, + target_offset.y - current_offset.y, { origin: scroller }) + .send(); + } + + function programmatic_scroll(scroller, current_offset, target_offset) { + scroller.scrollTo(target_offset.x, target_offset.y); + } + + async function test_scroll_start_target(test, scroller, msg, scrolling_function) { + await waitForCompositorCommit(); + let top_left_box = document.getElementById("user_top_left_box"); + + let expected_scroll_top = top_left_box.getBoundingClientRect().height; + let expected_scroll_left = top_left_box.getBoundingClientRect().width; + + assert_approx_equals(scroller.scrollTop, expected_scroll_top, 1, + "scroll-start-target sets initial vertical scroll position"); + assert_approx_equals(scroller.scrollLeft, expected_scroll_left, 1, + "scroll-start-target sets initial horizontal scroll position"); + + let scrollend_promise = new Promise((resolve) => { + scroller.addEventListener("scrollend", resolve); + }); + const current_offset = { x: scroller.scrollLeft, y: scroller.scrollTop }; + const target_offset = { + x: current_offset.x + 100, + y: current_offset.y + 100 + }; + await scrolling_function(scroller, current_offset, target_offset); + + // Only wait for scrollend if it is supported. + if (window.onscrollend == null || window.onscrollend != undefined) { + await scrollend_promise; + } + assert_approx_equals(scroller.scrollTop, target_offset.y, 1, + `${msg} (vertical)`); + assert_approx_equals(scroller.scrollLeft, target_offset.x, 1, + `${msg} (horizontal)`); + } + + promise_test(async (t) => { + let scroller = document.getElementById("user_scroller"); + const msg = "user scroll is not overriden in by scroll-start-target"; + await test_scroll_start_target(t, scroller, msg, user_scroll); + }, "scroll-start-target does not override user scroll"); + + promise_test(async (t) => { + let scroller = document.getElementById("programmatic_scroller"); + const msg = "programmatic scroll is not overriden in by scroll-start-target"; + await test_scroll_start_target(t, scroller, msg, programmatic_scroll); + }, "scroll-start-target does not override programmatic scroll"); + </script> +</body>
\ No newline at end of file diff --git a/testing/web-platform/tests/css/css-scroll-snap-2/scroll-start-target/scroll-start-target.tentative.html b/testing/web-platform/tests/css/css-scroll-snap-2/scroll-start-target/scroll-start-target.tentative.html new file mode 100644 index 0000000000..2e679c3739 --- /dev/null +++ b/testing/web-platform/tests/css/css-scroll-snap-2/scroll-start-target/scroll-start-target.tentative.html @@ -0,0 +1,98 @@ +<!DOCTYPE html> +<html> + +<head> + <meta charset="utf-8"> + <title> CSS Scroll Snap 2 Test: scroll-start-target*</title> + <link rel="help" href="https://drafts.csswg.org/css-scroll-snap-2/#scroll-start-target"> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> +</head> + +<body> + <style> + .spacer { + width: 1000px; + height: 1000px; + } + + .scroller { + width: 300px; + height: 300px; + border: solid 1px black; + overflow: scroll; + margin: 0px; + position: absolute; + } + + .box { + position: absolute; + width: 200px; + height: 200px; + } + + .top_left { + top: 0px; + left: 0px; + background-color: red; + } + + .target_for_x_and_y { + scroll-start-target: auto auto; + } + + .target_for_x { + scroll-start-target: none auto; + } + + .center { + top: 200px; + left: 200px; + background-color: purple; + } + + .bottom_right { + top: 400px; + left: 400px; + background-color: yellow; + } + </style> + <div class="scroller" id="scroller1"> + <div class="spacer"></div> + <div class="top_left box" id="top_left_box1"></div> + <div class="center box target_for_x_and_y" id="centerbox"></div> + <div class="bottom_right box"></div> + </div> + <div class="scroller" id="scroller2"> + <div class="spacer"></div> + <div class="top_left box" id="top_left_box2"></div> + <div class="center box target_for_x" id="centerbox2"></div> + <div class="bottom_right box"></div> + </div> + <script> + test((t) => { + let scroller = document.getElementById("scroller1"); + let top_left_box = document.getElementById("top_left_box1"); + + const expected_scroll_top = top_left_box.getBoundingClientRect().height; + const expected_scroll_left = top_left_box.getBoundingClientRect().width; + + assert_approx_equals(scroller.scrollTop, expected_scroll_top, 1, + "scroll-start-target sets initial vertical scroll position"); + assert_approx_equals(scroller.scrollLeft, expected_scroll_left, 1, + "scroll-start-target sets initial horizontal scroll position"); + }); + test((t) => { + let scroller = document.getElementById("scroller2"); + let top_left_box = document.getElementById("top_left_box2"); + + const expected_scroll_top = 0; + const expected_scroll_left = top_left_box.getBoundingClientRect().width; + + assert_approx_equals(scroller.scrollTop, expected_scroll_top, 1, + "scroll-start-target sets initial vertical scroll position"); + assert_approx_equals(scroller.scrollLeft, expected_scroll_left, 1, + "scroll-start-target sets initial horizontal scroll position"); + }); + </script> +</body>
\ No newline at end of file diff --git a/testing/web-platform/tests/css/css-scroll-snap-2/scroll-start-target/stash.py b/testing/web-platform/tests/css/css-scroll-snap-2/scroll-start-target/stash.py new file mode 100644 index 0000000000..3c65e2b59b --- /dev/null +++ b/testing/web-platform/tests/css/css-scroll-snap-2/scroll-start-target/stash.py @@ -0,0 +1,27 @@ +# Copyright 2023 The Chromium Authors +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. +""" +This file allows the different windows created by +css/css-scroll-snap-2/scroll-start-target-with-text-fragment-navigation.html +to store and retrieve data. + +scroll-start-target-with-text-fragment-navigation.html (test file) opens a window to +scroll-start-target-with-text-fragment-navigation-target.html which writes some data +which the test file will eventually read. This file handles the requests from +both windows. +""" + +import time + +def main(request, response): + key = request.GET.first(b"key") + + if request.method == u"POST": + # Received result data from target page + request.server.stash.put(key, request.body, u'/css/css-scroll-snap-2/scroll-start-target/') + return u"ok" + else: + # Request for result data from test page + value = request.server.stash.take(key, u'/css/css-scroll-snap-2/scroll-start-target/') + return value |