273 lines
9.3 KiB
HTML
273 lines
9.3 KiB
HTML
<!doctype html>
|
|
<meta charset=utf-8>
|
|
<script src="../testcommon.js"></script>
|
|
<style>
|
|
@keyframes anim1 {
|
|
to { left: 100px }
|
|
}
|
|
@keyframes anim2 {
|
|
to { top: 100px }
|
|
}
|
|
@keyframes multiPropAnim {
|
|
to { background: green, opacity: 0.5, left: 100px, top: 100px }
|
|
}
|
|
@keyframes empty { }
|
|
</style>
|
|
<body>
|
|
<script>
|
|
'use strict';
|
|
|
|
test(function(t) {
|
|
var div = addDiv(t);
|
|
assert_equals(div.getAnimations().length, 0,
|
|
'getAnimations returns an empty sequence for an element'
|
|
+ ' with no animations');
|
|
}, 'getAnimations for non-animated content');
|
|
|
|
async_test(function(t) {
|
|
var div = addDiv(t);
|
|
|
|
// Add an animation
|
|
div.style.animation = 'anim1 100s';
|
|
var animations = div.getAnimations();
|
|
assert_equals(animations.length, 1,
|
|
'getAnimations returns an Animation running CSS Animations');
|
|
animations[0].ready.then(t.step_func(function() {
|
|
var startTime = animations[0].startTime;
|
|
assert_true(startTime > 0 && startTime <= document.timeline.currentTime,
|
|
'CSS animation has a sensible start time');
|
|
|
|
// Wait a moment then add a second animation.
|
|
//
|
|
// We wait for the next frame so that we can test that the start times of
|
|
// the animations differ.
|
|
return waitForFrame();
|
|
})).then(t.step_func(function() {
|
|
div.style.animation = 'anim1 100s, anim2 100s';
|
|
animations = div.getAnimations();
|
|
assert_equals(animations.length, 2,
|
|
'getAnimations returns one Animation for each value of'
|
|
+ ' animation-name');
|
|
// Wait until both Animations are ready
|
|
// (We don't make any assumptions about the order of the Animations since
|
|
// that is the purpose of the following test.)
|
|
return waitForAllAnimations(animations);
|
|
})).then(t.step_func(function() {
|
|
assert_true(animations[0].startTime < animations[1].startTime,
|
|
'Additional Animations for CSS animations start after the original'
|
|
+ ' animation and appear later in the list');
|
|
t.done();
|
|
}));
|
|
}, 'getAnimations for CSS Animations');
|
|
|
|
test(function(t) {
|
|
var div = addDiv(t);
|
|
|
|
// Add an animation that targets multiple properties
|
|
div.style.animation = 'multiPropAnim 100s';
|
|
assert_equals(div.getAnimations().length, 1,
|
|
'getAnimations returns only one Animation for a CSS Animation'
|
|
+ ' that targets multiple properties');
|
|
}, 'getAnimations for multi-property animations');
|
|
|
|
async_test(function(t) {
|
|
var div = addDiv(t);
|
|
|
|
// Add an animation
|
|
div.style.backgroundColor = 'red';
|
|
div.style.animation = 'anim1 100s';
|
|
window.getComputedStyle(div).backgroundColor;
|
|
|
|
// Wait until a frame after the animation starts, then add a transition
|
|
var animations = div.getAnimations();
|
|
animations[0].ready.then(waitForFrame).then(t.step_func(function() {
|
|
div.style.transition = 'all 100s';
|
|
div.style.backgroundColor = 'green';
|
|
|
|
animations = div.getAnimations();
|
|
assert_equals(animations.length, 2,
|
|
'getAnimations returns Animations for both animations and'
|
|
+ ' transitions that run simultaneously');
|
|
return waitForAllAnimations(animations);
|
|
})).then(t.step_func(function() {
|
|
assert_true(animations[0].startTime > animations[1].startTime,
|
|
'Animations for transitions appear before animations even if they'
|
|
+ ' start later');
|
|
t.done();
|
|
}));
|
|
}, 'getAnimations for both CSS Animations and Transitions at once');
|
|
|
|
async_test(function(t) {
|
|
var div = addDiv(t);
|
|
|
|
// Set up event listener
|
|
div.addEventListener('animationend', t.step_func(function() {
|
|
assert_equals(div.getAnimations().length, 0,
|
|
'getAnimations does not return Animations for finished '
|
|
+ ' (and non-forwards-filling) CSS Animations');
|
|
t.done();
|
|
}));
|
|
|
|
// Add a very short animation
|
|
div.style.animation = 'anim1 0.01s';
|
|
}, 'getAnimations for CSS Animations that have finished');
|
|
|
|
async_test(function(t) {
|
|
var div = addDiv(t);
|
|
|
|
// Set up event listener
|
|
div.addEventListener('animationend', t.step_func(function() {
|
|
assert_equals(div.getAnimations().length, 1,
|
|
'getAnimations returns Animations for CSS Animations that have'
|
|
+ ' finished but are filling forwards');
|
|
t.done();
|
|
}));
|
|
|
|
// Add a very short animation
|
|
div.style.animation = 'anim1 0.01s forwards';
|
|
}, 'getAnimations for CSS Animations that have finished but are'
|
|
+ ' forwards filling');
|
|
|
|
test(function(t) {
|
|
var div = addDiv(t);
|
|
div.style.animation = 'none 100s';
|
|
|
|
var animations = div.getAnimations();
|
|
assert_equals(animations.length, 0,
|
|
'getAnimations returns an empty sequence for an element'
|
|
+ ' with animation-name: none');
|
|
|
|
div.style.animation = 'none 100s, anim1 100s';
|
|
animations = div.getAnimations();
|
|
assert_equals(animations.length, 1,
|
|
'getAnimations returns Animations only for those CSS Animations whose'
|
|
+ ' animation-name is not none');
|
|
}, 'getAnimations for CSS Animations with animation-name: none');
|
|
|
|
test(function(t) {
|
|
var div = addDiv(t);
|
|
div.style.animation = 'missing 100s';
|
|
var animations = div.getAnimations();
|
|
assert_equals(animations.length, 0,
|
|
'getAnimations returns an empty sequence for an element'
|
|
+ ' with animation-name: missing');
|
|
|
|
div.style.animation = 'anim1 100s, missing 100s';
|
|
animations = div.getAnimations();
|
|
assert_equals(animations.length, 1,
|
|
'getAnimations returns Animations only for those CSS Animations whose'
|
|
+ ' animation-name is found');
|
|
}, 'getAnimations for CSS Animations with animation-name: missing');
|
|
|
|
async_test(function(t) {
|
|
var div = addDiv(t);
|
|
div.style.animation = 'anim1 100s, notyet 100s';
|
|
var animations = div.getAnimations();
|
|
assert_equals(animations.length, 1,
|
|
'getAnimations initally only returns Animations for CSS Animations whose'
|
|
+ ' animation-name is found');
|
|
|
|
animations[0].ready.then(waitForFrame).then(t.step_func(function() {
|
|
var keyframes = '@keyframes notyet { to { left: 100px; } }';
|
|
document.styleSheets[0].insertRule(keyframes, 0);
|
|
animations = div.getAnimations();
|
|
assert_equals(animations.length, 2,
|
|
'getAnimations includes Animation when @keyframes rule is added'
|
|
+ ' later');
|
|
return waitForAllAnimations(animations);
|
|
})).then(t.step_func(function() {
|
|
assert_true(animations[0].startTime < animations[1].startTime,
|
|
'Newly added animation has a later start time');
|
|
document.styleSheets[0].deleteRule(0);
|
|
t.done();
|
|
}));
|
|
}, 'getAnimations for CSS Animations where the @keyframes rule is added'
|
|
+ ' later');
|
|
|
|
test(function(t) {
|
|
var div = addDiv(t);
|
|
div.style.animation = 'anim1 100s, anim1 100s';
|
|
assert_equals(div.getAnimations().length, 2,
|
|
'getAnimations returns one Animation for each CSS animation-name'
|
|
+ ' even if the names are duplicated');
|
|
}, 'getAnimations for CSS Animations with duplicated animation-name');
|
|
|
|
test(function(t) {
|
|
var div = addDiv(t);
|
|
div.style.animation = 'empty 100s';
|
|
assert_equals(div.getAnimations().length, 1,
|
|
'getAnimations returns Animations for CSS animations with an'
|
|
+ ' empty keyframes rule');
|
|
}, 'getAnimations for CSS Animations with empty keyframes rule');
|
|
|
|
async_test(function(t) {
|
|
var div = addDiv(t);
|
|
div.style.animation = 'anim1 100s 100s';
|
|
var animations = div.getAnimations();
|
|
assert_equals(animations.length, 1,
|
|
'getAnimations returns animations for CSS animations whose'
|
|
+ ' delay makes them start later');
|
|
animations[0].ready.then(waitForFrame).then(t.step_func(function() {
|
|
assert_true(animations[0].startTime <= document.timeline.currentTime,
|
|
'For CSS Animations in delay phase, the start time of the Animation is'
|
|
+ ' not in the future');
|
|
t.done();
|
|
}));
|
|
}, 'getAnimations for CSS animations in delay phase');
|
|
|
|
test(function(t) {
|
|
var div = addDiv(t);
|
|
div.style.animation = 'anim1 0s 100s';
|
|
assert_equals(div.getAnimations().length, 1,
|
|
'getAnimations returns animations for CSS animations whose'
|
|
+ ' duration is zero');
|
|
div.remove();
|
|
}, 'getAnimations for zero-duration CSS Animations');
|
|
|
|
test(function(t) {
|
|
var div = addDiv(t);
|
|
div.style.animation = 'anim1 100s';
|
|
var originalAnimation = div.getAnimations()[0];
|
|
|
|
// Update pause state (an Animation change)
|
|
div.style.animationPlayState = 'paused';
|
|
var pendingAnimation = div.getAnimations()[0];
|
|
assert_equals(pendingAnimation.playState, 'pending',
|
|
'animation\'s play state is updated');
|
|
assert_equals(originalAnimation, pendingAnimation,
|
|
'getAnimations returns the same objects even when their'
|
|
+ ' play state changes');
|
|
|
|
// Update duration (an Animation change)
|
|
div.style.animationDuration = '200s';
|
|
var extendedAnimation = div.getAnimations()[0];
|
|
// FIXME: Check extendedAnimation.effect.timing.duration has changed once the
|
|
// API is available
|
|
assert_equals(originalAnimation, extendedAnimation,
|
|
'getAnimations returns the same objects even when their'
|
|
+ ' duration changes');
|
|
}, 'getAnimations returns objects with the same identity');
|
|
|
|
test(function(t) {
|
|
var div = addDiv(t);
|
|
div.style.animation = 'anim1 100s';
|
|
|
|
assert_equals(div.getAnimations().length, 1,
|
|
'getAnimations returns an animation before cancelling');
|
|
|
|
var animation = div.getAnimations()[0];
|
|
|
|
animation.cancel();
|
|
assert_equals(div.getAnimations().length, 0,
|
|
'getAnimations does not return cancelled animations');
|
|
|
|
animation.play();
|
|
assert_equals(div.getAnimations().length, 1,
|
|
'getAnimations returns cancelled animations that have been re-started');
|
|
|
|
}, 'getAnimations for CSS Animations that are cancelled');
|
|
|
|
done();
|
|
</script>
|
|
</body>
|