200 lines
5.6 KiB
HTML
200 lines
5.6 KiB
HTML
<!DOCTYPE html>
|
|
<title>Changes to view-timeline are reflected in dependent elements</title>
|
|
<link rel="help" src="https://drafts.csswg.org/scroll-animations-1/#view-timeline-shorthand">
|
|
<script src="/resources/testharness.js"></script>
|
|
<script src="/resources/testharnessreport.js"></script>
|
|
<script src="/web-animations/testcommon.js"></script>
|
|
<script src="support/testcommon.js"></script>
|
|
<style>
|
|
@keyframes anim {
|
|
from { z-index: 0; }
|
|
to { z-index: 100; }
|
|
}
|
|
.scroller {
|
|
overflow: hidden;
|
|
width: 100px;
|
|
height: 100px;
|
|
}
|
|
.scroller > div {
|
|
height: 100px;
|
|
}
|
|
#target {
|
|
height: 0px;
|
|
z-index: -1;
|
|
}
|
|
</style>
|
|
<main id=main></main>
|
|
<script>
|
|
setup(assert_implements_animation_timeline);
|
|
|
|
function inflate(t, template) {
|
|
t.add_cleanup(() => main.replaceChildren());
|
|
main.append(template.content.cloneNode(true));
|
|
main.offsetTop;
|
|
}
|
|
async function scrollTop(e, value) {
|
|
e.scrollTop = value;
|
|
await waitForNextFrame();
|
|
}
|
|
async function scrollLeft(e, value) {
|
|
e.scrollLeft = value;
|
|
await waitForNextFrame();
|
|
}
|
|
</script>
|
|
|
|
<template id=dynamic_view_timeline_attachment>
|
|
<style>
|
|
#scroller {
|
|
timeline-scope: --t1;
|
|
}
|
|
.timeline {
|
|
view-timeline: --t1;
|
|
}
|
|
#target {
|
|
animation: anim 1s linear;
|
|
animation-timeline: --t1;
|
|
}
|
|
</style>
|
|
<div id=scroller class=scroller>
|
|
<div id=div75></div>
|
|
<div id=div25></div>
|
|
<div id=div_before></div>
|
|
<div id=target></div>
|
|
</div>
|
|
</template>
|
|
<script>
|
|
promise_test(async (t) => {
|
|
inflate(t, dynamic_view_timeline_attachment);
|
|
|
|
await scrollTop(scroller, 50);
|
|
|
|
// scrollTop=50 is 75% for div75.
|
|
div75.classList.add('timeline');
|
|
await waitForCSSScrollTimelineStyle();
|
|
assert_equals(getComputedStyle(target).zIndex, '75', 'div75');
|
|
|
|
// Identical timelines in div75 and div25 creates an ambiguity.
|
|
div25.classList.add('timeline');
|
|
await waitForCSSScrollTimelineStyle();
|
|
assert_equals(getComputedStyle(target).zIndex, '-1', 'ambiguous');
|
|
// Removing the timeline from div75 unambiguously links div25 to the
|
|
// timeline, making scrollTop=50 at 25% for div25.
|
|
div75.classList.remove('timeline');
|
|
await waitForCSSScrollTimelineStyle();
|
|
assert_equals(getComputedStyle(target).zIndex, '25', 'div25');
|
|
|
|
// scrollTop=50 is before the timeline start for div_before.
|
|
div25.classList.remove('timeline');
|
|
div_before.classList.add('timeline');
|
|
await waitForCSSScrollTimelineStyle();
|
|
assert_equals(getComputedStyle(target).zIndex, '-1', 'ahead of div_before');
|
|
// Scroll to 25% (for div_before) to verify that we're linked to that
|
|
// timeline.
|
|
await scrollTop(scroller, 150);
|
|
assert_equals(getComputedStyle(target).zIndex, '25', 'div_before');
|
|
|
|
// Linking the timeline back to div25 verifies that the new scrollTop=150 is
|
|
// actually at 75%.
|
|
div_before.classList.remove('timeline');
|
|
div25.classList.add('timeline');
|
|
await waitForCSSScrollTimelineStyle();
|
|
assert_equals(getComputedStyle(target).zIndex, '75', 'div25 again');
|
|
}, 'Dynamically changing view-timeline attachment');
|
|
</script>
|
|
|
|
<template id=dynamic_view_timeline_axis>
|
|
<style>
|
|
#timeline {
|
|
view-timeline: --t1;
|
|
width: 100px;
|
|
height: 100px;
|
|
margin: 100px;
|
|
}
|
|
#target {
|
|
animation: anim 1s linear;
|
|
animation-timeline: --t1;
|
|
}
|
|
</style>
|
|
<div id=scroller class=scroller>
|
|
<div id=timeline style="background: red;">
|
|
<div id=target></div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
<script>
|
|
promise_test(async (t) => {
|
|
inflate(t, dynamic_view_timeline_axis);
|
|
|
|
await scrollTop(scroller, 50); // 25% (vertical)
|
|
await scrollLeft(scroller, 20); // 10% (horizontal)
|
|
|
|
assert_equals(getComputedStyle(target).zIndex, '25', 'vertical');
|
|
timeline.style.viewTimelineAxis = 'x';
|
|
await waitForCSSScrollTimelineStyle();
|
|
assert_equals(getComputedStyle(target).zIndex, '10', 'horizontal');
|
|
}, 'Dynamically changing view-timeline-axis');
|
|
</script>
|
|
|
|
<template id=dynamic_view_timeline_inset>
|
|
<style>
|
|
#timeline {
|
|
width: 100px;
|
|
height: 100px;
|
|
margin: 100px;
|
|
view-timeline: --t1;
|
|
}
|
|
#target {
|
|
animation: anim 1s linear;
|
|
animation-timeline: --t1;
|
|
}
|
|
</style>
|
|
<div id=scroller class=scroller>
|
|
<div id=timeline style="background: red;">
|
|
<div id=target></div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
<script>
|
|
promise_test(async (t) => {
|
|
inflate(t, dynamic_view_timeline_inset);
|
|
|
|
await scrollTop(scroller, 50); // 25% (without inset).
|
|
|
|
assert_equals(getComputedStyle(target).zIndex, '25', 'without inset');
|
|
timeline.style.viewTimelineInset = '0px 50px';
|
|
await waitForCSSScrollTimelineStyle();
|
|
assert_equals(getComputedStyle(target).zIndex, '0', 'with inset');
|
|
}, 'Dynamically changing view-timeline-inset');
|
|
</script>
|
|
|
|
<template id=timeline_display_none>
|
|
<style>
|
|
#scroller {
|
|
timeline-scope: --t1;
|
|
}
|
|
#timeline {
|
|
view-timeline: --t1;
|
|
}
|
|
#target {
|
|
animation: anim 1s linear;
|
|
animation-timeline: --t1;
|
|
}
|
|
</style>
|
|
<div id=scroller class=scroller>
|
|
<div></div>
|
|
<div id=timeline></div>
|
|
<div id=target></div>
|
|
</div>
|
|
</template>
|
|
<script>
|
|
promise_test(async (t) => {
|
|
inflate(t, timeline_display_none);
|
|
|
|
await scrollTop(scroller, 50);
|
|
assert_equals(getComputedStyle(target).zIndex, '25', 'display:block');
|
|
timeline.style.display = 'none';
|
|
await waitForNextFrame();
|
|
// The timeline became inactive.
|
|
assert_equals(getComputedStyle(target).zIndex, '-1', 'display:none');
|
|
}, 'Element with scoped view-timeline becoming display:none');
|
|
</script>
|