Update web-platform-tests to revision b'02400d32d48521baa38663fe8601779994fcfb78'

This commit is contained in:
WPT Sync Bot 2023-05-21 01:35:12 +00:00
parent bc8cea2495
commit f0bb7a6f9c
483 changed files with 12767 additions and 2644 deletions

View file

@ -24,14 +24,14 @@
}
#scroller {
scroll-timeline: timeline;
scroll-timeline: --timeline;
}
#element {
z-index: -1;
animation-name: anim;
animation-duration: auto;
animation-timeline: timeline;
animation-timeline: --timeline;
}
</style>
<main>

View file

@ -32,8 +32,8 @@
}
.animate {
animation: anim auto linear;
view-timeline: timeline;
animation-timeline: timeline;
view-timeline: --timeline;
animation-timeline: --timeline;
animation-range-start: entry 0%;
animation-range-end: entry 100%;
}

View file

@ -37,8 +37,8 @@
background-color: green;
animation: anim-1 auto linear, anim-2 auto linear;
animation-range: normal, cover;
view-timeline: t1;
animation-timeline: t1, t1;
view-timeline: --t1;
animation-timeline: --t1, --t1;
}
</style>
<body>

View file

@ -0,0 +1,72 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<link rel="help" src="https://drafts.csswg.org/scroll-animations-1/#named-timeline-range">
<link rel="stylesheet" href="support/animation-range.css">
<style>
.meter {
animation: active-interval linear 100s paused;
animation-timeline: auto;
}
.bar {
animation: slide-in linear 100s paused;
animation-timeline: auto;
}
</style>
</head>
<body>
<h3>View timeline</h3>
<template id="meters">
<div class="meters">
<div class="cover"><div class="meter"><div class="bar"></div></div><div>Cover</div></div>
<div class="contain"><div class="meter"><div class="bar"></div></div><div>Contain</div></div>
<div class="entry"><div class="meter"><div class="bar"></div></div><div>Entry</div></div>
<div class="exit"><div class="meter"><div class="bar"></div></div><div>Exit</div></div>
</div>
</template>
<div class="flex">
<div>
<div class="scroller">
<div class="subject" style="margin-top: 90px;" data-progress=".08333,-1,.5,-1"></div>
<div class="spacer"></div>
</div>
</div>
<div>
<div class="scroller">
<div class="subject" style="margin-top: 70px;" data-progress=".25,.125,2,-1"></div>
<div class="spacer"></div>
</div>
</div>
<div>
<div class="scroller">
<div class="subject" style="margin-top: 10px;" data-progress=".75,.875,2,-1"></div>
<div class="spacer"></div>
</div>
</div>
<div>
<div class="scroller">
<div class="subject" style="margin-top: -10px;" data-progress=".91667,2,2,.5"></div>
<div class="spacer"></div>
</div>
</div>
</div>
</body>
<script>
let template = document.querySelector('#meters');
let subjects = document.querySelectorAll('.subject');
for (let i = 0; i < subjects.length; i++) {
let clone = template.content.cloneNode(true);
let meters = clone.querySelectorAll('.meter');
let progress = subjects[i].getAttribute('data-progress').split(',').map(s => parseFloat(s));
for (let meter of meters) {
let bar = meter.querySelector('.bar');
let startTime = -progress.splice(0, 1)[0] * 100;
meter.style.animationDelay = `${startTime}s`;
bar.style.animationDelay = `${startTime}s`;
}
subjects[i].appendChild(clone);
}
</script>
</html>

View file

@ -0,0 +1,57 @@
<!DOCTYPE html>
<html class="reftest-wait">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="help" src="https://drafts.csswg.org/scroll-animations-1/#named-timeline-range">
<link rel="match" href="animation-range-visual-test-ref.html">
<link rel="stylesheet" href="support/animation-range.css">
<script src="/common/reftest-wait.js"></script>
<script src="/web-animations/testcommon.js"></script>
</head>
<body>
<h3>View timeline</h3>
<template id="meters">
<div class="meters">
<div class="cover"><div class="meter"><div class="bar"></div></div><div>Cover</div></div>
<div class="contain"><div class="meter"><div class="bar"></div></div><div>Contain</div></div>
<div class="entry"><div class="meter"><div class="bar"></div></div><div>Entry</div></div>
<div class="exit"><div class="meter"><div class="bar"></div></div><div>Exit</div></div>
</div>
</template>
<div class="flex">
<div>
<div class="scroller">
<div class="subject" style="margin-top: 90px;"></div>
<div class="spacer"></div>
</div>
</div>
<div>
<div class="scroller">
<div class="subject" style="margin-top: 70px;"></div>
<div class="spacer"></div>
</div>
</div>
<div>
<div class="scroller">
<div class="subject" style="margin-top: 10px;"></div>
<div class="spacer"></div>
</div>
</div>
<div>
<div class="scroller">
<div class="subject" style="margin-top: -10px;"></div>
<div class="spacer"></div>
</div>
</div>
</div>
</body>
<script>
let template = document.querySelector('#meters');
let subjects = document.querySelectorAll('.subject');
for (let i = 0; i < subjects.length; i++) {
subjects[i].appendChild(template.content.cloneNode(true));
}
waitForCompositorReady().then(takeScreenshot);
</script>
</html>

View file

@ -49,7 +49,7 @@ test((t) => {
});
target.style.animation = 'anim 1s';
target.style.animationTimeline = 'timeline';
target.style.animationTimeline = '--timeline';
assert_equals(target.style.animation, '');
assert_equals(target.style.animationName, 'anim');
assert_equals(target.style.animationDuration, '1s');
@ -61,7 +61,7 @@ test((t) => {
});
target.style.animation = 'anim 1s';
target.style.animationTimeline = 'timeline';
target.style.animationTimeline = '--timeline';
assert_equals(getComputedStyle(target).animation, '');
assert_equals(getComputedStyle(target).animationName, 'anim');
assert_equals(getComputedStyle(target).animationDuration, '1s');

View file

@ -5,15 +5,15 @@
<script src="/css/support/computed-testcommon.js"></script>
</head>
<style>
#outer { animation-timeline: foo; }
#target { animation-timeline: bar; }
#outer { animation-timeline: --foo; }
#target { animation-timeline: --bar; }
</style>
<div id="outer">
<div id="target"></div>
</div>
<script>
test_computed_value('animation-timeline', 'initial', 'auto');
test_computed_value('animation-timeline', 'inherit', 'foo');
test_computed_value('animation-timeline', 'inherit', '--foo');
test_computed_value('animation-timeline', 'unset', 'auto');
test_computed_value('animation-timeline', 'revert', 'auto');
test_computed_value('animation-timeline', 'auto');
@ -22,9 +22,9 @@ test_computed_value('animation-timeline', 'auto, auto');
test_computed_value('animation-timeline', 'none, none');
test_computed_value('animation-timeline', 'auto, none');
test_computed_value('animation-timeline', 'none, auto');
test_computed_value('animation-timeline', 'test');
test_computed_value('animation-timeline', 'test1, test2');
test_computed_value('animation-timeline', 'test1, test2, none, test3, auto', 'test1, test2, none, test3, auto');
test_computed_value('animation-timeline', '--test');
test_computed_value('animation-timeline', '--test1, --test2');
test_computed_value('animation-timeline', '--test1, --test2, none, --test3, auto');
test(() => {
let style = getComputedStyle(document.getElementById('target'));
@ -39,13 +39,13 @@ test(() => {
// https://drafts.csswg.org/scroll-animations-1/#scroll-notation
//
// animation-timeline: scroll(<axis>? <scroller>?);
// <axis> = block | inline | vertical | horizontal
// <axis> = block | inline | x | y
// <scroller> = root | nearest | self
test_computed_value('animation-timeline', 'scroll()');
test_computed_value('animation-timeline', 'scroll(block)', 'scroll()');
test_computed_value('animation-timeline', 'scroll(inline)');
test_computed_value('animation-timeline', 'scroll(horizontal)');
test_computed_value('animation-timeline', 'scroll(vertical)');
test_computed_value('animation-timeline', 'scroll(x)');
test_computed_value('animation-timeline', 'scroll(y)');
test_computed_value('animation-timeline', 'scroll(root)');
test_computed_value('animation-timeline', 'scroll(nearest)', 'scroll()');
test_computed_value('animation-timeline', 'scroll(self)');
@ -54,20 +54,20 @@ test_computed_value('animation-timeline', 'scroll(inline nearest)', 'scroll(inli
test_computed_value('animation-timeline', 'scroll(nearest inline)', 'scroll(inline)');
test_computed_value('animation-timeline', 'scroll(block self)', 'scroll(self)');
test_computed_value('animation-timeline', 'scroll(self block)', 'scroll(self)');
test_computed_value('animation-timeline', 'scroll(vertical root)', 'scroll(root vertical)');
test_computed_value('animation-timeline', 'scroll(y root)', 'scroll(root y)');
// https://drafts.csswg.org/scroll-animations-1/#view-notation
test_computed_value('animation-timeline', 'view()');
test_computed_value('animation-timeline', 'view(block)', 'view()');
test_computed_value('animation-timeline', 'view(inline)', 'view(inline)');
test_computed_value('animation-timeline', 'view(horizontal)', 'view(horizontal)');
test_computed_value('animation-timeline', 'view(vertical)', 'view(vertical)');
test_computed_value('animation-timeline', 'view(vertical 1px)');
test_computed_value('animation-timeline', 'view(x)', 'view(x)');
test_computed_value('animation-timeline', 'view(y)', 'view(y)');
test_computed_value('animation-timeline', 'view(y 1px)');
test_computed_value('animation-timeline', 'view(1px auto)');
test_computed_value('animation-timeline', 'view(auto 1px)');
test_computed_value('animation-timeline', 'view(vertical 1px auto)');
test_computed_value('animation-timeline', 'view(1px vertical)', 'view(vertical 1px)');
test_computed_value('animation-timeline', 'view(vertical auto)', 'view(vertical)');
test_computed_value('animation-timeline', 'view(vertical auto auto)', 'view(vertical)');
test_computed_value('animation-timeline', 'view(y 1px auto)');
test_computed_value('animation-timeline', 'view(1px y)', 'view(y 1px)');
test_computed_value('animation-timeline', 'view(y auto)', 'view(y)');
test_computed_value('animation-timeline', 'view(y auto auto)', 'view(y)');
</script>

View file

@ -8,7 +8,7 @@
overflow: hidden;
height: 0px;
scroll-timeline-attachment: defer;
scroll-timeline-name: timeline1, timeline2, timeline3;
scroll-timeline-name: --timeline1, --timeline2, --timeline3;
}
.scroller {
overflow: hidden;
@ -24,13 +24,13 @@
to { width: 200px; }
}
#scroller1 {
scroll-timeline-name: timeline1;
scroll-timeline-name: --timeline1;
}
#scroller2 {
scroll-timeline-name: timeline2;
scroll-timeline-name: --timeline2;
}
#scroller3 {
scroll-timeline-name: timeline3;
scroll-timeline-name: --timeline3;
}
#element {
width: 0px;
@ -38,10 +38,10 @@
animation-name: expand;
animation-duration: 1000s;
animation-timing-function: linear;
animation-timeline: timeline1;
animation-timeline: --timeline1;
}
/* Ensure stable expectations if feature is not supported */
@supports not (animation-timeline:foo) {
@supports not (animation-timeline:--foo) {
#element { animation-play-state: paused; }
}
</style>
@ -82,7 +82,7 @@
test_animation_timeline(async () => {
await waitForNextFrame();
assert_equals(getComputedStyle(element).width, '120px');
element.style = 'animation-timeline:timeline2';
element.style = 'animation-timeline:--timeline2';
assert_equals(getComputedStyle(element).width, '140px');
}, 'Changing animation-timeline changes the timeline (sanity check)');
@ -100,7 +100,7 @@
assert_equals(getComputedStyle(element).width, '180px');
// Changing the animation-timeline property should have no effect.
element.style = 'animation-timeline:timeline2';
element.style = 'animation-timeline:--timeline2';
assert_equals(getComputedStyle(element).width, '180px');
}, 'animation-timeline ignored after setting timeline with JS (ScrollTimeline from JS)');
@ -110,14 +110,14 @@
let animation = element.getAnimations()[0];
let timeline1 = animation.timeline;
element.style = 'animation-timeline:timeline2';
element.style = 'animation-timeline:--timeline2';
assert_equals(getComputedStyle(element).width, '140px');
animation.timeline = timeline1;
assert_equals(getComputedStyle(element).width, '120px');
// Should have no effect.
element.style = 'animation-timeline:timeline3';
element.style = 'animation-timeline:--timeline3';
assert_equals(getComputedStyle(element).width, '120px');
}, 'animation-timeline ignored after setting timeline with JS (ScrollTimeline from CSS)');
@ -130,7 +130,7 @@
assert_equals(getComputedStyle(element).width, '120px');
// Changing the animation-timeline property should have no effect.
element.style = 'animation-timeline:timeline2';
element.style = 'animation-timeline:--timeline2';
assert_equals(getComputedStyle(element).width, '120px');
}, 'animation-timeline ignored after setting timeline with JS (document timeline)');
@ -141,7 +141,7 @@
assert_equals(getComputedStyle(element).width, '120px');
// Changing the animation-timeline property should have no effect.
element.style = 'animation-timeline:timeline2';
element.style = 'animation-timeline:--timeline2';
assert_equals(getComputedStyle(element).width, '120px');
}, 'animation-timeline ignored after setting timeline with JS (null)');
</script>

View file

@ -6,8 +6,8 @@
</head>
<style>
@keyframes test {
from { width: 100px; animation-timeline: foo; }
to { width: 100px; animation-timeline: foo; }
from { width: 100px; animation-timeline: --foo; }
to { width: 100px; animation-timeline: --foo; }
}
#target {
width: 50px;

View file

