// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
let transition = null;
addEventListener('pagereveal', e => {
if (e.viewTransition) {
_transitionDidStart(e.viewTransition);
}
});
// Allow tests to control when the transition starts. Tests call
// startTransitionAnimation() to complete the author DOM callback and allow the
// view-transition to start the animation.
let startTransitionAnimation = null;
let startPromise =
new Promise(resolve => {startTransitionAnimation = resolve;});
// Allow tests to wait until the snapshot has been taken and is ready to start
// transitioning. Tests use readyToStartPromise to wait until the the author
// updateDOM callback has been invoked.
let readyToStartResolve = null;
let readyToStartPromise =
new Promise(resolve => {readyToStartResolve = resolve;});
// Individual test files set this to perform the DOM update to the new
// transition state.
let updateDOM = null;
// Sets the animation time to just before the end (not the end itself) to
// prevent finishing the animation. Since the animations have steps timing
// function the state is equivalent to the end state itself.
function animateToEndState() {
if (transition == null)
throw new Error('Transition was already finished or never started.');
for (const anim of document.getAnimations())
anim.currentTime = anim.effect.getTiming().duration - 1;
}
// Finishes animations, and thus the view transition.
function finishAnimations() {
if (transition == null)
throw new Error('Transition was already finished or never started.');
for (const anim of document.getAnimations())
anim.finish();
}
// Creates a view transition. The transition will call the test's defined
// updateDOM function to mutate the DOM into the new state and resolve the
// readyToStartPromise when the DOM has been updated. The animation won't start
// until the test calls startTransitionAnimation().
function createTransition() {
if (transition != null)
throw new Error('In-progress transition already exists.');
if (updateDOM == null)
throw new Error('Test must set an updateDOM function');
let t = document.startViewTransition(() => {
updateDOM();
readyToStartResolve();
return startPromise;
});
_transitionDidStart(t);
}
// Lets the harness know about an active transition. This will cause its
// animations to be initially paused.
function _transitionDidStart(t) {
transition = t;
// Initially pause the animation at the old state so the test can take a
// screenshot. Tests can then use moveAnimationToNewState() to play the
// animation forward to the new state.
transition.ready.then(() => {
for (const anim of document.getAnimations()) {
anim.pause();
}
});
transition.finished.then( () => {
transition = null;
});
}