summaryrefslogtreecommitdiffstats
path: root/dom/animation/test/css-animations/file_animation-computed-timing.html
diff options
context:
space:
mode:
authorMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
committerMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
commit5f8de423f190bbb79a62f804151bc24824fa32d8 (patch)
tree10027f336435511475e392454359edea8e25895d /dom/animation/test/css-animations/file_animation-computed-timing.html
parent49ee0794b5d912db1f95dce6eb52d781dc210db5 (diff)
downloadUXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.gz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.lz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.xz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.zip
Add m-esr52 at 52.6.0
Diffstat (limited to 'dom/animation/test/css-animations/file_animation-computed-timing.html')
-rw-r--r--dom/animation/test/css-animations/file_animation-computed-timing.html566
1 files changed, 566 insertions, 0 deletions
diff --git a/dom/animation/test/css-animations/file_animation-computed-timing.html b/dom/animation/test/css-animations/file_animation-computed-timing.html
new file mode 100644
index 000000000..53597a473
--- /dev/null
+++ b/dom/animation/test/css-animations/file_animation-computed-timing.html
@@ -0,0 +1,566 @@
+<!doctype html>
+<meta charset=utf-8>
+<script src="../testcommon.js"></script>
+<style>
+@keyframes moveAnimation {
+ from { margin-left: 100px }
+ to { margin-left: 200px }
+}
+</style>
+<body>
+<script>
+
+'use strict';
+
+// --------------------
+// delay
+// --------------------
+test(function(t) {
+ var div = addDiv(t, {style: 'animation: moveAnimation 100s'});
+ var effect = div.getAnimations()[0].effect;
+ assert_equals(effect.getComputedTiming().delay, 0,
+ 'Initial value of delay');
+}, 'delay of a new animation');
+
+test(function(t) {
+ var div = addDiv(t, {style: 'animation: moveAnimation 100s -10s'});
+ var effect = div.getAnimations()[0].effect;
+ assert_equals(effect.getComputedTiming().delay, -10 * MS_PER_SEC,
+ 'Initial value of delay');
+}, 'Negative delay of a new animation');
+
+test(function(t) {
+ var div = addDiv(t, {style: 'animation: moveAnimation 100s 10s'});
+ var effect = div.getAnimations()[0].effect;
+ assert_equals(effect.getComputedTiming().delay, 10 * MS_PER_SEC,
+ 'Initial value of delay');
+}, 'Positive delay of a new animation');
+
+
+// --------------------
+// endDelay
+// --------------------
+test(function(t) {
+ var div = addDiv(t, {style: 'animation: moveAnimation 100s'});
+ var effect = div.getAnimations()[0].effect;
+ assert_equals(effect.getComputedTiming().endDelay, 0,
+ 'Initial value of endDelay');
+}, 'endDelay of a new animation');
+
+
+// --------------------
+// fill
+// --------------------
+test(function(t) {
+ var getEffectWithFill = function(fill) {
+ var div = addDiv(t, {style: 'animation: moveAnimation 100s ' + fill});
+ return div.getAnimations()[0].effect;
+ };
+
+ var effect = getEffectWithFill('');
+ assert_equals(effect.getComputedTiming().fill, 'none',
+ 'Initial value of fill');
+ effect = getEffectWithFill('forwards');
+ assert_equals(effect.getComputedTiming().fill, 'forwards',
+ 'Fill forwards');
+ effect = getEffectWithFill('backwards');
+ assert_equals(effect.getComputedTiming().fill, 'backwards',
+ 'Fill backwards');
+ effect = getEffectWithFill('both');
+ assert_equals(effect.getComputedTiming().fill, 'both',
+ 'Fill forwards and backwards');
+}, 'fill of a new animation');
+
+
+// --------------------
+// iterationStart
+// --------------------
+test(function(t) {
+ var div = addDiv(t, {style: 'animation: moveAnimation 100s'});
+ var effect = div.getAnimations()[0].effect;
+ assert_equals(effect.getComputedTiming().iterationStart, 0,
+ 'Initial value of iterationStart');
+}, 'iterationStart of a new animation');
+
+
+// --------------------
+// iterations
+// --------------------
+test(function(t) {
+ var div = addDiv(t, {style: 'animation: moveAnimation 100s'});
+ var effect = div.getAnimations()[0].effect;
+ assert_equals(effect.getComputedTiming().iterations, 1,
+ 'Initial value of iterations');
+}, 'iterations of a new animation');
+
+test(function(t) {
+ var div = addDiv(t, {style: 'animation: moveAnimation 100s 2016.5'});
+ var effect = div.getAnimations()[0].effect;
+ assert_equals(effect.getComputedTiming().iterations, 2016.5,
+ 'Initial value of iterations');
+}, 'iterations of a finitely repeating animation');
+
+test(function(t) {
+ var div = addDiv(t, {style: 'animation: moveAnimation 100s infinite'});
+ var effect = div.getAnimations()[0].effect;
+ assert_equals(effect.getComputedTiming().iterations, Infinity,
+ 'Initial value of iterations');
+}, 'iterations of an infinitely repeating animation');
+
+
+// --------------------
+// duration
+// --------------------
+test(function(t) {
+ var div = addDiv(t, {style: 'animation: moveAnimation 100s -10s infinite'});
+ var effect = div.getAnimations()[0].effect;
+ assert_equals(effect.getComputedTiming().duration, 100 * MS_PER_SEC,
+ 'Initial value of duration');
+}, 'duration of a new animation');
+
+
+// --------------------
+// direction
+// --------------------
+test(function(t) {
+ var getEffectWithDir = function(dir) {
+ var div = addDiv(t, {style: 'animation: moveAnimation 100s ' + dir});
+ return div.getAnimations()[0].effect;
+ };
+
+ var effect = getEffectWithDir('');
+ assert_equals(effect.getComputedTiming().direction, 'normal',
+ 'Initial value of normal direction');
+ effect = getEffectWithDir('reverse');
+ assert_equals(effect.getComputedTiming().direction, 'reverse',
+ 'Initial value of reverse direction');
+ effect = getEffectWithDir('alternate');
+ assert_equals(effect.getComputedTiming().direction, 'alternate',
+ 'Initial value of alternate direction');
+ effect = getEffectWithDir('alternate-reverse');
+ assert_equals(effect.getComputedTiming().direction, 'alternate-reverse',
+ 'Initial value of alternate-reverse direction');
+}, 'direction of a new animation');
+
+
+// --------------------
+// easing
+// --------------------
+test(function(t) {
+ var div = addDiv(t, {style: 'animation: moveAnimation 100s'});
+ var effect = div.getAnimations()[0].effect;
+ assert_equals(effect.getComputedTiming().easing, 'linear',
+ 'Initial value of easing');
+}, 'easing of a new animation');
+
+
+// ------------------------------
+// endTime
+// = max(start delay + active duration + end delay, 0)
+// --------------------
+test(function(t) {
+ var div = addDiv(t, {style: 'animation: moveAnimation 100s'});
+ var effect = div.getAnimations()[0].effect;
+ assert_equals(effect.getComputedTiming().endTime, 100 * MS_PER_SEC,
+ 'Initial value of endTime');
+}, 'endTime of an new animation');
+
+test(function(t) {
+ var div = addDiv(t, {style: 'animation: moveAnimation 100s -5s'});
+ var effect = div.getAnimations()[0].effect;
+ var answer = (100 - 5) * MS_PER_SEC;
+ assert_equals(effect.getComputedTiming().endTime, answer,
+ 'Initial value of endTime');
+}, 'endTime of an animation with a negative delay');
+
+test(function(t) {
+ var div = addDiv(t, {style: 'animation: moveAnimation 10s -100s infinite'});
+ var effect = div.getAnimations()[0].effect;
+ assert_equals(effect.getComputedTiming().endTime, Infinity,
+ 'Initial value of endTime');
+}, 'endTime of an infinitely repeating animation');
+
+test(function(t) {
+ var div = addDiv(t, {style: 'animation: moveAnimation 0s 100s infinite'});
+ var effect = div.getAnimations()[0].effect;
+ assert_equals(effect.getComputedTiming().endTime, 100 * MS_PER_SEC,
+ 'Initial value of endTime');
+}, 'endTime of an infinitely repeating zero-duration animation');
+
+test(function(t) {
+ // Fill forwards so div.getAnimations()[0] won't return an
+ // undefined value.
+ var div = addDiv(t, {style: 'animation: moveAnimation 10s -100s forwards'});
+ var effect = div.getAnimations()[0].effect;
+ assert_equals(effect.getComputedTiming().endTime, 0,
+ 'Initial value of endTime');
+}, 'endTime of an animation that finishes before its startTime');
+
+
+// --------------------
+// activeDuration
+// = iteration duration * iteration count
+// --------------------
+test(function(t) {
+ var div = addDiv(t, {style: 'animation: moveAnimation 100s 5'});
+ var effect = div.getAnimations()[0].effect;
+ var answer = 100 * MS_PER_SEC * 5;
+ assert_equals(effect.getComputedTiming().activeDuration, answer,
+ 'Initial value of activeDuration');
+}, 'activeDuration of a new animation');
+
+test(function(t) {
+ var div = addDiv(t, {style: 'animation: moveAnimation 100s infinite'});
+ var effect = div.getAnimations()[0].effect;
+ assert_equals(effect.getComputedTiming().activeDuration, Infinity,
+ 'Initial value of activeDuration');
+}, 'activeDuration of an infinitely repeating animation');
+
+test(function(t) {
+ var div = addDiv(t, {style: 'animation: moveAnimation 0s 1s infinite'});
+ var effect = div.getAnimations()[0].effect;
+ // If either the iteration duration or iteration count are zero,
+ // the active duration is zero.
+ assert_equals(effect.getComputedTiming().activeDuration, 0,
+ 'Initial value of activeDuration');
+}, 'activeDuration of an infinitely repeating zero-duration animation');
+
+test(function(t) {
+ var div = addDiv(t, {style: 'animation: moveAnimation 100s 1s 0'});
+ var effect = div.getAnimations()[0].effect;
+ // If either the iteration duration or iteration count are zero,
+ // the active duration is zero.
+ assert_equals(effect.getComputedTiming().activeDuration, 0,
+ 'Initial value of activeDuration');
+}, 'activeDuration of an animation with zero iterations');
+
+
+// --------------------
+// localTime
+// --------------------
+test(function(t) {
+ var div = addDiv(t, {style: 'animation: moveAnimation 100s'});
+ var effect = div.getAnimations()[0].effect;
+ assert_equals(effect.getComputedTiming().localTime, 0,
+ 'Initial value of localTime');
+}, 'localTime of a new animation');
+
+test(function(t) {
+ var div = addDiv(t, {style: 'animation: moveAnimation 100s'});
+ var anim = div.getAnimations()[0];
+ anim.currentTime = 5 * MS_PER_SEC;
+ assert_equals(anim.effect.getComputedTiming().localTime, anim.currentTime,
+ 'current localTime after setting currentTime');
+}, 'localTime of an animation is always equal to currentTime');
+
+promise_test(function(t) {
+ var div = addDiv(t, {style: 'animation: moveAnimation 100s'});
+
+ var anim = div.getAnimations()[0];
+ anim.playbackRate = 2; // 2 times faster
+
+ return anim.ready.then(function() {
+ assert_equals(anim.effect.getComputedTiming().localTime, anim.currentTime,
+ 'localTime is equal to currentTime');
+ return waitForFrame();
+ }).then(function() {
+ assert_equals(anim.effect.getComputedTiming().localTime, anim.currentTime,
+ 'localTime is equal to currentTime');
+ });
+}, 'localTime reflects playbackRate immediately');
+
+test(function(t) {
+ var div = addDiv(t);
+ var effect = new KeyframeEffectReadOnly(div, {left: ["0px", "100px"]});
+
+ assert_equals(effect.getComputedTiming().localTime, null,
+ 'localTime for orphaned effect');
+}, 'localTime of an AnimationEffect without an Animation');
+
+
+// --------------------
+// progress
+// Note: Default timing function is linear.
+// --------------------
+test(function(t) {
+ [{fill: '', progress: [ null, null ]},
+ {fill: 'none', progress: [ null, null ]},
+ {fill: 'forwards', progress: [ null, 1.0 ]},
+ {fill: 'backwards', progress: [ 0.0, null ]},
+ {fill: 'both', progress: [ 0.0, 1.0 ]}]
+ .forEach(function(test) {
+ var div =
+ addDiv(t, {style: 'animation: moveAnimation 100s 10s ' + test.fill});
+ var anim = div.getAnimations()[0];
+ assert_true(anim.effect.getComputedTiming().progress === test.progress[0],
+ 'initial progress with "' + test.fill + '" fill');
+ anim.finish();
+ assert_true(anim.effect.getComputedTiming().progress === test.progress[1],
+ 'finished progress with "' + test.fill + '" fill');
+ });
+}, 'progress of an animation with different fill modes');
+
+test(function(t) {
+ var div = addDiv(t, {style: 'animation: moveAnimation 10s 10 both'});
+ var anim = div.getAnimations()[0];
+
+ assert_equals(anim.effect.getComputedTiming().progress, 0.0,
+ 'Initial value of progress');
+ anim.currentTime += 2.5 * MS_PER_SEC;
+ assert_equals(anim.effect.getComputedTiming().progress, 0.25,
+ 'Value of progress');
+ anim.currentTime += 5 * MS_PER_SEC;
+ assert_equals(anim.effect.getComputedTiming().progress, 0.75,
+ 'Value of progress');
+ anim.currentTime += 5 * MS_PER_SEC;
+ assert_equals(anim.effect.getComputedTiming().progress, 0.25,
+ 'Value of progress');
+ anim.finish()
+ assert_equals(anim.effect.getComputedTiming().progress, 1.0,
+ 'Value of progress');
+}, 'progress of an integral repeating animation with normal direction');
+
+test(function(t) {
+ var div = addDiv(t);
+ // Note: FillMode here is "both" because
+ // 1. Since this a zero-duration animation, it will already have finished
+ // so it won't be returned by getAnimations() unless it fills forwards.
+ // 2. Fill backwards, so the progress before phase wouldn't be
+ // unresolved (null value).
+ var div = addDiv(t, {style: 'animation: moveAnimation 0s infinite both'});
+ var anim = div.getAnimations()[0];
+
+ assert_equals(anim.effect.getComputedTiming().progress, 1.0,
+ 'Initial value of progress in after phase');
+
+ // Seek backwards
+ anim.currentTime -= 1 * MS_PER_SEC;
+ assert_equals(anim.effect.getComputedTiming().progress, 0.0,
+ 'Value of progress before phase');
+}, 'progress of an infinitely repeating zero-duration animation');
+
+test(function(t) {
+ // Default iterations = 1
+ var div = addDiv(t, {style: 'animation: moveAnimation 0s both'});
+ var anim = div.getAnimations()[0];
+
+ assert_equals(anim.effect.getComputedTiming().progress, 1.0,
+ 'Initial value of progress in after phase');
+
+ // Seek backwards
+ anim.currentTime -= 1 * MS_PER_SEC;
+ assert_equals(anim.effect.getComputedTiming().progress, 0.0,
+ 'Value of progress before phase');
+}, 'progress of a finitely repeating zero-duration animation');
+
+test(function(t) {
+ var div = addDiv(t, {style: 'animation: moveAnimation 0s 5s 10.25 both'});
+ var anim = div.getAnimations()[0];
+
+ assert_equals(anim.effect.getComputedTiming().progress, 0.0,
+ 'Initial value of progress (before phase)');
+
+ // Using iteration duration of 1 now.
+ // currentIteration now is floor(10.25) = 10, so progress should be 25%.
+ anim.finish();
+ assert_equals(anim.effect.getComputedTiming().progress, 0.25,
+ 'Value of progress in after phase');
+}, 'progress of a non-integral repeating zero-duration animation');
+
+test(function(t) {
+ var div = addDiv(t, {style: 'animation: moveAnimation 0s 5s 10.25 both reverse'});
+ var anim = div.getAnimations()[0];
+
+ assert_equals(anim.effect.getComputedTiming().progress, 1.0,
+ 'Initial value of progress (before phase)');
+
+ // Seek forwards
+ anim.finish();
+ assert_equals(anim.effect.getComputedTiming().progress, 0.75,
+ 'Value of progress in after phase');
+}, 'Progress of a non-integral repeating zero-duration animation ' +
+ 'with reversing direction');
+
+test(function(t) {
+ var div = addDiv(t, {style: 'animation: moveAnimation 10s 10.25 both alternate'});
+ var anim = div.getAnimations()[0];
+
+ assert_equals(anim.effect.getComputedTiming().progress, 0.0,
+ 'Initial value of progress');
+ anim.currentTime += 2.5 * MS_PER_SEC;
+ assert_equals(anim.effect.getComputedTiming().progress, 0.25,
+ 'Value of progress');
+ anim.currentTime += 5 * MS_PER_SEC;
+ assert_equals(anim.effect.getComputedTiming().progress, 0.75,
+ 'Value of progress');
+ anim.currentTime += 5 * MS_PER_SEC;
+ assert_equals(anim.effect.getComputedTiming().progress, 0.75,
+ 'Value of progress');
+ anim.finish()
+ assert_equals(anim.effect.getComputedTiming().progress, 0.25,
+ 'Value of progress');
+}, 'progress of a non-integral repeating animation ' +
+ 'with alternate direction');
+
+test(function(t) {
+ var div = addDiv(t, {style: 'animation: moveAnimation 10s 10.25 both alternate-reverse'});
+ var anim = div.getAnimations()[0];
+
+ assert_equals(anim.effect.getComputedTiming().progress, 1.0,
+ 'Initial value of progress');
+ anim.currentTime += 2.5 * MS_PER_SEC;
+ assert_equals(anim.effect.getComputedTiming().progress, 0.75,
+ 'Value of progress');
+ anim.currentTime += 5 * MS_PER_SEC;
+ assert_equals(anim.effect.getComputedTiming().progress, 0.25,
+ 'Value of progress');
+ anim.currentTime += 5 * MS_PER_SEC;
+ assert_equals(anim.effect.getComputedTiming().progress, 0.25,
+ 'Value of progress');
+ anim.finish()
+ assert_equals(anim.effect.getComputedTiming().progress, 0.75,
+ 'Value of progress');
+}, 'progress of a non-integral repeating animation ' +
+ 'with alternate-reversing direction');
+
+test(function(t) {
+ var div = addDiv(t, {style: 'animation: moveAnimation 0s 10.25 both alternate'});
+ var anim = div.getAnimations()[0];
+
+ assert_equals(anim.effect.getComputedTiming().progress, 0.25,
+ 'Initial value of progress');
+ anim.currentTime += 2.5 * MS_PER_SEC;
+ assert_equals(anim.effect.getComputedTiming().progress, 0.25,
+ 'Value of progress');
+ anim.currentTime -= 5 * MS_PER_SEC;
+ assert_equals(anim.effect.getComputedTiming().progress, 0.0,
+ 'Value of progress');
+ anim.finish()
+ assert_equals(anim.effect.getComputedTiming().progress, 0.25,
+ 'Value of progress');
+}, 'progress of a non-integral repeating zero-duration animation ' +
+ 'with alternate direction');
+
+test(function(t) {
+ var div = addDiv(t, {style: 'animation: moveAnimation 0s 10.25 both alternate-reverse'});
+ var anim = div.getAnimations()[0];
+
+ assert_equals(anim.effect.getComputedTiming().progress, 0.75,
+ 'Initial value of progress');
+ anim.currentTime += 2.5 * MS_PER_SEC;
+ assert_equals(anim.effect.getComputedTiming().progress, 0.75,
+ 'Value of progress');
+ anim.currentTime -= 5 * MS_PER_SEC;
+ assert_equals(anim.effect.getComputedTiming().progress, 1.0,
+ 'Value of progress');
+ anim.finish()
+ assert_equals(anim.effect.getComputedTiming().progress, 0.75,
+ 'Value of progress');
+}, 'progress of a non-integral repeating zero-duration animation ' +
+ 'with alternate-reverse direction');
+
+
+// --------------------
+// currentIteration
+// --------------------
+test(function(t) {
+ var div = addDiv(t, {style: 'animation: moveAnimation 100s 2s'});
+ var effect = div.getAnimations()[0].effect;
+ assert_equals(effect.getComputedTiming().currentIteration, null,
+ 'Initial value of currentIteration before phase');
+}, 'currentIteration of a new animation with no backwards fill is unresolved ' +
+ 'in before phase');
+
+test(function(t) {
+ var div = addDiv(t, {style: 'animation: moveAnimation 100s'});
+ var anim = div.getAnimations()[0];
+ assert_equals(anim.effect.getComputedTiming().currentIteration, 0,
+ 'Initial value of currentIteration');
+}, 'currentIteration of a new animation is zero');
+
+test(function(t) {
+ // Note: FillMode here is "both" because
+ // 1. Since this a zero-duration animation, it will already have finished
+ // so it won't be returned by getAnimations() unless it fills forwards.
+ // 2. Fill backwards, so the currentIteration (before phase) wouldn't be
+ // unresolved (null value).
+ var div = addDiv(t, {style: 'animation: moveAnimation 0s infinite both'});
+ var anim = div.getAnimations()[0];
+
+ assert_equals(anim.effect.getComputedTiming().currentIteration, Infinity,
+ 'Initial value of currentIteration in after phase');
+
+ // Seek backwards
+ anim.currentTime -= 2 * MS_PER_SEC;
+ assert_equals(anim.effect.getComputedTiming().currentIteration, 0,
+ 'Value of currentIteration count during before phase');
+}, 'currentIteration of an infinitely repeating zero-duration animation');
+
+test(function(t) {
+ var div = addDiv(t, {style: 'animation: moveAnimation 0s 10.5 both'});
+ var anim = div.getAnimations()[0];
+
+ // Note: currentIteration = ceil(iteration start + iteration count) - 1
+ assert_equals(anim.effect.getComputedTiming().currentIteration, 10,
+ 'Initial value of currentIteration');
+
+ // Seek backwards
+ anim.currentTime -= 2 * MS_PER_SEC;
+ assert_equals(anim.effect.getComputedTiming().currentIteration, 0,
+ 'Value of currentIteration count during before phase');
+}, 'currentIteration of a finitely repeating zero-duration animation');
+
+test(function(t) {
+ var div = addDiv(t, {style: 'animation: moveAnimation 100s 5.5 forwards'});
+ var anim = div.getAnimations()[0];
+
+ assert_equals(anim.effect.getComputedTiming().currentIteration, 0,
+ 'Initial value of currentIteration');
+ // The 3rd iteration
+ // Note: currentIteration = floor(scaled active time / iteration duration)
+ anim.currentTime = 250 * MS_PER_SEC;
+ assert_equals(anim.effect.getComputedTiming().currentIteration, 2,
+ 'Value of currentIteration during the 3rd iteration');
+ // Finish
+ anim.finish();
+ assert_equals(anim.effect.getComputedTiming().currentIteration, 5,
+ 'Value of currentIteration in after phase');
+}, 'currentIteration of an animation with a non-integral iteration count');
+
+test(function(t) {
+ var div = addDiv(t, {style: 'animation: moveAnimation 100s 2 forwards'});
+ var anim = div.getAnimations()[0];
+
+ assert_equals(anim.effect.getComputedTiming().currentIteration, 0,
+ 'Initial value of currentIteration');
+ // Finish
+ anim.finish();
+ assert_equals(anim.effect.getComputedTiming().currentIteration, 1,
+ 'Value of currentIteration in after phase');
+}, 'currentIteration of an animation with an integral iteration count');
+
+test(function(t) {
+ var div = addDiv(t, {style: 'animation: moveAnimation 100s forwards'});
+ var anim = div.getAnimations()[0];
+ assert_equals(anim.effect.getComputedTiming().currentIteration, 0,
+ 'Initial value of currentIteration');
+ // Finish
+ anim.finish();
+ assert_equals(anim.effect.getComputedTiming().currentIteration, 0,
+ 'Value of currentIteration in after phase');
+}, 'currentIteration of an animation with a default iteration count');
+
+test(function(t) {
+ var div = addDiv(t);
+ var effect = new KeyframeEffectReadOnly(div, {left: ["0px", "100px"]});
+
+ assert_equals(effect.getComputedTiming().currentIteration, null,
+ 'currentIteration for orphaned effect');
+}, 'currentIteration of an AnimationEffect without an Animation');
+
+// TODO: If iteration duration is Infinity, currentIteration is 0.
+// However, we cannot set iteration duration to Infinity in CSS Animation now.
+
+done();
+</script>
+</body>