Skip to content

Commit 524f6f4

Browse files
vmpstrchromium-wpt-export-bot
authored andcommitted
VT: Implement waitUntil
This implements waitUntil by keeping a count of pending promises on VT and only allowing it to go beyond the animating phase when this count is 0. Based on resolution w3c/csswg-drafts#9901 (comment) Spec & chromestatus pending R=nrosenthal@google.com Bug: 346976175 Change-Id: I8f2270d532f8bb441c6a6746095eb7a535cc6833 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7028593 Commit-Queue: Vladimir Levin <vmpstr@chromium.org> Reviewed-by: Noam Rosenthal <nrosenthal@google.com> Cr-Commit-Position: refs/heads/main@{#1530874}
1 parent fd1cdd1 commit 524f6f4

File tree

3 files changed

+178
-0
lines changed

3 files changed

+178
-0
lines changed
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<!DOCTYPE html>
2+
<title>View transitions: waitUntil allows animation manipulation (reference)</title>
3+
<link rel="help" href="https://www.w3.org/TR/css-view-transitions-1/">
4+
<link rel="author" href="mailto:vmpstr@chromium.org">
5+
<style>
6+
body {
7+
background: lightpink;
8+
}
9+
.target {
10+
width: 100px;
11+
height: 100px;
12+
background: green;
13+
}
14+
</style>
15+
16+
<div class=target></div>
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
<!DOCTYPE html>
2+
<html class=reftest-wait>
3+
<title>View transitions: waitUntil allows animation manipulation</title>
4+
<link rel="help" href="https://www.w3.org/TR/css-view-transitions-1/">
5+
<link rel="author" href="mailto:vmpstr@chromium.org">
6+
<link rel="match" href="view-transition-waituntil-animation-manipulation-ref.html">
7+
<script src="/common/reftest-wait.js"></script>
8+
<style>
9+
:root { view-transition-name: none }
10+
11+
#target {
12+
width: 100px;
13+
height: 100px;
14+
background: green;
15+
view-transition-name: target;
16+
}
17+
18+
#target.after {
19+
background: red;
20+
}
21+
22+
::view-transition { background: lightpink; }
23+
::view-transition-group(*) {
24+
animation-duration: 1ms;
25+
}
26+
</style>
27+
28+
<div id=target></div>
29+
30+
<script>
31+
failIfNot(document.startViewTransition, "Missing document.startViewTransition");
32+
failIfNot(ViewTransition.prototype.waitUntil, "ViewTransition.waitUntil is not available");
33+
34+
async function runTest() {
35+
const transition = document.startViewTransition(() => target.classList.add("after"));
36+
transition.waitUntil(new Promise(() => {}));
37+
38+
transition.ready.then(async () => {
39+
// Let the animation run to the end.
40+
const animations = document.getAnimations();
41+
animations.forEach(a => {
42+
a.currentTime = 1;
43+
});
44+
45+
// Wait a few frames.
46+
await new Promise(requestAnimationFrame);
47+
await new Promise(requestAnimationFrame);
48+
await new Promise(requestAnimationFrame);
49+
50+
// Now, rewind the animation and take a screenshot.
51+
requestAnimationFrame(() => {
52+
animations.forEach(a => {
53+
a.play();
54+
a.pause();
55+
a.currentTime = 0;
56+
});
57+
takeScreenshot();
58+
});
59+
});
60+
}
61+
onload = () => requestAnimationFrame(() => requestAnimationFrame(runTest));
62+
</script>
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
<!DOCTYPE html>
2+
<meta charset="utf-8">
3+
<title>View Transition: waitUntil delays the finished promise</title>
4+
<link rel="help" href="https://drafts.csswg.org/css-view-transitions-1/">
5+
<link rel="author" href="mailto:vmpstr@chromium.org">
6+
7+
<script src="/resources/testharness.js"></script>
8+
<script src="/resources/testharnessreport.js"></script>
9+
10+
<style>
11+
#target {
12+
width: 100px;
13+
height: 100px;
14+
view-transition-name: target;
15+
}
16+
::view-transition-group(*) {
17+
animation-duration: 1ms;
18+
}
19+
</style>
20+
21+
<div id=target></div>
22+
23+
<script>
24+
promise_test(async t => {
25+
assert_implements(document.startViewTransition, "View Transitions are not supported");
26+
assert_implements(ViewTransition.prototype.waitUntil, "ViewTransition.waitUntil is not available");
27+
28+
let waitUntilPromiseResolve;
29+
const waitUntilPromise = new Promise(resolve => {
30+
waitUntilPromiseResolve = resolve;
31+
});
32+
33+
const transition = document.startViewTransition(() => {});
34+
transition.waitUntil(waitUntilPromise);
35+
36+
let finished = false;
37+
transition.finished.then(() => {
38+
finished = true;
39+
});
40+
41+
// Wait for longer than the animation duration.
42+
await new Promise(resolve => t.step_timeout(resolve, 100));
43+
44+
assert_false(finished, "transition.finished should not resolve before waitUntil promise");
45+
46+
waitUntilPromiseResolve();
47+
await transition.finished;
48+
49+
assert_true(finished, "transition.finished should resolve after waitUntil promise");
50+
}, "View transition finished promise is delayed by waitUntil");
51+
52+
promise_test(async t => {
53+
assert_implements(document.startViewTransition, "View Transitions are not supported");
54+
55+
let resolve1, resolve2;
56+
const promise1 = new Promise(r => resolve1 = r);
57+
const promise2 = new Promise(r => resolve2 = r);
58+
59+
const transition = document.startViewTransition(() => {});
60+
transition.waitUntil(promise1);
61+
transition.waitUntil(promise2);
62+
63+
let finished = false;
64+
transition.finished.then(() => finished = true);
65+
66+
// Wait for longer than the animation duration.
67+
await new Promise(resolve => t.step_timeout(resolve, 100));
68+
assert_false(finished, "transition.finished should not resolve before first promise");
69+
70+
resolve1();
71+
// Wait a bit to ensure the promise resolution propagates.
72+
await new Promise(resolve => t.step_timeout(resolve, 10));
73+
assert_false(finished, "transition.finished should not resolve after first promise but before second");
74+
75+
resolve2();
76+
await transition.finished;
77+
assert_true(finished, "transition.finished should resolve after both promises");
78+
}, "View transition finished promise is delayed by multiple waitUntil calls");
79+
80+
promise_test(async t => {
81+
assert_implements(document.startViewTransition, "View Transitions are not supported");
82+
83+
let reject1;
84+
const promise1 = new Promise((_, r) => reject1 = r);
85+
86+
const transition = document.startViewTransition(() => {});
87+
transition.waitUntil(promise1);
88+
89+
let finished = false;
90+
transition.finished.then(() => finished = true);
91+
92+
// Wait for longer than the animation duration.
93+
await new Promise(resolve => t.step_timeout(resolve, 100));
94+
assert_false(finished, "transition.finished should not resolve before rejected promise");
95+
96+
reject1(new DOMException("test", "AbortError"));
97+
await transition.finished;
98+
assert_true(finished, "transition.finished should resolve after rejected promise");
99+
}, "View transition finished promise is delayed by a rejecting waitUntil promise");
100+
</script>

0 commit comments

Comments
 (0)