@ -7,7 +7,7 @@
<style>
main {
scroll-timeline-attachment: defer;
scroll-timeline-name: top_timeline, bottom_timeline, left_timeline, right_timeline;
scroll-timeline-name: --top_timeline, --bottom_timeline, --left_timeline, --right_timeline;
}
.scroller {
@ -39,19 +39,19 @@
}
#top_scroller {
scroll-timeline-name: top_timeline;
scroll-timeline-name: --top_timeline;
scroll-timeline-axis: block;
}
#bottom_scroller {
scroll-timeline-name: bottom_timeline;
scroll-timeline-name: --bottom_timeline;
scroll-timeline-axis: inline;
}
#left_scroller {
scroll-timeline-name: left_timeline;
scroll-timeline-name: --left_timeline;
scroll-timeline-axis: block;
}
#right_scroller {
scroll-timeline-name: right_timeline;
scroll-timeline-name: --right_timeline;
scroll-timeline-axis: inline;
}
@ -59,10 +59,10 @@
animation-name: top, bottom, left, right;
animation-duration: 10s;
animation-timing-function: linear;
animation-timeline: top_timeline, bottom_timeline, left_timeline, right_timeline;
animation-timeline: --top_timeline, --bottom_timeline, --left_timeline, --right_timeline;
}
/* Ensure stable expectations if feature is not supported */
@supports not (animation-timeline:foo) {
@supports not (animation-timeline:--foo) {
#element { animation-play-state: paused; }
}
</style>

View file

@ -13,6 +13,11 @@
from { translate: 50px; }
to { translate: 150px; }
}
@keyframes anim-2 {
from { z-index: 0; }
to { z-index: 100; }
}
#target {
width: 100px;
height: 100px;
@ -74,6 +79,18 @@ function createScrollerAndTarget(t, scrollerSizeClass) {
return [createScroller(t, scrollerSizeClass), createTarget(t)];
}
async function waitForScrollTop(scroller, percentage) {
const maxScroll = scroller.scrollHeight - scroller.clientHeight;
scroller.scrollTop = maxScroll * percentage / 100;
return waitForNextFrame();
}
async function waitForScrollLeft(scroller, percentage) {
const maxScroll = scroller.scrollWidth - scroller.clientWidth;
scroller.scrollLeft = maxScroll * percentage / 100;
return waitForNextFrame();
}
// -------------------------
// Test scroll-timeline-name
// -------------------------
@ -91,11 +108,11 @@ promise_test(async t => {
document.body.appendChild(target);
target.appendChild(content);
target.style.scrollTimelineName = 'timeline';
target.style.scrollTimelineName = '--timeline';
target.style.animation = "anim 10s linear";
target.style.animationTimeline = 'timeline';
target.style.animationTimeline = '--timeline';
target.scrollTop = 50; // 50%, in [0, 100].
target.scrollTop = 50; // 50%
await waitForNextFrame();
assert_equals(getComputedStyle(target).translate, '100px');
@ -114,299 +131,77 @@ promise_test(async t => {
document.body.appendChild(parent);
parent.insertBefore(target, parent.firstElementChild);
parent.style.scrollTimelineName = 'timeline';
parent.style.scrollTimelineName = '--timeline';
target.style.animation = "anim 10s linear";
target.style.animationTimeline = 'timeline';
target.style.animationTimeline = '--timeline';
parent.scrollTop = 100; // 50%, in [0, 200].
parent.scrollTop = 100; // 50%
await waitForNextFrame();
assert_equals(getComputedStyle(target).translate, '100px');
}, "scroll-timeline-name is referenceable in animation-timeline on that " +
"element's descendants");
promise_test(async t => {
let [sibling, target] = createScrollerAndTarget(t);
// <div id='sibling' class='scroller'> ... </div>
// <div id='target'></div>
document.body.appendChild(sibling);
document.body.appendChild(target);
sibling.style.scrollTimelineName = 'timeline';
target.style.animation = "anim 10s linear";
target.style.animationTimeline = 'timeline';
sibling.scrollTop = 50; // 50%, in [0, 100].
await waitForNextFrame();
assert_equals(getComputedStyle(target).translate, '100px');
}, "scroll-timeline-name is referenceable in animation-timeline on that " +
"element's following siblings");
promise_test(async t => {
let [sibling, target] = createScrollerAndTarget(t);
let parent = document.createElement('div');
// <div id='sibling' class='scroller'> ... </div>
// <div id='parent'>
// <div id='target'></div>
// </div>
document.body.appendChild(sibling);
document.body.appendChild(parent);
parent.appendChild(target);
sibling.style.scrollTimelineName = 'timeline';
target.style.animation = "anim 10s linear";
target.style.animationTimeline = 'timeline';
sibling.scrollTop = 50; // 50%, in [0, 100].
await waitForNextFrame();
assert_equals(getComputedStyle(target).translate, '100px');
parent.remove();
}, "scroll-timeline-name is referenceable in animation-timeline on that " +
"element's following siblings' descendants");
// FIXME: We may use global scope for scroll-timeline-name.
// See https://github.com/w3c/csswg-drafts/issues/7047
promise_test(async t => {
let [sibling, target] = createScrollerAndTarget(t);
// <div id='target'></div>
// <div id='sibling' class='scroller'> ... </div>
document.body.appendChild(target);
// <div id='target'></div>
document.body.appendChild(sibling);
document.body.appendChild(target);
sibling.style.scrollTimelineName = 'timeline';
// Resolvable if using a deferred timeline, but otherwise can only resolve
// if an ancestor container of the target element.
sibling.style.scrollTimelineName = '--timeline';
target.style.animation = "anim 10s linear";
target.style.animationTimeline = 'timeline';
target.style.animationTimeline = '--timeline';
sibling.scrollTop = 50; // 50%, in [0, 100].
sibling.scrollTop = 50; // 50%
await waitForNextFrame();
assert_equals(getComputedStyle(target).translate, '50px',
'Animation with unknown timeline name holds current time at zero');
}, "scroll-timeline-name is not referenceable in animation-timeline on that " +
"element's previous siblings");
"element's siblings");
promise_test(async t => {
let [sibling, target] = createScrollerAndTarget(t);
let parent = document.createElement('div');
parent.className = 'scroller square-container';
let content = document.createElement('div');
content.className = 'content';
// <div id='parent' class='scroller'>
// <div id='sibling' class='scroller'> ... </div>
// <div id='target'></div>
// <div id='content'></div>
// </div>
document.body.appendChild(parent);
parent.appendChild(sibling);
parent.appendChild(target);
parent.appendChild(content);
parent.style.scrollTimelineName = 'timeline';
parent.style.scrollTimelineAxis = 'inline';
sibling.style.scrollTimelineName = 'timeline';
target.style.animation = "anim 10s linear";
target.style.animationTimeline = 'timeline';
parent.scrollTop = 50; // 25%, in [0, 200].
sibling.scrollTop = 50; // 50%, in [0, 100].
await waitForNextFrame();
assert_equals(getComputedStyle(target).translate, '100px');
content.remove();
parent.remove();
}, 'scroll-timeline-name is matched based on tree order, which considers ' +
'siblings closer than parents');
promise_test(async t => {
let sibling = document.createElement('div');
sibling.className = 'square';
sibling.style.overflowX = 'clip'; // This makes overflow-y be clip as well.
parent.className = 'square';
parent.style.overflowX = 'clip'; // This makes overflow-y be clip as well.
let target = document.createElement('div');
target.id = 'target';
// <div id='sibling' style='overflow-x: clip'></div>
// <div id='target'></div>
document.body.appendChild(sibling);
document.body.appendChild(target);
// <div id='parent' style='overflow-x: clip'>...
// <div id='target'></div>
// </div>
document.body.appendChild(parent);
parent.appendChild(target);
sibling.style.scrollTimelineName = 'timeline';
parent.style.scrollTimelineName = '--timeline';
target.style.animation = "anim 10s linear";
target.style.animationTimeline = 'timeline';
target.style.animationTimeline = '--timeline';
sibling.scrollTop = 50; // 50%, in [0, 100].
await waitForNextFrame();
assert_equals(getComputedStyle(target).translate, 'none',
'Animation with an unresolved current time');
target.remove();
sibling.remove();
parent.remove();
}, 'scroll-timeline-name on an element which is not a scroll-container');
promise_test(async t => {
let [sibling, target] = createScrollerAndTarget(t);
let main = document.createElement('div');
main.id = 'name';
let [scroller, target] = createScrollerAndTarget(t);
// <div id='main'>
// <div id='sibling' class='scroller'> ... </div>
// <div id='scroller' class='scroller'> ...
// <div id='target'></div>
// </div>
document.body.appendChild(main);
main.appendChild(sibling);
main.appendChild(target);
target.style.animation = 'anim 10s linear';
target.style.animationTimeline = 'timeline';
sibling.scrollTop = 50; // 50%, in [50, 150].
await waitForNextFrame();
// Unknown animation-timeline, current time held at zero.
assert_equals(getComputedStyle(target).translate, '50px');
// Ensure that #main (an ancestor of the scroller) needs style recalc.
main.style.background = 'lightgray';
sibling.style.scrollTimelineName = 'timeline';
await waitForCSSScrollTimelineStyle();
assert_equals(getComputedStyle(target).translate, '100px');
main.remove();
}, 'scroll-timeline-name affects subsequent siblings when changed');
promise_test(async t => {
let target = createTarget(t);
// <div id='target'></div>
document.body.appendChild(target);
target.style.animation = 'anim 10s linear';
target.style.animationTimeline = 'timeline';
// Unknown animation-timeline, current time held at zero.
assert_equals(getComputedStyle(target).translate, '50px');
let scroller = createScroller(t);
// <div class='scroller'> ... </div>
// <div id='target'></div>
document.body.insertBefore(scroller, target);
scroller.style.scrollTimelineName = 'timeline';
await waitForNextFrame();
assert_equals(getComputedStyle(target).translate, '50px');
// Ensure that time is not just held at zero.
scroller.scrollTop = 50; // 50%, in [50, 150].
await waitForNextFrame();
assert_equals(getComputedStyle(target).translate, '100px');
}, 'scroll-timeline-name on inserted element affects subsequent siblings');
promise_test(async t => {
let [scroller, target] = createScrollerAndTarget(t);
// <div class='scroller'> ... </div>
// <div id='target'></div>
document.body.appendChild(scroller);
document.body.appendChild(target);
scroller.scrollTop = 50; // 50%, in [50, 150].
await waitForNextFrame();
scroller.style.scrollTimelineName = 'timeline';
target.style.animation = 'anim 10s linear';
target.style.animationTimeline = 'timeline';
await waitForCSSScrollTimelineStyle();
assert_equals(getComputedStyle(target).translate, '100px');
const anim = target.getAnimations()[0];
assert_percents_equal(anim.startTime, 0);
assert_percents_equal(anim.currentTime, 50);
// This effectively removes the CSS-created ScrollTimeline on this element,
// thus invoking "setting the timeline of an animation" [1] with a null-
// timeline on affected elements. This in turn runs the procedure to set the
// current time to previous progress * end time. Ultimately, this sets the
// hold time of the animation.
// [1] https://www.w3.org/TR/web-animations-2/#setting-the-timeline
// [2] https://www.w3.org/TR/web-animations-2/
// #setting-the-current-time-of-an-animation
scroller.remove();
await waitForNextFrame();
assert_equals(getComputedStyle(target).translate, '100px');
assert_equals(anim.startTime, null);
assert_times_equal(anim.currentTime, 5000);
}, 'scroll-timeline-name on removed element affects subsequent siblings');
promise_test(async t => {
let [scroller, target] = createScrollerAndTarget(t);
// <div class='scroller' style='display:none'> ... </div>
// <div id='target'></div>
scroller.style.display = 'none';
document.body.appendChild(scroller);
document.body.appendChild(target);
scroller.style.scrollTimelineName = 'timeline';
target.style.animation = 'anim 10s linear';
target.style.animationTimeline = 'timeline';
// Unknown animation-timeline, current time held at zero.
assert_equals(getComputedStyle(target).translate, '50px');
scroller.style.display = 'block';
scroller.scrollTop = 50; // 50%, in [50, 150].
await waitForNextFrame();
assert_equals(getComputedStyle(target).translate, '100px');
}, 'scroll-timeline-name on element leaving display:none affects subsequent siblings');
promise_test(async t => {
let [scroller, target] = createScrollerAndTarget(t);
// <div class='scroller'> ... </div>
// <div id='target'></div>
document.body.appendChild(scroller);
document.body.appendChild(target);
scroller.scrollTop = 50; // 50%, in [50, 150].
await waitForNextFrame();
scroller.style.scrollTimelineName = 'timeline';
target.style.animation = 'anim 10s linear';
target.style.animationTimeline = 'timeline';
await waitForCSSScrollTimelineStyle();
assert_equals(getComputedStyle(target).translate, '100px');
const anim = target.getAnimations()[0];
assert_percents_equal(anim.startTime, 0);
assert_percents_equal(anim.currentTime, 50);
// See comment in the test "scroll-timeline-name on removed element ..." for
// an explantation of this result. (Setting display:none is similar to
// removing the element).
scroller.style.display = 'none';
await waitForNextFrame();
assert_equals(getComputedStyle(target).translate, '100px');
assert_equals(anim.startTime, null);
assert_times_equal(anim.currentTime, 5000);
}, 'scroll-timeline-name on element becoming display:none affects subsequent siblings');
promise_test(async t => {
let [scroller, target] = createScrollerAndTarget(t);
// <div id='scroller' class='scroller'> ... </div>
// <div id='target'></div>
document.body.appendChild(scroller);
document.body.appendChild(target);
scroller.appendChild(target);
scroller.style.scrollTimelineName = 'timeline';
scroller.style.display = 'none';
scroller.style.scrollTimelineName = '--timeline-A';
scroller.scrollTop = 50; // 25%
target.style.animation = "anim 10s linear";
target.style.animationTimeline = 'timeline';
target.style.animationTimeline = '--timeline-B';
await waitForNextFrame();
@ -416,75 +211,45 @@ promise_test(async t => {
// Hold time of animation is zero.
assert_equals(getComputedStyle(target).translate, '50px');
scroller.style.display = 'block';
scroller.scrollTop = 50;
scroller.style.scrollTimelineName = '--timeline-B';
await waitForNextFrame();
assert_true(!!anim.timeline, 'Failed to create timeline');
assert_equals(getComputedStyle(target).translate, '100px');
}, 'scroll-timeline-name on element not resolved until element becomes visible');
promise_test(async t => {
let [scroller, target] = createScrollerAndTarget(t);
// <div id='scroller' class='scroller'> ... </div>
// <div id='target'></div>
document.body.appendChild(scroller);
document.body.appendChild(target);
scroller.style.scrollTimelineName = 'timeline-A';
scroller.scrollTop = 50;
target.style.animation = "anim 10s linear";
target.style.animationTimeline = 'timeline-B';
await waitForNextFrame();
const anim = target.getAnimations()[0];
assert_true(!!anim, 'Failed to create animation');
assert_equals(anim.timeline, null);
// Hold time of animation is zero.
assert_equals(getComputedStyle(target).translate, '50px');
scroller.style.scrollTimelineName = 'timeline-B';
await waitForNextFrame();
assert_true(!!anim.timeline, 'Failed to create timeline');
assert_equals(getComputedStyle(target).translate, '100px');
assert_equals(getComputedStyle(target).translate, '75px');
}, 'Change in scroll-timeline-name to match animation timeline updates animation.');
promise_test(async t => {
let [scroller, target] = createScrollerAndTarget(t);
// <div id='scroller' class='scroller'> ... </div>
// <div id='target'></div>
// <div id='scroller' class='scroller'> ...
// <div id='target'></div>
// </div>
document.body.appendChild(scroller);
document.body.appendChild(target);
scroller.appendChild(target);
scroller.style.scrollTimelineName = 'timeline-A';
scroller.scrollTop = 50;
scroller.style.scrollTimelineName = '--timeline-A';
scroller.scrollTop = 50; // 25%
target.style.animation = "anim 10s linear";
target.style.animationTimeline = 'timeline-A';
target.style.animationTimeline = '--timeline-A';
await waitForNextFrame();
const anim = target.getAnimations()[0];
assert_true(!!anim, 'Failed to create animation');
assert_true(!!anim.timeline, 'Failed to create timeline');
assert_equals(getComputedStyle(target).translate, '100px');
assert_equals(getComputedStyle(target).translate, '75px');
assert_percents_equal(anim.startTime, 0);
assert_percents_equal(anim.currentTime, 50);
assert_percents_equal(anim.currentTime, 25);
scroller.style.scrollTimelineName = 'timeline-B';
scroller.style.scrollTimelineName = '--timeline-B';
await waitForNextFrame();
// Switching to a null timeline pauses the animation.
assert_equals(anim.timeline, null, 'Failed to remove timeline');
assert_equals(getComputedStyle(target).translate, '100px');
assert_equals(getComputedStyle(target).translate, '75px');
assert_equals(anim.startTime, null);
assert_times_equal(anim.currentTime, 5000);
assert_times_equal(anim.currentTime, 2500);
}, 'Change in scroll-timeline-name to no longer match animation timeline updates animation.');
promise_test(async t => {
@ -493,55 +258,23 @@ promise_test(async t => {
let scroller2 = createScroller(t);
target.style.animation = 'anim 10s linear';
target.style.animationTimeline = 'timeline';
scroller1.style.scrollTimelineName = 'timeline';
scroller2.style.scrollTimelineName = 'timeline';
target.style.animationTimeline = '--timeline';
scroller1.style.scrollTimelineName = '--timeline';
scroller1.id = 'A';
scroller2.id = 'B';
// <div class='scroller' id='A'> ... </div> (scroller1)
// <div class='scroller' id="B"> ... </div> (scroller2)
// <div id='target'></div>
// <div class='scroller' id='A'> ...
// <div class='scroller' id='B'> ...
// <div id='target'></div>
// </div>
// </div>
document.body.appendChild(scroller1);
document.body.appendChild(scroller2);
document.body.append(target);
scroller1.appendChild(scroller2);
scroller2.appendChild(target);
scroller1.scrollTop = 10; // 10%, in [50, 150].
scroller2.scrollTop = 50; // 50%, in [50, 150].
await waitForNextFrame();
// The named timeline lookup should select scroller2.
let anim = target.getAnimations()[0];
assert_true(!!anim, 'Failed to fetch animation');
assert_equals(anim.timeline.source.id, 'B');
assert_equals(getComputedStyle(target).translate, '100px');
scroller2.remove();
// Now it should select scroller1.
anim = target.getAnimations()[0];
assert_true(!!anim, 'Failed to fetch animation after update');
assert_true(!!anim.timeline, 'Animation no longer has a timeline');
assert_equals(anim.timeline.source.id, 'A', 'Timeline not updated');
assert_equals(getComputedStyle(target).translate, '60px');
}, 'Timeline lookup finds next candidate when element is removed');
promise_test(async t => {
let target = createTarget(t);
let scroller1 = createScroller(t);
target.style.animation = 'anim 10s linear';
target.style.animationTimeline = 'timeline';
scroller1.style.scrollTimelineName = 'timeline';
scroller1.id = 'A';
// <div class='scroller' id='A'> ... </div> (scroller1)
// <div id='target'></div>
document.body.appendChild(scroller1);
document.body.append(target);
scroller1.scrollTop = 10; // 10%, in [50, 150].
scroller1.style.scrollTimelineName = '--timeline';
scroller1.scrollTop = 50; // 25%
scroller2.scrollTop = 100; // 50%
await waitForNextFrame();
@ -549,21 +282,9 @@ promise_test(async t => {
assert_true(!!anim.timeline, 'Failed to retrieve animation');
assert_equals(anim.timeline.source.id, 'A');
assert_equals(getComputedStyle(target).translate, '60px');
await waitForNextFrame();
let scroller2 = createScroller(t);
scroller2.style.scrollTimelineName = 'timeline';
scroller2.id = 'B';
// <div class='scroller' id="A"> ... </div> (scroller1)
// <div class='scroller' id="B"> ... </div> (scroller2)
// <div id='target'></div>
document.body.insertBefore(scroller2, target);
scroller2.scrollTop = 50; // 50%, in [50, 150].
assert_equals(getComputedStyle(target).translate, '75px');
scroller2.style.scrollTimelineName = '--timeline';
await waitForNextFrame();
// The timeline should be updated to scroller2.
@ -573,12 +294,17 @@ promise_test(async t => {
}, 'Timeline lookup updates candidate when closer match available.');
promise_test(async t => {
let wrapper = createScroller(t);
wrapper.classList.remove('scroller');
let target = createTarget(t);
// <div id='target'></div>
document.body.append(target);
// <div id='wrapper'> ...
// <div id='target'></div>
// </div>
document.body.appendChild(wrapper);
wrapper.appendChild(target);
target.style.animation = "anim 10s linear";
target.style.animationTimeline = 'timeline';
target.style.animationTimeline = '--timeline';
await waitForNextFrame();
@ -589,21 +315,20 @@ promise_test(async t => {
await waitForNextFrame();
let scroller = createScroller(t);
scroller.style.scrollTimelineName = 'timeline';
// <div class='scroller'> ... </div> (scroller1)
// <div id='target'></div>
document.body.insertBefore(scroller, target);
scroller.scrollTop = 50; // 50%, in [50, 150].
wrapper.classList.add('scroller');
wrapper.style.scrollTimelineName = '--timeline';
// <div id='wrapper' class="scroller"> ...
// <div id='target'></div>
// </div>
wrapper.scrollTop = 50; // 25%
await waitForNextFrame();
// The timeline should be updated to scroller.
assert_equals(getComputedStyle(target).translate, '100px');
assert_equals(getComputedStyle(target).translate, '75px');
}, 'Timeline lookup updates candidate when match becomes available.');
// -------------------------
// Test scroll-timeline-axis
// -------------------------
@ -612,84 +337,94 @@ promise_test(async t => {
let [scroller, target] = createScrollerAndTarget(t);
scroller.style.writingMode = 'vertical-lr';
// <div id='scroller' class='scroller'> ...
// <div id='target'></div>
// </div>
document.body.appendChild(scroller);
document.body.appendChild(target);
scroller.appendChild(target);
scroller.style.scrollTimeline = 'timeline block';
target.style.animation = "anim 10s linear";
target.style.animationTimeline = 'timeline';
scroller.style.scrollTimeline = '--timeline block';
target.style.animation = "anim-2 10s linear";
target.style.animationTimeline = '--timeline';
scroller.scrollLeft = 50;
await waitForNextFrame();
assert_equals(getComputedStyle(target).translate, '100px');
await waitForScrollLeft(scroller, 50);
assert_equals(getComputedStyle(target).zIndex, '50');
}, 'scroll-timeline-axis is block');
promise_test(async t => {
let [scroller, target] = createScrollerAndTarget(t);
scroller.style.writingMode = 'vertical-lr';
// <div id='scroller' class='scroller'> ...
// <div id='target'></div>
// </div>
document.body.appendChild(scroller);
document.body.appendChild(target);
scroller.appendChild(target);
scroller.style.scrollTimeline = 'timeline inline';
target.style.animation = "anim 10s linear";
target.style.animationTimeline = 'timeline';
scroller.style.scrollTimeline = '--timeline inline';
target.style.animation = "anim-2 10s linear";
target.style.animationTimeline = '--timeline';
scroller.scrollTop = 50;
await waitForNextFrame();
assert_equals(getComputedStyle(target).translate, '100px');
await waitForScrollTop(scroller, 50);
assert_equals(getComputedStyle(target).zIndex, '50');
}, 'scroll-timeline-axis is inline');
promise_test(async t => {
let [scroller, target] = createScrollerAndTarget(t);
scroller.style.writingMode = 'vertical-lr';
// <div id='scroller' class='scroller'> ...
// <div id='target'></div>
// </div>
document.body.appendChild(scroller);
document.body.appendChild(target);
scroller.appendChild(target);
scroller.style.scrollTimeline = 'timeline horizontal';
target.style.animation = "anim 10s linear";
target.style.animationTimeline = 'timeline';
scroller.style.scrollTimeline = '--timeline x';
target.style.animation = "anim-2 10s linear";
target.style.animationTimeline = '--timeline';
scroller.scrollLeft = 50;
await waitForNextFrame();
assert_equals(getComputedStyle(target).translate, '100px');
}, 'scroll-timeline-axis is horizontal');
await waitForScrollLeft(scroller, 50);
assert_equals(getComputedStyle(target).zIndex, '50');
}, 'scroll-timeline-axis is x');
promise_test(async t => {
let [scroller, target] = createScrollerAndTarget(t);
scroller.style.writingMode = 'vertical-lr';
// <div id='scroller' class='scroller'> ...
// <div id='target'></div>
// </div>
document.body.appendChild(scroller);
document.body.appendChild(target);
scroller.appendChild(target);
scroller.style.scrollTimeline = 'timeline vertical';
target.style.animation = "anim 10s linear";
target.style.animationTimeline = 'timeline';
scroller.style.scrollTimeline = '--timeline y';
target.style.animation = "anim-2 10s linear";
target.style.animationTimeline = '--timeline';
scroller.scrollTop = 50;
await waitForNextFrame();
assert_equals(getComputedStyle(target).translate, '100px');
}, 'scroll-timeline-axis is vertical');
await waitForScrollTop(scroller, 50);
assert_equals(getComputedStyle(target).zIndex, '50');
}, 'scroll-timeline-axis is y');
promise_test(async t => {
let [scroller, target] = createScrollerAndTarget(t);
// <div id='scroller' class='scroller'> ...
// <div id='target'></div>
// </div>
document.body.appendChild(scroller);
document.body.appendChild(target);
scroller.appendChild(target);
scroller.style.scrollTimeline = 'timeline block';
target.style.animation = "anim 10s linear";
target.style.animationTimeline = 'timeline';
scroller.style.scrollTimeline = '--timeline block';
target.style.animation = "anim-2 10s linear";
target.style.animationTimeline = '--timeline';
scroller.scrollTop = 50;
scroller.scrollLeft = 25;
await waitForNextFrame();
assert_equals(getComputedStyle(target).translate, '100px');
await waitForScrollTop(scroller, 25);
await waitForScrollLeft(scroller, 75);
assert_equals(getComputedStyle(target).zIndex, '25');
scroller.style.scrollTimelineAxis = 'inline';
await waitForNextFrame();
assert_equals(getComputedStyle(target).translate, '75px');
assert_equals(getComputedStyle(target).zIndex, '75');
}, 'scroll-timeline-axis is mutated');
</script>

View file

@ -20,7 +20,7 @@
animation-timeline: none;
}
#element_unknown_timeline {
animation-timeline: unknown_timeline;
animation-timeline: --unknown_timeline;
}
</style>

View file

@ -16,10 +16,11 @@ test_valid_value('animation-timeline', 'auto, auto');
test_valid_value('animation-timeline', 'none, none');
test_valid_value('animation-timeline', 'auto, none');
test_valid_value('animation-timeline', 'none, auto');
test_valid_value('animation-timeline', 'test');
test_valid_value('animation-timeline', 'test1, test2');
test_valid_value('animation-timeline', 'test1, test2, none, test3, auto', ["test1, test2, none, test3, auto", 'test1, test2, none, test3, auto']);
test_valid_value('animation-timeline', '--test');
test_valid_value('animation-timeline', '--test1, --test2');
test_valid_value('animation-timeline', '--test1, --test2, none, --test3, auto');
test_invalid_value('animation-timeline', 'test1');
test_invalid_value('animation-timeline', '10px');
test_invalid_value('animation-timeline', 'auto auto');
test_invalid_value('animation-timeline', 'none none');
@ -32,13 +33,13 @@ test_invalid_value('animation-timeline', '"test"');
// https://drafts.csswg.org/scroll-animations-1/#scroll-notation
//
// animation-timeline: scroll(<axis>? <scroller>?);
// <axis> = block | inline | vertical | horizontal
// <axis> = block | inline | x | y
// <scroller> = root | nearest | self
test_valid_value('animation-timeline', 'scroll()');
test_valid_value('animation-timeline', 'scroll(block)', 'scroll()');
test_valid_value('animation-timeline', 'scroll(inline)');
test_valid_value('animation-timeline', 'scroll(horizontal)');
test_valid_value('animation-timeline', 'scroll(vertical)');
test_valid_value('animation-timeline', 'scroll(x)');
test_valid_value('animation-timeline', 'scroll(y)');
test_valid_value('animation-timeline', 'scroll(root)');
test_valid_value('animation-timeline', 'scroll(nearest)', 'scroll()');
test_valid_value('animation-timeline', 'scroll(self)');
@ -46,27 +47,27 @@ test_valid_value('animation-timeline', 'scroll(inline nearest)', 'scroll(inline)
test_valid_value('animation-timeline', 'scroll(nearest inline)', 'scroll(inline)');
test_valid_value('animation-timeline', 'scroll(block self)', 'scroll(self)');
test_valid_value('animation-timeline', 'scroll(self block)', 'scroll(self)');
test_valid_value('animation-timeline', 'scroll(vertical root)', 'scroll(root vertical)');
test_valid_value('animation-timeline', 'scroll(y root)', 'scroll(root y)');
test_invalid_value('animation-timeline', 'scroll(abc root)');
test_invalid_value('animation-timeline', 'scroll(abc)');
test_invalid_value('animation-timeline', 'scroll(vertical abc)');
test_invalid_value('animation-timeline', 'scroll(y abc)');
test_invalid_value('animation-timeline', 'scroll("string")');
// https://drafts.csswg.org/scroll-animations-1/#view-notation
test_valid_value('animation-timeline', 'view()');
test_valid_value('animation-timeline', 'view(block)', 'view()');
test_valid_value('animation-timeline', 'view(inline)');
test_valid_value('animation-timeline', 'view(horizontal)');
test_valid_value('animation-timeline', 'view(vertical)');
test_valid_value('animation-timeline', 'view(vertical 1px 2px)');
test_valid_value('animation-timeline', 'view(vertical 1px)');
test_valid_value('animation-timeline', 'view(vertical auto)', 'view(vertical)');
test_valid_value('animation-timeline', 'view(vertical auto auto)', 'view(vertical)');
test_valid_value('animation-timeline', 'view(vertical auto 1px)');
test_valid_value('animation-timeline', 'view(1px 2px vertical)', 'view(vertical 1px 2px)');
test_valid_value('animation-timeline', 'view(1px vertical)', 'view(vertical 1px)');
test_valid_value('animation-timeline', 'view(auto horizontal)', 'view(horizontal)');
test_valid_value('animation-timeline', 'view(x)');
test_valid_value('animation-timeline', 'view(y)');
test_valid_value('animation-timeline', 'view(y 1px 2px)');
test_valid_value('animation-timeline', 'view(y 1px)');
test_valid_value('animation-timeline', 'view(y auto)', 'view(y)');
test_valid_value('animation-timeline', 'view(y auto auto)', 'view(y)');
test_valid_value('animation-timeline', 'view(y auto 1px)');
test_valid_value('animation-timeline', 'view(1px 2px y)', 'view(y 1px 2px)');
test_valid_value('animation-timeline', 'view(1px y)', 'view(y 1px)');
test_valid_value('animation-timeline', 'view(auto x)', 'view(x)');
test_valid_value('animation-timeline', 'view(1px 2px)');
test_valid_value('animation-timeline', 'view(1px)');
test_valid_value('animation-timeline', 'view(1px 1px)', 'view(1px)');
@ -75,11 +76,11 @@ test_valid_value('animation-timeline', 'view(auto calc(1% + 1px))');
test_valid_value('animation-timeline', 'view(auto)', 'view()');
test_valid_value('animation-timeline', 'view(auto auto)', 'view()');
test_invalid_value('animation-timeline', 'view(vertical 1px 2px 3px)');
test_invalid_value('animation-timeline', 'view(1px vertical 3px)');
test_invalid_value('animation-timeline', 'view(y 1px 2px 3px)');
test_invalid_value('animation-timeline', 'view(1px y 3px)');
test_invalid_value('animation-timeline', 'view(1px 2px 3px)');
test_invalid_value('animation-timeline', 'view(abc block)');
test_invalid_value('animation-timeline', 'view(abc)');
test_invalid_value('animation-timeline', 'view(vertical abc)');
test_invalid_value('animation-timeline', 'view(y abc)');
test_invalid_value('animation-timeline', 'view("string")');
</script>

View file

@ -143,21 +143,21 @@ promise_test(async t => {
let [container, div] = createTargetWithStuff(t, 'block-content');
container.style.writingMode = 'vertical-lr';
div.style.animation = "anim 10s linear";
div.style.animationTimeline = "scroll(horizontal)";
div.style.animationTimeline = "scroll(x)";
await scrollLeft(container, 50);
assert_equals(getComputedStyle(div).translate, '100px');
}, 'animation-timeline: scroll(horizontal)');
}, 'animation-timeline: scroll(x)');
promise_test(async t => {
let [container, div] = createTargetWithStuff(t, 'inline-content');
container.style.writingMode = 'vertical-lr';
div.style.animation = "anim 10s linear";
div.style.animationTimeline = "scroll(vertical)";
div.style.animationTimeline = "scroll(y)";
await scrollTop(container, 50);
assert_equals(getComputedStyle(div).translate, '100px');
}, 'animation-timeline: scroll(vertical)');
}, 'animation-timeline: scroll(y)');
// TODO: Add more tests which change the overflow property of the container for
// scroll(nearest)

View file

@ -202,7 +202,7 @@ promise_test(async t => {
let [container, div] = createTargetWithStuff(t, ['target', 'content']);
container.style.overflow = 'hidden';
div.style.animation = "fade-out-without-timeline-range 1s linear";
div.style.animationTimeline = "view(horizontal)";
div.style.animationTimeline = "view(x)";
// So the range is [-200px, 100px], but it is impossible to scroll to the
// negative part.
@ -214,12 +214,12 @@ promise_test(async t => {
assert_equals(getComputedStyle(div).opacity, '0.2', 'At 80%');
await scrollLeft(container, 100);
assert_equals(getComputedStyle(div).opacity, '0', 'At 100%');
}, 'animation-timeline: view(horizontal) without timeline range name');
}, 'animation-timeline: view(x) without timeline range name');
promise_test(async t => {
let [container, div] = createTargetWithStuff(t, ['target', 'content']);
div.style.animation = "fade-out-without-timeline-range 1s linear";
div.style.animationTimeline = "view(vertical)";
div.style.animationTimeline = "view(y)";
// So the range is [-200px, 100px], but it is impossible to scroll to the
// negative part.
@ -231,13 +231,13 @@ promise_test(async t => {
assert_equals(getComputedStyle(div).opacity, '0.2', 'At 80%');
await scrollTop(container, 100);
assert_equals(getComputedStyle(div).opacity, '0', 'At 100%');
}, 'animation-timeline: view(vertical) without timeline range name');
}, 'animation-timeline: view(y) without timeline range name');
promise_test(async t => {
let [container, div] = createTargetWithStuff(t, ['target', 'content']);
container.style.overflow = 'hidden';
div.style.animation = "fade-out-without-timeline-range 1s linear";
div.style.animationTimeline = "view(horizontal 50px)";
div.style.animationTimeline = "view(x 50px)";
// So the range is [-150px, 50px], but it is impossible to scroll to the
// negative part.
@ -248,7 +248,7 @@ promise_test(async t => {
assert_equals(getComputedStyle(div).opacity, '0.2', 'At 80%');
await scrollLeft(container, 50);
assert_equals(getComputedStyle(div).opacity, '0', 'At 100%');
}, 'animation-timeline: view(horizontal 50px) without timeline range name');
}, 'animation-timeline: view(x 50px) without timeline range name');
promise_test(async t => {
let [container, div] = createTargetWithStuff(t, ['target', 'content']);
@ -384,7 +384,7 @@ promise_test(async t => {
let [container, div] = createTargetWithStuff(t, ['target', 'content']);
container.style.overflow = 'scroll';
div.style.animation = "fade-out 1s linear";
div.style.animationTimeline = "view(horizontal)";
div.style.animationTimeline = "view(x)";
await scrollLeft(container, 0);
assert_equals(getComputedStyle(div).opacity, '1', 'At exit 0%');
@ -392,13 +392,13 @@ promise_test(async t => {
assert_equals(getComputedStyle(div).opacity, '0.5', 'At exit 50%');
await scrollLeft(container, 100);
assert_equals(getComputedStyle(div).opacity, '0', 'At exit 100%');
}, 'animation-timeline: view(horizontal)');
}, 'animation-timeline: view(x)');
promise_test(async t => {
let [container, div] = createTargetWithStuff(t, ['target', 'content']);
container.style.overflow = 'scroll';
div.style.animation = "fade-out 1s linear";
div.style.animationTimeline = "view(vertical)";
div.style.animationTimeline = "view(y)";
await scrollTop(container, 0);
assert_equals(getComputedStyle(div).opacity, '1', 'At exit 0%');
@ -406,20 +406,20 @@ promise_test(async t => {
assert_equals(getComputedStyle(div).opacity, '0.5', 'At exit 50%');
await scrollTop(container, 100);
assert_equals(getComputedStyle(div).opacity, '0', 'At exit 100%');
}, 'animation-timeline: view(vertical)');
}, 'animation-timeline: view(y)');
promise_test(async t => {
let [container, div] = createTargetWithStuff(t, ['target', 'content']);
container.style.overflowY = 'hidden';
container.style.overflowX = 'scroll';
div.style.animation = "fade-out 1s linear";
div.style.animationTimeline = "view(horizontal 50px)";
div.style.animationTimeline = "view(x 50px)";
await scrollLeft(container, 0);
assert_equals(getComputedStyle(div).opacity, '0.5', 'At exit 50%');
await scrollLeft(container, 50);
assert_equals(getComputedStyle(div).opacity, '0', 'At exit 100%');
}, 'animation-timeline: view(horizontal 50px)');
}, 'animation-timeline: view(x 50px)');
promise_test(async t => {
let [container, div] = createTargetWithStuff(t, ['target', 'content']);

View file

@ -18,7 +18,7 @@
overflow-x: scroll;
height: 200px;
width: 200px;
scroll-timeline-name: timeline;
scroll-timeline-name: --timeline;
}
#spacer {
height: 200vh;
@ -28,7 +28,7 @@
height: 100px;
width: 100px;
animation: slide 1s linear;
animation-timeline: timeline;
animation-timeline: --timeline;
}
</style>
<body>

View file

@ -42,8 +42,8 @@
animation-duration: auto;
animation-fill-mode: both;
animation-timing-function: linear;
view-timeline: target;
animation-timeline: target;
view-timeline: --target;
animation-timeline: --target;
}
#target.anim-1 {
animation-name: anim-1;

View file

@ -12,7 +12,7 @@
}
#scroller {
scroll-timeline: timeline;
scroll-timeline: --timeline;
overflow: scroll;
width: 100px;
height: 100px;

