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/scroll-animations/css/timeline-scope.html | |
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/scroll-animations/css/timeline-scope.html')
-rw-r--r-- | testing/web-platform/tests/scroll-animations/css/timeline-scope.html | 322 |
1 files changed, 322 insertions, 0 deletions
diff --git a/testing/web-platform/tests/scroll-animations/css/timeline-scope.html b/testing/web-platform/tests/scroll-animations/css/timeline-scope.html new file mode 100644 index 0000000000..e4e90bc03a --- /dev/null +++ b/testing/web-platform/tests/scroll-animations/css/timeline-scope.html @@ -0,0 +1,322 @@ +<!DOCTYPE html> +<title>Behavior of the timeline-scope property</title> +<link rel="help" src="https://github.com/w3c/csswg-drafts/issues/7759"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/web-animations/testcommon.js"></script> + +<main id=main></main> +<script> + async function inflate(t, template) { + t.add_cleanup(() => main.replaceChildren()); + return runAndWaitForFrameUpdate(() => { + main.append(template.content.cloneNode(true)); + }); + } + + async function scrollTop(e, value) { + e.scrollTop = value; + await waitForNextFrame(); + } +</script> +<style> + @keyframes anim { + from { width: 0px; } + to { width: 200px; } + } + + .scroller { + overflow-y: hidden; + width: 200px; + height: 200px; + } + .scroller > .content { + margin: 400px 0px; + width: 100px; + height: 100px; + background-color: green; + } + .target { + background-color: coral; + width: 0px; + animation: anim auto linear; + animation-timeline: --t1; + } + .timeline { + scroll-timeline-name: --t1; + } + .scope { + timeline-scope: --t1; + } + +</style> + +<!-- Basic Behavior --> + +<template id=deferred_timeline> + <div class="scope"> + <div class=target>Test</div> + <div class="scroller timeline"> + <div class=content></div> + </div> + </div> +</template> +<script> + promise_test(async (t) => { + await inflate(t, deferred_timeline); + let scroller = main.querySelector('.scroller'); + let target = main.querySelector('.target'); + + const anim = target.getAnimations()[0]; + await anim.ready; + + await scrollTop(scroller, 350); // 50% + assert_equals(getComputedStyle(target).width, '100px'); // 0px => 200px, 50% + }, 'Descendant can attach to deferred timeline'); +</script> + +<template id=deferred_timeline_no_attachments> + <div class="scope"> + <div class=target>Test</div> + <div class="scroller"> + <div class=content></div> + </div> + </div> +</template> +<script> + promise_test(async (t) => { + await inflate(t, deferred_timeline_no_attachments); + let scroller = main.querySelector('.scroller'); + let target = main.querySelector('.target'); + await scrollTop(scroller, 350); // 50% + assert_equals(getComputedStyle(target).width, '0px'); + }, 'Deferred timeline with no attachments'); +</script> + +<template id=scroll_timeline_inner_interference> + <div class="scroller timeline"> + <div class=content> + <div class=target>Test</div> + <div class="scroller timeline"> + <div class=content></div> + </div> + </div> + </div> +</template> +<script> + promise_test(async (t) => { + await inflate(t, scroll_timeline_inner_interference); + let scroller = main.querySelector('.scroller'); + let target = main.querySelector('.target'); + await scrollTop(scroller, 350); // 50% + assert_equals(getComputedStyle(target).width, '100px'); // 0px => 200px, 50% + }, 'Inner timeline does not interfere with outer timeline'); +</script> + +<template id=deferred_timeline_two_attachments> + <div class="scope"> + <div class=target>Test</div> + <div class="scroller timeline"> + <div class=content></div> + </div> + <!-- Extra attachment --> + <div class="timeline"></div> + </div> +</template> +<script> + promise_test(async (t) => { + await inflate(t, deferred_timeline_two_attachments); + let scroller = main.querySelector('.scroller'); + let target = main.querySelector('.target'); + await scrollTop(scroller, 350); // 50% + assert_equals(getComputedStyle(target).width, '0px'); + }, 'Deferred timeline with two attachments'); +</script> + +<!-- Dynamic Reattachment --> + +<template id=deferred_timeline_reattach> + <div class="scope"> + <div class=target>Test</div> + <div class="scroller timeline"> + <div class=content></div> + </div> + <div class="scroller"> + <div class=content></div> + </div> + </div> +</template> +<script> + promise_test(async (t) => { + await inflate(t, deferred_timeline_reattach); + let scrollers = main.querySelectorAll('.scroller'); + assert_equals(scrollers.length, 2); + let target = main.querySelector('.target'); + await scrollTop(scrollers[0], 350); // 50% + await scrollTop(scrollers[1], 175); // 25% + + // Attached to scrollers[0]. + assert_equals(getComputedStyle(target).width, '100px'); // 0px => 200px, 50% + + // Reattach to scrollers[1]. + await runAndWaitForFrameUpdate(() => { + scrollers[0].classList.remove('timeline'); + scrollers[1].classList.add('timeline'); + }); + + assert_equals(getComputedStyle(target).width, '50px'); // 0px => 200px, 25% + }, 'Dynamically re-attaching'); +</script> + +<template id=deferred_timeline_dynamic_detach> + <div class="scope"> + <div class=target>Test</div> + <div class="scroller timeline"> + <div class=content></div> + </div> + <div class="scroller timeline"> + <div class=content></div> + </div> + </div> +</template> +<script> + promise_test(async (t) => { + await inflate(t, deferred_timeline_dynamic_detach); + let scrollers = main.querySelectorAll('.scroller'); + assert_equals(scrollers.length, 2); + let target = main.querySelector('.target'); + await scrollTop(scrollers[0], 350); // 50% + await scrollTop(scrollers[1], 175); // 25% + + // Attached to two timelines initially: + assert_equals(getComputedStyle(target).width, '0px'); + + // Detach scrollers[1]. + await runAndWaitForFrameUpdate(() => { + scrollers[1].classList.remove('timeline'); + }); + + assert_equals(getComputedStyle(target).width, '100px'); // 0px => 200px, 50% + + // Also detach scrollers[0]. + scrollers[0].classList.remove('timeline'); + + await waitForNextFrame(); + assert_equals(getComputedStyle(target).width, '0px'); + }, 'Dynamically detaching'); +</script> + +<template id=deferred_timeline_attached_removed> + <div class="scope"> + <div class=target>Test</div> + <div class="scroller timeline"> + <div class=content></div> + </div> + </div> +</template> +<script> + promise_test(async (t) => { + await inflate(t, deferred_timeline_attached_removed); + let scroller = main.querySelector('.scroller'); + let target = main.querySelector('.target'); + await scrollTop(scroller, 350); // 50% + assert_equals(getComputedStyle(target).width, '100px'); // 0px => 200px, 50% + + let scroller_parent = scroller.parentElement; + scroller.remove(); + await waitForNextFrame(); + assert_equals(getComputedStyle(target).width, '0px'); + + scroller_parent.append(scroller); + await scrollTop(scroller, 350); // 50% + assert_equals(getComputedStyle(target).width, '100px'); // 0px => 200px, 50% + }, 'Removing/inserting element with attaching timeline'); +</script> + +<template id=deferred_timeline_attached_display_none> + <div class="scope"> + <div class=target>Test</div> + <div class="scroller timeline"> + <div class=content></div> + </div> + </div> +</template> +<script> + promise_test(async (t) => { + await inflate(t, deferred_timeline_attached_display_none); + let scroller = main.querySelector('.scroller'); + let target = main.querySelector('.target'); + await scrollTop(scroller, 350); // 50% + assert_equals(getComputedStyle(target).width, '100px'); // 0px => 200px, 50% + + scroller.style.display = 'none'; + await waitForNextFrame(); + assert_equals(getComputedStyle(target).width, '0px'); + + scroller.style.display = 'block'; + await scrollTop(scroller, 350); // 50% + assert_equals(getComputedStyle(target).width, '100px'); // 0px => 200px, 50% + }, 'Ancestor attached element becoming display:none/block'); +</script> + +<template id=deferred_timeline_appearing> + <div class=container> + <div class=target>Test</div> + <div class="scroller timeline"> + <div class=content></div> + </div> + </div> +</template> +<script> + promise_test(async (t) => { + await inflate(t, deferred_timeline_appearing); + let container = main.querySelector('.container'); + let scroller = main.querySelector('.scroller'); + let target = main.querySelector('.target'); + + await scrollTop(scroller, 350); // 50% + + // Not attached to any timeline initially. + assert_equals(getComputedStyle(target).width, '0px'); + + // Add the deferred timeline. + container.classList.add('scope'); + await waitForNextFrame(); + assert_equals(getComputedStyle(target).width, '100px'); // 0px => 200px, 50% + + // Remove the deferred timeline. + container.classList.remove('scope'); + await waitForNextFrame(); + assert_equals(getComputedStyle(target).width, '0px'); + }, 'A deferred timeline appearing dynamically in the ancestor chain'); +</script> + +<template id=deferred_timeline_on_self> + <div class="scroller timeline scope"> + <div class=content> + <div class=target></div> + </div> + <div class=scroller2></div> + </div> +</template> +<script> + promise_test(async (t) => { + await inflate(t, deferred_timeline_on_self); + let scroller = main.querySelector('.scroller'); + let target = main.querySelector('.target'); + await scrollTop(scroller, 525); // 75% + + assert_equals(getComputedStyle(target).width, '150px'); // 0px => 200px, 75% + + // A second scroll-timeline now attaches to the same root. + let scroller2 = main.querySelector('.scroller2'); + scroller2.classList.add('timeline'); + await waitForNextFrame(); + + // The deferred timeline produced by timeline-scope is now inactive, + // but it doesn't matter, because we preferred to attach + // to the non-deferred timeline. + assert_equals(getComputedStyle(target).width, '150px'); // 0px => 200px, 75% + }, 'Animations prefer non-deferred timelines'); + +</script> |