| <!doctype html> | |
| <meta charset=utf-8> | |
| <title>AnimationEffect.updateTiming() for CSS animations</title> | |
| <!-- TODO: Add a more specific link for this once it is specified. --> | |
| <link rel="help" href="https://drafts.csswg.org/css-animations-2/"> | |
| <script src="/resources/testharness.js"></script> | |
| <script src="/resources/testharnessreport.js"></script> | |
| <script src="support/testcommon.js"></script> | |
| <style> | |
| @keyframes anim-empty { } | |
| </style> | |
| <body> | |
| <div id="log"></div> | |
| <script> | |
| "use strict"; | |
| test(t => { | |
| const div = addDiv(t); | |
| div.style.animation = 'anim-empty 100s'; | |
| const animation = div.getAnimations()[0]; | |
| animation.effect.updateTiming({ duration: 2 * MS_PER_SEC }); | |
| div.style.animationDuration = '4s'; | |
| div.style.animationDelay = '6s'; | |
| assert_equals( | |
| animation.effect.getTiming().duration, | |
| 2 * MS_PER_SEC, | |
| 'Duration should be the value set by the API' | |
| ); | |
| assert_equals( | |
| animation.effect.getTiming().delay, | |
| 6 * MS_PER_SEC, | |
| 'Delay should be the value set by style' | |
| ); | |
| }, 'AnimationEffect.updateTiming({ duration }) causes changes to the' | |
| + ' animation-duration to be ignored'); | |
| // The above test covers duration (with delay as a control). The remaining | |
| // properties are: | |
| // | |
| // iterations - animation-iteration-count | |
| // direction - animation-direction | |
| // delay - animation-delay | |
| // fill - animation-fill-mode | |
| // | |
| // Which we test in two batches, overriding two properties each time and using | |
| // the remaining two properties as control values to check they are NOT | |
| // overridden. | |
| test(t => { | |
| const div = addDiv(t); | |
| div.style.animation = 'anim-empty 100s'; | |
| const animation = div.getAnimations()[0]; | |
| animation.effect.updateTiming({ iterations: 2, direction: 'reverse' }); | |
| div.style.animationIterationCount = '4'; | |
| div.style.animationDirection = 'alternate'; | |
| div.style.animationDelay = '6s'; | |
| div.style.animationFillMode = 'both'; | |
| assert_equals( | |
| animation.effect.getTiming().iterations, | |
| 2, | |
| 'Iterations should be the value set by the API' | |
| ); | |
| assert_equals( | |
| animation.effect.getTiming().direction, | |
| 'reverse', | |
| 'Direction should be the value set by the API' | |
| ); | |
| assert_equals( | |
| animation.effect.getTiming().delay, | |
| 6 * MS_PER_SEC, | |
| 'Delay should be the value set by style' | |
| ); | |
| assert_equals( | |
| animation.effect.getTiming().fill, | |
| 'both', | |
| 'Fill should be the value set by style' | |
| ); | |
| }, 'AnimationEffect.updateTiming({ iterations, direction }) causes changes to' | |
| + ' the animation-iteration-count and animation-direction to be ignored'); | |
| test(t => { | |
| const div = addDiv(t); | |
| div.style.animation = 'anim-empty 100s'; | |
| const animation = div.getAnimations()[0]; | |
| animation.effect.updateTiming({ delay: 2 * MS_PER_SEC, fill: 'both' }); | |
| div.style.animationDelay = '4s'; | |
| div.style.animationFillMode = 'forwards'; | |
| div.style.animationIterationCount = '6'; | |
| div.style.animationDirection = 'reverse'; | |
| assert_equals( | |
| animation.effect.getTiming().delay, | |
| 2 * MS_PER_SEC, | |
| 'Delay should be the value set by the API' | |
| ); | |
| assert_equals( | |
| animation.effect.getTiming().fill, | |
| 'both', | |
| 'Fill should be the value set by the API' | |
| ); | |
| assert_equals( | |
| animation.effect.getTiming().iterations, | |
| 6, | |
| 'Iterations should be the value set by style' | |
| ); | |
| assert_equals( | |
| animation.effect.getTiming().direction, | |
| 'reverse', | |
| 'Direction should be the value set by style' | |
| ); | |
| }, 'AnimationEffect.updateTiming({ delay, fill }) causes changes to' | |
| + ' the animation-delay and animation-fill-mode to be ignored'); | |
| test(t => { | |
| const div = addDiv(t); | |
| div.style.animation = 'anim-empty 100s'; | |
| const animation = div.getAnimations()[0]; | |
| assert_throws_js(TypeError, () => { | |
| animation.effect.updateTiming({ duration: 2 * MS_PER_SEC, iterations: -1 }); | |
| }, 'Negative iteration count should cause an error to be thrown'); | |
| div.style.animationDuration = '4s'; | |
| assert_equals( | |
| animation.effect.getTiming().duration, | |
| 4 * MS_PER_SEC, | |
| 'Duration should be the value set by style' | |
| ); | |
| }, 'AnimationEffect.updateTiming() does override to changes from animation-*' | |
| + ' properties if there is an error'); | |
| test(t => { | |
| const div = addDiv(t); | |
| div.style.animation = 'anim-empty 100s'; | |
| const animation = div.getAnimations()[0]; | |
| animation.effect.updateTiming({ | |
| easing: 'steps(4)', | |
| endDelay: 2 * MS_PER_SEC, | |
| iterationStart: 4, | |
| }); | |
| div.style.animationDuration = '6s'; | |
| div.style.animationTimingFunction = 'ease-in'; | |
| assert_equals( | |
| animation.effect.getTiming().easing, | |
| 'steps(4)', | |
| 'endDelay should be the value set by the API' | |
| ); | |
| assert_equals( | |
| animation.effect.getTiming().endDelay, | |
| 2 * MS_PER_SEC, | |
| 'endDelay should be the value set by the API' | |
| ); | |
| assert_equals( | |
| animation.effect.getTiming().iterationStart, | |
| 4, | |
| 'iterationStart should be the value set by style' | |
| ); | |
| }, 'AnimationEffect properties that do not map to animation-* properties' | |
| + ' should not be changed when animation-* style is updated'); | |
| </script> | |
| </body> |