View file

@ -13,7 +13,7 @@
}
#scroller {
scroll-timeline: timeline;
scroll-timeline: --timeline;
overflow: scroll;
width: 100px;
height: 100px;
@ -29,10 +29,10 @@
height: 100px;
background-color: green;
animation: anim 1s linear;
animation-timeline: timeline;
animation-timeline: --timeline;
}
@supports not (animation-timeline:timeline) {
@supports not (animation-timeline:--timeline) {
#box {
animation-play-state: paused;
}

View file

@ -21,18 +21,18 @@
}
#scroller1 {
scroll-timeline: top_timeline;
scroll-timeline: --top_timeline;
}
#element {
animation-name: top;
animation-duration: 10s;
animation-timing-function: linear;
animation-timeline: top_timeline;
animation-timeline: --top_timeline;
position: absolute;
}
/* Ensure stable expectations if feature is not supported */
@supports not (animation-timeline:foo) {
@supports not (animation-timeline:--foo) {
#element { animation-play-state: paused; }
}
</style>

View file

@ -39,10 +39,10 @@
background-color: coral;
width: 0px;
animation: anim auto linear;
animation-timeline: t1;
animation-timeline: --t1;
}
.timeline {
scroll-timeline-name: t1;
scroll-timeline-name: --t1;
}
.local {
scroll-timeline-attachment: local;
@ -96,6 +96,25 @@
}, 'Deferred timeline with no attachments');
</script>
<template id=scroll_timeline_defer_no_attach_to_prev_sibling>
<div class="timeline defer">
<div class="scroller timeline">
<div class=content></div>
</div>
<div class=target>Test</div>
</div>
</template>
<script>
promise_test(async (t) => {
inflate(t, scroll_timeline_defer_no_attach_to_prev_sibling);
let scroller = main.querySelector('.scroller');
let target = main.querySelector('.target');
await scrollTop(scroller, 350); // 50%
assert_equals(getComputedStyle(target).width, '0px');
assert_equals(getComputedStyle(target).getPropertyValue('--applied'), '');
}, 'Deferred timeline with no attachments to previous sibling');
</script>
<template id=scroll_timeline_local_ancestor>
<div class="scroller timeline local">
<div class=content>
@ -142,7 +161,7 @@
<template id=scroll_timeline_defer_axis>
<div class="timeline defer" style="scroll-timeline-axis:inline">
<div class=target>Test</div>
<div class="scroller timeline ancestor" style="scroll-timeline-axis:vertical">
<div class="scroller timeline ancestor" style="scroll-timeline-axis:y">
<div class=content></div>
</div>
</div>
@ -154,7 +173,7 @@
assert_equals(target.getAnimations().length, 1);
let anim = target.getAnimations()[0];
assert_not_equals(anim.timeline, null);
assert_equals(anim.timeline.axis, 'vertical');
assert_equals(anim.timeline.axis, 'y');
}, 'Axis of deferred timeline is taken from attached timeline');
</script>
@ -162,7 +181,7 @@
<template id=scroll_timeline_defer_axis_multiple>
<div class="timeline defer" style="scroll-timeline-axis:inline">
<div class=target>Test</div>
<div class="scroller timeline ancestor" style="scroll-timeline-axis:vertical">
<div class="scroller timeline ancestor" style="scroll-timeline-axis:y">
<div class=content></div>
</div>
<!-- Extra attachment -->

