mirror of
https://github.com/servo/servo.git
synced 2025-08-03 20:50:07 +01:00
Update web-platform-tests to revision e91d7d8c9a1f14438e44000dcd05ce6e658e4ae5
This commit is contained in:
parent
242e7e2630
commit
1a3fdf7a13
567 changed files with 9823 additions and 2333 deletions
|
@ -0,0 +1,62 @@
|
|||
<!DOCTYPE html>
|
||||
<link rel="help" src="https://drafts.csswg.org/scroll-animations-1/#scroll-timeline-at-rule">
|
||||
<link rel="help" src="https://drafts.csswg.org/scroll-animations-1/#phase-algorithm">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/web-animations/testcommon.js"></script>
|
||||
<style>
|
||||
#scroller {
|
||||
overflow: scroll;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
}
|
||||
#contents {
|
||||
height: 200px;
|
||||
}
|
||||
@keyframes expand {
|
||||
from { width: 100px; }
|
||||
to { width: 200px; }
|
||||
}
|
||||
#element {
|
||||
width: 0px;
|
||||
}
|
||||
/* Ensure stable expectations if feature is not supported */
|
||||
@supports not (animation-timeline:foo) {
|
||||
#element { animation-play-state: paused; }
|
||||
}
|
||||
</style>
|
||||
<div id=scroller>
|
||||
<div id=contents></div>
|
||||
</div>
|
||||
<div id=container></div>
|
||||
<script>
|
||||
promise_test(async (t) => {
|
||||
try {
|
||||
// Make sure scroller has a layout box.
|
||||
await waitForNextFrame();
|
||||
|
||||
container.innerHTML = `
|
||||
<div id=element></div>
|
||||
<style>
|
||||
@scroll-timeline timeline {
|
||||
source: selector(#scroller);
|
||||
time-range: 10s;
|
||||
start: 50px;
|
||||
end: 100px;
|
||||
}
|
||||
#element {
|
||||
animation: expand 10s linear;
|
||||
animation-timeline: timeline;
|
||||
}
|
||||
</style>
|
||||
`;
|
||||
// Animation should not apply in before phase.
|
||||
assert_equals(getComputedStyle(element).width, '0px');
|
||||
await waitForNextFrame();
|
||||
// Animation should still not apply.
|
||||
assert_equals(getComputedStyle(element).width, '0px');
|
||||
} finally {
|
||||
container.innerHTML = '';
|
||||
}
|
||||
}, 'Animation does not apply when timeline phase is before');
|
||||
</script>
|
|
@ -0,0 +1,50 @@
|
|||
<!DOCTYPE html>
|
||||
<link rel="help" src="https://drafts.csswg.org/scroll-animations-1/#scroll-timeline-at-rule">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/web-animations/testcommon.js"></script>
|
||||
<style>
|
||||
#scroller {
|
||||
overflow: scroll;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
}
|
||||
#contents {
|
||||
height: 200px;
|
||||
}
|
||||
@keyframes expand {
|
||||
from { width: 100px; }
|
||||
to { width: 200px; }
|
||||
}
|
||||
@scroll-timeline timeline {
|
||||
source: selector(#scroller);
|
||||
time-range: 10s;
|
||||
start: 0px;
|
||||
end: 100px;
|
||||
}
|
||||
@scroll-timeline timeline {
|
||||
source: selector(#scroller);
|
||||
time-range: 1s;
|
||||
start: 0px;
|
||||
end: 50px;
|
||||
}
|
||||
#element {
|
||||
animation: expand 10s linear;
|
||||
animation-timeline: timeline;
|
||||
}
|
||||
/* Ensure stable expectations if feature is not supported */
|
||||
@supports not (animation-timeline:foo) {
|
||||
#element { animation-play-state: paused; }
|
||||
}
|
||||
</style>
|
||||
<div id=scroller>
|
||||
<div id=contents></div>
|
||||
</div>
|
||||
<div id=element></div>
|
||||
<script>
|
||||
promise_test(async (t) => {
|
||||
scroller.scrollTop = 25;
|
||||
await waitForNextFrame();
|
||||
assert_equals(getComputedStyle(element).width, '105px');
|
||||
}, 'Latest @scroll-timeline rule wins');
|
||||
</script>
|
|
@ -0,0 +1,59 @@
|
|||
<!DOCTYPE html>
|
||||
<link rel="help" src="https://drafts.csswg.org/scroll-animations-1/#scroll-timeline-at-rule">
|
||||
<link rel="help" src="https://drafts.csswg.org/scroll-animations-1/#phase-algorithm">
|
||||
<link rel="help" src="https://drafts.csswg.org/scroll-animations-1/#avoiding-cycles">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/web-animations/testcommon.js"></script>
|
||||
<style>
|
||||
#scroller {
|
||||
overflow: scroll;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
}
|
||||
#contents {
|
||||
height: 200px;
|
||||
}
|
||||
@keyframes expand {
|
||||
from { width: 100px; }
|
||||
to { width: 200px; }
|
||||
}
|
||||
#element {
|
||||
width: 0px;
|
||||
animation: expand 10s linear paused;
|
||||
animation-timeline: timeline;
|
||||
}
|
||||
</style>
|
||||
<div id="container"></div>
|
||||
<div id=element></div>
|
||||
<script>
|
||||
|
||||
promise_test(async (t) => {
|
||||
try {
|
||||
container.innerHTML = `
|
||||
<div id=scroller>
|
||||
<div id=contents></div>
|
||||
</div>
|
||||
<style>
|
||||
@scroll-timeline timeline {
|
||||
source: selector(#scroller);
|
||||
time-range: 10s;
|
||||
start: 0px;
|
||||
end: 100px;
|
||||
}
|
||||
</style>
|
||||
`;
|
||||
|
||||
// The source has no layout box at the time the scroll timeline is created.
|
||||
assert_equals(getComputedStyle(element).width, '0px');
|
||||
scroller.offsetTop; // Ensure a layout box for the scroller.
|
||||
// Wait for an update to the timeline state:
|
||||
await waitForNextFrame();
|
||||
// The timeline should now be active, and the animation should apply:
|
||||
assert_equals(getComputedStyle(element).width, '100px');
|
||||
} finally {
|
||||
container.innerHTML = '';
|
||||
}
|
||||
}, 'Animation does not apply when timeline is initially inactive');
|
||||
|
||||
</script>
|
|
@ -0,0 +1,129 @@
|
|||
<!DOCTYPE html>
|
||||
<link rel="help" src="https://drafts.csswg.org/scroll-animations-1/#scroll-timeline-at-rule">
|
||||
<link rel="help" src="https://drafts.csswg.org/scroll-animations-1/#descdef-scroll-timeline-orientation">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/web-animations/testcommon.js"></script>
|
||||
<style>
|
||||
#scroller {
|
||||
overflow: scroll;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
}
|
||||
#contents {
|
||||
height: 300px;
|
||||
width: 300px;
|
||||
}
|
||||
@keyframes expand {
|
||||
from { width: 100px; }
|
||||
to { width: 200px; }
|
||||
}
|
||||
@scroll-timeline timeline_auto {
|
||||
source: selector(#scroller);
|
||||
orientation: auto;
|
||||
time-range: 10s;
|
||||
start: 0px;
|
||||
end: 100px;
|
||||
}
|
||||
@scroll-timeline timeline_vertical {
|
||||
source: selector(#scroller);
|
||||
orientation: vertical;
|
||||
time-range: 10s;
|
||||
start: 0px;
|
||||
end: 100px;
|
||||
}
|
||||
@scroll-timeline timeline_horizontal {
|
||||
source: selector(#scroller);
|
||||
orientation: horizontal;
|
||||
time-range: 10s;
|
||||
start: 0px;
|
||||
end: 100px;
|
||||
}
|
||||
@scroll-timeline timeline_block {
|
||||
source: selector(#scroller);
|
||||
orientation: block;
|
||||
time-range: 10s;
|
||||
start: 0px;
|
||||
end: 100px;
|
||||
}
|
||||
@scroll-timeline timeline_inline {
|
||||
source: selector(#scroller);
|
||||
orientation: inline;
|
||||
time-range: 10s;
|
||||
start: 0px;
|
||||
end: 100px;
|
||||
}
|
||||
#container > div {
|
||||
width: 0px;
|
||||
animation: expand 10s linear;
|
||||
}
|
||||
/* Ensure stable expectations if feature is not supported */
|
||||
@supports not (animation-timeline:foo) {
|
||||
#container > div { animation-play-state: paused; }
|
||||
}
|
||||
.horizontal { writing-mode: horizontal-tb; }
|
||||
.vertical { writing-mode: vertical-lr; }
|
||||
#element_auto { animation-timeline: timeline_auto; }
|
||||
#element_vertical { animation-timeline: timeline_vertical; }
|
||||
#element_horizontal { animation-timeline: timeline_horizontal; }
|
||||
#element_block_in_horizontal { animation-timeline: timeline_block; }
|
||||
#element_inline_in_horizontal { animation-timeline: timeline_inline; }
|
||||
#element_block_in_vertical { animation-timeline: timeline_block; }
|
||||
#element_inline_in_vertical { animation-timeline: timeline_inline; }
|
||||
</style>
|
||||
<div id=scroller>
|
||||
<div id=contents></div>
|
||||
</div>
|
||||
<div id=container>
|
||||
<div id=element_auto></div>
|
||||
<div id=element_vertical></div>
|
||||
<div id=element_horizontal></div>
|
||||
<div id=element_block_in_horizontal class="horizontal"></div>
|
||||
<div id=element_inline_in_horizontal class="horizontal"></div>
|
||||
<div id=element_block_in_vertical class="vertical"></div>
|
||||
<div id=element_inline_in_vertical class="vertical"></div>
|
||||
</div>
|
||||
<script>
|
||||
// Animations linked to a vertical scroll-timelines are at 75% progress.
|
||||
scroller.scrollTop = 75;
|
||||
// Animations linked to a horizontal scroll-timelines are at 25% progress.
|
||||
scroller.scrollLeft = 25;
|
||||
|
||||
promise_test(async (t) => {
|
||||
await waitForNextFrame();
|
||||
assert_equals(getComputedStyle(element_auto).width, '175px');
|
||||
}, 'Orientation auto behaves as expected');
|
||||
|
||||
promise_test(async (t) => {
|
||||
await waitForNextFrame();
|
||||
assert_equals(getComputedStyle(element_vertical).width, '175px');
|
||||
}, 'Orientation vertical behaves as expected');
|
||||
|
||||
promise_test(async (t) => {
|
||||
await waitForNextFrame();
|
||||
assert_equals(getComputedStyle(element_horizontal).width, '125px');
|
||||
}, 'Orientation horizontal behaves as expected');
|
||||
|
||||
promise_test(async (t) => {
|
||||
await waitForNextFrame();
|
||||
assert_equals(getComputedStyle(element_block_in_horizontal).width, '175px');
|
||||
}, 'Orientation block behaves as expected in horizontal writing-mode');
|
||||
|
||||
promise_test(async (t) => {
|
||||
await waitForNextFrame();
|
||||
assert_equals(getComputedStyle(element_inline_in_horizontal).width, '125px');
|
||||
}, 'Orientation inline behaves as expected in horizontal writing-mode');
|
||||
|
||||
promise_test(async (t) => {
|
||||
await waitForNextFrame();
|
||||
assert_equals(getComputedStyle(element_block_in_vertical).writingMode, 'vertical-lr');
|
||||
assert_equals(getComputedStyle(element_block_in_vertical).width, '125px');
|
||||
}, 'Orientation block behaves as expected in vertical writing-mode');
|
||||
|
||||
promise_test(async (t) => {
|
||||
await waitForNextFrame();
|
||||
assert_equals(getComputedStyle(element_inline_in_vertical).writingMode, 'vertical-lr');
|
||||
assert_equals(getComputedStyle(element_inline_in_vertical).width, '175px');
|
||||
}, 'Orientation inline behaves as expected in vertical writing-mode');
|
||||
|
||||
</script>
|
|
@ -0,0 +1,52 @@
|
|||
<!DOCTYPE html>
|
||||
<link rel="help" src="https://drafts.csswg.org/scroll-animations-1/#scroll-timeline-at-rule">
|
||||
<link rel="help" src="https://drafts.csswg.org/scroll-animations-1/#avoiding-cycles">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/web-animations/testcommon.js"></script>
|
||||
<style>
|
||||
#scroller {
|
||||
overflow: scroll;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
}
|
||||
#contents {
|
||||
height: 200px;
|
||||
}
|
||||
@keyframes expand {
|
||||
from { width: 100px; }
|
||||
to { width: 200px; }
|
||||
}
|
||||
@scroll-timeline timeline {
|
||||
source: selector(#scroller);
|
||||
time-range: 10s;
|
||||
start: 0px;
|
||||
end: 100px;
|
||||
}
|
||||
#element {
|
||||
width: 0px;
|
||||
animation: expand 10s linear;
|
||||
animation-timeline: timeline;
|
||||
}
|
||||
/* Ensure stable expectations if feature is not supported */
|
||||
@supports not (animation-timeline:foo) {
|
||||
#element { animation-play-state: paused; }
|
||||
}
|
||||
</style>
|
||||
<div id=scroller>
|
||||
<div id=contents></div>
|
||||
</div>
|
||||
<div id=element></div>
|
||||
<script>
|
||||
promise_test(async (t) => {
|
||||
// The scroll timeline is initially inactive until the first frame.
|
||||
assert_equals(getComputedStyle(element).width, '0px');
|
||||
await waitForNextFrame();
|
||||
scroller.scrollTop = 50;
|
||||
// Scrolling position should not yet be reflected in the animation,
|
||||
// since the new scroll position has not yet been sampled.
|
||||
assert_equals(getComputedStyle(element).width, '100px');
|
||||
await waitForNextFrame();
|
||||
assert_equals(getComputedStyle(element).width, '150px');
|
||||
}, 'Scroll position is sampled once per frame');
|
||||
</script>
|
|
@ -0,0 +1,135 @@
|
|||
<!DOCTYPE html>
|
||||
<link rel="help" src="https://drafts.csswg.org/scroll-animations-1/#scroll-timeline-at-rule">
|
||||
<link rel="help" src="https://drafts.csswg.org/scroll-animations-1/#descdef-scroll-timeline-source">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/web-animations/testcommon.js"></script>
|
||||
<style>
|
||||
:root {
|
||||
height: 100vh;
|
||||
overflow: scroll;
|
||||
}
|
||||
body {
|
||||
height: 200vh;
|
||||
}
|
||||
.scroller {
|
||||
overflow: scroll;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
}
|
||||
#boxless {
|
||||
display: none;
|
||||
}
|
||||
.contents {
|
||||
height: 300px;
|
||||
}
|
||||
@keyframes expand {
|
||||
from { width: 100px; }
|
||||
to { width: 200px; }
|
||||
}
|
||||
@scroll-timeline timeline_source_none {
|
||||
source: none;
|
||||
time-range: 10s;
|
||||
start: 0px;
|
||||
end: 100px;
|
||||
}
|
||||
@scroll-timeline timeline_source_auto {
|
||||
source: auto;
|
||||
time-range: 10s;
|
||||
start: 0px;
|
||||
end: 100px;
|
||||
}
|
||||
@scroll-timeline timeline_source_selector {
|
||||
source: selector(#scroller);
|
||||
time-range: 10s;
|
||||
start: 0px;
|
||||
end: 100px;
|
||||
}
|
||||
@scroll-timeline timeline_source_unspecified {
|
||||
time-range: 10s;
|
||||
start: 0px;
|
||||
end: 100px;
|
||||
}
|
||||
@scroll-timeline timeline_source_nonexistent_id {
|
||||
source: selector(#doesnotexist);
|
||||
time-range: 10s;
|
||||
start: 0px;
|
||||
end: 100px;
|
||||
}
|
||||
@scroll-timeline timeline_source_no_layout_box {
|
||||
source: selector(#boxless);
|
||||
time-range: 10s;
|
||||
start: 0px;
|
||||
end: 100px;
|
||||
}
|
||||
#container > div {
|
||||
width: 0px;
|
||||
animation: expand 10s linear;
|
||||
}
|
||||
/* Ensure stable expectations if feature is not supported */
|
||||
@supports not (animation-timeline:foo) {
|
||||
#container > div { animation-play-state: paused; }
|
||||
}
|
||||
#element_source_none { animation-timeline: timeline_source_none; }
|
||||
#element_source_auto { animation-timeline: timeline_source_auto; }
|
||||
#element_source_unspecified { animation-timeline: timeline_source_unspecified; }
|
||||
#element_source_selector { animation-timeline: timeline_source_selector; }
|
||||
#element_source_nonexistent_id { animation-timeline: timeline_source_nonexistent_id; }
|
||||
#element_source_no_layout_box { animation-timeline: timeline_source_no_layout_box; }
|
||||
</style>
|
||||
<body>
|
||||
<div class=scroller id=scroller>
|
||||
<div class=contents></div>
|
||||
</div>
|
||||
<div class=scroller id=boxless>
|
||||
<div class=contents></div>
|
||||
</div>
|
||||
<div id=container>
|
||||
<div id=element_source_none></div>
|
||||
<div id=element_source_auto></div>
|
||||
<div id=element_source_unspecified></div>
|
||||
<div id=element_source_selector></div>
|
||||
<div id=element_source_nonexistent_id></div>
|
||||
<div id=element_source_no_layout_box></div>
|
||||
</div>
|
||||
<script>
|
||||
// Set progress of animations linked to #scroller to 75%.
|
||||
scroller.scrollTop = 75;
|
||||
// Set progress of animations linked to document.scrollingElement to 25%.
|
||||
document.scrollingElement.scrollTop = 25;
|
||||
|
||||
promise_test(async (t) => {
|
||||
await waitForNextFrame();
|
||||
assert_equals(getComputedStyle(element_source_none).width, '0px');
|
||||
}, 'Source none causes inactive timeline');
|
||||
|
||||
promise_test(async (t) => {
|
||||
await waitForNextFrame();
|
||||
assert_equals(getComputedStyle(element_source_auto).width, '125px');
|
||||
}, 'Source auto selects scrollingElement of the document');
|
||||
|
||||
promise_test(async (t) => {
|
||||
await waitForNextFrame();
|
||||
assert_equals(getComputedStyle(element_source_unspecified).width, '125px');
|
||||
}, 'Unspecified source behaves like auto');
|
||||
|
||||
promise_test(async (t) => {
|
||||
await waitForNextFrame();
|
||||
assert_equals(getComputedStyle(element_source_selector).width, '175px');
|
||||
}, 'Source selector(<id-selector>) selects an element');
|
||||
|
||||
promise_test(async (t) => {
|
||||
await waitForNextFrame();
|
||||
assert_equals(getComputedStyle(element_source_nonexistent_id).width, '0px');
|
||||
}, 'Unknown source causes inactive timeline');
|
||||
|
||||
promise_test(async (t) => {
|
||||
await waitForNextFrame();
|
||||
assert_equals(getComputedStyle(element_source_no_layout_box).width, '0px');
|
||||
}, 'Source with no layout box causes inactive timeline');
|
||||
|
||||
// TODO(https://github.com/w3c/csswg-drafts/issues/5289): Add tests for
|
||||
// sources that change when behavior is clarified.
|
||||
|
||||
</script>
|
||||
</body>
|
|
@ -0,0 +1,187 @@
|
|||
<!DOCTYPE html>
|
||||
<link rel="help" src="https://drafts.csswg.org/scroll-animations-1/#scroll-timeline-at-rule">
|
||||
<link rel="help" src="https://drafts.csswg.org/scroll-animations-1/#scroll-timeline-offset-section">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/web-animations/testcommon.js"></script>
|
||||
<style>
|
||||
#scroller {
|
||||
overflow: scroll;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
}
|
||||
#contents {
|
||||
height: 300px;
|
||||
}
|
||||
@keyframes expand {
|
||||
from { width: 100px; }
|
||||
to { width: 200px; }
|
||||
}
|
||||
@scroll-timeline timeline_0px_100px {
|
||||
source: selector(#scroller);
|
||||
time-range: 10s;
|
||||
start: 0px;
|
||||
end: 100px;
|
||||
}
|
||||
@scroll-timeline timeline_50px_100px {
|
||||
source: selector(#scroller);
|
||||
time-range: 10s;
|
||||
start: 50px;
|
||||
end: 100px;
|
||||
}
|
||||
@scroll-timeline timeline_auto_auto {
|
||||
source: selector(#scroller);
|
||||
time-range: 10s;
|
||||
start: auto;
|
||||
end: auto;
|
||||
}
|
||||
@scroll-timeline timeline_50px_auto {
|
||||
source: selector(#scroller);
|
||||
time-range: 10s;
|
||||
start: 50px;
|
||||
end: auto;
|
||||
}
|
||||
@scroll-timeline timeline_auto_100px {
|
||||
source: selector(#scroller);
|
||||
time-range: 10s;
|
||||
start: auto;
|
||||
end: 100px;
|
||||
}
|
||||
@scroll-timeline timeline_25p_75p {
|
||||
source: selector(#scroller);
|
||||
time-range: 10s;
|
||||
start: 25%;
|
||||
end: 75%;
|
||||
}
|
||||
@scroll-timeline timeline_calc_calc {
|
||||
source: selector(#scroller);
|
||||
time-range: 10s;
|
||||
start: calc(25% + 10px);
|
||||
end: calc(75% + 10px);
|
||||
}
|
||||
#container > div {
|
||||
width: 0px;
|
||||
animation: expand 10s linear;
|
||||
}
|
||||
/* Ensure stable expectations if feature is not supported */
|
||||
@supports not (animation-timeline:foo) {
|
||||
#container > div { animation-play-state: paused; }
|
||||
}
|
||||
#element_0px_100px { animation-timeline: timeline_0px_100px; }
|
||||
#element_50px_100px { animation-timeline: timeline_50px_100px; }
|
||||
#element_auto_auto { animation-timeline: timeline_auto_auto; }
|
||||
#element_50px_auto { animation-timeline: timeline_50px_auto; }
|
||||
#element_auto_100px { animation-timeline: timeline_auto_100px; }
|
||||
#element_25p_75p { animation-timeline: timeline_25p_75p; }
|
||||
#element_calc_calc { animation-timeline: timeline_calc_calc; }
|
||||
</style>
|
||||
<div id=scroller>
|
||||
<div id=contents></div>
|
||||
</div>
|
||||
<div id=container>
|
||||
<div id=element_0px_100px></div>
|
||||
<div id=element_50px_100px></div>
|
||||
<div id=element_auto_auto></div>
|
||||
<div id=element_50px_auto></div>
|
||||
<div id=element_auto_100px></div>
|
||||
<div id=element_25p_75p></div>
|
||||
<div id=element_calc_calc></div>
|
||||
</div>
|
||||
<script>
|
||||
|
||||
// Scrolls top to 'offset', waits for a frame, then call the provided
|
||||
// assertions function.
|
||||
function test_scroll(element, offset, assertions, description) {
|
||||
promise_test(async (t) => {
|
||||
scroller.scrollTop = offset;
|
||||
await waitForNextFrame();
|
||||
assertions();
|
||||
}, `${description} [${element.id}]`);
|
||||
}
|
||||
|
||||
// Tests that the computed value of 'width' on element is the expected value
|
||||
// after scrolling top to the specifed offset.
|
||||
function test_width_at_scroll_top(element, offset, expected) {
|
||||
test_scroll(element, offset, () => {
|
||||
assert_equals(getComputedStyle(element).width, expected);
|
||||
}, `Scroll at offset ${offset} updates animation correctly`);
|
||||
}
|
||||
|
||||
// Tests that the computed value of 'width' on element is (approximately)
|
||||
// the expected value after scrolling top to the offset specified by
|
||||
// 'fraction'. The 'fraction' parameter is either a number which maps [0, 1]
|
||||
// to the full scroll range, or a function which accepts the maximum scroll,
|
||||
// and returns a specific offset.
|
||||
function test_approximate_width_at_fraction(element, fraction, expected) {
|
||||
const max = scroller.scrollHeight - scroller.clientHeight;
|
||||
const offsetFunction = (typeof fraction == 'function') ? fraction : () => max * fraction;
|
||||
const resolvedOffset = Math.floor(offsetFunction(max));
|
||||
test_scroll(element, resolvedOffset, () => {
|
||||
assert_approx_equals(parseInt(getComputedStyle(element).width), parseInt(expected), 5);
|
||||
}, `Scroll at offset ${resolvedOffset} updates animation correctly`);
|
||||
}
|
||||
|
||||
// [0px, 100px]
|
||||
test_width_at_scroll_top(element_0px_100px, 0, '100px');
|
||||
test_width_at_scroll_top(element_0px_100px, 1, '101px');
|
||||
test_width_at_scroll_top(element_0px_100px, 50, '150px');
|
||||
test_width_at_scroll_top(element_0px_100px, 99, '199px');
|
||||
test_width_at_scroll_top(element_0px_100px, 100, '0px');
|
||||
test_width_at_scroll_top(element_0px_100px, 101, '0px');
|
||||
|
||||
// [50px, 100px]
|
||||
test_width_at_scroll_top(element_50px_100px, 0, '0px');
|
||||
test_width_at_scroll_top(element_50px_100px, 1, '0px');
|
||||
test_width_at_scroll_top(element_50px_100px, 49, '0px');
|
||||
test_width_at_scroll_top(element_50px_100px, 50, '100px');
|
||||
test_width_at_scroll_top(element_50px_100px, 51, '102px');
|
||||
test_width_at_scroll_top(element_50px_100px, 99, '198px');
|
||||
test_width_at_scroll_top(element_50px_100px, 100, '0px');
|
||||
test_width_at_scroll_top(element_50px_100px, 101, '0px');
|
||||
|
||||
// [auto, auto]
|
||||
test_approximate_width_at_fraction(element_auto_auto, 0, '100px');
|
||||
test_approximate_width_at_fraction(element_auto_auto, 0.1, '110px');
|
||||
test_approximate_width_at_fraction(element_auto_auto, 0.5, '150px');
|
||||
test_approximate_width_at_fraction(element_auto_auto, 0.9, '190px');
|
||||
|
||||
// TODO: Effects for scroll linked animations are not inclusive at max scroll
|
||||
// https://github.com/w3c/csswg-drafts/issues/5223
|
||||
test_approximate_width_at_fraction(element_auto_auto, 1, '0px');
|
||||
|
||||
// [50px, auto]
|
||||
{
|
||||
let offset = (t) => (max => 50 * (1 - t) + max * t);
|
||||
test_width_at_scroll_top(element_50px_auto, 0, '0px');
|
||||
test_width_at_scroll_top(element_50px_auto, 49, '0px');
|
||||
test_width_at_scroll_top(element_50px_auto, 50, '100px');
|
||||
test_approximate_width_at_fraction(element_50px_auto, offset(0.5), '150px');
|
||||
test_approximate_width_at_fraction(element_50px_auto, offset(0.9), '190px');
|
||||
test_approximate_width_at_fraction(element_50px_auto, 1, '0px');
|
||||
}
|
||||
|
||||
// [auto, 100px]
|
||||
test_width_at_scroll_top(element_auto_100px, 0, '100px');
|
||||
test_width_at_scroll_top(element_auto_100px, 1, '101px');
|
||||
test_width_at_scroll_top(element_auto_100px, 50, '150px');
|
||||
test_width_at_scroll_top(element_auto_100px, 99, '199px');
|
||||
test_width_at_scroll_top(element_auto_100px, 100, '0px');
|
||||
|
||||
// [25%, 75%]
|
||||
test_approximate_width_at_fraction(element_25p_75p, 0, '0px');
|
||||
test_approximate_width_at_fraction(element_25p_75p, 0.1, '0px');
|
||||
test_approximate_width_at_fraction(element_25p_75p, 0.2, '0px');
|
||||
test_approximate_width_at_fraction(element_25p_75p, 0.35, '120px');
|
||||
test_approximate_width_at_fraction(element_25p_75p, 0.55, '160px');
|
||||
test_approximate_width_at_fraction(element_25p_75p, 0.8, '0px');
|
||||
test_approximate_width_at_fraction(element_25p_75p, 1, '0px');
|
||||
|
||||
// [calc(25% + 10px), calc(75% + 10px)]
|
||||
{
|
||||
let offset = (t) => (max => (max * 0.25 + 10) * (1 - t) + (max * 0.75 + 10) * t);
|
||||
test_approximate_width_at_fraction(element_calc_calc, offset(0), '0px');
|
||||
test_approximate_width_at_fraction(element_calc_calc, offset(0.5), '150px');
|
||||
test_approximate_width_at_fraction(element_calc_calc, offset(1.1), '0px');
|
||||
}
|
||||
|
||||
</script>
|
|
@ -0,0 +1,75 @@
|
|||
<!DOCTYPE html>
|
||||
<link rel="help" src="https://drafts.csswg.org/scroll-animations-1/#scroll-timeline-at-rule">
|
||||
<link rel="help" src="https://drafts.csswg.org/scroll-animations-1/#descdef-scroll-timeline-time-range">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/web-animations/testcommon.js"></script>
|
||||
<style>
|
||||
#scroller {
|
||||
overflow: scroll;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
}
|
||||
#contents {
|
||||
height: 200px;
|
||||
}
|
||||
@keyframes expand {
|
||||
from { width: 100px; }
|
||||
to { width: 200px; }
|
||||
}
|
||||
@scroll-timeline timeline_10s {
|
||||
source: selector(#scroller);
|
||||
time-range: 10s;
|
||||
start: 0px;
|
||||
end: 100px;
|
||||
}
|
||||
@scroll-timeline timeline_1s {
|
||||
source: selector(#scroller);
|
||||
time-range: 1s;
|
||||
start: 0px;
|
||||
end: 100px;
|
||||
}
|
||||
@scroll-timeline timeline_1000ms {
|
||||
source: selector(#scroller);
|
||||
time-range: 1000ms;
|
||||
start: 0px;
|
||||
end: 100px;
|
||||
}
|
||||
#container > div {
|
||||
width: 0px;
|
||||
animation: expand 10s linear;
|
||||
}
|
||||
/* Ensure stable expectations if feature is not supported */
|
||||
@supports not (animation-timeline:foo) {
|
||||
#container > div { animation-play-state: paused; }
|
||||
}
|
||||
#element_10s { animation-timeline: timeline_10s; }
|
||||
#element_1s { animation-timeline: timeline_1s; }
|
||||
#element_1000ms { animation-timeline: timeline_1000ms; }
|
||||
</style>
|
||||
<div id=scroller>
|
||||
<div id=contents></div>
|
||||
</div>
|
||||
<div id=container>
|
||||
<div id=element_10s></div>
|
||||
<div id=element_1s></div>
|
||||
<div id=element_1000ms></div>
|
||||
</div>
|
||||
<script>
|
||||
scroller.scrollTop = 50;
|
||||
|
||||
promise_test(async (t) => {
|
||||
await waitForNextFrame();
|
||||
assert_equals(getComputedStyle(element_10s).width, '150px');
|
||||
}, 'Timerange mapped correctly (10s)');
|
||||
|
||||
promise_test(async (t) => {
|
||||
await waitForNextFrame();
|
||||
assert_equals(getComputedStyle(element_1s).width, '105px');
|
||||
}, 'Timerange mapped correctly (1s)');
|
||||
|
||||
promise_test(async (t) => {
|
||||
await waitForNextFrame();
|
||||
assert_equals(getComputedStyle(element_1s).width, '105px');
|
||||
}, 'Timerange mapped correctly (1000ms)');
|
||||
</script>
|
|
@ -112,6 +112,7 @@ test_source(' selector(#foo) ', 'selector(#foo)');
|
|||
test_source('none');
|
||||
test_source(' none ', 'none');
|
||||
test_source('selector(#a\\9 b)');
|
||||
test_source('auto');
|
||||
|
||||
test_source('#foo', 'none');
|
||||
test_source('', 'none');
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue