mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-10-08 08:17:31 +09:00
import FIREFOX_52_6_0esr_RELEASE from mozilla-esr52 hg repo
This commit is contained in:
commit
dcd9973243
150858 changed files with 23884658 additions and 0 deletions
|
|
@ -0,0 +1,142 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset=utf-8>
|
||||
<title>Active time tests</title>
|
||||
<link rel="help" href="https://w3c.github.io/web-animations/#calculating-the-active-time">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="../../testcommon.js"></script>
|
||||
<body>
|
||||
<div id="log"></div>
|
||||
<script>
|
||||
'use strict';
|
||||
|
||||
test(function(t) {
|
||||
var tests = [ { fill: 'none', progress: null },
|
||||
{ fill: 'backwards', progress: 0 },
|
||||
{ fill: 'forwards', progress: null },
|
||||
{ fill: 'both', progress: 0 } ];
|
||||
tests.forEach(function(test) {
|
||||
var anim = createDiv(t).animate(null, { delay: 1, fill: test.fill });
|
||||
assert_equals(anim.effect.getComputedTiming().progress, test.progress,
|
||||
'Progress in before phase when using \'' + test.fill
|
||||
+ '\' fill');
|
||||
});
|
||||
}, 'Active time in before phase');
|
||||
|
||||
test(function(t) {
|
||||
var anim = createDiv(t).animate(null, 1000);
|
||||
anim.currentTime = 500;
|
||||
assert_times_equal(anim.effect.getComputedTiming().progress, 0.5);
|
||||
}, 'Active time in active phase and no start delay is the local time');
|
||||
|
||||
test(function(t) {
|
||||
var anim = createDiv(t).animate(null, { duration: 1000, delay: 500 });
|
||||
anim.currentTime = 1000;
|
||||
assert_times_equal(anim.effect.getComputedTiming().progress, 0.5);
|
||||
}, 'Active time in active phase and positive start delay is the local time'
|
||||
+ ' minus the start delay');
|
||||
|
||||
test(function(t) {
|
||||
var anim = createDiv(t).animate(null, { duration: 1000, delay: -500 });
|
||||
assert_times_equal(anim.effect.getComputedTiming().progress, 0.5);
|
||||
}, 'Active time in active phase and negative start delay is the local time'
|
||||
+ ' minus the start delay');
|
||||
|
||||
test(function(t) {
|
||||
var anim = createDiv(t).animate(null);
|
||||
assert_equals(anim.effect.getComputedTiming().progress, null);
|
||||
}, 'Active time in after phase with no fill is unresolved');
|
||||
|
||||
test(function(t) {
|
||||
var anim = createDiv(t).animate(null, { fill: 'backwards' });
|
||||
assert_equals(anim.effect.getComputedTiming().progress, null);
|
||||
}, 'Active time in after phase with backwards-only fill is unresolved');
|
||||
|
||||
test(function(t) {
|
||||
var anim = createDiv(t).animate(null, { duration: 1000,
|
||||
iterations: 2.3,
|
||||
delay: 500, // Should have no effect
|
||||
fill: 'forwards' });
|
||||
anim.finish();
|
||||
assert_equals(anim.effect.getComputedTiming().currentIteration, 2);
|
||||
assert_times_equal(anim.effect.getComputedTiming().progress, 0.3);
|
||||
}, 'Active time in after phase with forwards fill is the active duration');
|
||||
|
||||
test(function(t) {
|
||||
var anim = createDiv(t).animate(null, { duration: 0,
|
||||
iterations: Infinity,
|
||||
fill: 'forwards' });
|
||||
anim.finish();
|
||||
assert_equals(anim.effect.getComputedTiming().currentIteration, Infinity);
|
||||
assert_equals(anim.effect.getComputedTiming().progress, 1);
|
||||
}, 'Active time in after phase with forwards fill, zero-duration, and '
|
||||
+ ' infinite iteration count is the active duration');
|
||||
|
||||
test(function(t) {
|
||||
var anim = createDiv(t).animate(null, { duration: 1000,
|
||||
iterations: 2.3,
|
||||
delay: 500,
|
||||
endDelay: 4000,
|
||||
fill: 'forwards' });
|
||||
anim.finish();
|
||||
assert_equals(anim.effect.getComputedTiming().currentIteration, 2);
|
||||
assert_times_equal(anim.effect.getComputedTiming().progress, 0.3);
|
||||
}, 'Active time in after phase with forwards fill and positive end delay'
|
||||
+ ' is the active duration');
|
||||
|
||||
test(function(t) {
|
||||
var anim = createDiv(t).animate(null, { duration: 1000,
|
||||
iterations: 2.3,
|
||||
delay: 500,
|
||||
endDelay: -800,
|
||||
fill: 'forwards' });
|
||||
anim.finish();
|
||||
assert_equals(anim.effect.getComputedTiming().currentIteration, 1);
|
||||
assert_times_equal(anim.effect.getComputedTiming().progress, 0.5);
|
||||
}, 'Active time in after phase with forwards fill and negative end delay'
|
||||
+ ' is the active duration + end delay');
|
||||
|
||||
test(function(t) {
|
||||
var anim = createDiv(t).animate(null, { duration: 1000,
|
||||
iterations: 2.3,
|
||||
delay: 500,
|
||||
endDelay: -2500,
|
||||
fill: 'forwards' });
|
||||
anim.finish();
|
||||
assert_equals(anim.effect.getComputedTiming().currentIteration, 0);
|
||||
assert_equals(anim.effect.getComputedTiming().progress, 0);
|
||||
}, 'Active time in after phase with forwards fill and negative end delay'
|
||||
+ ' greater in magnitude than the active duration is zero');
|
||||
|
||||
test(function(t) {
|
||||
var anim = createDiv(t).animate(null, { duration: 1000,
|
||||
iterations: 2.3,
|
||||
delay: 500,
|
||||
endDelay: -4000,
|
||||
fill: 'forwards' });
|
||||
anim.finish();
|
||||
assert_equals(anim.effect.getComputedTiming().currentIteration, 0);
|
||||
assert_equals(anim.effect.getComputedTiming().progress, 0);
|
||||
}, 'Active time in after phase with forwards fill and negative end delay'
|
||||
+ ' greater in magnitude than the sum of the active duration and start delay'
|
||||
+ ' is zero');
|
||||
|
||||
test(function(t) {
|
||||
var anim = createDiv(t).animate(null, { duration: 1000,
|
||||
iterations: 2.3,
|
||||
delay: 500,
|
||||
fill: 'both' });
|
||||
anim.finish();
|
||||
assert_equals(anim.effect.getComputedTiming().currentIteration, 2);
|
||||
assert_times_equal(anim.effect.getComputedTiming().progress, 0.3);
|
||||
}, 'Active time in after phase with \'both\' fill is the active duration');
|
||||
|
||||
test(function(t) {
|
||||
// Create an effect with a non-zero duration so we ensure we're not just
|
||||
// testing the after-phase behavior.
|
||||
var effect = new KeyframeEffect(null, null, 1);
|
||||
assert_equals(effect.getComputedTiming().progress, null);
|
||||
}, 'Active time when the local time is unresolved, is unresolved');
|
||||
|
||||
</script>
|
||||
</body>
|
||||
|
|
@ -0,0 +1,584 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset=utf-8>
|
||||
<title>Current iteration tests</title>
|
||||
<link rel="help" href="https://w3c.github.io/web-animations/#current-iteration">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="../../testcommon.js"></script>
|
||||
<body>
|
||||
<div id="log"></div>
|
||||
<script>
|
||||
'use strict';
|
||||
|
||||
function runTests(tests, description) {
|
||||
tests.forEach(function(currentTest) {
|
||||
var testParams = '';
|
||||
for (var attr in currentTest.input) {
|
||||
testParams += ' ' + attr + ':' + currentTest.input[attr];
|
||||
}
|
||||
test(function(t) {
|
||||
var div = createDiv(t);
|
||||
var anim = div.animate({ opacity: [ 0, 1 ] }, currentTest.input);
|
||||
assert_equals(anim.effect.getComputedTiming().currentIteration,
|
||||
currentTest.before);
|
||||
anim.currentTime = currentTest.input.delay || 0;
|
||||
assert_equals(anim.effect.getComputedTiming().currentIteration,
|
||||
currentTest.active);
|
||||
if (typeof currentTest.after !== 'undefined') {
|
||||
anim.finish();
|
||||
assert_equals(anim.effect.getComputedTiming().currentIteration,
|
||||
currentTest.after);
|
||||
}
|
||||
}, description + ':' + testParams);
|
||||
});
|
||||
}
|
||||
|
||||
async_test(function(t) {
|
||||
var div = createDiv(t);
|
||||
var anim = div.animate({ opacity: [ 0, 1 ] }, { delay: 1 });
|
||||
assert_equals(anim.effect.getComputedTiming().currentIteration, null);
|
||||
anim.finished.then(t.step_func(function() {
|
||||
assert_equals(anim.effect.getComputedTiming().currentIteration, null);
|
||||
t.done();
|
||||
}));
|
||||
}, 'Test currentIteration during before and after phase when fill is none');
|
||||
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
//
|
||||
// Zero iteration duration tests
|
||||
//
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
runTests([
|
||||
{
|
||||
input: { iterations: 0,
|
||||
iterationStart: 0,
|
||||
duration: 0,
|
||||
delay: 1,
|
||||
fill: 'both' },
|
||||
before: 0,
|
||||
active: 0,
|
||||
after: 0
|
||||
},
|
||||
|
||||
{
|
||||
input: { iterations: 0,
|
||||
iterationStart: 0,
|
||||
duration: 100,
|
||||
delay: 1,
|
||||
fill: 'both' },
|
||||
before: 0,
|
||||
active: 0,
|
||||
after: 0
|
||||
},
|
||||
|
||||
{
|
||||
input: { iterations: 0,
|
||||
iterationStart: 0,
|
||||
duration: Infinity,
|
||||
delay: 1,
|
||||
fill: 'both' },
|
||||
before: 0,
|
||||
active: 0,
|
||||
after: 0
|
||||
},
|
||||
|
||||
{
|
||||
input: { iterations: 0,
|
||||
iterationStart: 2.5,
|
||||
duration: 0,
|
||||
delay: 1,
|
||||
fill: 'both' },
|
||||
before: 2,
|
||||
active: 2,
|
||||
after: 2
|
||||
},
|
||||
|
||||
{
|
||||
input: { iterations: 0,
|
||||
iterationStart: 2.5,
|
||||
duration: 100,
|
||||
delay: 1,
|
||||
fill: 'both' },
|
||||
before: 2,
|
||||
active: 2,
|
||||
after: 2
|
||||
},
|
||||
|
||||
{
|
||||
input: { iterations: 0,
|
||||
iterationStart: 2.5,
|
||||
duration: Infinity,
|
||||
delay: 1,
|
||||
fill: 'both' },
|
||||
before: 2,
|
||||
active: 2,
|
||||
after: 2
|
||||
},
|
||||
|
||||
{
|
||||
input: { iterations: 0,
|
||||
iterationStart: 3,
|
||||
duration: 0,
|
||||
delay: 1,
|
||||
fill: 'both' },
|
||||
before: 3,
|
||||
active: 3,
|
||||
after: 3
|
||||
},
|
||||
|
||||
{
|
||||
input: { iterations: 0,
|
||||
iterationStart: 3,
|
||||
duration: 100,
|
||||
delay: 1,
|
||||
fill: 'both' },
|
||||
before: 3,
|
||||
active: 3,
|
||||
after: 3
|
||||
},
|
||||
|
||||
{
|
||||
input: { iterations: 0,
|
||||
iterationStart: 3,
|
||||
duration: Infinity,
|
||||
delay: 1,
|
||||
fill: 'both' },
|
||||
before: 3,
|
||||
active: 3,
|
||||
after: 3
|
||||
}
|
||||
], 'Test zero iterations');
|
||||
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
//
|
||||
// Tests where the iteration count is an integer
|
||||
//
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
runTests([
|
||||
{
|
||||
input: { iterations: 3,
|
||||
iterationStart: 0,
|
||||
duration: 0,
|
||||
delay: 1,
|
||||
fill: 'both' },
|
||||
before: 0,
|
||||
active: 2,
|
||||
after: 2
|
||||
},
|
||||
|
||||
{
|
||||
input: { iterations: 3,
|
||||
iterationStart: 0,
|
||||
duration: 100,
|
||||
delay: 1,
|
||||
fill: 'both' },
|
||||
before: 0,
|
||||
active: 0,
|
||||
after: 2
|
||||
},
|
||||
|
||||
{
|
||||
input: { iterations: 3,
|
||||
iterationStart: 0,
|
||||
duration: Infinity,
|
||||
delay: 1,
|
||||
fill: 'both' },
|
||||
before: 0,
|
||||
active: 0
|
||||
},
|
||||
|
||||
{
|
||||
input: { iterations: 3,
|
||||
iterationStart: 2.5,
|
||||
duration: 0,
|
||||
delay: 1,
|
||||
fill: 'both' },
|
||||
before: 2,
|
||||
active: 5,
|
||||
after: 5
|
||||
},
|
||||
|
||||
{
|
||||
input: { iterations: 3,
|
||||
iterationStart: 2.5,
|
||||
duration: 100,
|
||||
delay: 1,
|
||||
fill: 'both' },
|
||||
before: 2,
|
||||
active: 2,
|
||||
after: 5
|
||||
},
|
||||
|
||||
{
|
||||
input: { iterations: 3,
|
||||
iterationStart: 2.5,
|
||||
duration: Infinity,
|
||||
delay: 1,
|
||||
fill: 'both' },
|
||||
before: 2,
|
||||
active: 2
|
||||
},
|
||||
|
||||
{
|
||||
input: { iterations: 3,
|
||||
iterationStart: 3,
|
||||
duration: 0,
|
||||
delay: 1,
|
||||
fill: 'both' },
|
||||
before: 3,
|
||||
active: 5,
|
||||
after: 5
|
||||
},
|
||||
|
||||
{
|
||||
input: { iterations: 3,
|
||||
iterationStart: 3,
|
||||
duration: 100,
|
||||
delay: 1,
|
||||
fill: 'both' },
|
||||
before: 3,
|
||||
active: 3,
|
||||
after: 5
|
||||
},
|
||||
|
||||
{
|
||||
input: { iterations: 3,
|
||||
iterationStart: 3,
|
||||
duration: Infinity,
|
||||
delay: 1,
|
||||
fill: 'both' },
|
||||
before: 3,
|
||||
active: 3
|
||||
}
|
||||
], 'Test integer iterations');
|
||||
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
//
|
||||
// Tests where the iteration count is a fraction
|
||||
//
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
runTests([
|
||||
{
|
||||
input: { iterations: 3.5,
|
||||
iterationStart: 0,
|
||||
duration: 0,
|
||||
delay: 1,
|
||||
fill: 'both' },
|
||||
before: 0,
|
||||
active: 3,
|
||||
after: 3
|
||||
},
|
||||
|
||||
{
|
||||
input: { iterations: 3.5,
|
||||
iterationStart: 0,
|
||||
duration: 100,
|
||||
delay: 1,
|
||||
fill: 'both' },
|
||||
before: 0,
|
||||
active: 0,
|
||||
after: 3
|
||||
},
|
||||
|
||||
{
|
||||
input: { iterations: 3.5,
|
||||
iterationStart: 0,
|
||||
duration: Infinity,
|
||||
delay: 1,
|
||||
fill: 'both' },
|
||||
before: 0,
|
||||
active: 0
|
||||
},
|
||||
|
||||
{
|
||||
input: { iterations: 3.5,
|
||||
iterationStart: 2.5,
|
||||
duration: 0,
|
||||
delay: 1,
|
||||
fill: 'both' },
|
||||
before: 2,
|
||||
active: 5,
|
||||
after: 5
|
||||
},
|
||||
|
||||
{
|
||||
input: { iterations: 3.5,
|
||||
iterationStart: 2.5,
|
||||
duration: 100,
|
||||
delay: 1,
|
||||
fill: 'both' },
|
||||
before: 2,
|
||||
active: 2,
|
||||
after: 5
|
||||
},
|
||||
|
||||
{
|
||||
input: { iterations: 3.5,
|
||||
iterationStart: 2.5,
|
||||
duration: Infinity,
|
||||
delay: 1,
|
||||
fill: 'both' },
|
||||
before: 2,
|
||||
active: 2
|
||||
},
|
||||
|
||||
{
|
||||
input: { iterations: 3.5,
|
||||
iterationStart: 3,
|
||||
duration: 0,
|
||||
delay: 1,
|
||||
fill: 'both' },
|
||||
before: 3,
|
||||
active: 6,
|
||||
after: 6
|
||||
},
|
||||
|
||||
{
|
||||
input: { iterations: 3.5,
|
||||
iterationStart: 3,
|
||||
duration: 100,
|
||||
delay: 1,
|
||||
fill: 'both' },
|
||||
before: 3,
|
||||
active: 3,
|
||||
after: 6
|
||||
},
|
||||
|
||||
{
|
||||
input: { iterations: 3.5,
|
||||
iterationStart: 3,
|
||||
duration: Infinity,
|
||||
delay: 1,
|
||||
fill: 'both' },
|
||||
before: 3,
|
||||
active: 3
|
||||
}
|
||||
], 'Test fractional iterations');
|
||||
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
//
|
||||
// Tests where the iteration count is Infinity
|
||||
//
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
runTests([
|
||||
{
|
||||
input: { iterations: Infinity,
|
||||
iterationStart: 0,
|
||||
duration: 0,
|
||||
delay: 1,
|
||||
fill: 'both' },
|
||||
before: 0,
|
||||
active: Infinity,
|
||||
after: Infinity
|
||||
},
|
||||
|
||||
{
|
||||
input: { iterations: Infinity,
|
||||
iterationStart: 0,
|
||||
duration: 100,
|
||||
delay: 1,
|
||||
fill: 'both' },
|
||||
before: 0,
|
||||
active: 0
|
||||
},
|
||||
|
||||
{
|
||||
input: { iterations: Infinity,
|
||||
iterationStart: 0,
|
||||
duration: Infinity,
|
||||
delay: 1,
|
||||
fill: 'both' },
|
||||
before: 0,
|
||||
active: 0
|
||||
},
|
||||
|
||||
{
|
||||
input: { iterations: Infinity,
|
||||
iterationStart: 2.5,
|
||||
duration: 0,
|
||||
delay: 1,
|
||||
fill: 'both' },
|
||||
before: 2,
|
||||
active: Infinity,
|
||||
after: Infinity
|
||||
},
|
||||
|
||||
{
|
||||
input: { iterations: Infinity,
|
||||
iterationStart: 2.5,
|
||||
duration: 100,
|
||||
delay: 1,
|
||||
fill: 'both' },
|
||||
before: 2,
|
||||
active: 2
|
||||
},
|
||||
|
||||
{
|
||||
input: { iterations: Infinity,
|
||||
iterationStart: 2.5,
|
||||
duration: Infinity,
|
||||
delay: 1,
|
||||
fill: 'both' },
|
||||
before: 2,
|
||||
active: 2
|
||||
},
|
||||
|
||||
{
|
||||
input: { iterations: Infinity,
|
||||
iterationStart: 3,
|
||||
duration: 0,
|
||||
delay: 1,
|
||||
fill: 'both' },
|
||||
before: 3,
|
||||
active: Infinity,
|
||||
after: Infinity
|
||||
},
|
||||
|
||||
{
|
||||
input: { iterations: Infinity,
|
||||
iterationStart: 3,
|
||||
duration: 100,
|
||||
delay: 1,
|
||||
fill: 'both' },
|
||||
before: 3,
|
||||
active: 3
|
||||
},
|
||||
|
||||
{
|
||||
input: { iterations: Infinity,
|
||||
iterationStart: 3,
|
||||
duration: Infinity,
|
||||
delay: 1,
|
||||
fill: 'both' },
|
||||
before: 3,
|
||||
active: 3
|
||||
}
|
||||
], 'Test infinity iterations');
|
||||
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
//
|
||||
// End delay tests
|
||||
//
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
runTests([
|
||||
{
|
||||
input: { duration: 100,
|
||||
delay: 1,
|
||||
fill: 'both',
|
||||
endDelay: 50 },
|
||||
before: 0,
|
||||
active: 0,
|
||||
after: 0
|
||||
},
|
||||
|
||||
{
|
||||
input: { duration: 100,
|
||||
delay: 1,
|
||||
fill: 'both',
|
||||
endDelay: -50 },
|
||||
before: 0,
|
||||
active: 0,
|
||||
after: 0
|
||||
},
|
||||
|
||||
{
|
||||
input: { duration: 100,
|
||||
delay: 1,
|
||||
fill: 'both',
|
||||
endDelay: -100 },
|
||||
before: 0,
|
||||
active: 0,
|
||||
after: 0
|
||||
},
|
||||
|
||||
{
|
||||
input: { duration: 100,
|
||||
delay: 1,
|
||||
fill: 'both',
|
||||
endDelay: -200 },
|
||||
before: 0,
|
||||
active: 0,
|
||||
after: 0
|
||||
},
|
||||
|
||||
{
|
||||
input: { iterationStart: 0.5,
|
||||
duration: 100,
|
||||
delay: 1,
|
||||
fill: 'both',
|
||||
endDelay: 50 },
|
||||
before: 0,
|
||||
active: 0,
|
||||
after: 1
|
||||
},
|
||||
|
||||
{
|
||||
input: { iterationStart: 0.5,
|
||||
duration: 100,
|
||||
delay: 1,
|
||||
fill: 'both',
|
||||
endDelay: -50 },
|
||||
before: 0,
|
||||
active: 0,
|
||||
after: 0
|
||||
},
|
||||
|
||||
{
|
||||
input: { iterationStart: 0.5,
|
||||
duration: 100,
|
||||
delay: 1,
|
||||
fill: 'both',
|
||||
endDelay: -100 },
|
||||
before: 0,
|
||||
active: 0,
|
||||
after: 0
|
||||
},
|
||||
|
||||
{
|
||||
input: { iterations: 2,
|
||||
duration: 100,
|
||||
delay: 1,
|
||||
fill: 'both',
|
||||
endDelay: -100 },
|
||||
before: 0,
|
||||
active: 0,
|
||||
after: 0
|
||||
},
|
||||
|
||||
{
|
||||
input: { iterations: 1,
|
||||
iterationStart: 2,
|
||||
duration: 100,
|
||||
delay: 1,
|
||||
fill: 'both',
|
||||
endDelay: -50 },
|
||||
before: 2,
|
||||
active: 2,
|
||||
after: 2
|
||||
},
|
||||
|
||||
{
|
||||
input: { iterations: 1,
|
||||
iterationStart: 2,
|
||||
duration: 100,
|
||||
delay: 1,
|
||||
fill: 'both',
|
||||
endDelay: -100 },
|
||||
before: 2,
|
||||
active: 2,
|
||||
after: 2
|
||||
},
|
||||
], 'Test end delay');
|
||||
|
||||
</script>
|
||||
</body>
|
||||
|
|
@ -0,0 +1,191 @@
|
|||
<!doctype html>
|
||||
<meta charset=utf-8>
|
||||
<title>Tests for phases and states</title>
|
||||
<link rel="help" href="https://w3c.github.io/web-animations/#animation-effect-phases-and-states">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="../../testcommon.js"></script>
|
||||
<body>
|
||||
<div id="log"></div>
|
||||
<script>
|
||||
'use strict';
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
//
|
||||
// Phases
|
||||
//
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
function assert_phase_at_time(animation, phase, currentTime) {
|
||||
animation.currentTime = currentTime;
|
||||
|
||||
if (phase === 'active') {
|
||||
// If the fill mode is 'none', then progress will only be non-null if we
|
||||
// are in the active phase.
|
||||
animation.effect.timing.fill = 'none';
|
||||
assert_not_equals(animation.effect.getComputedTiming().progress, null,
|
||||
'Animation effect is in active phase when current time'
|
||||
+ ' is ' + currentTime + 'ms');
|
||||
} else {
|
||||
// The easiest way to distinguish between the 'before' phase and the 'after'
|
||||
// phase is to toggle the fill mode. For example, if the progress is null
|
||||
// will the fill node is 'none' but non-null when the fill mode is
|
||||
// 'backwards' then we are in the before phase.
|
||||
animation.effect.timing.fill = 'none';
|
||||
assert_equals(animation.effect.getComputedTiming().progress, null,
|
||||
'Animation effect is in ' + phase + ' phase when current time'
|
||||
+ ' is ' + currentTime + 'ms'
|
||||
+ ' (progress is null with \'none\' fill mode)');
|
||||
|
||||
animation.effect.timing.fill = phase === 'before'
|
||||
? 'backwards'
|
||||
: 'forwards';
|
||||
assert_not_equals(animation.effect.getComputedTiming().progress, null,
|
||||
'Animation effect is in ' + phase + ' phase when current'
|
||||
+ ' time is ' + currentTime + 'ms'
|
||||
+ ' (progress is non-null with appropriate fill mode)');
|
||||
}
|
||||
}
|
||||
|
||||
test(function(t) {
|
||||
var animation = createDiv(t).animate(null, 1);
|
||||
|
||||
[ { currentTime: -1, phase: 'before' },
|
||||
{ currentTime: 0, phase: 'active' },
|
||||
{ currentTime: 1, phase: 'after' } ]
|
||||
.forEach(function(test) {
|
||||
assert_phase_at_time(animation, test.phase, test.currentTime);
|
||||
});
|
||||
}, 'Phase calculation for a simple animation effect');
|
||||
|
||||
test(function(t) {
|
||||
var animation = createDiv(t).animate(null, { duration: 1, delay: 1 });
|
||||
|
||||
[ { currentTime: 0, phase: 'before' },
|
||||
{ currentTime: 1, phase: 'active' },
|
||||
{ currentTime: 2, phase: 'after' } ]
|
||||
.forEach(function(test) {
|
||||
assert_phase_at_time(animation, test.phase, test.currentTime);
|
||||
});
|
||||
}, 'Phase calculation for an animation effect with a positive start delay');
|
||||
|
||||
test(function(t) {
|
||||
var animation = createDiv(t).animate(null, { duration: 1, delay: -1 });
|
||||
|
||||
[ { currentTime: -2, phase: 'before' },
|
||||
{ currentTime: -1, phase: 'before' },
|
||||
{ currentTime: 0, phase: 'after' } ]
|
||||
.forEach(function(test) {
|
||||
assert_phase_at_time(animation, test.phase, test.currentTime);
|
||||
});
|
||||
}, 'Phase calculation for an animation effect with a negative start delay');
|
||||
|
||||
test(function(t) {
|
||||
var animation = createDiv(t).animate(null, { duration: 1, endDelay: 1 });
|
||||
|
||||
[ { currentTime: -1, phase: 'before' },
|
||||
{ currentTime: 0, phase: 'active' },
|
||||
{ currentTime: 1, phase: 'after' },
|
||||
{ currentTime: 2, phase: 'after' } ]
|
||||
.forEach(function(test) {
|
||||
assert_phase_at_time(animation, test.phase, test.currentTime);
|
||||
});
|
||||
}, 'Phase calculation for an animation effect with a positive end delay');
|
||||
|
||||
test(function(t) {
|
||||
var animation = createDiv(t).animate(null, { duration: 2, endDelay: -1 });
|
||||
|
||||
[ { currentTime: -1, phase: 'before' },
|
||||
{ currentTime: 0, phase: 'active' },
|
||||
{ currentTime: 0.9, phase: 'active' },
|
||||
{ currentTime: 1, phase: 'after' } ]
|
||||
.forEach(function(test) {
|
||||
assert_phase_at_time(animation, test.phase, test.currentTime);
|
||||
});
|
||||
}, 'Phase calculation for an animation effect with a negative end delay lesser'
|
||||
+ ' in magnitude than the active duration');
|
||||
|
||||
test(function(t) {
|
||||
var animation = createDiv(t).animate(null, { duration: 1, endDelay: -1 });
|
||||
|
||||
[ { currentTime: -1, phase: 'before' },
|
||||
{ currentTime: 0, phase: 'after' },
|
||||
{ currentTime: 1, phase: 'after' } ]
|
||||
.forEach(function(test) {
|
||||
assert_phase_at_time(animation, test.phase, test.currentTime);
|
||||
});
|
||||
}, 'Phase calculation for an animation effect with a negative end delay equal'
|
||||
+ ' in magnitude to the active duration');
|
||||
|
||||
test(function(t) {
|
||||
var animation = createDiv(t).animate(null, { duration: 1, endDelay: -2 });
|
||||
|
||||
[ { currentTime: -2, phase: 'before' },
|
||||
{ currentTime: -1, phase: 'before' },
|
||||
{ currentTime: 0, phase: 'after' } ]
|
||||
.forEach(function(test) {
|
||||
assert_phase_at_time(animation, test.phase, test.currentTime);
|
||||
});
|
||||
}, 'Phase calculation for an animation effect with a negative end delay'
|
||||
+ ' greater in magnitude than the active duration');
|
||||
|
||||
test(function(t) {
|
||||
var animation = createDiv(t).animate(null, { duration: 2,
|
||||
delay: 1,
|
||||
endDelay: -1 });
|
||||
|
||||
[ { currentTime: 0, phase: 'before' },
|
||||
{ currentTime: 1, phase: 'active' },
|
||||
{ currentTime: 2, phase: 'after' } ]
|
||||
.forEach(function(test) {
|
||||
assert_phase_at_time(animation, test.phase, test.currentTime);
|
||||
});
|
||||
}, 'Phase calculation for an animation effect with a positive start delay'
|
||||
+ ' and a negative end delay lesser in magnitude than the active duration');
|
||||
|
||||
test(function(t) {
|
||||
var animation = createDiv(t).animate(null, { duration: 1,
|
||||
delay: -1,
|
||||
endDelay: -1 });
|
||||
|
||||
[ { currentTime: -2, phase: 'before' },
|
||||
{ currentTime: -1, phase: 'before' },
|
||||
{ currentTime: 0, phase: 'after' } ]
|
||||
.forEach(function(test) {
|
||||
assert_phase_at_time(animation, test.phase, test.currentTime);
|
||||
});
|
||||
}, 'Phase calculation for an animation effect with a negative start delay'
|
||||
+ ' and a negative end delay equal in magnitude to the active duration');
|
||||
|
||||
test(function(t) {
|
||||
var animation = createDiv(t).animate(null, { duration: 1,
|
||||
delay: -1,
|
||||
endDelay: -2 });
|
||||
|
||||
[ { currentTime: -3, phase: 'before' },
|
||||
{ currentTime: -2, phase: 'before' },
|
||||
{ currentTime: -1, phase: 'before' },
|
||||
{ currentTime: 0, phase: 'after' } ]
|
||||
.forEach(function(test) {
|
||||
assert_phase_at_time(animation, test.phase, test.currentTime);
|
||||
});
|
||||
}, 'Phase calculation for an animation effect with a negative start delay'
|
||||
+ ' and a negative end delay equal greater in magnitude than the active'
|
||||
+ ' duration');
|
||||
|
||||
test(function(t) {
|
||||
var animation = createDiv(t).animate(null, 1);
|
||||
animation.playbackRate = -1;
|
||||
|
||||
[ { currentTime: -1, phase: 'before' },
|
||||
{ currentTime: 0, phase: 'before' },
|
||||
{ currentTime: 1, phase: 'active' },
|
||||
{ currentTime: 2, phase: 'after' } ]
|
||||
.forEach(function(test) {
|
||||
assert_phase_at_time(animation, test.phase, test.currentTime);
|
||||
});
|
||||
}, 'Phase calculation for a simple animation effect with negative playback'
|
||||
+ ' rate');
|
||||
|
||||
</script>
|
||||
</body>
|
||||
|
|
@ -0,0 +1,575 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset=utf-8>
|
||||
<title>Simple iteration progress tests</title>
|
||||
<link rel="help"
|
||||
href="https://w3c.github.io/web-animations/#simple-iteration-progress">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="../../testcommon.js"></script>
|
||||
<body>
|
||||
<div id="log"></div>
|
||||
<script>
|
||||
'use strict';
|
||||
|
||||
function runTests(tests, description) {
|
||||
tests.forEach(function(currentTest) {
|
||||
var testParams = '';
|
||||
for (var attr in currentTest.input) {
|
||||
testParams += ' ' + attr + ':' + currentTest.input[attr];
|
||||
}
|
||||
test(function(t) {
|
||||
var div = createDiv(t);
|
||||
var anim = div.animate({ opacity: [ 0, 1 ] }, currentTest.input);
|
||||
assert_equals(anim.effect.getComputedTiming().progress,
|
||||
currentTest.before);
|
||||
anim.currentTime = currentTest.input.delay || 0;
|
||||
assert_equals(anim.effect.getComputedTiming().progress,
|
||||
currentTest.active);
|
||||
if (typeof currentTest.after !== 'undefined') {
|
||||
anim.finish();
|
||||
assert_equals(anim.effect.getComputedTiming().progress,
|
||||
currentTest.after);
|
||||
}
|
||||
}, description + ':' + testParams);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
//
|
||||
// Zero iteration duration tests
|
||||
//
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
runTests([
|
||||
{
|
||||
input: { iterations: 0,
|
||||
iterationStart: 0,
|
||||
duration: 0,
|
||||
delay: 1,
|
||||
fill: 'both' },
|
||||
before: 0,
|
||||
active: 0,
|
||||
after: 0
|
||||
},
|
||||
|
||||
{
|
||||
input: { iterations: 0,
|
||||
iterationStart: 0,
|
||||
duration: 100,
|
||||
delay: 1,
|
||||
fill: 'both' },
|
||||
before: 0,
|
||||
active: 0,
|
||||
after: 0
|
||||
},
|
||||
|
||||
{
|
||||
input: { iterations: 0,
|
||||
iterationStart: 0,
|
||||
duration: Infinity,
|
||||
delay: 1,
|
||||
fill: 'both' },
|
||||
before: 0,
|
||||
active: 0,
|
||||
after: 0
|
||||
},
|
||||
|
||||
{
|
||||
input: { iterations: 0,
|
||||
iterationStart: 2.5,
|
||||
duration: 0,
|
||||
delay: 1,
|
||||
fill: 'both' },
|
||||
before: 0.5,
|
||||
active: 0.5,
|
||||
after: 0.5
|
||||
},
|
||||
|
||||
{
|
||||
input: { iterations: 0,
|
||||
iterationStart: 2.5,
|
||||
duration: 100,
|
||||
delay: 1,
|
||||
fill: 'both' },
|
||||
before: 0.5,
|
||||
active: 0.5,
|
||||
after: 0.5
|
||||
},
|
||||
|
||||
{
|
||||
input: { iterations: 0,
|
||||
iterationStart: 2.5,
|
||||
duration: Infinity,
|
||||
delay: 1,
|
||||
fill: 'both' },
|
||||
before: 0.5,
|
||||
active: 0.5,
|
||||
after: 0.5
|
||||
},
|
||||
|
||||
{
|
||||
input: { iterations: 0,
|
||||
iterationStart: 3,
|
||||
duration: 0,
|
||||
delay: 1,
|
||||
fill: 'both' },
|
||||
before: 0,
|
||||
active: 0,
|
||||
after: 0
|
||||
},
|
||||
|
||||
{
|
||||
input: { iterations: 0,
|
||||
iterationStart: 3,
|
||||
duration: 100,
|
||||
delay: 1,
|
||||
fill: 'both' },
|
||||
before: 0,
|
||||
active: 0,
|
||||
after: 0
|
||||
},
|
||||
|
||||
{
|
||||
input: { iterations: 0,
|
||||
iterationStart: 3,
|
||||
duration: Infinity,
|
||||
delay: 1,
|
||||
fill: 'both' },
|
||||
before: 0,
|
||||
active: 0,
|
||||
after: 0
|
||||
}
|
||||
], 'Test zero iterations');
|
||||
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
//
|
||||
// Tests where the iteration count is an integer
|
||||
//
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
runTests([
|
||||
{
|
||||
input: { iterations: 3,
|
||||
iterationStart: 0,
|
||||
duration: 0,
|
||||
delay: 1,
|
||||
fill: 'both' },
|
||||
before: 0,
|
||||
active: 1,
|
||||
after: 1
|
||||
},
|
||||
|
||||
{
|
||||
input: { iterations: 3,
|
||||
iterationStart: 0,
|
||||
duration: 100,
|
||||
delay: 1,
|
||||
fill: 'both' },
|
||||
before: 0,
|
||||
active: 0,
|
||||
after: 1
|
||||
},
|
||||
|
||||
{
|
||||
input: { iterations: 3,
|
||||
iterationStart: 0,
|
||||
duration: Infinity,
|
||||
delay: 1,
|
||||
fill: 'both' },
|
||||
before: 0,
|
||||
active: 0
|
||||
},
|
||||
|
||||
{
|
||||
input: { iterations: 3,
|
||||
iterationStart: 2.5,
|
||||
duration: 0,
|
||||
delay: 1,
|
||||
fill: 'both' },
|
||||
before: 0.5,
|
||||
active: 0.5,
|
||||
after: 0.5
|
||||
},
|
||||
|
||||
{
|
||||
input: { iterations: 3,
|
||||
iterationStart: 2.5,
|
||||
duration: 100,
|
||||
delay: 1,
|
||||
fill: 'both' },
|
||||
before: 0.5,
|
||||
active: 0.5,
|
||||
after: 0.5
|
||||
},
|
||||
|
||||
{
|
||||
input: { iterations: 3,
|
||||
iterationStart: 2.5,
|
||||
duration: Infinity,
|
||||
delay: 1,
|
||||
fill: 'both' },
|
||||
before: 0.5,
|
||||
active: 0.5
|
||||
},
|
||||
|
||||
{
|
||||
input: { iterations: 3,
|
||||
iterationStart: 3,
|
||||
duration: 0,
|
||||
delay: 1,
|
||||
fill: 'both' },
|
||||
before: 0,
|
||||
active: 1,
|
||||
after: 1
|
||||
},
|
||||
|
||||
{
|
||||
input: { iterations: 3,
|
||||
iterationStart: 3,
|
||||
duration: 100,
|
||||
delay: 1,
|
||||
fill: 'both' },
|
||||
before: 0,
|
||||
active: 0,
|
||||
after: 1
|
||||
},
|
||||
|
||||
{
|
||||
input: { iterations: 3,
|
||||
iterationStart: 3,
|
||||
duration: Infinity,
|
||||
delay: 1,
|
||||
fill: 'both' },
|
||||
before: 0,
|
||||
active: 0
|
||||
}
|
||||
], 'Test integer iterations');
|
||||
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
//
|
||||
// Tests where the iteration count is a fraction
|
||||
//
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
runTests([
|
||||
{
|
||||
input: { iterations: 3.5,
|
||||
iterationStart: 0,
|
||||
duration: 0,
|
||||
delay: 1,
|
||||
fill: 'both' },
|
||||
before: 0,
|
||||
active: 0.5,
|
||||
after: 0.5
|
||||
},
|
||||
|
||||
{
|
||||
input: { iterations: 3.5,
|
||||
iterationStart: 0,
|
||||
duration: 100,
|
||||
delay: 1,
|
||||
fill: 'both' },
|
||||
before: 0,
|
||||
active: 0,
|
||||
after: 0.5
|
||||
},
|
||||
|
||||
{
|
||||
input: { iterations: 3.5,
|
||||
iterationStart: 0,
|
||||
duration: Infinity,
|
||||
delay: 1,
|
||||
fill: 'both' },
|
||||
before: 0,
|
||||
active: 0
|
||||
},
|
||||
|
||||
{
|
||||
input: { iterations: 3.5,
|
||||
iterationStart: 2.5,
|
||||
duration: 0,
|
||||
delay: 1,
|
||||
fill: 'both' },
|
||||
before: 0.5,
|
||||
active: 1,
|
||||
after: 1
|
||||
},
|
||||
|
||||
{
|
||||
input: { iterations: 3.5,
|
||||
iterationStart: 2.5,
|
||||
duration: 100,
|
||||
delay: 1,
|
||||
fill: 'both' },
|
||||
before: 0.5,
|
||||
active: 0.5,
|
||||
after: 1
|
||||
},
|
||||
|
||||
{
|
||||
input: { iterations: 3.5,
|
||||
iterationStart: 2.5,
|
||||
duration: Infinity,
|
||||
delay: 1,
|
||||
fill: 'both' },
|
||||
before: 0.5,
|
||||
active: 0.5
|
||||
},
|
||||
|
||||
{
|
||||
input: { iterations: 3.5,
|
||||
iterationStart: 3,
|
||||
duration: 0,
|
||||
delay: 1,
|
||||
fill: 'both' },
|
||||
before: 0,
|
||||
active: 0.5,
|
||||
after: 0.5
|
||||
},
|
||||
|
||||
{
|
||||
input: { iterations: 3.5,
|
||||
iterationStart: 3,
|
||||
duration: 100,
|
||||
delay: 1,
|
||||
fill: 'both' },
|
||||
before: 0,
|
||||
active: 0,
|
||||
after: 0.5
|
||||
},
|
||||
|
||||
{
|
||||
input: { iterations: 3.5,
|
||||
iterationStart: 3,
|
||||
duration: Infinity,
|
||||
delay: 1,
|
||||
fill: 'both' },
|
||||
before: 0,
|
||||
active: 0
|
||||
}
|
||||
], 'Test fractional iterations');
|
||||
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
//
|
||||
// Tests where the iteration count is Infinity
|
||||
//
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
runTests([
|
||||
{
|
||||
input: { iterations: Infinity,
|
||||
iterationStart: 0,
|
||||
duration: 0,
|
||||
delay: 1,
|
||||
fill: 'both' },
|
||||
before: 0,
|
||||
active: 1,
|
||||
after: 1
|
||||
},
|
||||
|
||||
{
|
||||
input: { iterations: Infinity,
|
||||
iterationStart: 0,
|
||||
duration: 100,
|
||||
delay: 1,
|
||||
fill: 'both' },
|
||||
before: 0,
|
||||
active: 0
|
||||
},
|
||||
|
||||
{
|
||||
input: { iterations: Infinity,
|
||||
iterationStart: 0,
|
||||
duration: Infinity,
|
||||
delay: 1,
|
||||
fill: 'both' },
|
||||
before: 0,
|
||||
active: 0
|
||||
},
|
||||
|
||||
{
|
||||
input: { iterations: Infinity,
|
||||
iterationStart: 2.5,
|
||||
duration: 0,
|
||||
delay: 1,
|
||||
fill: 'both' },
|
||||
before: 0.5,
|
||||
active: 0.5,
|
||||
after: 0.5
|
||||
},
|
||||
|
||||
{
|
||||
input: { iterations: Infinity,
|
||||
iterationStart: 2.5,
|
||||
duration: 100,
|
||||
delay: 1,
|
||||
fill: 'both' },
|
||||
before: 0.5,
|
||||
active: 0.5
|
||||
},
|
||||
|
||||
{
|
||||
input: { iterations: Infinity,
|
||||
iterationStart: 2.5,
|
||||
duration: Infinity,
|
||||
delay: 1,
|
||||
fill: 'both' },
|
||||
before: 0.5,
|
||||
active: 0.5
|
||||
},
|
||||
|
||||
{
|
||||
input: { iterations: Infinity,
|
||||
iterationStart: 3,
|
||||
duration: 0,
|
||||
delay: 1,
|
||||
fill: 'both' },
|
||||
before: 0,
|
||||
active: 1,
|
||||
after: 1
|
||||
},
|
||||
|
||||
{
|
||||
input: { iterations: Infinity,
|
||||
iterationStart: 3,
|
||||
duration: 100,
|
||||
delay: 1,
|
||||
fill: 'both' },
|
||||
before: 0,
|
||||
active: 0
|
||||
},
|
||||
|
||||
{
|
||||
input: { iterations: Infinity,
|
||||
iterationStart: 3,
|
||||
duration: Infinity,
|
||||
delay: 1,
|
||||
fill: 'both' },
|
||||
before: 0,
|
||||
active: 0
|
||||
}
|
||||
], 'Test infinity iterations');
|
||||
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
//
|
||||
// End delay tests
|
||||
//
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
runTests([
|
||||
{
|
||||
input: { duration: 100,
|
||||
delay: 1,
|
||||
fill: 'both',
|
||||
endDelay: 50 },
|
||||
before: 0,
|
||||
active: 0,
|
||||
after: 1
|
||||
},
|
||||
|
||||
{
|
||||
input: { duration: 100,
|
||||
delay: 1,
|
||||
fill: 'both',
|
||||
endDelay: -50 },
|
||||
before: 0,
|
||||
active: 0,
|
||||
after: 0.5
|
||||
},
|
||||
|
||||
{
|
||||
input: { duration: 100,
|
||||
delay: 1,
|
||||
fill: 'both',
|
||||
endDelay: -100 },
|
||||
before: 0,
|
||||
active: 0,
|
||||
after: 0
|
||||
},
|
||||
|
||||
{
|
||||
input: { duration: 100,
|
||||
delay: 1,
|
||||
fill: 'both',
|
||||
endDelay: -200 },
|
||||
before: 0,
|
||||
active: 0,
|
||||
after: 0
|
||||
},
|
||||
|
||||
{
|
||||
input: { iterationStart: 0.5,
|
||||
duration: 100,
|
||||
delay: 1,
|
||||
fill: 'both',
|
||||
endDelay: 50 },
|
||||
before: 0.5,
|
||||
active: 0.5,
|
||||
after: 0.5
|
||||
},
|
||||
|
||||
{
|
||||
input: { iterationStart: 0.5,
|
||||
duration: 100,
|
||||
delay: 1,
|
||||
fill: 'both',
|
||||
endDelay: -50 },
|
||||
before: 0.5,
|
||||
active: 0.5,
|
||||
after: 1
|
||||
},
|
||||
|
||||
{
|
||||
input: { iterationStart: 0.5,
|
||||
duration: 100,
|
||||
delay: 1,
|
||||
fill: 'both',
|
||||
endDelay: -100 },
|
||||
before: 0.5,
|
||||
active: 0.5,
|
||||
after: 0.5
|
||||
},
|
||||
|
||||
{
|
||||
input: { iterations: 2,
|
||||
duration: 100,
|
||||
delay: 1,
|
||||
fill: 'both',
|
||||
endDelay: -100 },
|
||||
before: 0,
|
||||
active: 0,
|
||||
after: 1
|
||||
},
|
||||
|
||||
{
|
||||
input: { iterations: 1,
|
||||
iterationStart: 2,
|
||||
duration: 100,
|
||||
delay: 1,
|
||||
fill: 'both',
|
||||
endDelay: -50 },
|
||||
before: 0,
|
||||
active: 0,
|
||||
after: 0.5
|
||||
},
|
||||
|
||||
{
|
||||
input: { iterations: 1,
|
||||
iterationStart: 2,
|
||||
duration: 100,
|
||||
delay: 1,
|
||||
fill: 'both',
|
||||
endDelay: -100 },
|
||||
before: 0,
|
||||
active: 0,
|
||||
after: 0
|
||||
},
|
||||
], 'Test end delay');
|
||||
|
||||
</script>
|
||||
</body>
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset=utf-8>
|
||||
<title>Tests for current time</title>
|
||||
<link rel="help" href="https://w3c.github.io/web-animations/#current-time">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="../../testcommon.js"></script>
|
||||
<body>
|
||||
<div id="log"></div>
|
||||
<script>
|
||||
'use strict';
|
||||
|
||||
test(function(t) {
|
||||
var animation =
|
||||
new Animation(new KeyframeEffect(createDiv(t), null, 100 * MS_PER_SEC),
|
||||
document.timeline);
|
||||
|
||||
animation.play();
|
||||
assert_equals(animation.currentTime, 0,
|
||||
'Current time returns the hold time set when entering the play-pending ' +
|
||||
'state');
|
||||
}, 'The current time returns the hold time when set');
|
||||
|
||||
promise_test(function(t) {
|
||||
var animation =
|
||||
new Animation(new KeyframeEffect(createDiv(t), null, 100 * MS_PER_SEC),
|
||||
null);
|
||||
|
||||
return animation.ready.then(function() {
|
||||
assert_equals(animation.currentTime, null);
|
||||
});
|
||||
}, 'The current time is unresolved when there is no associated timeline ' +
|
||||
'(and no hold time is set)');
|
||||
|
||||
// FIXME: Test that the current time is unresolved when we have an inactive
|
||||
// timeline if we find a way of creating an inactive timeline!
|
||||
|
||||
test(function(t) {
|
||||
var animation =
|
||||
new Animation(new KeyframeEffect(createDiv(t), null, 100 * MS_PER_SEC),
|
||||
document.timeline);
|
||||
|
||||
animation.startTime = null;
|
||||
assert_equals(animation.currentTime, null);
|
||||
}, 'The current time is unresolved when the start time is unresolved ' +
|
||||
'(and no hold time is set)');
|
||||
|
||||
promise_test(function(t) {
|
||||
var animation =
|
||||
new Animation(new KeyframeEffect(createDiv(t), null, 100 * MS_PER_SEC),
|
||||
document.timeline);
|
||||
|
||||
animation.playbackRate = 2;
|
||||
animation.startTime = document.timeline.currentTime - 25 * MS_PER_SEC;
|
||||
|
||||
var timelineTime = document.timeline.currentTime;
|
||||
var startTime = animation.startTime;
|
||||
var playbackRate = animation.playbackRate;
|
||||
assert_times_equal(animation.currentTime,
|
||||
(timelineTime - startTime) * playbackRate,
|
||||
'Animation has a unresolved start time');
|
||||
}, 'The current time is calculated from the timeline time, start time and ' +
|
||||
'playback rate');
|
||||
</script>
|
||||
</body>
|
||||
|
|
@ -0,0 +1,207 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset=utf-8>
|
||||
<title>Setting the start time tests</title>
|
||||
<link rel="help" href="https://w3c.github.io/web-animations/#set-the-animation-start-time">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="../../testcommon.js"></script>
|
||||
<body>
|
||||
<div id="log"></div>
|
||||
<script>
|
||||
'use strict';
|
||||
|
||||
test(function(t)
|
||||
{
|
||||
// It should only be possible to set *either* the start time or the current
|
||||
// time for an animation that does not have an active timeline.
|
||||
|
||||
var animation =
|
||||
new Animation(new KeyframeEffect(createDiv(t), null, 100 * MS_PER_SEC),
|
||||
null);
|
||||
|
||||
assert_equals(animation.currentTime, null, 'Intial current time');
|
||||
assert_equals(animation.startTime, null, 'Intial start time');
|
||||
|
||||
animation.currentTime = 1000;
|
||||
assert_equals(animation.currentTime, 1000,
|
||||
'Setting the current time succeeds');
|
||||
assert_equals(animation.startTime, null,
|
||||
'Start time remains null after setting current time');
|
||||
|
||||
animation.startTime = 1000;
|
||||
assert_equals(animation.startTime, 1000,
|
||||
'Setting the start time succeeds');
|
||||
assert_equals(animation.currentTime, null,
|
||||
'Setting the start time clears the current time');
|
||||
|
||||
animation.startTime = null;
|
||||
assert_equals(animation.startTime, null,
|
||||
'Setting the start time to an unresolved time succeeds');
|
||||
assert_equals(animation.currentTime, null, 'The current time is unaffected');
|
||||
|
||||
}, 'Setting the start time of an animation without an active timeline');
|
||||
|
||||
test(function(t)
|
||||
{
|
||||
// Setting an unresolved start time on an animation without an active
|
||||
// timeline should not clear the current time.
|
||||
|
||||
var animation =
|
||||
new Animation(new KeyframeEffect(createDiv(t), null, 100 * MS_PER_SEC),
|
||||
null);
|
||||
|
||||
assert_equals(animation.currentTime, null, 'Intial current time');
|
||||
assert_equals(animation.startTime, null, 'Intial start time');
|
||||
|
||||
animation.currentTime = 1000;
|
||||
assert_equals(animation.currentTime, 1000,
|
||||
'Setting the current time succeeds');
|
||||
assert_equals(animation.startTime, null,
|
||||
'Start time remains null after setting current time');
|
||||
|
||||
animation.startTime = null;
|
||||
assert_equals(animation.startTime, null, 'Start time remains unresolved');
|
||||
assert_equals(animation.currentTime, 1000, 'Current time is unaffected');
|
||||
|
||||
}, 'Setting an unresolved start time an animation without an active timeline'
|
||||
+ ' does not clear the current time');
|
||||
|
||||
test(function(t)
|
||||
{
|
||||
var animation =
|
||||
new Animation(new KeyframeEffect(createDiv(t), null, 100 * MS_PER_SEC),
|
||||
document.timeline);
|
||||
|
||||
// So long as a hold time is set, querying the current time will return
|
||||
// the hold time.
|
||||
|
||||
// Since the start time is unresolved at this point, setting the current time
|
||||
// will set the hold time
|
||||
animation.currentTime = 1000;
|
||||
assert_equals(animation.currentTime, 1000,
|
||||
'The current time is calculated from the hold time');
|
||||
|
||||
// If we set the start time, however, we should clear the hold time.
|
||||
animation.startTime = document.timeline.currentTime - 2000;
|
||||
assert_times_equal(animation.currentTime, 2000,
|
||||
'The current time is calculated from the start time,'
|
||||
+ ' not the hold time');
|
||||
|
||||
// Sanity check
|
||||
assert_equals(animation.playState, 'running',
|
||||
'Animation reports it is running after setting a resolved'
|
||||
+ ' start time');
|
||||
}, 'Setting the start time clears the hold time');
|
||||
|
||||
test(function(t)
|
||||
{
|
||||
var animation =
|
||||
new Animation(new KeyframeEffect(createDiv(t), null, 100 * MS_PER_SEC),
|
||||
document.timeline);
|
||||
|
||||
// Set up a running animation (i.e. both start time and current time
|
||||
// are resolved).
|
||||
animation.startTime = document.timeline.currentTime - 1000;
|
||||
assert_equals(animation.playState, 'running');
|
||||
assert_times_equal(animation.currentTime, 1000,
|
||||
'Current time is resolved for a running animation')
|
||||
|
||||
// Clear start time
|
||||
animation.startTime = null;
|
||||
assert_times_equal(animation.currentTime, 1000,
|
||||
'Hold time is set after start time is made unresolved');
|
||||
assert_equals(animation.playState, 'paused',
|
||||
'Animation reports it is paused after setting an unresolved'
|
||||
+ ' start time');
|
||||
}, 'Setting an unresolved start time sets the hold time');
|
||||
|
||||
promise_test(function(t)
|
||||
{
|
||||
var animation =
|
||||
new Animation(new KeyframeEffect(createDiv(t), null, 100 * MS_PER_SEC),
|
||||
document.timeline);
|
||||
|
||||
var readyPromiseCallbackCalled = false;
|
||||
animation.ready.then(function() { readyPromiseCallbackCalled = true; } );
|
||||
|
||||
// Put the animation in the play-pending state
|
||||
animation.play();
|
||||
|
||||
// Sanity check
|
||||
assert_equals(animation.playState, 'pending',
|
||||
'Animation is in play-pending state');
|
||||
|
||||
// Setting the start time should resolve the 'ready' promise, i.e.
|
||||
// it should schedule a microtask to run the promise callbacks.
|
||||
animation.startTime = document.timeline.currentTime;
|
||||
assert_false(readyPromiseCallbackCalled,
|
||||
'Ready promise callback is not called synchronously');
|
||||
|
||||
// If we schedule another microtask then it should run immediately after
|
||||
// the ready promise resolution microtask.
|
||||
return Promise.resolve().then(function() {
|
||||
assert_true(readyPromiseCallbackCalled,
|
||||
'Ready promise callback called after setting startTime');
|
||||
});
|
||||
}, 'Setting the start time resolves a pending ready promise');
|
||||
|
||||
promise_test(function(t)
|
||||
{
|
||||
var animation =
|
||||
new Animation(new KeyframeEffect(createDiv(t), null, 100 * MS_PER_SEC),
|
||||
document.timeline);
|
||||
|
||||
var readyPromiseCallbackCalled = false;
|
||||
animation.ready.then(function() { readyPromiseCallbackCalled = true; } );
|
||||
|
||||
// Put the animation in the pause-pending state
|
||||
animation.startTime = document.timeline.currentTime;
|
||||
animation.pause();
|
||||
|
||||
// Sanity check
|
||||
assert_equals(animation.playState, 'pending',
|
||||
'Animation is in pause-pending state');
|
||||
|
||||
// Setting the start time should resolve the 'ready' promise although
|
||||
// the resolution callbacks when be run in a separate microtask.
|
||||
animation.startTime = null;
|
||||
assert_false(readyPromiseCallbackCalled,
|
||||
'Ready promise callback is not called synchronously');
|
||||
|
||||
return Promise.resolve().then(function() {
|
||||
assert_true(readyPromiseCallbackCalled,
|
||||
'Ready promise callback called after setting startTime');
|
||||
});
|
||||
}, 'Setting the start time resolves a pending pause task');
|
||||
|
||||
promise_test(function(t)
|
||||
{
|
||||
var animation =
|
||||
new Animation(new KeyframeEffect(createDiv(t), null, 100 * MS_PER_SEC),
|
||||
document.timeline);
|
||||
|
||||
// Set start time such that the current time is past the end time
|
||||
animation.startTime = document.timeline.currentTime
|
||||
- 110 * MS_PER_SEC;
|
||||
assert_equals(animation.playState, 'finished',
|
||||
'Seeked to finished state using the startTime');
|
||||
|
||||
// If the 'did seek' flag is true, the current time should be greater than
|
||||
// the effect end.
|
||||
assert_greater_than(animation.currentTime,
|
||||
animation.effect.getComputedTiming().endTime,
|
||||
'Setting the start time updated the finished state with'
|
||||
+ ' the \'did seek\' flag set to true');
|
||||
|
||||
// Furthermore, that time should persist if we have correctly updated
|
||||
// the hold time
|
||||
var finishedCurrentTime = animation.currentTime;
|
||||
return waitForAnimationFrames(1).then(function() {
|
||||
assert_equals(animation.currentTime, finishedCurrentTime,
|
||||
'Current time does not change after seeking past the effect'
|
||||
+ ' end time by setting the current time');
|
||||
});
|
||||
}, 'Setting the start time updates the finished state');
|
||||
|
||||
</script>
|
||||
</body>
|
||||
|
|
@ -0,0 +1,95 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset=utf-8>
|
||||
<title>Setting the target effect tests</title>
|
||||
<link rel='help' href='https://w3c.github.io/web-animations/#setting-the-target-effect'>
|
||||
<script src='/resources/testharness.js'></script>
|
||||
<script src='/resources/testharnessreport.js'></script>
|
||||
<script src='../../testcommon.js'></script>
|
||||
<body>
|
||||
<div id='log'></div>
|
||||
<script>
|
||||
'use strict';
|
||||
|
||||
promise_test(function(t) {
|
||||
var anim = createDiv(t).animate({ marginLeft: [ '0px', '100px' ] },
|
||||
100 * MS_PER_SEC);
|
||||
assert_equals(anim.playState, 'pending');
|
||||
|
||||
var retPromise = anim.ready.then(function() {
|
||||
assert_unreached('ready promise is fulfilled');
|
||||
}).catch(function(err) {
|
||||
assert_equals(err.name, 'AbortError',
|
||||
'ready promise is rejected with AbortError');
|
||||
});
|
||||
|
||||
anim.effect = null;
|
||||
assert_equals(anim.playState, 'paused');
|
||||
|
||||
return retPromise;
|
||||
}, 'If new effect is null and old effect is not null, we reset the pending ' +
|
||||
'tasks and ready promise is rejected');
|
||||
|
||||
promise_test(function(t) {
|
||||
var anim = new Animation();
|
||||
anim.pause();
|
||||
assert_equals(anim.playState, 'pending');
|
||||
|
||||
anim.effect = new KeyframeEffectReadOnly(createDiv(t),
|
||||
{ marginLeft: [ '0px', '100px' ] },
|
||||
100 * MS_PER_SEC);
|
||||
assert_equals(anim.playState, 'pending');
|
||||
|
||||
return anim.ready.then(function() {
|
||||
assert_equals(anim.playState, 'paused');
|
||||
});
|
||||
}, 'If animation has a pending pause task, reschedule that task to run ' +
|
||||
'as soon as animation is ready.');
|
||||
|
||||
promise_test(function(t) {
|
||||
var anim = new Animation();
|
||||
anim.play();
|
||||
assert_equals(anim.playState, 'pending');
|
||||
|
||||
anim.effect = new KeyframeEffectReadOnly(createDiv(t),
|
||||
{ marginLeft: [ '0px', '100px' ] },
|
||||
100 * MS_PER_SEC);
|
||||
assert_equals(anim.playState, 'pending');
|
||||
|
||||
return anim.ready.then(function() {
|
||||
assert_equals(anim.playState, 'running');
|
||||
});
|
||||
}, 'If animation has a pending play task, reschedule that task to run ' +
|
||||
'as soon as animation is ready to play new effect.');
|
||||
|
||||
promise_test(function(t) {
|
||||
var animA = createDiv(t).animate({ marginLeft: [ '0px', '100px' ] },
|
||||
100 * MS_PER_SEC);
|
||||
var animB = new Animation();
|
||||
|
||||
return animA.ready.then(function() {
|
||||
animB.effect = animA.effect;
|
||||
assert_equals(animA.effect, null);
|
||||
assert_equals(animA.playState, 'finished');
|
||||
});
|
||||
}, 'When setting the effect of an animation to the effect of an existing ' +
|
||||
'animation, the existing animation\'s target effect should be set to null.');
|
||||
|
||||
test(function(t) {
|
||||
var animA = createDiv(t).animate({ marginLeft: [ '0px', '100px' ] },
|
||||
100 * MS_PER_SEC);
|
||||
var animB = new Animation();
|
||||
var effect = animA.effect;
|
||||
animA.currentTime = 50 * MS_PER_SEC;
|
||||
animB.currentTime = 20 * MS_PER_SEC;
|
||||
assert_equals(effect.getComputedTiming().progress, 0.5,
|
||||
'Original timing comes from first animation');
|
||||
animB.effect = effect;
|
||||
assert_equals(effect.getComputedTiming().progress, 0.2,
|
||||
'After setting the effect on a different animation, ' +
|
||||
'it uses the new animation\'s timing');
|
||||
}, 'After setting the target effect of animation to the target effect of an ' +
|
||||
'existing animation, the target effect\'s timing is updated to reflect ' +
|
||||
'the current time of the new animation.');
|
||||
|
||||
</script>
|
||||
</body>
|
||||
|
|
@ -0,0 +1,276 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset=utf-8>
|
||||
<title>Setting the timeline tests</title>
|
||||
<link rel="help" href="https://w3c.github.io/web-animations/#setting-the-timeline">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="../../testcommon.js"></script>
|
||||
<body>
|
||||
<div id="log"></div>
|
||||
<script>
|
||||
'use strict';
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
//
|
||||
// Tests from no timeline to timeline
|
||||
//
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
test(function(t) {
|
||||
var animation =
|
||||
new Animation(new KeyframeEffect(createDiv(t), null, 100 * MS_PER_SEC),
|
||||
null);
|
||||
animation.currentTime = 50 * MS_PER_SEC;
|
||||
assert_equals(animation.playState, 'paused');
|
||||
|
||||
animation.timeline = document.timeline;
|
||||
|
||||
assert_equals(animation.playState, 'paused');
|
||||
assert_times_equal(animation.currentTime, 50 * MS_PER_SEC);
|
||||
}, 'After setting timeline on paused animation it is still paused');
|
||||
|
||||
test(function(t) {
|
||||
var animation =
|
||||
new Animation(new KeyframeEffect(createDiv(t), null, 100 * MS_PER_SEC),
|
||||
null);
|
||||
animation.currentTime = 200 * MS_PER_SEC;
|
||||
assert_equals(animation.playState, 'paused');
|
||||
|
||||
animation.timeline = document.timeline;
|
||||
|
||||
assert_equals(animation.playState, 'paused');
|
||||
assert_times_equal(animation.currentTime, 200 * MS_PER_SEC);
|
||||
}, 'After setting timeline on animation paused outside active interval'
|
||||
+ ' it is still paused');
|
||||
|
||||
test(function(t) {
|
||||
var animation =
|
||||
new Animation(new KeyframeEffect(createDiv(t), null, 100 * MS_PER_SEC),
|
||||
null);
|
||||
assert_equals(animation.playState, 'idle');
|
||||
|
||||
animation.timeline = document.timeline;
|
||||
|
||||
assert_equals(animation.playState, 'idle');
|
||||
}, 'After setting timeline on an idle animation without a start time'
|
||||
+ ' it is still idle');
|
||||
|
||||
test(function(t) {
|
||||
var animation =
|
||||
new Animation(new KeyframeEffect(createDiv(t), null, 100 * MS_PER_SEC),
|
||||
null);
|
||||
animation.startTime = document.timeline.currentTime;
|
||||
assert_equals(animation.playState, 'idle');
|
||||
|
||||
animation.timeline = document.timeline;
|
||||
|
||||
assert_equals(animation.playState, 'running');
|
||||
}, 'After setting timeline on an idle animation with a start time'
|
||||
+ ' it is running');
|
||||
|
||||
test(function(t) {
|
||||
var animation =
|
||||
new Animation(new KeyframeEffect(createDiv(t), null, 100 * MS_PER_SEC),
|
||||
null);
|
||||
animation.startTime = document.timeline.currentTime - 200 * MS_PER_SEC;
|
||||
assert_equals(animation.playState, 'idle');
|
||||
|
||||
animation.timeline = document.timeline;
|
||||
|
||||
assert_equals(animation.playState, 'finished');
|
||||
}, 'After setting timeline on an idle animation with a sufficiently ancient'
|
||||
+ ' start time it is finished');
|
||||
|
||||
test(function(t) {
|
||||
var animation =
|
||||
new Animation(new KeyframeEffect(createDiv(t), null, 100 * MS_PER_SEC),
|
||||
null);
|
||||
animation.play();
|
||||
assert_equals(animation.playState, 'pending');
|
||||
|
||||
animation.timeline = document.timeline;
|
||||
|
||||
assert_equals(animation.playState, 'pending');
|
||||
}, 'After setting timeline on a play-pending animation it is still pending');
|
||||
|
||||
promise_test(function(t) {
|
||||
var animation =
|
||||
new Animation(new KeyframeEffect(createDiv(t), null, 100 * MS_PER_SEC),
|
||||
null);
|
||||
animation.play();
|
||||
assert_equals(animation.playState, 'pending');
|
||||
|
||||
animation.timeline = document.timeline;
|
||||
|
||||
return animation.ready.then(function() {
|
||||
assert_equals(animation.playState, 'running');
|
||||
});
|
||||
}, 'After setting timeline on a play-pending animation it begins playing'
|
||||
+ ' after pending');
|
||||
|
||||
test(function(t) {
|
||||
var animation =
|
||||
new Animation(new KeyframeEffect(createDiv(t), null, 100 * MS_PER_SEC),
|
||||
null);
|
||||
animation.startTime = document.timeline.currentTime;
|
||||
animation.pause();
|
||||
animation.timeline = null;
|
||||
assert_equals(animation.playState, 'pending');
|
||||
|
||||
animation.timeline = document.timeline;
|
||||
|
||||
assert_equals(animation.playState, 'pending');
|
||||
}, 'After setting timeline on a pause-pending animation it is still pending');
|
||||
|
||||
promise_test(function(t) {
|
||||
var animation =
|
||||
new Animation(new KeyframeEffect(createDiv(t), null, 100 * MS_PER_SEC),
|
||||
null);
|
||||
animation.startTime = document.timeline.currentTime;
|
||||
animation.pause();
|
||||
animation.timeline = null;
|
||||
assert_equals(animation.playState, 'pending');
|
||||
|
||||
animation.timeline = document.timeline;
|
||||
|
||||
return animation.ready.then(function() {
|
||||
assert_equals(animation.playState, 'paused');
|
||||
});
|
||||
}, 'After setting timeline on a pause-pending animation it becomes paused'
|
||||
+ ' after pending');
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
//
|
||||
// Tests from timeline to no timeline
|
||||
//
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
test(function(t) {
|
||||
var animation =
|
||||
new Animation(new KeyframeEffect(createDiv(t), null, 100 * MS_PER_SEC),
|
||||
document.timeline);
|
||||
animation.currentTime = 50 * MS_PER_SEC;
|
||||
assert_equals(animation.playState, 'paused');
|
||||
|
||||
animation.timeline = null;
|
||||
|
||||
assert_equals(animation.playState, 'paused');
|
||||
assert_times_equal(animation.currentTime, 50 * MS_PER_SEC);
|
||||
}, 'After clearing timeline on paused animation it is still paused');
|
||||
|
||||
test(function(t) {
|
||||
var animation =
|
||||
new Animation(new KeyframeEffect(createDiv(t), null, 100 * MS_PER_SEC),
|
||||
document.timeline);
|
||||
var initialStartTime = document.timeline.currentTime - 200 * MS_PER_SEC;
|
||||
animation.startTime = initialStartTime;
|
||||
assert_equals(animation.playState, 'finished');
|
||||
|
||||
animation.timeline = null;
|
||||
|
||||
assert_equals(animation.playState, 'idle');
|
||||
assert_times_equal(animation.startTime, initialStartTime);
|
||||
}, 'After clearing timeline on finished animation it is idle');
|
||||
|
||||
test(function(t) {
|
||||
var animation =
|
||||
new Animation(new KeyframeEffect(createDiv(t), null, 100 * MS_PER_SEC),
|
||||
document.timeline);
|
||||
var initialStartTime = document.timeline.currentTime - 50 * MS_PER_SEC;
|
||||
animation.startTime = initialStartTime;
|
||||
assert_equals(animation.playState, 'running');
|
||||
|
||||
animation.timeline = null;
|
||||
|
||||
assert_equals(animation.playState, 'idle');
|
||||
assert_times_equal(animation.startTime, initialStartTime);
|
||||
}, 'After clearing timeline on running animation it is idle');
|
||||
|
||||
test(function(t) {
|
||||
var animation =
|
||||
new Animation(new KeyframeEffect(createDiv(t), null, 100 * MS_PER_SEC),
|
||||
document.timeline);
|
||||
assert_equals(animation.playState, 'idle');
|
||||
|
||||
animation.timeline = null;
|
||||
|
||||
assert_equals(animation.playState, 'idle');
|
||||
assert_equals(animation.startTime, null);
|
||||
}, 'After clearing timeline on idle animation it is still idle');
|
||||
|
||||
test(function(t) {
|
||||
var animation = createDiv(t).animate(null, 100 * MS_PER_SEC);
|
||||
assert_equals(animation.playState, 'pending');
|
||||
|
||||
animation.timeline = null;
|
||||
|
||||
assert_equals(animation.playState, 'pending');
|
||||
}, 'After clearing timeline on play-pending animation it is still pending');
|
||||
|
||||
promise_test(function(t) {
|
||||
var animation = createDiv(t).animate(null, 100 * MS_PER_SEC);
|
||||
assert_equals(animation.playState, 'pending');
|
||||
|
||||
animation.timeline = null;
|
||||
animation.timeline = document.timeline;
|
||||
|
||||
assert_equals(animation.playState, 'pending');
|
||||
return animation.ready.then(function() {
|
||||
assert_equals(animation.playState, 'running');
|
||||
});
|
||||
}, 'After clearing and re-setting timeline on play-pending animation it'
|
||||
+ ' begins to play');
|
||||
|
||||
test(function(t) {
|
||||
var animation =
|
||||
new Animation(new KeyframeEffect(createDiv(t), null, 100 * MS_PER_SEC),
|
||||
document.timeline);
|
||||
animation.startTime = document.timeline.currentTime;
|
||||
animation.pause();
|
||||
assert_equals(animation.playState, 'pending');
|
||||
|
||||
animation.timeline = null;
|
||||
|
||||
assert_equals(animation.playState, 'pending');
|
||||
}, 'After clearing timeline on a pause-pending animation it is still pending');
|
||||
|
||||
promise_test(function(t) {
|
||||
var animation =
|
||||
new Animation(new KeyframeEffect(createDiv(t), null, 100 * MS_PER_SEC),
|
||||
document.timeline);
|
||||
animation.startTime = document.timeline.currentTime;
|
||||
animation.pause();
|
||||
assert_equals(animation.playState, 'pending');
|
||||
|
||||
animation.timeline = null;
|
||||
animation.timeline = document.timeline;
|
||||
|
||||
assert_equals(animation.playState, 'pending');
|
||||
return animation.ready.then(function() {
|
||||
assert_equals(animation.playState, 'paused');
|
||||
});
|
||||
}, 'After clearing and re-setting timeline on a pause-pending animation it'
|
||||
+ ' becomes paused');
|
||||
|
||||
promise_test(function(t) {
|
||||
var animation =
|
||||
new Animation(new KeyframeEffect(createDiv(t), null, 100 * MS_PER_SEC),
|
||||
document.timeline);
|
||||
var initialStartTime = document.timeline.currentTime - 50 * MS_PER_SEC;
|
||||
animation.startTime = initialStartTime;
|
||||
animation.pause();
|
||||
animation.play();
|
||||
|
||||
animation.timeline = null;
|
||||
animation.timeline = document.timeline;
|
||||
assert_equals(animation.playState, 'pending');
|
||||
|
||||
return animation.ready.then(function() {
|
||||
assert_equals(animation.playState, 'running');
|
||||
assert_times_equal(animation.startTime, initialStartTime);
|
||||
});
|
||||
}, 'After clearing and re-setting timeline on an animation in the middle of'
|
||||
+ ' an aborted pause, it continues playing using the same start time');
|
||||
|
||||
</script>
|
||||
</body>
|
||||
|
|
@ -0,0 +1,331 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset=utf-8>
|
||||
<title>Tests for updating the finished state of an animation</title>
|
||||
<link rel="help" href="https://w3c.github.io/web-animations/#updating-the-finished-state">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="../../testcommon.js"></script>
|
||||
<body>
|
||||
<div id="log"></div>
|
||||
<script>
|
||||
'use strict';
|
||||
|
||||
//
|
||||
// NOTE TO THE POOR PERSON WHO HAS TO MERGE THIS WITH THE TEST OF THE SAME
|
||||
// NAME FROM BLINK
|
||||
//
|
||||
// There is a pull request from Blink at:
|
||||
//
|
||||
// https://github.com/w3c/web-platform-tests/pull/3328
|
||||
//
|
||||
// which this file will surely conflict with.
|
||||
//
|
||||
// However, those tests cover a different part of the same algorithm. They
|
||||
// are mostly concerned with testing events and promises rather than the
|
||||
// timing part of the algorithm.
|
||||
//
|
||||
// The tests below cover the first part of the algorithm. So, please keep both
|
||||
// sets of tests and delete this comment. Preferably put the tests in this
|
||||
// file first.
|
||||
//
|
||||
// Thank you!
|
||||
//
|
||||
|
||||
|
||||
// CASE 1: playback rate > 0 and current time >= target effect end
|
||||
// (Also the start time is resolved and there is pending task)
|
||||
|
||||
// Did seek = false
|
||||
promise_test(function(t) {
|
||||
var anim = createDiv(t).animate(null, 100 * MS_PER_SEC);
|
||||
|
||||
// Here and in the following tests we wait until ready resolves as
|
||||
// otherwise we don't have a resolved start time. We test the case
|
||||
// where the start time is unresolved in a subsequent test.
|
||||
return anim.ready.then(function() {
|
||||
// Seek to 1ms before the target end and then wait 1ms
|
||||
anim.currentTime = 100 * MS_PER_SEC - 1;
|
||||
return waitForAnimationFramesWithDelay(1);
|
||||
}).then(function() {
|
||||
assert_equals(anim.currentTime, 100 * MS_PER_SEC,
|
||||
'Hold time is set to target end clamping current time');
|
||||
});
|
||||
}, 'Updating the finished state when playing past end');
|
||||
|
||||
// Did seek = true
|
||||
promise_test(function(t) {
|
||||
var anim = createDiv(t).animate(null, 100 * MS_PER_SEC);
|
||||
return anim.ready.then(function() {
|
||||
anim.currentTime = 200 * MS_PER_SEC;
|
||||
return waitForAnimationFrames(1);
|
||||
}).then(function() {
|
||||
assert_equals(anim.currentTime, 200 * MS_PER_SEC,
|
||||
'Hold time is set so current time should NOT change');
|
||||
});
|
||||
}, 'Updating the finished state when seeking past end');
|
||||
|
||||
// Test current time == target end
|
||||
//
|
||||
// We can't really write a test for current time == target end with
|
||||
// did seek = false since that would imply setting up an animation where
|
||||
// the next animation frame time happens to exactly align with the target end.
|
||||
//
|
||||
// Fortunately, we don't need to test that case since even if the implementation
|
||||
// fails to set the hold time on such a tick, it should be mostly unobservable
|
||||
// (on the subsequent tick the hold time will be set to the same value anyway).
|
||||
|
||||
// Did seek = true
|
||||
promise_test(function(t) {
|
||||
var anim = createDiv(t).animate(null, 100 * MS_PER_SEC);
|
||||
return anim.ready.then(function() {
|
||||
anim.currentTime = 100 * MS_PER_SEC;
|
||||
return waitForAnimationFrames(1);
|
||||
}).then(function() {
|
||||
assert_equals(anim.currentTime, 100 * MS_PER_SEC,
|
||||
'Hold time is set so current time should NOT change');
|
||||
});
|
||||
}, 'Updating the finished state when seeking exactly to end');
|
||||
|
||||
|
||||
// CASE 2: playback rate < 0 and current time <= 0
|
||||
// (Also the start time is resolved and there is pending task)
|
||||
|
||||
// Did seek = false
|
||||
promise_test(function(t) {
|
||||
var anim = createDiv(t).animate(null, 100 * MS_PER_SEC);
|
||||
anim.playbackRate = -1;
|
||||
anim.play(); // Make sure animation is not initially finished
|
||||
return anim.ready.then(function() {
|
||||
// Seek to 1ms before 0 and then wait 1ms
|
||||
anim.currentTime = 1;
|
||||
return waitForAnimationFramesWithDelay(1);
|
||||
}).then(function() {
|
||||
assert_equals(anim.currentTime, 0 * MS_PER_SEC,
|
||||
'Hold time is set to zero clamping current time');
|
||||
});
|
||||
}, 'Updating the finished state when playing in reverse past zero');
|
||||
|
||||
// Did seek = true
|
||||
promise_test(function(t) {
|
||||
var anim = createDiv(t).animate(null, 100 * MS_PER_SEC);
|
||||
anim.playbackRate = -1;
|
||||
anim.play();
|
||||
return anim.ready.then(function() {
|
||||
anim.currentTime = -100 * MS_PER_SEC;
|
||||
return waitForAnimationFrames(1);
|
||||
}).then(function() {
|
||||
assert_equals(anim.currentTime, -100 * MS_PER_SEC,
|
||||
'Hold time is set so current time should NOT change');
|
||||
});
|
||||
}, 'Updating the finished state when seeking a reversed animation past zero');
|
||||
|
||||
// As before, it's difficult to test current time == 0 for did seek = false but
|
||||
// it doesn't really matter.
|
||||
|
||||
// Did seek = true
|
||||
promise_test(function(t) {
|
||||
var anim = createDiv(t).animate(null, 100 * MS_PER_SEC);
|
||||
anim.playbackRate = -1;
|
||||
anim.play();
|
||||
return anim.ready.then(function() {
|
||||
anim.currentTime = 0;
|
||||
return waitForAnimationFrames(1);
|
||||
}).then(function() {
|
||||
assert_equals(anim.currentTime, 0 * MS_PER_SEC,
|
||||
'Hold time is set so current time should NOT change');
|
||||
});
|
||||
}, 'Updating the finished state when seeking a reversed animation exactly'
|
||||
+ ' to zero');
|
||||
|
||||
// CASE 3: playback rate > 0 and current time < target end OR
|
||||
// playback rate < 0 and current time > 0
|
||||
// (Also the start time is resolved and there is pending task)
|
||||
|
||||
// Did seek = false; playback rate > 0
|
||||
promise_test(function(t) {
|
||||
var anim = createDiv(t).animate(null, 100 * MS_PER_SEC);
|
||||
|
||||
// We want to test that the hold time is cleared so first we need to
|
||||
// put the animation in a state where the hold time is set.
|
||||
anim.finish();
|
||||
return anim.ready.then(function() {
|
||||
assert_equals(anim.currentTime, 100 * MS_PER_SEC,
|
||||
'Hold time is initially set');
|
||||
// Then extend the duration so that the hold time is cleared and on
|
||||
// the next tick the current time will increase.
|
||||
anim.effect.timing.duration *= 2;
|
||||
return waitForAnimationFrames(1);
|
||||
}).then(function() {
|
||||
assert_greater_than(anim.currentTime, 100 * MS_PER_SEC,
|
||||
'Hold time is not set so current time should increase');
|
||||
});
|
||||
}, 'Updating the finished state when playing before end');
|
||||
|
||||
// Did seek = true; playback rate > 0
|
||||
promise_test(function(t) {
|
||||
var anim = createDiv(t).animate(null, 100 * MS_PER_SEC);
|
||||
anim.finish();
|
||||
return anim.ready.then(function() {
|
||||
anim.currentTime = 50 * MS_PER_SEC;
|
||||
// When did seek = true, updating the finished state: (i) updates
|
||||
// the animation's start time and (ii) clears the hold time.
|
||||
// We can test both by checking that the currentTime is initially
|
||||
// updated and then increases.
|
||||
assert_equals(anim.currentTime, 50 * MS_PER_SEC, 'Start time is updated');
|
||||
return waitForAnimationFrames(1);
|
||||
}).then(function() {
|
||||
assert_greater_than(anim.currentTime, 50 * MS_PER_SEC,
|
||||
'Hold time is not set so current time should increase');
|
||||
});
|
||||
}, 'Updating the finished state when seeking before end');
|
||||
|
||||
// Did seek = false; playback rate < 0
|
||||
//
|
||||
// Unfortunately it is not possible to test this case. We need to have
|
||||
// a hold time set, a resolved start time, and then perform some
|
||||
// operation that updates the finished state with did seek set to true.
|
||||
//
|
||||
// However, the only situation where this could arrive is when we
|
||||
// replace the timeline and that procedure is likely to change. For all
|
||||
// other cases we either have an unresolved start time (e.g. when
|
||||
// paused), we don't have a set hold time (e.g. regular playback), or
|
||||
// the current time is zero (and anything that gets us out of that state
|
||||
// will set did seek = true).
|
||||
|
||||
// Did seek = true; playback rate < 0
|
||||
promise_test(function(t) {
|
||||
var anim = createDiv(t).animate(null, 100 * MS_PER_SEC);
|
||||
anim.playbackRate = -1;
|
||||
return anim.ready.then(function() {
|
||||
anim.currentTime = 50 * MS_PER_SEC;
|
||||
assert_equals(anim.currentTime, 50 * MS_PER_SEC, 'Start time is updated');
|
||||
return waitForAnimationFrames(1);
|
||||
}).then(function() {
|
||||
assert_less_than(anim.currentTime, 50 * MS_PER_SEC,
|
||||
'Hold time is not set so current time should decrease');
|
||||
});
|
||||
}, 'Updating the finished state when seeking a reversed animation before end');
|
||||
|
||||
// CASE 4: playback rate == 0
|
||||
|
||||
// current time < 0
|
||||
promise_test(function(t) {
|
||||
var anim = createDiv(t).animate(null, 100 * MS_PER_SEC);
|
||||
anim.playbackRate = 0;
|
||||
return anim.ready.then(function() {
|
||||
anim.currentTime = -100 * MS_PER_SEC;
|
||||
return waitForAnimationFrames(1);
|
||||
}).then(function() {
|
||||
assert_equals(anim.currentTime, -100 * MS_PER_SEC,
|
||||
'Hold time should not be cleared so current time should'
|
||||
+ ' NOT change');
|
||||
});
|
||||
}, 'Updating the finished state when playback rate is zero and the'
|
||||
+ ' current time is less than zero');
|
||||
|
||||
// current time < target end
|
||||
promise_test(function(t) {
|
||||
var anim = createDiv(t).animate(null, 100 * MS_PER_SEC);
|
||||
anim.playbackRate = 0;
|
||||
return anim.ready.then(function() {
|
||||
anim.currentTime = 50 * MS_PER_SEC;
|
||||
return waitForAnimationFrames(1);
|
||||
}).then(function() {
|
||||
assert_equals(anim.currentTime, 50 * MS_PER_SEC,
|
||||
'Hold time should not be cleared so current time should'
|
||||
+ ' NOT change');
|
||||
});
|
||||
}, 'Updating the finished state when playback rate is zero and the'
|
||||
+ ' current time is less than end');
|
||||
|
||||
// current time > target end
|
||||
promise_test(function(t) {
|
||||
var anim = createDiv(t).animate(null, 100 * MS_PER_SEC);
|
||||
anim.playbackRate = 0;
|
||||
return anim.ready.then(function() {
|
||||
anim.currentTime = 200 * MS_PER_SEC;
|
||||
return waitForAnimationFrames(1);
|
||||
}).then(function() {
|
||||
assert_equals(anim.currentTime, 200 * MS_PER_SEC,
|
||||
'Hold time should not be cleared so current time should'
|
||||
+ ' NOT change');
|
||||
});
|
||||
}, 'Updating the finished state when playback rate is zero and the'
|
||||
+ ' current time is greater than end');
|
||||
|
||||
// CASE 5: current time unresolved
|
||||
|
||||
promise_test(function(t) {
|
||||
var anim = createDiv(t).animate(null, 100 * MS_PER_SEC);
|
||||
anim.cancel();
|
||||
// Trigger a change that will cause the "update the finished state"
|
||||
// procedure to run.
|
||||
anim.effect.timing.duration = 200 * MS_PER_SEC;
|
||||
assert_equals(anim.currentTime, null,
|
||||
'The animation hold time / start time should not be updated');
|
||||
// The "update the finished state" procedure is supposed to run after any
|
||||
// change to timing, but just in case an implementation defers that, let's
|
||||
// wait a frame and check that the hold time / start time has still not been
|
||||
// updated.
|
||||
return waitForAnimationFrames(1).then(function() {
|
||||
assert_equals(anim.currentTime, null,
|
||||
'The animation hold time / start time should not be updated');
|
||||
});
|
||||
}, 'Updating the finished state when current time is unresolved');
|
||||
|
||||
// CASE 6: has a pending task
|
||||
|
||||
test(function(t) {
|
||||
var anim = createDiv(t).animate(null, 100 * MS_PER_SEC);
|
||||
anim.cancel();
|
||||
anim.currentTime = 75 * MS_PER_SEC;
|
||||
anim.play();
|
||||
// We now have a pending task and a resolved current time.
|
||||
//
|
||||
// In the next step we will adjust the timing so that the current time
|
||||
// is greater than the target end. At this point the "update the finished
|
||||
// state" procedure should run and if we fail to check for a pending task
|
||||
// we will set the hold time to the target end, i.e. 50ms.
|
||||
anim.effect.timing.duration = 50 * MS_PER_SEC;
|
||||
assert_equals(anim.currentTime, 75 * MS_PER_SEC,
|
||||
'Hold time should not be updated');
|
||||
}, 'Updating the finished state when there is a pending task');
|
||||
|
||||
// CASE 7: start time unresolved
|
||||
|
||||
// Did seek = false
|
||||
promise_test(function(t) {
|
||||
var anim = createDiv(t).animate(null, 100 * MS_PER_SEC);
|
||||
anim.cancel();
|
||||
// Make it so that only the start time is unresolved (to avoid overlapping
|
||||
// with the test case where current time is unresolved)
|
||||
anim.currentTime = 150 * MS_PER_SEC;
|
||||
// Trigger a change that will cause the "update the finished state"
|
||||
// procedure to run (did seek = false).
|
||||
anim.effect.timing.duration = 200 * MS_PER_SEC;
|
||||
return waitForAnimationFrames(1).then(function() {
|
||||
assert_equals(anim.currentTime, 150 * MS_PER_SEC,
|
||||
'The animation hold time should not be updated');
|
||||
assert_equals(anim.startTime, null,
|
||||
'The animation start time should not be updated');
|
||||
});
|
||||
}, 'Updating the finished state when start time is unresolved and'
|
||||
+ ' did seek = false');
|
||||
|
||||
// Did seek = true
|
||||
test(function(t) {
|
||||
var anim = createDiv(t).animate(null, 100 * MS_PER_SEC);
|
||||
anim.cancel();
|
||||
anim.currentTime = 150 * MS_PER_SEC;
|
||||
// Trigger a change that will cause the "update the finished state"
|
||||
// procedure to run.
|
||||
anim.currentTime = 50 * MS_PER_SEC;
|
||||
assert_equals(anim.currentTime, 50 * MS_PER_SEC,
|
||||
'The animation hold time should not be updated');
|
||||
assert_equals(anim.startTime, null,
|
||||
'The animation start time should not be updated');
|
||||
}, 'Updating the finished state when start time is unresolved and'
|
||||
+ ' did seek = true');
|
||||
|
||||
</script>
|
||||
</body>
|
||||
Loading…
Add table
Add a link
Reference in a new issue