View file

@ -5,7 +5,7 @@
<script src="/css/support/computed-testcommon.js"></script>
<style>
#outer { scroll-timeline-axis: inline; }
#target { scroll-timeline-axis: vertical; }
#target { scroll-timeline-axis: y; }
</style>
<div id="outer">
<div id="target"></div>
@ -17,11 +17,11 @@ test_computed_value('scroll-timeline-axis', 'unset', 'block');
test_computed_value('scroll-timeline-axis', 'revert', 'block');
test_computed_value('scroll-timeline-axis', 'block');
test_computed_value('scroll-timeline-axis', 'inline');
test_computed_value('scroll-timeline-axis', 'vertical');
test_computed_value('scroll-timeline-axis', 'horizontal');
test_computed_value('scroll-timeline-axis', 'y');
test_computed_value('scroll-timeline-axis', 'x');
test_computed_value('scroll-timeline-axis', 'block, inline');
test_computed_value('scroll-timeline-axis', 'inline, block');
test_computed_value('scroll-timeline-axis', 'block, vertical, horizontal, inline');
test_computed_value('scroll-timeline-axis', 'block, y, x, inline');
test_computed_value('scroll-timeline-axis', 'inline, inline, inline, inline');
test(() => {

View file

@ -14,11 +14,11 @@ test_valid_value('scroll-timeline-axis', 'revert');
test_valid_value('scroll-timeline-axis', 'block');
test_valid_value('scroll-timeline-axis', 'inline');
test_valid_value('scroll-timeline-axis', 'vertical');
test_valid_value('scroll-timeline-axis', 'horizontal');
test_valid_value('scroll-timeline-axis', 'y');
test_valid_value('scroll-timeline-axis', 'x');
test_valid_value('scroll-timeline-axis', 'block, inline');
test_valid_value('scroll-timeline-axis', 'inline, block');
test_valid_value('scroll-timeline-axis', 'block, vertical, horizontal, inline');
test_valid_value('scroll-timeline-axis', 'block, y, x, inline');
test_valid_value('scroll-timeline-axis', 'inline, inline, inline, inline');
test_invalid_value('scroll-timeline-axis', 'abc');

View file

@ -19,26 +19,26 @@
to { width: 200px; }
}
#timeline_initial_axis {
scroll-timeline: timeline_initial_axis;
scroll-timeline: --timeline_initial_axis;
}
#timeline_vertical {
scroll-timeline: timeline_vertical vertical;
#timeline_y {
scroll-timeline: --timeline_y y;
}
#timeline_horizontal {
scroll-timeline: timeline_horizontal horizontal;
#timeline_x {
scroll-timeline: --timeline_x x;
}
#timeline_block_in_horizontal {
scroll-timeline: timeline_block_in_horizontal block;
scroll-timeline: --timeline_block_in_horizontal block;
}
#timeline_inline_in_horizontal {
scroll-timeline: timeline_inline_in_horizontal inline;
scroll-timeline: --timeline_inline_in_horizontal inline;
}
#timeline_block_in_vertical {
scroll-timeline: timeline_block_in_vertical block;
scroll-timeline: --timeline_block_in_vertical block;
writing-mode: vertical-lr;
}
#timeline_inline_in_vertical {
scroll-timeline: timeline_inline_in_vertical inline;
scroll-timeline: --timeline_inline_in_vertical inline;
writing-mode: vertical-lr;
}
.target {
@ -49,28 +49,28 @@
position: absolute;
}
/* Ensure stable expectations if feature is not supported */
@supports not (animation-timeline:foo) {
@supports not (animation-timeline:--foo) {
.target { animation-play-state: paused; }
}
#element_initial_axis { animation-timeline: timeline_initial_axis; }
#element_vertical { animation-timeline: timeline_vertical; }
#element_horizontal { animation-timeline: timeline_horizontal; }
#element_block_in_horizontal { animation-timeline: timeline_block_in_horizontal; }
#element_inline_in_horizontal { animation-timeline: timeline_inline_in_horizontal; }
#element_block_in_vertical { animation-timeline: timeline_block_in_vertical; }
#element_inline_in_vertical { animation-timeline: timeline_inline_in_vertical; }
#element_initial_axis { animation-timeline: --timeline_initial_axis; }
#element_y { animation-timeline: --timeline_y; }
#element_x { animation-timeline: --timeline_x; }
#element_block_in_horizontal { animation-timeline: --timeline_block_in_horizontal; }
#element_inline_in_horizontal { animation-timeline: --timeline_inline_in_horizontal; }
#element_block_in_vertical { animation-timeline: --timeline_block_in_vertical; }
#element_inline_in_vertical { animation-timeline: --timeline_inline_in_vertical; }
</style>
<div class=scroller id=timeline_initial_axis>
<div class=contents></div>
<div class=target id=element_initial_axis></div>
</div>
<div class=scroller id=timeline_vertical>
<div class=scroller id=timeline_y>
<div class=contents></div>
<div class=target id=element_vertical></div>
<div class=target id=element_y></div>
</div>
<div class=scroller id=timeline_horizontal>
<div class=scroller id=timeline_x>
<div class=contents></div>
<div class=target id=element_horizontal></div>
<div class=target id=element_x></div>
</div>
<div class=scroller id=timeline_block_in_horizontal>
<div class=contents></div>
@ -91,11 +91,11 @@
<script>
// Animations linked to vertical scroll-timelines are at 75% progress.
timeline_initial_axis.scrollTop = 75;
timeline_vertical.scrollTop = 75;
timeline_y.scrollTop = 75;
timeline_block_in_horizontal.scrollTop = 75;
timeline_inline_in_vertical.scrollTop = 75;
// Animations linked to horizontal scroll-timelines are at 25% progress.
timeline_horizontal.scrollLeft = 25;
timeline_x.scrollLeft = 25;
timeline_block_in_vertical.scrollLeft = 25;
timeline_inline_in_horizontal.scrollLeft = 25;
@ -106,12 +106,12 @@
promise_test(async (t) => {
await waitForNextFrame();
assert_equals(getComputedStyle(element_vertical).width, '175px');
assert_equals(getComputedStyle(element_y).width, '175px');
}, 'Vertical axis');
promise_test(async (t) => {
await waitForNextFrame();
assert_equals(getComputedStyle(element_horizontal).width, '125px');
assert_equals(getComputedStyle(element_x).width, '125px');
}, 'Horizontal axis');
promise_test(async (t) => {

View file

@ -6,6 +6,15 @@
<script src="/web-animations/testcommon.js"></script>
<script src="support/testcommon.js"></script>
<style>
main {
scroll-timeline-attachment: defer;
scroll-timeline-name: --timeline;
}
.scroller {
scroll-timeline-attachment: ancestor;
}
main > div {
overflow: hidden;
width: 100px;
@ -29,9 +38,13 @@
animation-timing-function: steps(10, end);
}
</style>
<main>
<div id=scroller1><div></div></div>
<div id=scroller2><div></div></div>
<main id=main>
<div id=scroller1 class=scroller>
<div></div>
</div>
<div id=scroller2 class=scroller>
<div></div>
</div>
<div id=container></div>
</main>
<script>
@ -64,6 +77,7 @@
} finally {
while (container.firstChild)
container.firstChild.remove();
main.style = '';
scroller1.style = '';
scroller2.style = '';
}
@ -96,8 +110,8 @@
await assert_width(element, '100px');
// Switch to scroll timeline.
scroller1.style.scrollTimelineName = 'timeline';
element.style.animationTimeline = 'timeline';
scroller1.style.scrollTimelineName = '--timeline';
element.style.animationTimeline = '--timeline';
await assert_width(element, '120px');
// Switching from ScrollTimeline -> DocumentTimeline should preserve
@ -117,8 +131,8 @@
assert_true(anim.pending, "The animation is in play pending");
// Switch to scroll timeline for a pending animation.
scroller1.style.scrollTimelineName = 'timeline';
element.style.animationTimeline = 'timeline';
scroller1.style.scrollTimelineName = '--timeline';
element.style.animationTimeline = '--timeline';
await anim.ready;
assert_false(anim.pending, "The animation is not pending");
@ -130,18 +144,19 @@
let element = insertElement();
// Note: #scroller1 is at 20%, and #scroller2 is at 40%.
scroller1.style.scrollTimelineName = 'timeline1';
scroller2.style.scrollTimelineName = 'timeline2';
scroller1.style.scrollTimelineName = '--timeline1';
scroller2.style.scrollTimelineName = '--timeline2';
main.style.scrollTimelineName = "--timeline1, --timeline2";
await assert_width(element, '100px');
element.style.animationTimeline = 'timeline1';
element.style.animationTimeline = '--timeline1';
await assert_width(element, '120px');
element.style.animationTimeline = 'timeline2';
element.style.animationTimeline = '--timeline2';
await assert_width(element, '140px');
element.style.animationTimeline = 'timeline1';
element.style.animationTimeline = '--timeline1';
await assert_width(element, '120px');
// Switching from ScrollTimeline -> DocumentTimeline should preserve
@ -154,7 +169,7 @@
dynamic_rule_test(async (t, assert_width) => {
let element = insertElement();
scroller1.style.scrollTimelineName = 'timeline';
scroller1.style.scrollTimelineName = '--timeline';
// DocumentTimeline applies by default.
await assert_width(element, '100px');
@ -164,7 +179,7 @@
await element.getAnimations()[0].ready;
// DocumentTimeline -> none
element.style.animationTimeline = 'none';
element.style.animationTimeline = '--none';
await assert_width(element, '0px');
// none -> DocumentTimeline
@ -172,50 +187,35 @@
await assert_width(element, '100px');
// DocumentTimeline -> ScrollTimeline
element.style.animationTimeline = 'timeline';
element.style.animationTimeline = '--timeline';
await assert_width(element, '120px');
// ScrollTimeline -> none
element.style.animationTimeline = 'none';
element.style.animationTimeline = '--none';
await assert_width(element, '120px');
// none -> ScrollTimeline
element.style.animationTimeline = 'timeline';
element.style.animationTimeline = '--timeline';
await assert_width(element, '120px');
}, 'Changing to/from animation-timeline:none');
dynamic_rule_test(async (t, assert_width) => {
let element = insertElement();
element.style.animationTimeline = 'timeline';
// Unknown animation-timeline, current time held at zero.
await assert_width(element, '100px');
scroller1.style.scrollTimelineName = 'timeline';
await assert_width(element, '120px');
scroller2.style.scrollTimelineName = 'timeline';
await assert_width(element, '140px');
}, 'Changing scroll-timeline on preceding elements affects target element');
dynamic_rule_test(async (t, assert_width) => {
let element = insertElement();
element.style.animationDirection = 'reverse';
element.style.animationTimeline = 'timeline';
element.style.animationTimeline = '--timeline';
// Unknown animation-timeline, current time held at zero.
await assert_width(element, '200px');
// Inactive animation-timeline. Animation is inactive.
await assert_width(element, '0px');
// Note: #scroller1 is at 20%.
scroller1.style.scrollTimelineName = 'timeline';
scroller1.style.scrollTimelineName = '--timeline';
await assert_width(element, '180px');
// Note: #scroller2 is at 40%.
scroller2.style.scrollTimelineName = 'timeline';
scroller1.style.scrollTimelineName = '';
scroller2.style.scrollTimelineName = '--timeline';
await assert_width(element, '160px');
element.style.animationDirection = '';
@ -224,13 +224,13 @@
dynamic_rule_test(async (t, assert_width) => {
let element = insertElement();
element.style.animationTimeline = 'timeline';
element.style.animationTimeline = '--timeline';
// Unknown animation-timeline, current time held at zero.
await assert_width(element, '100px');
// Inactive animation-timeline. Animation effect is inactive.
await assert_width(element, '0px');
// Note: #scroller1 is at 20%.
scroller1.style.scrollTimelineName = 'timeline';
scroller1.style.scrollTimelineName = '--timeline';
await assert_width(element, '120px');
element.style.animationPlayState = 'paused';
@ -239,26 +239,26 @@
await assert_width(element, '120px');
// Note: #scroller2 is at 40%.
scroller2.style.scrollTimelineName = 'timeline';
scroller1.style.scrollTimelineName = '';
scroller2.style.scrollTimelineName = '--timeline';
// Even when switching timelines, we should be at the same position until
// we unpause.
// Should be at the same position until we unpause.
await assert_width(element, '120px');
// Unpausing should synchronize to the scroll position.
element.style.animationPlayState = '';
await assert_width(element, '140px');
}, 'Switching timelines while paused');
}, 'Change to timeline attachment while paused');
dynamic_rule_test(async (t, assert_width) => {
let element = insertElement();
// Note: #scroller1 is at 20%.
scroller1.style.scrollTimelineName = 'timeline';
scroller1.style.scrollTimelineName = '--timeline';
await assert_width(element, '100px');
element.style.animationTimeline = 'timeline';
element.style.animationTimeline = '--timeline';
element.style.animationPlayState = 'paused';
// Pausing should happen before the timeline is modified. (Tentative).

View file

@ -29,7 +29,7 @@
/* This does not apply initially. */
@container (width > 200px) {
#scroller {
scroll-timeline: timeline;
scroll-timeline: --timeline;
}
}
@ -42,7 +42,7 @@
height: 10px;
width: 10px;
animation: recolor 10s linear;
animation-timeline: timeline;
animation-timeline: --timeline;
background-color: rgb(0, 0, 0);
}
</style>

View file

@ -27,12 +27,12 @@
<template id=basic>
<style>
#timeline {
scroll-timeline: timeline;
scroll-timeline: --timeline;
}
#element {
width: 0px;
animation: expand 10s linear paused;
animation-timeline: timeline;
animation-timeline: --timeline;
}
</style>
<div id="container">
@ -57,7 +57,7 @@
#element {
width: 0px;
animation: expand 10s linear paused;
animation-timeline: timeline;
animation-timeline: --timeline;
}
</style>
<div id="container">

