Files
palemoon27/dom/animation/test/css-animations/file_element-get-animations.html
T
roytam1 279b2f1b52 import changes from `dev' branch of rmottola/Arctic-Fox:
- Bug 1136897 - Don't evict expired entries from disk. r=michal (6af5d87e8)
- Bug 1188745 - Rename nsTArray::SizeOfExcludingThis() as ShallowSizeOfExcludingThis(). r=froydnj. (3dbb2875a)
- Bug 1150810 part 1 - Move DocumentTimeline methods up to AnimationTimeline; r=jwatt (3d8c679af)
- Bug 1171817 part 1 - Cancel animations when destroying the property holding them; r=dbaron (6f28fbf46)
- Bug 1171817 part 2 - Add CSSAnimation::GetOwningElement; r=dbaron (700decca6)
- Bug 1171817 part 3 - Add CSSTransition::GetOwningElement; r=dbaron (e6da3c726)
- Bug 1171817 part 4 - Add const version of AsCSSAnimation/AsCSSTransition methods; r=dbaron (f264ebad7)
- Bug 1171817 part 5 - Add a sequence number member to Animations; r=dbaron (b041eeb6b)
- Bug 1171817 part 6 - Add Animation::HasLowerCompositeOrderThan; r=dbaron (df97cf295)
- Bug 1171817 part 7 - Add Animation::IsUsingCustomCompositeOrder; r=dbaron (5735f03a2)
- Bug 1171817 part 8 - Override sequence numbers for CSS animations; r=dbaron (50671de0f)
- Bug 1171817 part 9 - Add override of HasLowerCompositeOrderThan for CSS animations; r=dbaron (b467ffd3c)
- Bug 1171817 part 10 - Override sequence numbers for transitions; r=dbron (3703102f6)
- Bug 1171817 part 11 - Add CSSTransition::TransitionProperty(); r=dbaron (c889aa8ec)
- Bug 1171817 part 13 - Add override of HasLowerCompositeOrderThan for CSS transitions; r=dbaron (8c628cac4)
- Bug 1171817 part 14 - Add AnimationPtrComparator class; r=dbaron (c522180c9)
- Bug 1171817 part 15 - Factor out common code for comparing owning elements into a separate class; r=dbaron (132998a2c)
- Bug 1171817 part 16 - Always cancel transitions before removing them; r=dbaron (01113a650)
- Bug 1150810 part 2 - Replace references to DocumentTimeline with AnimationTimeline; r=jwatt (d377ba63f)
- Bug 1150810 part 3 - Make IsPossiblyOrphanedPendingAnimation return true when there is no rendered doc; r=jwatt (63b2b6760)
- Bug 1150810 part 4 - Store global on Animation; r=smaug, jwatt (fd099d639)
- Bug 1150810 part 5 - Handle Timeline() returning null; r=jwatt (641bd865d)
2021-03-26 17:01:09 +08:00

310 lines
11 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);
// FIXME: This test does too many things. It should be split up.
// 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, { style: 'animation: anim1 100s' });
assert_class_string(div.getAnimations()[0], 'CSSAnimation',
'Interface of returned animation is CSSAnimation');
}, 'getAnimations returns CSSAnimation objects 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');
assert_class_string(animations[0], 'CSSTransition',
'First-returned animation is the CSS Transition');
assert_class_string(animations[1], 'CSSAnimation',
'Second-returned animation is the CSS Animation');
t.done();
}));
}, 'getAnimations for both CSS Animations and CSS 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');
async_test(function(t) {
var div = addDiv(t);
div.style.animation = 'anim2 100s';
div.getAnimations()[0].ready.then(t.step_func(function() {
// Prepend to the list and test that even though anim1 was triggered
// *after* anim2, it should come first because it appears first
// in the animation-name property.
div.style.animation = 'anim1 100s, anim2 100s';
var anims = div.getAnimations();
assert_equals(anims[0].animationName, 'anim1',
'animation order after prepending to list');
assert_equals(anims[1].animationName, 'anim2',
'animation order after prepending to list');
// Normally calling cancel and play would this push anim1 to the top of
// the stack but it shouldn't for CSS animations that map an the
// animation-name property.
var anim1 = anims[0];
anim1.cancel();
anim1.play();
anims = div.getAnimations();
assert_equals(anims[0].animationName, 'anim1',
'animation order after cancelling and restarting');
assert_equals(anims[1].animationName, 'anim2',
'animation order after cancelling and restarting');
t.done();
}));
}, 'getAnimations for CSS Animations follows animation-name order');
done();
</script>
</body>