diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 01:47:29 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 01:47:29 +0000 |
commit | 0ebf5bdf043a27fd3dfb7f92e0cb63d88954c44d (patch) | |
tree | a31f07c9bcca9d56ce61e9a1ffd30ef350d513aa /testing/web-platform/tests/css/css-scroll-snap/snap-after-relayout | |
parent | Initial commit. (diff) | |
download | firefox-esr-0ebf5bdf043a27fd3dfb7f92e0cb63d88954c44d.tar.xz firefox-esr-0ebf5bdf043a27fd3dfb7f92e0cb63d88954c44d.zip |
Adding upstream version 115.8.0esr.upstream/115.8.0esr
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'testing/web-platform/tests/css/css-scroll-snap/snap-after-relayout')
11 files changed, 905 insertions, 0 deletions
diff --git a/testing/web-platform/tests/css/css-scroll-snap/snap-after-relayout/adding-only-snap-area.html b/testing/web-platform/tests/css/css-scroll-snap/snap-after-relayout/adding-only-snap-area.html new file mode 100644 index 0000000000..53141707bb --- /dev/null +++ b/testing/web-platform/tests/css/css-scroll-snap/snap-after-relayout/adding-only-snap-area.html @@ -0,0 +1,55 @@ +<!DOCTYPE html> +<title> + Adding a new snap area when there are none should make the scroller snap to it. +</title> +<link rel="help" href="https://drafts.csswg.org/css-scroll-snap/#re-snap" /> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<style> +div { + position: absolute; + margin: 0; +} + +#scroller { + height: 500px; + width: 500px; + overflow: hidden; + scroll-snap-type: both mandatory; +} + +#target { + width: 300px; + height: 300px; + top: 100px; + left: 100px; + background-color: green; + scroll-snap-align: start; +} + +.area { + width: 2000px; + height: 2000px; +} +</style> + +<div id="scroller"> + <div class="area"></div> + <div id="target"></div> +</div> + +<script> +const target = document.getElementById("target"); +const scroller = document.getElementById("scroller"); + +test(() => { + scroller.removeChild(target); + scroller.scrollTo(0,0); + assert_equals(scroller.scrollTop, 0); + assert_equals(scroller.scrollLeft, 0); + + scroller.appendChild(target); + assert_equals(scroller.scrollTop, 100); + assert_equals(scroller.scrollLeft, 100); +}, "Adding a new snap area when there are none should make the scroller snap to it."); +</script> diff --git a/testing/web-platform/tests/css/css-scroll-snap/snap-after-relayout/adding-snap-area-while-snapped.html b/testing/web-platform/tests/css/css-scroll-snap/snap-after-relayout/adding-snap-area-while-snapped.html new file mode 100644 index 0000000000..d26359658f --- /dev/null +++ b/testing/web-platform/tests/css/css-scroll-snap/snap-after-relayout/adding-snap-area-while-snapped.html @@ -0,0 +1,66 @@ +<!DOCTYPE html> +<title> + Adding a new snap area while already snapped should not make the scroller snap to it. +</title> +<link rel="help" href="https://drafts.csswg.org/css-scroll-snap/#re-snap" /> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<style> +div { + position: absolute; + margin: 0; +} + +#scroller { + height: 500px; + width: 500px; + overflow: hidden; + scroll-snap-type: both mandatory; +} + +#initial-target { + width: 300px; + height: 300px; + top: 100px; + left: 100px; + background-color: green; + scroll-snap-align: start; +} + +#other-target { + width: 300px; + height: 300px; + top: 300px; + left: 300px; + background-color: red; + scroll-snap-align: start; +} + +.area { + width: 2000px; + height: 2000px; +} +</style> + +<div id="scroller"> + <div class="area"></div> + <div id="initial-target"></div> + <div id="other-target"></div> +</div> + +<script> +const initial_target = document.getElementById("initial-target"); +const other_target = document.getElementById("other-target"); +const scroller = document.getElementById("scroller"); + +test(() => { + scroller.removeChild(other_target); + scroller.scrollTo(0,0); + assert_equals(scroller.scrollTop, 100); + assert_equals(scroller.scrollLeft, 100); + + scroller.appendChild(other_target); + assert_equals(scroller.scrollTop, 100); + assert_equals(scroller.scrollLeft, 100); +}, "Adding a new snap area while already snapped should not make the scroller snap to it."); +</script> diff --git a/testing/web-platform/tests/css/css-scroll-snap/snap-after-relayout/changing-scroll-snap-align.html b/testing/web-platform/tests/css/css-scroll-snap/snap-after-relayout/changing-scroll-snap-align.html new file mode 100644 index 0000000000..3be68fe841 --- /dev/null +++ b/testing/web-platform/tests/css/css-scroll-snap/snap-after-relayout/changing-scroll-snap-align.html @@ -0,0 +1,121 @@ +<!DOCTYPE html> +<title> + Updating the snap alignment of a snap container's content should make the snap + container resnap accordingly. +</title> +<link rel="help" href="https://drafts.csswg.org/css-scroll-snap/#re-snap" /> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<style> +div { + position: absolute; + margin: 0; +} + +#scroller { + height: 200px; + width: 200px; + overflow: hidden; + scroll-snap-type: both mandatory; +} + +#initial-target { + width: 300px; + height: 300px; + top: 100px; + left: 100px; + background-color: green; + scroll-snap-align: start; +} + +#other-target { + width: 300px; + height: 300px; + top: 300px; + left: 300px; + background-color: red; + scroll-snap-align: start; +} + +.area { + width: 2000px; + height: 2000px; +} + +.snap-area { + scroll-snap-align: start !important; +} +</style> + +<div id="scroller"> + <div class="area"></div> + <div id="initial-target"></div> + <div id="other-target"></div> +</div> + +<script> +const initial_target = document.getElementById("initial-target"); +const other_target = document.getElementById("other-target"); +const scroller = document.getElementById("scroller"); + +function cleanup() { + initial_target.style.setProperty("scroll-snap-align", "start"); + other_target.style.setProperty("scroll-snap-align", "start"); + initial_target.removeAttribute("class"); +} + +test(t => { + t.add_cleanup(cleanup); + scroller.scrollTo(0,0); + assert_equals(scroller.scrollTop, 100); + assert_equals(scroller.scrollLeft, 100); + + initial_target.style.setProperty("scroll-snap-align", "end"); + // target.top + target.height - scroller.height + assert_equals(scroller.scrollTop, 200); + assert_equals(scroller.scrollLeft, 200); +}, "Changing the current target's snap alignment should make the scroller" ++ " resnap to it even if another snap position is closer to the current offset"); + +test(t => { + t.add_cleanup(cleanup); + scroller.scrollTo(0,0); + assert_equals(scroller.scrollTop, 100); + assert_equals(scroller.scrollLeft, 100); + + initial_target.style.setProperty("scroll-snap-align", "none"); + assert_equals(scroller.scrollTop, 300); + assert_equals(scroller.scrollLeft, 300); +}, "Removing the current target's snap alignment should make the scroller" ++ " resnap to a new snap area."); + +test(t => { + t.add_cleanup(cleanup); + initial_target.style.setProperty("scroll-snap-align", "none"); + other_target.style.setProperty("scroll-snap-align", "none"); + + scroller.scrollTo(0,0); + assert_equals(scroller.scrollTop, 0); + assert_equals(scroller.scrollLeft, 0); + + initial_target.style.setProperty("scroll-snap-align", "start"); + assert_equals(scroller.scrollTop, 100); + assert_equals(scroller.scrollLeft, 100); +}, "Changing an element snap alignment from none to start should make the" ++ "scroller resnap."); + +test(t => { + t.add_cleanup(cleanup); + initial_target.style.setProperty("scroll-snap-align", "none"); + other_target.style.setProperty("scroll-snap-align", "none"); + + scroller.scrollTo(0,0); + assert_equals(scroller.scrollTop, 0); + assert_equals(scroller.scrollLeft, 0); + + initial_target.classList.add("snap-area"); + assert_equals(scroller.scrollTop, 100); + assert_equals(scroller.scrollLeft, 100); +}, "Changing an element snap alignment from none to start by adding a class" ++ " should make the scroller resnap."); +</script> diff --git a/testing/web-platform/tests/css/css-scroll-snap/snap-after-relayout/changing-scroll-snap-type-on-root-element.html b/testing/web-platform/tests/css/css-scroll-snap/snap-after-relayout/changing-scroll-snap-type-on-root-element.html new file mode 100644 index 0000000000..c86f39b9d6 --- /dev/null +++ b/testing/web-platform/tests/css/css-scroll-snap/snap-after-relayout/changing-scroll-snap-type-on-root-element.html @@ -0,0 +1,95 @@ +<!DOCTYPE html> +<html> +<title> + Updating the scroll-snap-type of the root element should make it resnap accordingly. + This is another vairant of changing-scroll-snap-type.html for the root element. +</title> +<link rel="help" href="https://drafts.csswg.org/css-scroll-snap/#re-snap" /> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<style> +div { + position: absolute; + margin: 0; +} + +html { + overflow: hidden; + scroll-snap-type: none; +} + +#y-target { + width: 300px; + height: 300px; + top: 100px; + left: 0; + background-color: green; + scroll-snap-align: start none; +} + +#x-target { + width: 300px; + height: 300px; + top: 0; + left: 100px; + background-color: red; + scroll-snap-align: none start; +} + +.area { + width: 1000vw; + height: 1000vh; +} +</style> + +<div class="area"></div> +<div id="x-target"></div> +<div id="y-target"></div> + +<script> +const x_target = document.getElementById("x_target"); +const y_target = document.getElementById("y_target"); +const scroller = document.documentElement; + +function cleanup() { + scroller.style.setProperty("scroll-snap-type", "none"); +} + +test(t => { + t.add_cleanup(cleanup); + scroller.scrollTo(0,0); + assert_equals(scroller.scrollTop, 0); + assert_equals(scroller.scrollLeft, 0); + + scroller.style.setProperty("scroll-snap-type", "y mandatory"); + assert_equals(scroller.scrollTop, 100); + assert_equals(scroller.scrollLeft, 0); +}, "Changing the scroller's snap type to y should make it resnap on the y-axis."); + +test(t => { + t.add_cleanup(cleanup); + scroller.scrollTo(0,0); + assert_equals(scroller.scrollTop, 0); + assert_equals(scroller.scrollLeft, 0); + + scroller.style.setProperty("scroll-snap-type", "x mandatory"); + assert_equals(scroller.scrollLeft, 100); + assert_equals(scroller.scrollTop, 0); +}, "Changing the scroller's snap type to x should make it resnap on the x-axis."); + + +test(t => { + t.add_cleanup(cleanup); + scroller.scrollTo(0,0); + assert_equals(scroller.scrollTop, 0); + assert_equals(scroller.scrollLeft, 0); + + scroller.style.setProperty("scroll-snap-type", "x mandatory"); + assert_equals(scroller.scrollLeft, 100); + assert_equals(scroller.scrollTop, 0); + + scroller.style.setProperty("scroll-snap-type", "y mandatory"); + assert_equals(scroller.scrollTop, 100); +}, "Changing the scroller's snap type axis should make it resnap."); +</script> +</html> diff --git a/testing/web-platform/tests/css/css-scroll-snap/snap-after-relayout/changing-scroll-snap-type.html b/testing/web-platform/tests/css/css-scroll-snap/snap-after-relayout/changing-scroll-snap-type.html new file mode 100644 index 0000000000..70774b3d40 --- /dev/null +++ b/testing/web-platform/tests/css/css-scroll-snap/snap-after-relayout/changing-scroll-snap-type.html @@ -0,0 +1,96 @@ +<!DOCTYPE html> +<title> + Updating the scroll-snap-type of a snap container should make it resnap accordingly. +</title> +<link rel="help" href="https://drafts.csswg.org/css-scroll-snap/#re-snap" /> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<style> +div { + position: absolute; + margin: 0; +} + +#scroller { + height: 500px; + width: 500px; + overflow: hidden; + scroll-snap-type: none; +} + +#y-target { + width: 300px; + height: 300px; + top: 100px; + left: 0; + background-color: green; + scroll-snap-align: start none; +} + +#x-target { + width: 300px; + height: 300px; + top: 0; + left: 100px; + background-color: red; + scroll-snap-align: none start; +} + +.area { + width: 2000px; + height: 2000px; +} +</style> + +<div id="scroller"> + <div class="area"></div> + <div id="x-target"></div> + <div id="y-target"></div> +</div> + +<script> +const x_target = document.getElementById("x_target"); +const y_target = document.getElementById("y_target"); +const scroller = document.getElementById("scroller"); + +function cleanup() { + scroller.style.setProperty("scroll-snap-type", "none"); +} + +test(t => { + t.add_cleanup(cleanup); + scroller.scrollTo(0,0); + assert_equals(scroller.scrollTop, 0); + assert_equals(scroller.scrollLeft, 0); + + scroller.style.setProperty("scroll-snap-type", "y mandatory"); + assert_equals(scroller.scrollTop, 100); + assert_equals(scroller.scrollLeft, 0); +}, "Changing the scroller's snap type to y should make it resnap on the y-axis."); + +test(t => { + t.add_cleanup(cleanup); + scroller.scrollTo(0,0); + assert_equals(scroller.scrollTop, 0); + assert_equals(scroller.scrollLeft, 0); + + scroller.style.setProperty("scroll-snap-type", "x mandatory"); + assert_equals(scroller.scrollLeft, 100); + assert_equals(scroller.scrollTop, 0); +}, "Changing the scroller's snap type to x should make it resnap on the x-axis."); + + +test(t => { + t.add_cleanup(cleanup); + scroller.scrollTo(0,0); + assert_equals(scroller.scrollTop, 0); + assert_equals(scroller.scrollLeft, 0); + + scroller.style.setProperty("scroll-snap-type", "x mandatory"); + assert_equals(scroller.scrollLeft, 100); + assert_equals(scroller.scrollTop, 0); + + scroller.style.setProperty("scroll-snap-type", "y mandatory"); + assert_equals(scroller.scrollTop, 100); +}, "Changing the scroller's snap type axis should make it resnap."); +</script> diff --git a/testing/web-platform/tests/css/css-scroll-snap/snap-after-relayout/focus-element-no-snap.html b/testing/web-platform/tests/css/css-scroll-snap/snap-after-relayout/focus-element-no-snap.html new file mode 100644 index 0000000000..9ec004c628 --- /dev/null +++ b/testing/web-platform/tests/css/css-scroll-snap/snap-after-relayout/focus-element-no-snap.html @@ -0,0 +1,51 @@ +<!doctype html> +<title>Resnap to focused element after relayout</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<style> + +#snapper { + width: 100px; + height: 200px; + overflow-x: scroll; + scroll-snap-type: x mandatory; + color: white; + background-color: oldlace; + display: flex; + align-items: center; +} +.child { + margin-right: 0.5rem; + height: 90%; + scroll-snap-align: start; + padding: 1rem; + display: flex; + align-items: center; + justify-content: center; + text-align: center; + width: 100px; + height: 100px; + background-color: indigo; +} +</style> + +<link rel="help" href="https://drafts.csswg.org/css-scroll-snap/#re-snap"> + +<div id=snapper> + <div class="child no-snap" tabindex=-1></div> + <div class=child></div> + <div class="child" id ="focus" tabindex=-1></div> + <div class="child" tabindex=-1></div> + <div class=child></div> + <div class=child></div> +</div> + +<script> + +test(t => { + document.getElementById("focus").focus(); + const element = document.getElementById("snapper"); + element.style.width = "101px"; + assert_equals(element.scrollLeft, 0); +}); +</script> diff --git a/testing/web-platform/tests/css/css-scroll-snap/snap-after-relayout/move-current-target.html b/testing/web-platform/tests/css/css-scroll-snap/snap-after-relayout/move-current-target.html new file mode 100644 index 0000000000..ccadc884c5 --- /dev/null +++ b/testing/web-platform/tests/css/css-scroll-snap/snap-after-relayout/move-current-target.html @@ -0,0 +1,116 @@ +<!DOCTYPE html> +<title> + Moving the current snap target should make the scroller resnap to it. +</title> +<link rel="help" href="https://drafts.csswg.org/css-scroll-snap/#re-snap" /> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<style> +div { + position: relative; + margin: 0; +} + +#block { + height: 100px; + width: 100px; +} + +#scroller { + height: 500px; + width: 500px; + overflow: hidden; + scroll-snap-type: both mandatory; +} + +#initial-target { + width: 300px; + height: 300px; + left: 100px; + top: 0; + transform: none; + background-color: green; + scroll-snap-align: start; +} + +#other-target { + width: 300px; + height: 300px; + left: 300px; + background-color: red; + scroll-snap-align: start; +} + +.area { + width: 2000px; + height: 2000px; +} +</style> + +<div id="scroller"> + <div id="block"></div> + <div id="initial-target"></div> + <div id="other-target"></div> + <div class="area"></div> +</div> + +<script> +const initial_target = document.getElementById("initial-target"); +const other_target = document.getElementById("other-target"); +const block = document.getElementById("block"); +const scroller = document.getElementById("scroller"); + +function cleanup() { + initial_target.style.setProperty("transform", "none"); + initial_target.style.setProperty("top", "0"); + block.style.setProperty("height", "100px"); +} + +test(t => { + t.add_cleanup(cleanup); + scroller.scrollTo(0,0); + assert_equals(scroller.scrollTop, 100); + assert_equals(scroller.scrollLeft, 100); + + initial_target.style.setProperty("top", "300px"); + assert_equals(scroller.scrollTop, 400); + assert_equals(scroller.scrollLeft, 100); +}, "Moving the current snap target should make the scroller resnap to it."); + +test(t => { + t.add_cleanup(cleanup); + scroller.scrollTo(0,0); + assert_equals(scroller.scrollTop, 100); + assert_equals(scroller.scrollLeft, 100); + + block.style.setProperty("height", "200px"); + assert_equals(scroller.scrollTop, 200); + assert_equals(scroller.scrollLeft, 100); +}, "Changing the layout of other elements should be able to cause resnapping to \ +the target."); + +test(t => { + t.add_cleanup(cleanup); + scroller.scrollTo(0,0); + assert_equals(scroller.scrollTop, 100); + assert_equals(scroller.scrollLeft, 100); + + initial_target.style.setProperty("transform", "translate(0,100px)"); + assert_equals(scroller.scrollTop, 200); + assert_equals(scroller.scrollLeft, 100); +}, "Transforming the current snap target should make the scroller resnap to it."); + +test(t => { + t.add_cleanup(cleanup); + initial_target.style.setProperty("top", "100px"); + scroller.scrollTo(0,0); + assert_equals(scroller.scrollTop, 200); + assert_equals(scroller.scrollLeft, 100); + + initial_target.style.setProperty("transform", "translate(0,100px)"); + initial_target.style.setProperty("top", "0"); + assert_equals(scroller.scrollTop, 200); + assert_equals(scroller.scrollLeft, 100); +}, "Applying two property changes that do not change the visual offset of the \ +target should not change the scroll offset."); +</script> diff --git a/testing/web-platform/tests/css/css-scroll-snap/snap-after-relayout/not-resnap-outside-proximity-threshold.html b/testing/web-platform/tests/css/css-scroll-snap/snap-after-relayout/not-resnap-outside-proximity-threshold.html new file mode 100644 index 0000000000..b2c5720efb --- /dev/null +++ b/testing/web-platform/tests/css/css-scroll-snap/snap-after-relayout/not-resnap-outside-proximity-threshold.html @@ -0,0 +1,66 @@ +<!DOCTYPE html> +<title> + Not re-snap once after a scroll operation has finished without snapping + because the scroll destination was outside of the snap proximity threshold. +</title> +<!-- This test assumes that all major browsers' default scroll-snap proximity + thresholds are greater than 200px. --> +<link rel="help" href="https://drafts.csswg.org/css-scroll-snap/#re-snap" /> +<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1780154"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.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> + +<div id="scroller"> + <div class="area"></div> + <div class="snap" style="top: 0px;"></div> + <div class="snap" style="top: 500px;"></div> +</div> + +<script> +test(() => { + // The initial snap position is at (0, 0). + assert_equals(scroller.scrollTop, 0); + assert_equals(scroller.scrollLeft, 0); + + // 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); + + assert_equals(scroller.scrollTop, 250); + assert_equals(scroller.scrollLeft, 0); + + // Changing the initial snap target position, but still it's outside of the + // threshold. + document.querySelectorAll(".snap")[0].style.top = "10px"; + + // Not re-snap to the last snap point. + assert_equals(scroller.scrollTop, 250); + assert_equals(scroller.scrollLeft, 0); +}, "Not re-snap once after a scroll operation has finished without snapping " + + "because the scroll destination was outside of the snap proximity threshold."); +</script> diff --git a/testing/web-platform/tests/css/css-scroll-snap/snap-after-relayout/remove-current-target.html b/testing/web-platform/tests/css/css-scroll-snap/snap-after-relayout/remove-current-target.html new file mode 100644 index 0000000000..82bddf8074 --- /dev/null +++ b/testing/web-platform/tests/css/css-scroll-snap/snap-after-relayout/remove-current-target.html @@ -0,0 +1,65 @@ +<!DOCTYPE html> +<title> + Removing the current snap target should make the scroller snap to a new target. +</title> +<link rel="help" href="https://drafts.csswg.org/css-scroll-snap/#re-snap" /> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<style> +div { + position: absolute; + margin: 0; +} + +#scroller { + height: 500px; + width: 500px; + overflow: hidden; + scroll-snap-type: both mandatory; +} + +#initial-target { + width: 300px; + height: 300px; + top: 100px; + left: 100px; + background-color: red; + scroll-snap-align: start; +} + +#other-target { + width: 300px; + height: 300px; + top: 300px; + left: 300px; + background-color: green; + scroll-snap-align: start; +} + +.area { + width: 2000px; + height: 2000px; +} +</style> + +<div id="scroller"> + <div class="area"></div> + <div id="initial-target"></div> + <div id="other-target"></div> +</div> + +<script> +const initial_target = document.getElementById("initial-target"); +const other_target = document.getElementById("other-target"); +const scroller = document.getElementById("scroller"); + +test(() => { + scroller.scrollTo(0,0); + assert_equals(scroller.scrollTop, 100); + assert_equals(scroller.scrollLeft, 100); + + scroller.removeChild(initial_target); + assert_equals(scroller.scrollTop, 300); + assert_equals(scroller.scrollLeft, 300); +}, "Removing the current snap target should make the scroller snap to a new target."); +</script> diff --git a/testing/web-platform/tests/css/css-scroll-snap/snap-after-relayout/resnap-to-focused.html b/testing/web-platform/tests/css/css-scroll-snap/snap-after-relayout/resnap-to-focused.html new file mode 100644 index 0000000000..637c578a85 --- /dev/null +++ b/testing/web-platform/tests/css/css-scroll-snap/snap-after-relayout/resnap-to-focused.html @@ -0,0 +1,82 @@ +<!doctype html> +<title>Resnap to focused element after relayout</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<style> + +#snapper { + counter-reset: child 0; + width: 200px; + scroll-snap-type: block mandatory; + overflow:hidden; + height: 100px; +} +.child { + width: 100px; + height: 100px; + background:red; + text-align: center; + box-sizing: border-box; + counter-increment: child; + float: left; +} +.child.f { + background: green; + scroll-snap-align: center; +} +.child::before { + content: counter(child); +} + +</style> + +<link rel=author title="Tab Atkins-Bittner" href="https://www.xanthir.com/contact/"> +<link rel="help" href="https://drafts.csswg.org/css-scroll-snap/#re-snap"> +<!-- +When re-snapping after a layout change, +if multiple elements were capable of being the snap target previously, +and one of them is focused, +you must resnap to the focused one. +--> +<div id=snapper> + <div class="child no-snap" tabindex=-1></div> + <div class=child></div> + <div class="child f" tabindex=-1></div> + <div class="child f" tabindex=-1></div> + <div class=child></div> + <div class=child></div> +</div> + +<script> + +var container = document.querySelector("#snapper"); +var [one,two] = document.querySelectorAll(".child.f"); +var unsnappable = document.querySelector(".child.no-snap"); + +async_test(t=>{ + requestAnimationFrame(()=>{ + testSnap(t, one, 3); + requestAnimationFrame(()=>{ + testSnap(t, two, 4); + requestAnimationFrame(()=>{ + testSnap(t, one, 3); + t.done(); + }); + }); + }); +}); + +function testSnap(t, child, expectedRow) { + t.step(()=>{ + unsnappable.focus(); + container.style.width = "200px"; + var startingRow = container.scrollTop/100 + 1; + assert_equals(startingRow, 2, "Initially snapped to row 2"); + child.focus(); + container.style.width = "100px"; + var endingRow = container.scrollTop/100 + 1; + assert_equals(endingRow, expectedRow, `After resize, should snap to row ${expectedRow}.`); + }); +} + +</script> diff --git a/testing/web-platform/tests/css/css-scroll-snap/snap-after-relayout/snap-to-different-targets.html b/testing/web-platform/tests/css/css-scroll-snap/snap-after-relayout/snap-to-different-targets.html new file mode 100644 index 0000000000..7ad659d8a6 --- /dev/null +++ b/testing/web-platform/tests/css/css-scroll-snap/snap-after-relayout/snap-to-different-targets.html @@ -0,0 +1,92 @@ +<!DOCTYPE html> +<title> + The scroller should try to resnap to targets for both axes if possible. +</title> +<link rel="help" href="https://drafts.csswg.org/css-scroll-snap/#re-snap" /> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<style> +div { + position: absolute; + margin: 0; +} + +#scroller { + height: 500px; + width: 500px; + overflow: hidden; + scroll-snap-type: both mandatory; +} + +#x-axis-target { + scroll-snap-align: none start; + background-color: blue; + width: 100px; + height: 100px; + top: 400px; + left: 200px; +} + +#y-axis-target { + scroll-snap-align: start none; + background-color: green; + width: 100px; + height: 100px; + top: 200px; + left: 400px; +} + +#far-x-axis-target { + scroll-snap-align: none start; + background-color: blue; + width: 100px; + height: 100px; + top: 1200px; + left: 300px; +} + +#far-y-axis-target { + scroll-snap-align: start none; + background-color: green; + width: 100px; + height: 100px; + top: 300px; + left: 1200px; +} + +.area { + width: 2000px; + height: 2000px; +} +</style> + +<div id="scroller"> + <div class="area"></div> + <div id="x-axis-target"></div> + <div id="y-axis-target"></div> + <div id="far-x-axis-target"></div> + <div id="far-y-axis-target"></div> +</div> + +<script> + +const x_target = document.getElementById("x-axis-target"); +const y_target = document.getElementById("y-axis-target"); +const scroller = document.getElementById("scroller"); + +test(t => { + // The scroller should be snapped to the two closest points on first layout. + assert_equals(scroller.scrollTop, 200); + assert_equals(scroller.scrollLeft, 200); + x_target.style.setProperty("left", "1000px"); + y_target.style.setProperty("top", "1000px"); + + // The style change makes it impossible for the scroller to snap to both + // targets, but at least one of the targets should be preserved. The scroller + // should then re-evaluate the snap point for the other axis. + const snapped_to_x = scroller.scrollLeft == 1000 && scroller.scrollTop == 300; + const snapped_to_y = scroller.scrollTop == 1000 && scroller.scrollLeft == 300; + assert_true(snapped_to_x || snapped_to_y); +}, "Scroller should snap to at least one of the targets if unable to snap to\ +both after a layout change."); +</script> |