View file

@ -18,7 +18,7 @@
main {
height: 0px;
overflow: hidden;
scroll-timeline: timeline1 defer, timeline2 defer;
scroll-timeline: --timeline1 defer, --timeline2 defer;
}
.scroller {
height: 100px;
@ -30,12 +30,12 @@
#element1 {
width: 1px;
animation: expand_width 10s;
animation-timeline: timeline1;
animation-timeline: --timeline1;
}
#element2 {
height: 1px;
animation: expand_height 10s;
animation-timeline: timeline2;
animation-timeline: --timeline2;
}
</style>
<main id=main>
@ -61,7 +61,7 @@
let events1 = [];
let events2 = [];
insertScroller('timeline1');
insertScroller('--timeline1');
// Even though the scroller was just inserted into the DOM, |timeline1|
// remains inactive until the next frame.
//
@ -69,7 +69,7 @@
assert_equals(getComputedStyle(element1).width, '1px');
(new ResizeObserver(entries => {
events1.push(entries);
insertScroller('timeline2');
insertScroller('--timeline2');
assert_equals(getComputedStyle(element2).height, '1px');
})).observe(element1);

View file

@ -5,24 +5,24 @@
<script src="/css/support/computed-testcommon.js"></script>
</head>
<style>
#outer { scroll-timeline-name: foo; }
#target { scroll-timeline-name: bar; }
#outer { scroll-timeline-name: --foo; }
#target { scroll-timeline-name: --bar; }
</style>
<div id="outer">
<div id="target"></div>
</div>
<script>
test_computed_value('scroll-timeline-name', 'initial', 'none');
test_computed_value('scroll-timeline-name', 'inherit', 'foo');
test_computed_value('scroll-timeline-name', 'inherit', '--foo');
test_computed_value('scroll-timeline-name', 'unset', 'none');
test_computed_value('scroll-timeline-name', 'revert', 'none');
test_computed_value('scroll-timeline-name', 'none');
test_computed_value('scroll-timeline-name', 'test');
test_computed_value('scroll-timeline-name', 'foo, bar');
test_computed_value('scroll-timeline-name', 'bar, foo');
test_computed_value('scroll-timeline-name', 'a, b, c, D, e');
test_computed_value('scroll-timeline-name', '--foo');
test_computed_value('scroll-timeline-name', '--foo, --bar');
test_computed_value('scroll-timeline-name', '--bar, --foo');
test_computed_value('scroll-timeline-name', '--a, --b, --c, --D, --e');
test_computed_value('scroll-timeline-name', 'none, none');
test_computed_value('scroll-timeline-name', 'a, b, c, none, d, e');
test_computed_value('scroll-timeline-name', '--a, --b, --c, none, --d, --e');
test(() => {
let style = getComputedStyle(document.getElementById('target'));

View file

@ -12,15 +12,16 @@ test_valid_value('scroll-timeline-name', 'unset');
test_valid_value('scroll-timeline-name', 'revert');
test_valid_value('scroll-timeline-name', 'none');
test_valid_value('scroll-timeline-name', 'abc');
test_valid_value('scroll-timeline-name', ' abc', 'abc');
test_valid_value('scroll-timeline-name', 'aBc');
test_valid_value('scroll-timeline-name', 'foo, bar');
test_valid_value('scroll-timeline-name', 'bar, foo');
test_valid_value('scroll-timeline-name', '--abc');
test_valid_value('scroll-timeline-name', ' --abc', '--abc');
test_valid_value('scroll-timeline-name', '--aBc');
test_valid_value('scroll-timeline-name', '--foo, --bar');
test_valid_value('scroll-timeline-name', '--bar, --foo');
test_valid_value('scroll-timeline-name', 'none, none');
test_valid_value('scroll-timeline-name', 'a, none, b');
test_valid_value('scroll-timeline-name', 'auto');
test_valid_value('scroll-timeline-name', '--a, none, --b');
test_invalid_value('scroll-timeline-name', 'auto');
test_invalid_value('scroll-timeline-name', 'abc');
test_invalid_value('scroll-timeline-name', 'default');
test_invalid_value('scroll-timeline-name', '10px');
test_invalid_value('scroll-timeline-name', 'foo bar');

View file

@ -31,10 +31,10 @@
<style>
.target {
animation: anim 10s linear;
animation-timeline: timeline;
animation-timeline: --timeline;
}
main > .scroller {
scroll-timeline: timeline horizontal;
scroll-timeline: --timeline x;
}
</style>
<div class=scroller>
@ -42,7 +42,7 @@
<template shadowrootmode=open>
<style>
:host {
scroll-timeline: timeline vertical;
scroll-timeline: --timeline y;
}
</style>
<slot></slot>
@ -60,7 +60,7 @@
assert_equals(target.getAnimations().length, 1);
let anim = target.getAnimations()[0];
assert_not_equals(anim.timeline, null);
assert_equals(anim.timeline.axis, 'vertical');
assert_equals(anim.timeline.axis, 'y');
}, 'Outer animation can see scroll timeline defined by :host');
</script>
@ -69,17 +69,17 @@
<style>
.target {
animation: anim 10s linear;
animation-timeline: timeline;
animation-timeline: --timeline;
}
.host {
scroll-timeline: timeline horizontal;
scroll-timeline: --timeline x;
}
</style>
<div class=host>
<template shadowrootmode=open>
<style>
::slotted(.scroller) {
scroll-timeline: timeline vertical;
scroll-timeline: --timeline y;
}
</style>
<slot></slot>
@ -98,7 +98,7 @@
assert_equals(target.getAnimations().length, 1);
let anim = target.getAnimations()[0];
assert_not_equals(anim.timeline, null);
assert_equals(anim.timeline.axis, 'vertical');
assert_equals(anim.timeline.axis, 'y');
}, 'Outer animation can see scroll timeline defined by ::slotted');
</script>
@ -106,10 +106,10 @@
<template id=scroll_timeline_part>
<style>
.host {
scroll-timeline: timeline vertical;
scroll-timeline: --timeline y;
}
.host::part(foo) {
scroll-timeline: timeline horizontal;
scroll-timeline: --timeline x;
}
</style>
<div class=host>
@ -122,7 +122,7 @@
}
.target {
animation: anim2 10s linear;
animation-timeline: timeline;
animation-timeline: --timeline;
}
</style>
<div part=foo>
@ -140,7 +140,7 @@
assert_equals(target.getAnimations().length, 1);
let anim = target.getAnimations()[0];
assert_not_equals(anim.timeline, null);
assert_equals(anim.timeline.axis, 'horizontal');
assert_equals(anim.timeline.axis, 'x');
}, 'Inner animation can see scroll timeline defined by ::part');
</script>
@ -149,10 +149,10 @@
<style>
.target {
animation: anim 10s linear;
animation-timeline: timeline;
animation-timeline: --timeline;
}
.host {
scroll-timeline: timeline horizontal;
scroll-timeline: --timeline x;
}
</style>
<div class=scroller>
@ -160,7 +160,7 @@
<template shadowrootmode=open>
<style>
div {
scroll-timeline: timeline vertical;
scroll-timeline: --timeline y;
}
</style>
<div>
@ -180,6 +180,6 @@
assert_equals(target.getAnimations().length, 1);
let anim = target.getAnimations()[0];
assert_not_equals(anim.timeline, null);
assert_equals(anim.timeline.axis, 'vertical');
assert_equals(anim.timeline.axis, 'y');
}, 'Slotted element can see scroll timeline within the shadow');
</script>

View file

@ -16,7 +16,7 @@
overflow-x: scroll;
display: flex;
flex-direction: row;
scroll-timeline: timeline inline;
scroll-timeline: --timeline inline;
}
.progress {

View file

@ -8,7 +8,7 @@
overflow: hidden;
width: 100px;
height: 100px;
scroll-timeline: timeline;
scroll-timeline: --timeline;
}
#contents {
height: 200px;
@ -20,10 +20,10 @@
#element {
width: 0px;
animation: expand 10s linear;
animation-timeline: timeline;
animation-timeline: --timeline;
}
/* Ensure stable expectations if feature is not supported */
@supports not (animation-timeline:foo) {
@supports not (animation-timeline:--foo) {
#element { animation-play-state: paused; }
}
</style>

View file

@ -9,67 +9,67 @@
<script>
test_valid_value('scroll-timeline', 'none block', 'none');
test_valid_value('scroll-timeline', 'none inline');
test_valid_value('scroll-timeline', 'abc horizontal');
test_valid_value('scroll-timeline', 'abc inline');
test_valid_value('scroll-timeline', 'aBc inline');
test_valid_value('scroll-timeline', 'inline inline');
test_valid_value('scroll-timeline', 'abc');
test_valid_value('scroll-timeline', '--abc x');
test_valid_value('scroll-timeline', '--abc inline');
test_valid_value('scroll-timeline', '--aBc inline');
test_valid_value('scroll-timeline', '--inline inline');
test_valid_value('scroll-timeline', '--abc');
test_valid_value('scroll-timeline', 'inline block', 'inline');
test_valid_value('scroll-timeline', 'block block', 'block');
test_valid_value('scroll-timeline', 'vertical block', 'vertical');
test_valid_value('scroll-timeline', 'horizontal block', 'horizontal');
test_valid_value('scroll-timeline', '--inline block', '--inline');
test_valid_value('scroll-timeline', '--block block', '--block');
test_valid_value('scroll-timeline', '--y block', '--y');
test_valid_value('scroll-timeline', '--x block', '--x');
test_valid_value('scroll-timeline', 'a, b, c');
test_valid_value('scroll-timeline', 'a inline, b block, c vertical', 'a inline, b, c vertical');
test_valid_value('scroll-timeline', 'auto');
test_valid_value('scroll-timeline', 'abc defer vertical', 'abc vertical defer');
test_valid_value('scroll-timeline', 'abc vertical defer');
test_valid_value('scroll-timeline', '--a, --b, --c');
test_valid_value('scroll-timeline', '--a inline, --b block, --c y', '--a inline, --b, --c y');
test_valid_value('scroll-timeline', '--auto');
test_valid_value('scroll-timeline', '--abc defer y', '--abc y defer');
test_valid_value('scroll-timeline', '--abc y defer');
test_invalid_value('scroll-timeline', '');
test_invalid_value('scroll-timeline', 'abc abc');
test_invalid_value('scroll-timeline', '--abc --abc');
test_invalid_value('scroll-timeline', 'block none');
test_invalid_value('scroll-timeline', 'inline abc');
test_invalid_value('scroll-timeline', 'inline --abc');
test_invalid_value('scroll-timeline', 'default');
test_invalid_value('scroll-timeline', ',');
test_invalid_value('scroll-timeline', ',,block,,');
test_computed_value('scroll-timeline', 'none block', 'none');
test_computed_value('scroll-timeline', 'abc inline');
test_computed_value('scroll-timeline', 'none vertical');
test_computed_value('scroll-timeline', 'abc horizontal');
test_computed_value('scroll-timeline', 'vertical vertical');
test_computed_value('scroll-timeline', 'abc');
test_computed_value('scroll-timeline', 'inline block', 'inline');
test_computed_value('scroll-timeline', 'block block', 'block');
test_computed_value('scroll-timeline', 'vertical block', 'vertical');
test_computed_value('scroll-timeline', 'horizontal block', 'horizontal');
test_computed_value('scroll-timeline', 'a, b, c');
test_computed_value('scroll-timeline', 'a inline, b block, c vertical', 'a inline, b, c vertical');
test_computed_value('scroll-timeline', 'abc defer vertical', 'abc vertical defer');
test_computed_value('scroll-timeline', 'abc vertical defer');
test_computed_value('scroll-timeline', '--abc inline');
test_computed_value('scroll-timeline', 'none y');
test_computed_value('scroll-timeline', '--abc x');
test_computed_value('scroll-timeline', '--y y');
test_computed_value('scroll-timeline', '--abc');
test_computed_value('scroll-timeline', '--inline block', '--inline');
test_computed_value('scroll-timeline', '--block block', '--block');
test_computed_value('scroll-timeline', '--y block', '--y');
test_computed_value('scroll-timeline', '--x block', '--x');
test_computed_value('scroll-timeline', '--a, --b, --c');
test_computed_value('scroll-timeline', '--a inline, --b block, --c y', '--a inline, --b, --c y');
test_computed_value('scroll-timeline', '--abc defer y', '--abc y defer');
test_computed_value('scroll-timeline', '--abc y defer');
test_shorthand_value('scroll-timeline', 'abc vertical local',
test_shorthand_value('scroll-timeline', '--abc y local',
{
'scroll-timeline-name': 'abc',
'scroll-timeline-axis': 'vertical',
'scroll-timeline-name': '--abc',
'scroll-timeline-axis': 'y',
'scroll-timeline-attachment': 'local',
});
test_shorthand_value('scroll-timeline', 'inline horizontal defer',
test_shorthand_value('scroll-timeline', '--inline x defer',
{
'scroll-timeline-name': 'inline',
'scroll-timeline-axis': 'horizontal',
'scroll-timeline-name': '--inline',
'scroll-timeline-axis': 'x',
'scroll-timeline-attachment': 'defer',
});
test_shorthand_value('scroll-timeline', 'abc vertical ancestor, def',
test_shorthand_value('scroll-timeline', '--abc y ancestor, --def',
{
'scroll-timeline-name': 'abc, def',
'scroll-timeline-axis': 'vertical, block',
'scroll-timeline-name': '--abc, --def',
'scroll-timeline-axis': 'y, block',
'scroll-timeline-attachment': 'ancestor, local',
});
test_shorthand_value('scroll-timeline', 'abc, def',
test_shorthand_value('scroll-timeline', '--abc, --def',
{
'scroll-timeline-name': 'abc, def',
'scroll-timeline-name': '--abc, --def',
'scroll-timeline-axis': 'block, block',
'scroll-timeline-attachment': 'local, local',
});
@ -89,16 +89,16 @@ function test_shorthand_contraction(shorthand, longhands, expected) {
}
test_shorthand_contraction('scroll-timeline', {
'scroll-timeline-name': 'abc',
'scroll-timeline-name': '--abc',
'scroll-timeline-axis': 'inline',
'scroll-timeline-attachment': 'defer',
}, 'abc inline defer');
}, '--abc inline defer');
test_shorthand_contraction('scroll-timeline', {
'scroll-timeline-name': 'a, b',
'scroll-timeline-name': '--a, --b',
'scroll-timeline-axis': 'inline, block',
'scroll-timeline-attachment': 'ancestor, local',
}, 'a inline ancestor, b');
}, '--a inline ancestor, --b');
test_shorthand_contraction('scroll-timeline', {
'scroll-timeline-name': 'none, none',
@ -109,13 +109,13 @@ test_shorthand_contraction('scroll-timeline', {
// Longhands with different lengths:
test_shorthand_contraction('scroll-timeline', {
'scroll-timeline-name': 'a, b, c',
'scroll-timeline-name': '--a, --b, --c',
'scroll-timeline-axis': 'inline, inline',
'scroll-timeline-attachment': 'local, local',
}, '');
test_shorthand_contraction('scroll-timeline', {
'scroll-timeline-name': 'a, b',
'scroll-timeline-name': '--a, --b',
'scroll-timeline-axis': 'inline, inline, inline',
'scroll-timeline-attachment': 'local, local',
}, '');

View file

@ -1,52 +0,0 @@
<!DOCTYPE html>
<title>scroll-timeline and container queries</title>
<link rel="help" src="https://drafts.csswg.org/scroll-animations-1/#scroll-timeline-shorthand">
<link rel="help" src="https://drafts.csswg.org/css-contain-3/#container-queries">
<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>
#scroller {
overflow: auto;
width: auto;
height: 100px;
}
#scroller > div {
height: 200px;
}
@keyframes anim {
from { background-color: rgb(100, 100, 100); }
to { background-color: rgb(200, 200, 200); }
}
#element {
height: 10px;
width: 10px;
animation: anim 10s linear;
animation-timeline: timeline;
background-color: rgb(0, 0, 0);
}
</style>
<div>
<div id=scroller>
<div></div>
</div>
<div>
<div id=element></div>
</div>
</div>
<script>
setup(assert_implements_animation_timeline);
promise_test(async (t) => {
element.offsetTop;
scroller.scrollTop = 50;
await waitForNextFrame();
// Unknown timeline, time held at zero.
assert_equals(getComputedStyle(element).backgroundColor, 'rgb(100, 100, 100)');
scroller.style.scrollTimeline = 'timeline';
await waitForCSSScrollTimelineStyle();
assert_equals(getComputedStyle(element).backgroundColor, 'rgb(150, 150, 150)');
}, 'Timelines appearing on preceding siblings are visible to getComputedStyle');
</script>

View file

@ -18,7 +18,7 @@
overflow: hidden;
width: 300px;
height: 200px;
scroll-timeline: timeline;
scroll-timeline: --timeline;
}
#target {
margin-bottom: 800px;
@ -33,7 +33,7 @@
}
#target.update {
animation-play-state: running;
animation-timeline: timeline;
animation-timeline: --timeline;
animation-duration: auto;
}
</style>

View file

@ -0,0 +1,82 @@
.flex {
display: flex;
}
.flex > div {
position: relative;
height: 160px;
margin: 0 10px;
}
.scroller {
width: 100px;
height: 100px;
overflow: auto;
border: 1px solid black;
}
.subject {
view-timeline-name: --view;
width: 20px;
height: 20px;
margin: 0 auto;
background: green;
}
.meters {
position: absolute;
left: 0;
top: 110px;
height: 50px;
}
.meters > div {
display: flex;
align-items: center;
}
@keyframes active-interval {
0% { opacity: 1; }
100% { opacity: 1; }
}
.meter {
width: 50px;
position: relative;
border: 2px solid black;
height: 5px;
overflow: clip;
opacity: 0.4;
animation: active-interval linear;
animation-timeline: --view;
}
@keyframes slide-in {
0% { transform: translateX(-100%)}
100% { transform: translateX(0%)}
}
.bar {
width: 100%;
height: 100%;
background: blue;
transform: translateX(-100%);
animation: slide-in linear;
animation-timeline: --view;
}
.spacer {
height: 400px;
}
.contain .bar, .contain .meter {
animation-range: contain;
}
.entry .bar, .entry .meter {
animation-range: entry;
}
.exit .bar, .exit .meter {
animation-range: exit;
}

View file

@ -14,6 +14,6 @@ async function waitForCSSScrollTimelineStyle() {
}
function assert_implements_animation_timeline() {
assert_implements(CSS.supports('animation-timeline:foo'),
assert_implements(CSS.supports('animation-timeline:--foo'),
'animation-timeline not supported');
}

View file

@ -27,7 +27,7 @@
overflow-x: hidden;
width: 300px;
height: 200px;
view-timeline: sibling defer;
view-timeline: --sibling defer;
}
#sibling {
margin-top: 800px;
@ -36,7 +36,7 @@
width: 100px;
height: 50px;
background-color: blue;
view-timeline: sibling block ancestor;
view-timeline: --sibling block ancestor;
}
#target {
margin-bottom: 800px;
@ -50,14 +50,14 @@
/* using document timeline by default */
animation-range-start: contain 0%;
animation-range-end: contain 100%;
view-timeline: target block;
view-timeline: --target block;
}
#target.with-view-timeline {
animation-timeline: target;
animation-timeline: --target;
}
#target.with-view-timeline.retarget {
animation-timeline: sibling;
animation-timeline: --sibling;
}
</style>
<body>
@ -90,7 +90,7 @@
// Once a view-timeline is added, the kefyrames must update to reflect
// the new keyframe offsets.
target.classList.add('with-view-timeline');
assert_equals(getComputedStyle(target).animationTimeline, 'target',
assert_equals(getComputedStyle(target).animationTimeline, '--target',
'Switch to view timeline');
await waitForNextFrame();
@ -110,7 +110,7 @@
assert_frame_lists_equal(frames, expected);
target.classList.add('retarget');
assert_equals(getComputedStyle(target).animationTimeline, 'sibling',
assert_equals(getComputedStyle(target).animationTimeline, '--sibling',
'Switch to another view timeline');
await waitForNextFrame();
frames = anim.effect.getKeyframes();

View file

@ -13,10 +13,10 @@
<style type="text/css">
@keyframes anim {
cover 0% {
margin-left: 0px;
margin-left: 0px;
}
50% {
opacity: 0.5;
opacity: 0.5;
}
cover 100% {
margin-right: 0px;
@ -24,35 +24,34 @@
}
#scroller {
scroll-timeline-attachment: defer t1;
border: 10px solid lightgray;
border: 10px solid lightgray;
overflow-y: scroll;
overflow-x: hidden;
width: 300px;
height: 200px;
view-timeline: --t1 defer;
}
#block {
scroll-timeline-attachment: ancestor;
margin-top: 800px;
margin-left: 10px;
margin-right: 10px;
width: 100px;
height: 50px;
background-color: blue;
view-timeline: t1 block;
margin-top: 800px;
margin-left: 10px;
margin-right: 10px;
width: 100px;
height: 50px;
background-color: blue;
view-timeline: --t1 ancestor;
}
#target {
margin-bottom: 800px;
margin-left: 10px;
margin-right: 10px;
margin-left: 10px;
margin-right: 10px;
width: 100px;
height: 100px;
z-index: -1;
background-color: green;
animation: anim auto both linear;
animation-range-start: contain 0%;
animation-range-end: contain 100%;
animation-timeline: t1;
animation: anim auto both linear;
animation-range-start: contain 0%;
animation-range-end: contain 100%;
animation-timeline: --t1;
}
</style>
<body>
@ -74,16 +73,16 @@
let frames = anim.effect.getKeyframes();
let expected_resolved_offsets = [
{ offset: 0, computedOffset: 0, easing: "linear", composite: "replace",
{ offset: 0, computedOffset: 0, easing: "linear", composite: "replace",
marginRight: "10px", opacity: "1" },
{ offset: 1/2, computedOffset: 1/2, easing: "linear",
composite: "auto", opacity: "0.5" },
{ offset: 1, computedOffset: 1, easing: "linear", composite: "replace",
marginLeft: "10px", opacity: "1" },
{ offset: { rangeName: 'cover', offset: CSS.percent(0) },
{ offset: { rangeName: "cover", offset: CSS.percent(0) },
computedOffset: -1/3, easing: "linear",
composite: "auto", marginLeft: "0px" },
{ offset: { rangeName: 'cover', offset: CSS.percent(100) },
{ offset: { rangeName: "cover", offset: CSS.percent(100) },
computedOffset: 4/3, easing: "linear", composite: "auto",
marginRight: "0px" },
];

View file

@ -17,9 +17,9 @@
background-color: rgba(0, 0, 255);
height: 200px;
width: 200px;
view-timeline-name: foo;
view-timeline-name: --foo;
animation: linear 1s both fade-in-out-animation;
animation-timeline: foo;
animation-timeline: --foo;
}
#container {

View file

@ -0,0 +1,35 @@
<!DOCTYPE html>
<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/7759">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/css/support/computed-testcommon.js"></script>
</head>
<style>
#outer { timeline-scope: foo; }
#target { timeline-scope: bar; }
</style>
<div id="outer">
<div id="target"></div>
</div>
<script>
test_computed_value('timeline-scope', 'initial', 'none');
test_computed_value('timeline-scope', 'inherit', 'foo');
test_computed_value('timeline-scope', 'unset', 'none');
test_computed_value('timeline-scope', 'revert', 'none');
test_computed_value('timeline-scope', 'none');
test_computed_value('timeline-scope', 'test');
test_computed_value('timeline-scope', 'foo, bar');
test_computed_value('timeline-scope', 'bar, foo');
test_computed_value('timeline-scope', 'a, b, c, D, e');
test(() => {
let style = getComputedStyle(document.getElementById('target'));
assert_not_equals(Array.from(style).indexOf('timeline-scope'), -1);
}, 'The timeline-scope property shows up in CSSStyleDeclaration enumeration');
test(() => {
let style = document.getElementById('target').style;
assert_not_equals(style.cssText.indexOf('timeline-scope'), -1);
}, 'The timeline-scope property shows up in CSSStyleDeclaration.cssText');
</script>

View file

@ -0,0 +1,29 @@
<!DOCTYPE html>
<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/7759">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/css/support/parsing-testcommon.js"></script>
<div id="target"></div>
<script>
test_valid_value('timeline-scope', 'initial');
test_valid_value('timeline-scope', 'inherit');
test_valid_value('timeline-scope', 'unset');
test_valid_value('timeline-scope', 'revert');
test_valid_value('timeline-scope', 'none');
test_valid_value('timeline-scope', 'abc');
test_valid_value('timeline-scope', ' abc', 'abc');
test_valid_value('timeline-scope', 'aBc');
test_valid_value('timeline-scope', 'foo, bar');
test_valid_value('timeline-scope', 'bar, foo');
test_valid_value('timeline-scope', 'auto');
test_invalid_value('timeline-scope', 'none, abc');
test_invalid_value('timeline-scope', '10px');
test_invalid_value('timeline-scope', 'foo bar');
test_invalid_value('timeline-scope', '"foo" "bar"');
test_invalid_value('timeline-scope', 'rgb(1, 2, 3)');
test_invalid_value('timeline-scope', '#fefefe');
</script>

View file

@ -0,0 +1,314 @@
<!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>
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();
}
</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) => {
inflate(t, deferred_timeline);
let scroller = main.querySelector('.scroller');
let target = main.querySelector('.target');
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) => {
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) => {
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) => {
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) => {
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].
scrollers[0].classList.remove('timeline');
scrollers[1].classList.add('timeline');
await waitForNextFrame();
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) => {
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].
scrollers[1].classList.remove('timeline');
await waitForNextFrame();
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) => {
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) => {
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) => {
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) => {
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>

View file

@ -27,8 +27,8 @@
z-index: -1;
background-color: green;
animation: anim auto both linear;
animation-timeline: t1;
view-timeline: t1 block;
animation-timeline: --t1;
view-timeline: --t1 block;
}
.restrict-range {
animation-range-start: contain 0%;

View file

@ -52,9 +52,9 @@
<template id=default_view_timeline>
<style>
#target {
view-timeline: t1;
view-timeline: --t1;
animation: anim 1s linear;
animation-timeline: t1;
animation-timeline: --t1;
}
</style>
<div id=scroller class=vertical-scroller>
@ -87,9 +87,9 @@
<template id=horizontal_timeline>
<style>
#target {
view-timeline: t1 horizontal;
view-timeline: --t1 x;
animation: anim 1s linear;
animation-timeline: t1;
animation-timeline: --t1;
}
</style>
<div id=scroller class=horizontal-scroller>
@ -122,7 +122,7 @@
<template id=multiple_timelines>
<style>
#timelines {
view-timeline: tv vertical ancestor, th horizontal ancestor;
view-timeline: --tv y ancestor, --th x ancestor;
background-color: red;
}
#scroller {
@ -132,7 +132,7 @@
display: grid;
grid-template-columns: 50px 50px 50px 50px 50px 50px 50px;
grid-template-row: 50px 50px 50px 50px 50px 50px 50px;
view-timeline: tv defer, th defer;
view-timeline: --tv defer, --th defer;
}
#scroller > div {
z-index: -1;
@ -141,11 +141,11 @@
}
#target_v {
animation: anim 1s linear;
animation-timeline: tv;
animation-timeline: --tv;
}
#target_h {
animation: anim 1s linear;
animation-timeline: th;
animation-timeline: --th;
}
</style>
<div id=scroller>

View file

@ -39,10 +39,10 @@
background-color: coral;
width: 0px;
animation: anim auto linear;
animation-timeline: t1;
animation-timeline: --t1;
}
.timeline {
view-timeline-name: t1;
view-timeline-name: --t1;
}
.local {
view-timeline-attachment: local;
@ -122,7 +122,7 @@
<div class="timeline defer" style="view-timeline-axis:inline">
<div class=target>Test</div>
<div class=scroller>
<div class="content timeline ancestor" style="view-timeline-axis:vertical"></div>
<div class="content timeline ancestor" style="view-timeline-axis:y"></div>
</div>
</div>
</template>
@ -133,7 +133,7 @@
assert_equals(target.getAnimations().length, 1);
let anim = target.getAnimations()[0];
assert_not_equals(anim.timeline, null);
assert_equals(anim.timeline.axis, 'vertical');
assert_equals(anim.timeline.axis, 'y');
}, 'Axis of deferred timeline is taken from attached timeline');
</script>
@ -141,7 +141,7 @@
<div class="timeline defer" style="view-timeline-axis:inline">
<div class=target>Test</div>
<div class=scroller>
<div class="content timeline ancestor" style="view-timeline-axis:vertical"></div>
<div class="content timeline ancestor" style="view-timeline-axis:y"></div>
<!-- Extra attachment -->
<div class="timeline ancestor"></div>
</div>
@ -403,11 +403,11 @@
<!-- ViewTimelines and ScrollTimelines -->
<template id=view_scroll_timeline_defer>
<div style="scroll-timeline: t1 defer">
<div style="scroll-timeline: --t1 defer">
<div class=target>Test1</div>
<div class="timeline defer">
<div class=target>Test2</div>
<div class=scroller style="scroll-timeline: t1 ancestor;">
<div class=scroller style="scroll-timeline: --t1 ancestor;">
<div class="content timeline ancestor" style="view-timeline-inset: 0px 50px"></div>
</div>
</div>

View file

@ -6,7 +6,7 @@
</head>
<style>
#outer { view-timeline-axis: block, inline; }
#target { view-timeline-axis: vertical; }
#target { view-timeline-axis: y; }
</style>
<div id=outer>
<div id=target></div>
@ -18,11 +18,11 @@ test_computed_value('view-timeline-axis', 'unset', 'block');
test_computed_value('view-timeline-axis', 'revert', 'block');
test_computed_value('view-timeline-axis', 'block');
test_computed_value('view-timeline-axis', 'inline');
test_computed_value('view-timeline-axis', 'vertical');
test_computed_value('view-timeline-axis', 'horizontal');
test_computed_value('view-timeline-axis', 'y');
test_computed_value('view-timeline-axis', 'x');
test_computed_value('view-timeline-axis', 'block, inline');
test_computed_value('view-timeline-axis', 'inline, block');
test_computed_value('view-timeline-axis', 'block, vertical, horizontal, inline');
test_computed_value('view-timeline-axis', 'block, y, x, inline');
test_computed_value('view-timeline-axis', 'inline, inline, inline, inline');
test(() => {

View file

@ -13,11 +13,11 @@ test_valid_value('view-timeline-axis', 'revert');
test_valid_value('view-timeline-axis', 'block');
test_valid_value('view-timeline-axis', 'inline');
test_valid_value('view-timeline-axis', 'vertical');
test_valid_value('view-timeline-axis', 'horizontal');
test_valid_value('view-timeline-axis', 'y');
test_valid_value('view-timeline-axis', 'x');
test_valid_value('view-timeline-axis', 'block, inline');
test_valid_value('view-timeline-axis', 'inline, block');
test_valid_value('view-timeline-axis', 'block, vertical, horizontal, inline');
test_valid_value('view-timeline-axis', 'block, y, x, inline');
test_valid_value('view-timeline-axis', 'inline, inline, inline, inline');
test_invalid_value('view-timeline-axis', 'abc');

View file

@ -14,7 +14,7 @@
overflow: hidden;
width: 100px;
height: 100px;
view-timeline: t1 defer;
view-timeline: --t1 defer;
}
.scroller > div {
height: 100px;
@ -46,11 +46,11 @@
<template id=dynamic_view_timeline_name>
<style>
.timeline {
view-timeline: t1 ancestor;
view-timeline: --t1 ancestor;
}
#target {
animation: anim 1s linear;
animation-timeline: t1;
animation-timeline: --t1;
}
</style>
<div id=scroller class=scroller>
@ -106,11 +106,11 @@
width: 100px;
height: 100px;
margin: 100px;
view-timeline: t1 ancestor;
view-timeline: --t1 ancestor;
}
#target {
animation: anim 1s linear;
animation-timeline: t1;
animation-timeline: --t1;
}
</style>
<div id=scroller class=scroller>
@ -126,7 +126,7 @@
await scrollLeft(scroller, 20); // 10% (horizontal)
assert_equals(getComputedStyle(target).zIndex, '25', 'vertical');
timeline.style.viewTimelineAxis = 'horizontal';
timeline.style.viewTimelineAxis = 'x';
await waitForCSSScrollTimelineStyle();
assert_equals(getComputedStyle(target).zIndex, '10', 'horizontal');
}, 'Dynamically changing view-timeline-axis');
@ -138,11 +138,11 @@
width: 100px;
height: 100px;
margin: 100px;
view-timeline: t1 ancestor;
view-timeline: --t1 ancestor;
}
#target {
animation: anim 1s linear;
animation-timeline: t1;
animation-timeline: --t1;
}
</style>
<div id=scroller class=scroller>
@ -166,11 +166,11 @@
<template id=timeline_display_none>
<style>
#timeline {
view-timeline: t1 ancestor;
view-timeline: --t1 ancestor;
}
#target {
animation: anim 1s linear;
animation-timeline: t1;
animation-timeline: --t1;
}
</style>
<div id=scroller class=scroller>

View file

@ -91,10 +91,10 @@
<template id=test_one_value>
<style>
#target {
view-timeline: t1;
view-timeline: --t1;
view-timeline-inset: 10px;
animation: anim 1s linear;
animation-timeline: t1;
animation-timeline: --t1;
}
</style>
<div id=scroller class=vertical>
@ -115,10 +115,10 @@
<template id=test_two_values>
<style>
#target {
view-timeline: t1;
view-timeline: --t1;
view-timeline-inset: 10px 20px;
animation: anim 1s linear;
animation-timeline: t1;
animation-timeline: --t1;
}
</style>
<div id=scroller class=vertical>
@ -140,10 +140,10 @@
<style>
#target {
font-size: 10px;
view-timeline: t1;
view-timeline: --t1;
view-timeline-inset: 10px 2em;
animation: anim 1s linear;
animation-timeline: t1;
animation-timeline: --t1;
}
</style>
<div id=scroller class=vertical>
@ -165,10 +165,10 @@
<style>
#target {
font-size: 10px;
view-timeline: t1;
view-timeline: --t1;
view-timeline-inset: calc(5px + max(1%, 5%)) 20%;
animation: anim 1s linear;
animation-timeline: t1;
animation-timeline: --t1;
}
</style>
<div id=scroller class=vertical>
@ -189,10 +189,10 @@
<template id=test_outset>
<style>
#target {
view-timeline: t1;
view-timeline: --t1;
view-timeline-inset: -10px -20px;
animation: anim 1s linear;
animation-timeline: t1;
animation-timeline: --t1;
}
</style>
<div id=scroller class=vertical>
@ -213,10 +213,10 @@
<template id=test_horizontal>
<style>
#target {
view-timeline: t1 horizontal;
view-timeline: --t1 x;
view-timeline-inset: 10px 20px;
animation: anim 1s linear;
animation-timeline: t1;
animation-timeline: --t1;
}
</style>
<div id=scroller>
@ -237,10 +237,10 @@
<template id=test_block>
<style>
#target {
view-timeline: t1 block;
view-timeline: --t1 block;
view-timeline-inset: 10px 20px;
animation: anim 1s linear;
animation-timeline: t1;
animation-timeline: --t1;
}
</style>
<div id=scroller>
@ -261,10 +261,10 @@
<template id=test_inline>
<style>
#target {
view-timeline: t1 inline;
view-timeline: --t1 inline;
view-timeline-inset: 10px 20px;
animation: anim 1s linear;
animation-timeline: t1;
animation-timeline: --t1;
}
</style>
<div id=scroller>
@ -288,10 +288,10 @@
scroll-padding-block: 10px 20px;
}
#target {
view-timeline: t1 block;
view-timeline: --t1 block;
view-timeline-inset: auto auto;
animation: anim 1s linear;
animation-timeline: t1;
animation-timeline: --t1;
}
</style>
<div id=scroller>
@ -316,10 +316,10 @@
writing-mode: vertical-lr;
}
#target {
view-timeline: t1 block;
view-timeline: --t1 block;
view-timeline-inset: auto auto;
animation: anim 1s linear;
animation-timeline: t1;
animation-timeline: --t1;
}
</style>
<div id=scroller>
@ -344,10 +344,10 @@
writing-mode: vertical-rl;
}
#target {
view-timeline: t1 block;
view-timeline: --t1 block;
view-timeline-inset: auto auto;
animation: anim 1s linear;
animation-timeline: t1;
animation-timeline: --t1;
}
</style>
<div id=scroller>
@ -372,10 +372,10 @@
scroll-padding-inline: 10px 20px;
}
#target {
view-timeline: t1 inline;
view-timeline: --t1 inline;
view-timeline-inset: auto auto;
animation: anim 1s linear;
animation-timeline: t1;
animation-timeline: --t1;
}
</style>
<div id=scroller>
@ -400,10 +400,10 @@
writing-mode: vertical-rl;
}
#target {
view-timeline: t1 inline;
view-timeline: --t1 inline;
view-timeline-inset: auto auto;
animation: anim 1s linear;
animation-timeline: t1;
animation-timeline: --t1;
}
</style>
<div id=scroller>
@ -428,10 +428,10 @@
writing-mode: vertical-lr;
}
#target {
view-timeline: t1 inline;
view-timeline: --t1 inline;
view-timeline-inset: auto auto;
animation: anim 1s linear;
animation-timeline: t1;
animation-timeline: --t1;
}
</style>
<div id=scroller>
@ -456,10 +456,10 @@
direction: rtl;
}
#target {
view-timeline: t1 inline;
view-timeline: --t1 inline;
view-timeline-inset: auto auto;
animation: anim 1s linear;
animation-timeline: t1;
animation-timeline: --t1;
}
</style>
<div id=scroller>
@ -485,10 +485,10 @@
direction: rtl;
}
#target {
view-timeline: t1 inline;
view-timeline: --t1 inline;
view-timeline-inset: auto auto;
animation: anim 1s linear;
animation-timeline: t1;
animation-timeline: --t1;
}
</style>
<div id=scroller>
@ -514,10 +514,10 @@
direction: rtl;
}
#target {
view-timeline: t1 inline;
view-timeline: --t1 inline;
view-timeline-inset: auto auto;
animation: anim 1s linear;
animation-timeline: t1;
animation-timeline: --t1;
}
</style>
<div id=scroller>
@ -541,10 +541,10 @@
scroll-padding-block: 10px 20px;
}
#target {
view-timeline: t1 vertical;
view-timeline: --t1 y;
view-timeline-inset: auto auto;
animation: anim 1s linear;
animation-timeline: t1;
animation-timeline: --t1;
}
</style>
<div id=scroller>
@ -559,7 +559,7 @@
await assertValueAt(scroller, target, { scrollTop:125 + 5, expected:50 }); // 50%
await assertValueAt(scroller, target, { scrollTop:200 - 10, expected:100 }); // 100%
await assertValueAt(scroller, target, { scrollTop:200, expected:-1 });
}, 'view-timeline-inset:auto, vertical');
}, 'view-timeline-inset:auto, y');
</script>
<template id=test_auto_vertical_vertical_rl>
@ -569,10 +569,10 @@
writing-mode: vertical-rl;
}
#target {
view-timeline: t1 vertical;
view-timeline: --t1 y;
view-timeline-inset: auto auto;
animation: anim 1s linear;
animation-timeline: t1;
animation-timeline: --t1;
}
</style>
<div id=scroller>
@ -587,7 +587,7 @@
await assertValueAt(scroller, target, { scrollTop:125 + 5, expected:50 }); // 50%
await assertValueAt(scroller, target, { scrollTop:200 - 10, expected:100 }); // 100%
await assertValueAt(scroller, target, { scrollTop:200, expected:-1 });
}, 'view-timeline-inset:auto, vertical, vertical-rl');
}, 'view-timeline-inset:auto, y, vertical-rl');
</script>
<template id=test_auto_vertical_vertical_rl_rtl>
@ -598,10 +598,10 @@
direction: rtl;
}
#target {
view-timeline: t1 vertical;
view-timeline: --t1 y;
view-timeline-inset: auto auto;
animation: anim 1s linear;
animation-timeline: t1;
animation-timeline: --t1;
}
</style>
<div id=scroller>
@ -616,7 +616,7 @@
await assertValueAt(scroller, target, { scrollTop:-(125 + 5), expected:50 }); // 50%
await assertValueAt(scroller, target, { scrollTop:-(200 - 10), expected:100 }); // 100%
await assertValueAt(scroller, target, { scrollTop:-200, expected:-1 });
}, 'view-timeline-inset:auto, vertical, vertical-rl, rtl');
}, 'view-timeline-inset:auto, y, vertical-rl, rtl');
</script>
<template id=test_auto_horizontal>
@ -625,10 +625,10 @@
scroll-padding-inline: 10px 20px;
}
#target {
view-timeline: t1 horizontal;
view-timeline: --t1 x;
view-timeline-inset: auto auto;
animation: anim 1s linear;
animation-timeline: t1;
animation-timeline: --t1;
}
</style>
<div id=scroller>
@ -643,7 +643,7 @@
await assertValueAt(scroller, target, { scrollLeft:135 + 5, expected:50 }); // 50%
await assertValueAt(scroller, target, { scrollLeft:200 - 10, expected:100 }); // 100%
await assertValueAt(scroller, target, { scrollLeft:200, expected:-1 });
}, 'view-timeline-inset:auto, horizontal');
}, 'view-timeline-inset:auto, x');
</script>
<template id=test_auto_horizontal_rtl>
@ -653,10 +653,10 @@
direction: rtl;
}
#target {
view-timeline: t1 horizontal;
view-timeline: --t1 x;
view-timeline-inset: auto auto;
animation: anim 1s linear;
animation-timeline: t1;
animation-timeline: --t1;
}
</style>
<div id=scroller>
@ -671,7 +671,7 @@
await assertValueAt(scroller, target, { scrollLeft:-(135 + 5), expected:50 }); // 50%
await assertValueAt(scroller, target, { scrollLeft:-(200 - 10), expected:100 }); // 100%
await assertValueAt(scroller, target, { scrollLeft:-200, expected:-1 });
}, 'view-timeline-inset:auto, horizontal, rtl');
}, 'view-timeline-inset:auto, x, rtl');
</script>
<template id=test_auto_horizontal_vertical_lr>
@ -681,10 +681,10 @@
writing-mode: vertical-lr;
}
#target {
view-timeline: t1 horizontal;
view-timeline: --t1 x;
view-timeline-inset: auto auto;
animation: anim 1s linear;
animation-timeline: t1;
animation-timeline: --t1;
}
</style>
<div id=scroller>
@ -699,7 +699,7 @@
await assertValueAt(scroller, target, { scrollLeft:135 + 5, expected:50 }); // 50%
await assertValueAt(scroller, target, { scrollLeft:200 - 10, expected:100 }); // 100%
await assertValueAt(scroller, target, { scrollLeft:200, expected:-1 });
}, 'view-timeline-inset:auto, horizontal, vertical-lr');
}, 'view-timeline-inset:auto, x, vertical-lr');
</script>
<template id=test_auto_horizontal_vertical_rl>
@ -709,10 +709,10 @@
writing-mode: vertical-rl;
}
#target {
view-timeline: t1 horizontal;
view-timeline: --t1 x;
view-timeline-inset: auto auto;
animation: anim 1s linear;
animation-timeline: t1;
animation-timeline: --t1;
}
</style>
<div id=scroller>
@ -727,7 +727,7 @@
await assertValueAt(scroller, target, { scrollLeft:-(135 + 5), expected:50 }); // 50%
await assertValueAt(scroller, target, { scrollLeft:-(200 - 10), expected:100 }); // 100%
await assertValueAt(scroller, target, { scrollLeft:-200, expected:-1 });
}, 'view-timeline-inset:auto, horizontal, vertical-rl');
}, 'view-timeline-inset:auto, x, vertical-rl');
</script>
<template id=test_auto_mix>
@ -737,10 +737,10 @@
scroll-padding-block: 50px calc(10% + 1em);
}
#target {
view-timeline: t1;
view-timeline: --t1;
view-timeline-inset: 10% auto;
animation: anim 1s linear;
animation-timeline: t1;
animation-timeline: --t1;
}
</style>
<div id=scroller>

View file

@ -38,10 +38,10 @@
z-index: -1;
background-color: green;
animation: anim auto both linear;
animation-timeline: t1;
animation-timeline: --t1;
animation-range-start: contain 0%;
animation-range-end: contain 100%;
view-timeline: t1 block;
view-timeline: --t1 block;
}
</style>
<body>

View file

@ -33,9 +33,9 @@
<style>
#target {
height: 0px;
view-timeline: t1;
view-timeline: --t1;
animation: anim 1s linear;
animation-timeline: t1;
animation-timeline: --t1;
}
</style>
<div id=scroller class=scroller>
@ -58,15 +58,15 @@
<template id=timeline_preceding_sibling>
<style>
#scroller {
view-timeline: t1 defer;
view-timeline: --t1 defer;
}
#timeline {
height: 0px;
view-timeline: t1 ancestor;
view-timeline: --t1 ancestor;
}
#target {
animation: anim 1s linear;
animation-timeline: t1;
animation-timeline: --t1;
}
</style>
<div id=scroller class=scroller>
@ -91,11 +91,11 @@
<style>
#timeline {
height: 0px;
view-timeline: t1;
view-timeline: --t1;
}
#target {
animation: anim 1s linear;
animation-timeline: t1;
animation-timeline: --t1;
}
</style>
<div id=scroller class=scroller>
@ -122,15 +122,15 @@
<template id=timeline_ancestor_sibling>
<style>
#scroller {
view-timeline: t1 defer;
view-timeline: --t1 defer;
}
#timeline {
height: 0px;
view-timeline: t1 ancestor;
view-timeline: --t1 ancestor;
}
#target {
animation: anim 1s linear;
animation-timeline: t1;
animation-timeline: --t1;
}
</style>
<div id=scroller class=scroller>
@ -157,15 +157,15 @@
<template id=timeline_ancestor_sibling_conflict>
<style>
#scroller {
view-timeline: t1 defer;
view-timeline: --t1 defer;
}
#timeline1, #timeline2 {
height: 0px;
view-timeline: t1 ancestor;
view-timeline: --t1 ancestor;
}
#target {
animation: anim 1s linear;
animation-timeline: t1;
animation-timeline: --t1;
}
</style>
<div id=scroller class=scroller>
@ -193,18 +193,18 @@
<template id=timeline_ancestor_closer_timeline_wins>
<style>
#scroller {
view-timeline: t1 defer;
view-timeline: --t1 defer;
}
#timeline {
height: 0px;
view-timeline: t1 ancestor;
view-timeline: --t1 ancestor;
}
#parent {
scroll-timeline: t1 defer;
scroll-timeline: --t1 defer;
}
#target {
animation: anim 1s linear;
animation-timeline: t1;
animation-timeline: --t1;
}
</style>
<div id=scroller class=scroller>
@ -229,13 +229,13 @@
<template id=timeline_ancestor_scroll_timeline_wins_on_same_element>
<style>
#scroller {
view-timeline: t1 defer;
scroll-timeline: t1 defer;
view-timeline: --t1 defer;
scroll-timeline: --t1 defer;
}
#timelines {
height: 0px;
view-timeline: t1 ancestor;
scroll-timeline: t1 ancestor;
view-timeline: --t1 ancestor;
scroll-timeline: --t1 ancestor;
overflow: auto;
}
#timelines > div {
@ -243,7 +243,7 @@
}
#target {
animation: anim 1s linear;
animation-timeline: t1;
animation-timeline: --t1;
}
</style>
<div id=scroller class=scroller>

View file

@ -5,24 +5,24 @@
<script src="/css/support/computed-testcommon.js"></script>
</head>
<style>
#outer { view-timeline-name: foo, bar; }
#target { view-timeline-name: faz; }
#outer { view-timeline-name: --foo, --bar; }
#target { view-timeline-name: --faz; }
</style>
<div id=outer>
<div id=target></div>
</div>
<script>
test_computed_value('view-timeline-name', 'initial', 'none');
test_computed_value('view-timeline-name', 'inherit', 'foo, bar');
test_computed_value('view-timeline-name', 'inherit', '--foo, --bar');
test_computed_value('view-timeline-name', 'unset', 'none');
test_computed_value('view-timeline-name', 'revert', 'none');
test_computed_value('view-timeline-name', 'none');
test_computed_value('view-timeline-name', 'foo');
test_computed_value('view-timeline-name', 'foo, bar');
test_computed_value('view-timeline-name', 'bar, foo');
test_computed_value('view-timeline-name', 'a, b, c, D, e');
test_computed_value('view-timeline-name', '--foo');
test_computed_value('view-timeline-name', '--foo, --bar');
test_computed_value('view-timeline-name', '--bar, --foo');
test_computed_value('view-timeline-name', '--a, --b, --c, --D, --e');
test_computed_value('view-timeline-name', 'none, none');
test_computed_value('view-timeline-name', 'a, b, c, none, d, e');
test_computed_value('view-timeline-name', '--a, --b, --c, none, --d, --e');
test(() => {
let style = getComputedStyle(document.getElementById('target'));

View file

@ -11,16 +11,16 @@ test_valid_value('view-timeline-name', 'unset');
test_valid_value('view-timeline-name', 'revert');
test_valid_value('view-timeline-name', 'none');
test_valid_value('view-timeline-name', 'abc');
test_valid_value('view-timeline-name', ' abc', 'abc');
test_valid_value('view-timeline-name', 'abc ', 'abc');
test_valid_value('view-timeline-name', 'aBc');
test_valid_value('view-timeline-name', 'foo, bar');
test_valid_value('view-timeline-name', 'bar, foo');
test_valid_value('view-timeline-name', '--abc');
test_valid_value('view-timeline-name', ' --abc', '--abc');
test_valid_value('view-timeline-name', '--aBc');
test_valid_value('view-timeline-name', '--foo, --bar');
test_valid_value('view-timeline-name', '--bar, --foo');
test_valid_value('view-timeline-name', 'none, none');
test_valid_value('view-timeline-name', 'a, none, b');
test_valid_value('view-timeline-name', 'auto');
test_valid_value('view-timeline-name', '--a, none, --b');
test_invalid_value('view-timeline-name', 'auto');
test_invalid_value('view-timeline-name', 'abc');
test_invalid_value('view-timeline-name', 'default');
test_invalid_value('view-timeline-name', '10px');
test_invalid_value('view-timeline-name', 'foo bar');

View file

@ -32,10 +32,10 @@
<style>
.target {
animation: anim 10s linear;
animation-timeline: timeline;
animation-timeline: --timeline;
}
.scroller > div {
view-timeline: timeline horizontal;
view-timeline: --timeline x;
}
</style>
<div class=scroller>
@ -44,7 +44,7 @@
<template shadowrootmode=open>
<style>
:host {
view-timeline: timeline vertical;
view-timeline: --timeline y;
}
</style>
</template>
@ -61,7 +61,7 @@
assert_equals(target.getAnimations().length, 1);
let anim = target.getAnimations()[0];
assert_not_equals(anim.timeline, null);
assert_equals(anim.timeline.axis, 'vertical');
assert_equals(anim.timeline.axis, 'y');
}, 'Outer animation can see view timeline defined by :host');
</script>
@ -70,10 +70,10 @@
<style>
.target {
animation: anim 10s linear;
animation-timeline: timeline;
animation-timeline: --timeline;
}
.host {
view-timeline: timeline horizontal;
view-timeline: --timeline x;
}
</style>
<div class=scroller>
@ -81,7 +81,7 @@
<template shadowrootmode=open>
<style>
::slotted(.target) {
view-timeline: timeline vertical;
view-timeline: --timeline y;
}
</style>
<slot></slot>
@ -99,7 +99,7 @@
assert_equals(target.getAnimations().length, 1);
let anim = target.getAnimations()[0];
assert_not_equals(anim.timeline, null);
assert_equals(anim.timeline.axis, 'vertical');
assert_equals(anim.timeline.axis, 'y');
}, 'Outer animation can see view timeline defined by ::slotted');
</script>
@ -107,10 +107,10 @@
<template id=view_timeline_part>
<style>
.host {
view-timeline: timeline vertical;
view-timeline: --timeline y;
}
.host::part(foo) {
view-timeline: timeline horizontal;
view-timeline: --timeline x;
}
</style>
<div class=host>
@ -123,7 +123,7 @@
}
.target {
animation: anim2 10s linear;
animation-timeline: timeline;
animation-timeline: --timeline;
}
</style>
<div part=foo>
@ -141,7 +141,7 @@
assert_equals(target.getAnimations().length, 1);
let anim = target.getAnimations()[0];
assert_not_equals(anim.timeline, null);
assert_equals(anim.timeline.axis, 'horizontal');
assert_equals(anim.timeline.axis, 'x');
}, 'Inner animation can see view timeline defined by ::part');
</script>
@ -150,10 +150,10 @@
<style>
.target {
animation: anim 10s linear;
animation-timeline: timeline;
animation-timeline: --timeline;
}
.host {
view-timeline: timeline horizontal;
view-timeline: --timeline x;
}
</style>
<div class=scroller>
@ -161,7 +161,7 @@
<template shadowrootmode=open>
<style>
div {
view-timeline: timeline vertical;
view-timeline: --timeline y;
}
</style>
<div>
@ -181,6 +181,6 @@
assert_equals(target.getAnimations().length, 1);
let anim = target.getAnimations()[0];
assert_not_equals(anim.timeline, null);
assert_equals(anim.timeline.axis, 'vertical');
assert_equals(anim.timeline.axis, 'y');
}, 'Slotted element can see view timeline within the shadow');
</script>

View file

@ -58,13 +58,13 @@
let scroller = main.querySelector('#scroller');
let target = main.querySelector('#target');
target.style.viewTimeline = 't1 block';
target.style.viewTimeline = '--t1 block';
// TODO(crbug.com/1375998): Create the timeline in a separate frame to
// work around a bug.
await waitForNextFrame();
target.style.animation = 'anim auto linear';
target.style.animationTimeline = 't1';
target.style.animationTimeline = '--t1';
target.style.animationRangeStart = options.rangeStart;
target.style.animationRangeEnd = options.rangeEnd;

View file

@ -29,8 +29,8 @@
z-index: -1;
background-color: green;
animation: anim auto linear;
animation-timeline: timeline;
view-timeline: timeline;
animation-timeline: --timeline;
view-timeline: --timeline;
}
#target.exit-range {
animation-range-start: exit 0%;

View file

@ -29,8 +29,8 @@
z-index: -1;
background-color: green;
animation: anim auto linear;
animation-timeline: timeline;
view-timeline: timeline;
animation-timeline: --timeline;
view-timeline: --timeline;
}
#target.exit-range {
animation-range-start: exit 0%;

View file

@ -9,63 +9,63 @@
<script src="/css/support/shorthand-testcommon.js"></script>
<div id="target"></div>
<script>
test_valid_value('view-timeline', 'abcd');
test_valid_value('view-timeline', '--abcd');
test_valid_value('view-timeline', 'none block', 'none');
test_valid_value('view-timeline', 'none inline');
// view-timeline-name: inline/block/horizontal/vertical.
test_valid_value('view-timeline', 'inline block', 'inline');
test_valid_value('view-timeline', 'block block', 'block');
test_valid_value('view-timeline', 'vertical block', 'vertical');
test_valid_value('view-timeline', 'horizontal block', 'horizontal');
// view-timeline-name: inline/block/x/y.
test_valid_value('view-timeline', '--inline block', '--inline');
test_valid_value('view-timeline', '--block block', '--block');
test_valid_value('view-timeline', '--y block', '--y');
test_valid_value('view-timeline', '--x block', '--x');
test_valid_value('view-timeline', 'a, b, c');
test_valid_value('view-timeline', 'a inline, b block, c vertical', 'a inline, b, c vertical');
test_valid_value('view-timeline', 'auto');
test_valid_value('view-timeline', 'abc defer vertical', 'abc vertical defer');
test_valid_value('view-timeline', 'abc vertical defer');
test_valid_value('view-timeline', '--a, --b, --c');
test_valid_value('view-timeline', '--a inline, --b block, --c y', '--a inline, --b, --c y');
test_valid_value('view-timeline', '--auto');
test_valid_value('view-timeline', '--abc defer y', '--abc y defer');
test_valid_value('view-timeline', '--abc y defer');
test_invalid_value('view-timeline', 'abc abc');
test_invalid_value('view-timeline', '--abc --abc');
test_invalid_value('view-timeline', 'block none');
test_invalid_value('view-timeline', 'none none');
test_invalid_value('view-timeline', 'default');
test_invalid_value('view-timeline', ',');
test_invalid_value('view-timeline', ',,block,,');
test_invalid_value('view-timeline', ',,--block,,');
test_computed_value('view-timeline', 'abcd');
test_computed_value('view-timeline', '--abcd');
test_computed_value('view-timeline', 'none block', 'none');
test_computed_value('view-timeline', 'none inline');
test_computed_value('view-timeline', 'inline block', 'inline');
test_computed_value('view-timeline', 'block block', 'block');
test_computed_value('view-timeline', 'vertical block', 'vertical');
test_computed_value('view-timeline', 'horizontal block', 'horizontal');
test_computed_value('view-timeline', 'a, b, c');
test_computed_value('view-timeline', 'a inline, b block, c vertical', 'a inline, b, c vertical');
test_computed_value('view-timeline', 'abc defer vertical', 'abc vertical defer');
test_computed_value('view-timeline', 'abc vertical defer');
test_computed_value('view-timeline', '--inline block', '--inline');
test_computed_value('view-timeline', '--block block', '--block');
test_computed_value('view-timeline', '--y block', '--y');
test_computed_value('view-timeline', '--x block', '--x');
test_computed_value('view-timeline', '--a, --b, --c');
test_computed_value('view-timeline', '--a inline, --b block, --c y', '--a inline, --b, --c y');
test_computed_value('view-timeline', '--abc defer y', '--abc y defer');
test_computed_value('view-timeline', '--abc y defer');
test_shorthand_value('view-timeline', 'abc vertical',
test_shorthand_value('view-timeline', '--abc y',
{
'view-timeline-name': 'abc',
'view-timeline-axis': 'vertical',
'view-timeline-name': '--abc',
'view-timeline-axis': 'y',
'view-timeline-attachment': 'local',
});
test_shorthand_value('view-timeline', 'abc vertical defer, def',
test_shorthand_value('view-timeline', '--abc y defer, --def',
{
'view-timeline-name': 'abc, def',
'view-timeline-axis': 'vertical, block',
'view-timeline-name': '--abc, --def',
'view-timeline-axis': 'y, block',
'view-timeline-attachment': 'defer, local',
});
test_shorthand_value('view-timeline', 'abc, def',
test_shorthand_value('view-timeline', '--abc, --def',
{
'view-timeline-name': 'abc, def',
'view-timeline-name': '--abc, --def',
'view-timeline-axis': 'block, block',
'view-timeline-attachment': 'local, local',
});
test_shorthand_value('view-timeline', 'inline horizontal ancestor',
test_shorthand_value('view-timeline', '--inline x ancestor',
{
'view-timeline-name': 'inline',
'view-timeline-axis': 'horizontal',
'view-timeline-name': '--inline',
'view-timeline-axis': 'x',
'view-timeline-attachment': 'ancestor',
});
@ -84,16 +84,16 @@ function test_shorthand_contraction(shorthand, longhands, expected) {
}
test_shorthand_contraction('view-timeline', {
'view-timeline-name': 'abc',
'view-timeline-name': '--abc',
'view-timeline-axis': 'inline',
'view-timeline-attachment': 'ancestor',
}, 'abc inline ancestor');
}, '--abc inline ancestor');
test_shorthand_contraction('view-timeline', {
'view-timeline-name': 'a, b',
'view-timeline-name': '--a, --b',
'view-timeline-axis': 'inline, block',
'view-timeline-attachment': 'defer, local',
}, 'a inline defer, b');
}, '--a inline defer, --b');
test_shorthand_contraction('view-timeline', {
'view-timeline-name': 'none, none',
@ -104,13 +104,13 @@ test_shorthand_contraction('view-timeline', {
// Longhands with different lengths:
test_shorthand_contraction('view-timeline', {
'view-timeline-name': 'a, b, c',
'view-timeline-name': '--a, --b, --c',
'view-timeline-axis': 'inline, inline',
'view-timeline-attachment': 'local, local',
}, '');
test_shorthand_contraction('view-timeline', {
'view-timeline-name': 'a, b',
'view-timeline-name': '--a, --b',
'view-timeline-axis': 'inline, inline, inline',
'view-timeline-attachment': 'local, local',
}, '');

View file

@ -30,8 +30,8 @@
z-index: -1;
background-color: green;
animation: anim auto both linear;
animation-timeline: timeline;
view-timeline: timeline;
animation-timeline: --timeline;
view-timeline: --timeline;
animation-range: exit;
}
#target.bounds-update {

View file

@ -43,10 +43,10 @@
<template id=omitted_axis>
<style>
#target {
view-timeline-name: t1, t2; /* Two items */
view-timeline-name: --t1, --t2; /* Two items */
view-timeline-axis: inline; /* One item */
animation: anim 1s linear;
animation-timeline: t2;
animation-timeline: --t2;
}
</style>
<div id=scroller class=scroller>
@ -76,10 +76,10 @@
<template id=omitted_inset>
<style>
#target {
view-timeline-name: t1, t2; /* Two items */
view-timeline-name: --t1, --t2; /* Two items */
view-timeline-inset: 100px; /* One item */
animation: anim 1s linear;
animation-timeline: t2;
animation-timeline: --t2;
}
</style>
<div id=scroller class=scroller>

View file

@ -27,8 +27,8 @@
z-index: -1;
background-color: green;
animation: anim auto linear;
animation-timeline: t1;
view-timeline: t1 block;
animation-timeline: --t1;
view-timeline: --t1 block;
animation-range-start: entry 0%;
animation-range-end: entry 100%;
/* Sentinel value when in before or after phase of the animation. */