mirror of
https://github.com/servo/servo.git
synced 2025-08-09 23:45:35 +01:00
Update web-platform-tests to revision e87f38097902e16348d4e17f4fe3bc2d0112bff1
This commit is contained in:
parent
2f8fa32e91
commit
db5631a086
381 changed files with 11610 additions and 4232 deletions
|
@ -20,13 +20,13 @@ test(t => {
|
|||
iterations: 10,
|
||||
iterationComposite: 'accumulate' });
|
||||
|
||||
anim.currentTime = anim.effect.timing.duration / 2;
|
||||
anim.currentTime = anim.effect.getComputedTiming().duration / 2;
|
||||
assert_equals(getComputedStyle(div).alignContent, 'flex-end',
|
||||
'Animated align-content style at 50s of the first iteration');
|
||||
anim.currentTime = anim.effect.timing.duration * 2;
|
||||
anim.currentTime = anim.effect.getComputedTiming().duration * 2;
|
||||
assert_equals(getComputedStyle(div).alignContent, 'flex-start',
|
||||
'Animated align-content style at 0s of the third iteration');
|
||||
anim.currentTime += anim.effect.timing.duration / 2;
|
||||
anim.currentTime += anim.effect.getComputedTiming().duration / 2;
|
||||
assert_equals(getComputedStyle(div).alignContent, 'flex-end',
|
||||
'Animated align-content style at 50s of the third iteration');
|
||||
}, 'iteration composition of discrete type animation (align-content)');
|
||||
|
@ -41,13 +41,13 @@ test(t => {
|
|||
iterationComposite: 'accumulate' });
|
||||
anim.pause();
|
||||
|
||||
anim.currentTime = anim.effect.timing.duration / 2;
|
||||
anim.currentTime = anim.effect.getComputedTiming().duration / 2;
|
||||
assert_equals(getComputedStyle(div).marginLeft, '5px',
|
||||
'Animated margin-left style at 50s of the first iteration');
|
||||
anim.currentTime = anim.effect.timing.duration * 2;
|
||||
anim.currentTime = anim.effect.getComputedTiming().duration * 2;
|
||||
assert_equals(getComputedStyle(div).marginLeft, '20px',
|
||||
'Animated margin-left style at 0s of the third iteration');
|
||||
anim.currentTime += anim.effect.timing.duration / 2;
|
||||
anim.currentTime += anim.effect.getComputedTiming().duration / 2;
|
||||
assert_equals(getComputedStyle(div).marginLeft, '25px',
|
||||
'Animated margin-left style at 50s of the third iteration');
|
||||
}, 'iteration composition of <length> type animation');
|
||||
|
@ -66,13 +66,13 @@ test(t => {
|
|||
iterationComposite: 'accumulate' });
|
||||
anim.pause();
|
||||
|
||||
anim.currentTime = anim.effect.timing.duration / 2;
|
||||
anim.currentTime = anim.effect.getComputedTiming().duration / 2;
|
||||
assert_equals(getComputedStyle(div).width, '25px',
|
||||
'Animated width style at 50s of the first iteration');
|
||||
anim.currentTime = anim.effect.timing.duration * 2;
|
||||
anim.currentTime = anim.effect.getComputedTiming().duration * 2;
|
||||
assert_equals(getComputedStyle(div).width, '100px',
|
||||
'Animated width style at 0s of the third iteration');
|
||||
anim.currentTime += anim.effect.timing.duration / 2;
|
||||
anim.currentTime += anim.effect.getComputedTiming().duration / 2;
|
||||
assert_equals(getComputedStyle(div).width, '125px',
|
||||
'Animated width style at 50s of the third iteration');
|
||||
}, 'iteration composition of <percentage> type animation');
|
||||
|
@ -87,13 +87,13 @@ test(t => {
|
|||
iterationComposite: 'accumulate' });
|
||||
anim.pause();
|
||||
|
||||
anim.currentTime = anim.effect.timing.duration / 2;
|
||||
anim.currentTime = anim.effect.getComputedTiming().duration / 2;
|
||||
assert_equals(getComputedStyle(div).color, 'rgb(60, 60, 60)',
|
||||
'Animated color style at 50s of the first iteration');
|
||||
anim.currentTime = anim.effect.timing.duration * 2;
|
||||
anim.currentTime = anim.effect.getComputedTiming().duration * 2;
|
||||
assert_equals(getComputedStyle(div).color, 'rgb(240, 240, 240)',
|
||||
'Animated color style at 0s of the third iteration');
|
||||
anim.currentTime += anim.effect.timing.duration / 2;
|
||||
anim.currentTime += anim.effect.getComputedTiming().duration / 2;
|
||||
assert_equals(getComputedStyle(div).color, 'rgb(255, 255, 255)',
|
||||
'Animated color style at 50s of the third iteration');
|
||||
}, 'iteration composition of <color> type animation');
|
||||
|
@ -108,13 +108,13 @@ test(t => {
|
|||
iterationComposite: 'accumulate' });
|
||||
anim.pause();
|
||||
|
||||
anim.currentTime = anim.effect.timing.duration / 2;
|
||||
anim.currentTime = anim.effect.getComputedTiming().duration / 2;
|
||||
assert_equals(getComputedStyle(div).color, 'rgb(30, 90, 30)',
|
||||
'Animated color style at 50s of the first iteration');
|
||||
anim.currentTime = anim.effect.timing.duration * 2;
|
||||
anim.currentTime = anim.effect.getComputedTiming().duration * 2;
|
||||
assert_equals(getComputedStyle(div).color, 'rgb(120, 240, 120)',
|
||||
'Animated color style at 0s of the third iteration');
|
||||
anim.currentTime += anim.effect.timing.duration / 2;
|
||||
anim.currentTime += anim.effect.getComputedTiming().duration / 2;
|
||||
// The green color is (240 + 180) / 2 = 210
|
||||
assert_equals(getComputedStyle(div).color, 'rgb(150, 210, 150)',
|
||||
'Animated color style at 50s of the third iteration');
|
||||
|
@ -131,13 +131,13 @@ test(t => {
|
|||
iterationComposite: 'accumulate' });
|
||||
anim.pause();
|
||||
|
||||
anim.currentTime = anim.effect.timing.duration / 2;
|
||||
anim.currentTime = anim.effect.getComputedTiming().duration / 2;
|
||||
assert_equals(getComputedStyle(div).flexGrow, '5',
|
||||
'Animated flex-grow style at 50s of the first iteration');
|
||||
anim.currentTime = anim.effect.timing.duration * 2;
|
||||
anim.currentTime = anim.effect.getComputedTiming().duration * 2;
|
||||
assert_equals(getComputedStyle(div).flexGrow, '20',
|
||||
'Animated flex-grow style at 0s of the third iteration');
|
||||
anim.currentTime += anim.effect.timing.duration / 2;
|
||||
anim.currentTime += anim.effect.getComputedTiming().duration / 2;
|
||||
assert_equals(getComputedStyle(div).flexGrow, '25',
|
||||
'Animated flex-grow style at 50s of the third iteration');
|
||||
}, 'iteration composition of <number> type animation');
|
||||
|
@ -154,13 +154,13 @@ test(t => {
|
|||
iterationComposite: 'accumulate' });
|
||||
anim.pause();
|
||||
|
||||
anim.currentTime = anim.effect.timing.duration / 2;
|
||||
anim.currentTime = anim.effect.getComputedTiming().duration / 2;
|
||||
assert_equals(getComputedStyle(div).clip, 'rect(5px, 5px, 5px, 5px)',
|
||||
'Animated clip style at 50s of the first iteration');
|
||||
anim.currentTime = anim.effect.timing.duration * 2;
|
||||
anim.currentTime = anim.effect.getComputedTiming().duration * 2;
|
||||
assert_equals(getComputedStyle(div).clip, 'rect(20px, 20px, 20px, 20px)',
|
||||
'Animated clip style at 0s of the third iteration');
|
||||
anim.currentTime += anim.effect.timing.duration / 2;
|
||||
anim.currentTime += anim.effect.getComputedTiming().duration / 2;
|
||||
assert_equals(getComputedStyle(div).clip, 'rect(25px, 25px, 25px, 25px)',
|
||||
'Animated clip style at 50s of the third iteration');
|
||||
}, 'iteration composition of <shape> type animation');
|
||||
|
@ -175,13 +175,13 @@ test(t => {
|
|||
iterationComposite: 'accumulate' });
|
||||
anim.pause();
|
||||
|
||||
anim.currentTime = anim.effect.timing.duration / 2;
|
||||
anim.currentTime = anim.effect.getComputedTiming().duration / 2;
|
||||
assert_equals(getComputedStyle(div).width, '5px',
|
||||
'Animated calc width style at 50s of the first iteration');
|
||||
anim.currentTime = anim.effect.timing.duration * 2;
|
||||
anim.currentTime = anim.effect.getComputedTiming().duration * 2;
|
||||
assert_equals(getComputedStyle(div).width, '20px',
|
||||
'Animated calc width style at 0s of the third iteration');
|
||||
anim.currentTime += anim.effect.timing.duration / 2;
|
||||
anim.currentTime += anim.effect.getComputedTiming().duration / 2;
|
||||
assert_equals(getComputedStyle(div).width, '25px',
|
||||
'Animated calc width style at 50s of the third iteration');
|
||||
}, 'iteration composition of <calc()> value animation');
|
||||
|
@ -200,15 +200,15 @@ test(t => {
|
|||
iterationComposite: 'accumulate' });
|
||||
anim.pause();
|
||||
|
||||
anim.currentTime = anim.effect.timing.duration / 2;
|
||||
anim.currentTime = anim.effect.getComputedTiming().duration / 2;
|
||||
assert_equals(getComputedStyle(div).width, '10px',
|
||||
// 100px * 5% + 5px
|
||||
'Animated calc width style at 50s of the first iteration');
|
||||
anim.currentTime = anim.effect.timing.duration * 2;
|
||||
anim.currentTime = anim.effect.getComputedTiming().duration * 2;
|
||||
assert_equals(getComputedStyle(div).width,
|
||||
'40px', // 100px * (10% + 10%) + (10px + 10px)
|
||||
'Animated calc width style at 0s of the third iteration');
|
||||
anim.currentTime += anim.effect.timing.duration / 2;
|
||||
anim.currentTime += anim.effect.getComputedTiming().duration / 2;
|
||||
assert_equals(getComputedStyle(div).width,
|
||||
'50px', // (40px + 60px) / 2
|
||||
'Animated calc width style at 50s of the third iteration');
|
||||
|
@ -225,13 +225,13 @@ test(t => {
|
|||
iterationComposite: 'accumulate' });
|
||||
anim.pause();
|
||||
|
||||
anim.currentTime = anim.effect.timing.duration / 2;
|
||||
anim.currentTime = anim.effect.getComputedTiming().duration / 2;
|
||||
assert_equals(getComputedStyle(div).opacity, '0.2',
|
||||
'Animated opacity style at 50s of the first iteration');
|
||||
anim.currentTime = anim.effect.timing.duration * 2;
|
||||
anim.currentTime = anim.effect.getComputedTiming().duration * 2;
|
||||
assert_equals(getComputedStyle(div).opacity, '0.8',
|
||||
'Animated opacity style at 0s of the third iteration');
|
||||
anim.currentTime += anim.effect.timing.duration / 2;
|
||||
anim.currentTime += anim.effect.getComputedTiming().duration / 2;
|
||||
assert_equals(getComputedStyle(div).opacity, '1', // (0.8 + 1.2) * 0.5
|
||||
'Animated opacity style at 50s of the third iteration');
|
||||
}, 'iteration composition of opacity animation');
|
||||
|
@ -247,15 +247,15 @@ test(t => {
|
|||
iterationComposite: 'accumulate' });
|
||||
anim.pause();
|
||||
|
||||
anim.currentTime = anim.effect.timing.duration / 2;
|
||||
anim.currentTime = anim.effect.getComputedTiming().duration / 2;
|
||||
assert_equals(getComputedStyle(div).boxShadow,
|
||||
'rgb(60, 60, 60) 5px 5px 5px 0px',
|
||||
'Animated box-shadow style at 50s of the first iteration');
|
||||
anim.currentTime = anim.effect.timing.duration * 2;
|
||||
anim.currentTime = anim.effect.getComputedTiming().duration * 2;
|
||||
assert_equals(getComputedStyle(div).boxShadow,
|
||||
'rgb(240, 240, 240) 20px 20px 20px 0px',
|
||||
'Animated box-shadow style at 0s of the third iteration');
|
||||
anim.currentTime += anim.effect.timing.duration / 2;
|
||||
anim.currentTime += anim.effect.getComputedTiming().duration / 2;
|
||||
assert_equals(getComputedStyle(div).boxShadow,
|
||||
'rgb(255, 255, 255) 25px 25px 25px 0px',
|
||||
'Animated box-shadow style at 50s of the third iteration');
|
||||
|
@ -271,13 +271,13 @@ test(t => {
|
|||
iterationComposite: 'accumulate' });
|
||||
anim.pause();
|
||||
|
||||
anim.currentTime = anim.effect.timing.duration / 2;
|
||||
anim.currentTime = anim.effect.getComputedTiming().duration / 2;
|
||||
assert_equals(getComputedStyle(div).filter, 'blur(5px)',
|
||||
'Animated filter blur style at 50s of the first iteration');
|
||||
anim.currentTime = anim.effect.timing.duration * 2;
|
||||
anim.currentTime = anim.effect.getComputedTiming().duration * 2;
|
||||
assert_equals(getComputedStyle(div).filter, 'blur(20px)',
|
||||
'Animated filter blur style at 0s of the third iteration');
|
||||
anim.currentTime += anim.effect.timing.duration / 2;
|
||||
anim.currentTime += anim.effect.getComputedTiming().duration / 2;
|
||||
assert_equals(getComputedStyle(div).filter, 'blur(25px)',
|
||||
'Animated filter blur style at 50s of the third iteration');
|
||||
}, 'iteration composition of filter blur animation');
|
||||
|
@ -293,15 +293,15 @@ test(t => {
|
|||
iterationComposite: 'accumulate' });
|
||||
anim.pause();
|
||||
|
||||
anim.currentTime = anim.effect.timing.duration / 2;
|
||||
anim.currentTime = anim.effect.getComputedTiming().duration / 2;
|
||||
assert_equals(getComputedStyle(div).filter,
|
||||
'brightness(1.4)',
|
||||
'Animated filter brightness style at 50s of the first iteration');
|
||||
anim.currentTime = anim.effect.timing.duration * 2;
|
||||
anim.currentTime = anim.effect.getComputedTiming().duration * 2;
|
||||
assert_equals(getComputedStyle(div).filter,
|
||||
'brightness(2.6)', // brightness(1) + brightness(0.8) + brightness(0.8)
|
||||
'Animated filter brightness style at 0s of the third iteration');
|
||||
anim.currentTime += anim.effect.timing.duration / 2;
|
||||
anim.currentTime += anim.effect.getComputedTiming().duration / 2;
|
||||
assert_equals(getComputedStyle(div).filter,
|
||||
'brightness(3)', // (brightness(2.6) + brightness(3.4)) * 0.5
|
||||
'Animated filter brightness style at 50s of the third iteration');
|
||||
|
@ -318,15 +318,15 @@ test(t => {
|
|||
iterationComposite: 'accumulate' });
|
||||
anim.pause();
|
||||
|
||||
anim.currentTime = anim.effect.timing.duration / 2;
|
||||
anim.currentTime = anim.effect.getComputedTiming().duration / 2;
|
||||
assert_equals(getComputedStyle(div).filter,
|
||||
'brightness(0.5)',
|
||||
'Animated filter brightness style at 50s of the first iteration');
|
||||
anim.currentTime = anim.effect.timing.duration * 2;
|
||||
anim.currentTime = anim.effect.getComputedTiming().duration * 2;
|
||||
assert_equals(getComputedStyle(div).filter,
|
||||
'brightness(0)', // brightness(1) is an identity element, not accumulated.
|
||||
'Animated filter brightness style at 0s of the third iteration');
|
||||
anim.currentTime += anim.effect.timing.duration / 2;
|
||||
anim.currentTime += anim.effect.getComputedTiming().duration / 2;
|
||||
assert_equals(getComputedStyle(div).filter,
|
||||
'brightness(0.5)', // brightness(1) is an identity element, not accumulated.
|
||||
'Animated filter brightness style at 50s of the third iteration');
|
||||
|
@ -343,15 +343,15 @@ test(t => {
|
|||
iterationComposite: 'accumulate' });
|
||||
anim.pause();
|
||||
|
||||
anim.currentTime = anim.effect.timing.duration / 2;
|
||||
anim.currentTime = anim.effect.getComputedTiming().duration / 2;
|
||||
assert_equals(getComputedStyle(div).filter,
|
||||
'drop-shadow(rgb(60, 60, 60) 5px 5px 5px)',
|
||||
'Animated filter drop-shadow style at 50s of the first iteration');
|
||||
anim.currentTime = anim.effect.timing.duration * 2;
|
||||
anim.currentTime = anim.effect.getComputedTiming().duration * 2;
|
||||
assert_equals(getComputedStyle(div).filter,
|
||||
'drop-shadow(rgb(240, 240, 240) 20px 20px 20px)',
|
||||
'Animated filter drop-shadow style at 0s of the third iteration');
|
||||
anim.currentTime += anim.effect.timing.duration / 2;
|
||||
anim.currentTime += anim.effect.getComputedTiming().duration / 2;
|
||||
assert_equals(getComputedStyle(div).filter,
|
||||
'drop-shadow(rgb(255, 255, 255) 25px 25px 25px)',
|
||||
'Animated filter drop-shadow style at 50s of the third iteration');
|
||||
|
@ -368,15 +368,15 @@ test(t => {
|
|||
iterationComposite: 'accumulate' });
|
||||
anim.pause();
|
||||
|
||||
anim.currentTime = anim.effect.timing.duration / 2;
|
||||
anim.currentTime = anim.effect.getComputedTiming().duration / 2;
|
||||
assert_equals(getComputedStyle(div).filter,
|
||||
'brightness(1.5) contrast(1.5)',
|
||||
'Animated filter list at 50s of the first iteration');
|
||||
anim.currentTime = anim.effect.timing.duration * 2;
|
||||
anim.currentTime = anim.effect.getComputedTiming().duration * 2;
|
||||
assert_equals(getComputedStyle(div).filter,
|
||||
'brightness(3) contrast(3)',
|
||||
'Animated filter list at 0s of the third iteration');
|
||||
anim.currentTime += anim.effect.timing.duration / 2;
|
||||
anim.currentTime += anim.effect.getComputedTiming().duration / 2;
|
||||
assert_equals(getComputedStyle(div).filter,
|
||||
'brightness(3.5) contrast(3.5)',
|
||||
'Animated filter list at 50s of the third iteration');
|
||||
|
@ -393,18 +393,18 @@ test(t => {
|
|||
iterationComposite: 'accumulate' });
|
||||
anim.pause();
|
||||
|
||||
anim.currentTime = anim.effect.timing.duration / 2;
|
||||
anim.currentTime = anim.effect.getComputedTiming().duration / 2;
|
||||
assert_equals(getComputedStyle(div).filter,
|
||||
'contrast(2) brightness(2)', // discrete
|
||||
'Animated filter list at 50s of the first iteration');
|
||||
anim.currentTime = anim.effect.timing.duration * 2;
|
||||
anim.currentTime = anim.effect.getComputedTiming().duration * 2;
|
||||
assert_equals(getComputedStyle(div).filter,
|
||||
// We can't accumulate 'contrast(2) brightness(2)' onto
|
||||
// the first list 'brightness(1) contrast(1)' because of
|
||||
// mismatch of the order.
|
||||
'brightness(1) contrast(1)',
|
||||
'Animated filter list at 0s of the third iteration');
|
||||
anim.currentTime += anim.effect.timing.duration / 2;
|
||||
anim.currentTime += anim.effect.getComputedTiming().duration / 2;
|
||||
assert_equals(getComputedStyle(div).filter,
|
||||
// We *can* accumulate 'contrast(2) brightness(2)' onto
|
||||
// the same list 'contrast(2) brightness(2)' here.
|
||||
|
@ -424,15 +424,15 @@ test(t => {
|
|||
iterationComposite: 'accumulate' });
|
||||
anim.pause();
|
||||
|
||||
anim.currentTime = anim.effect.timing.duration / 2;
|
||||
anim.currentTime = anim.effect.getComputedTiming().duration / 2;
|
||||
assert_equals(getComputedStyle(div).filter,
|
||||
'sepia(0.5) contrast(1.5)',
|
||||
'Animated filter list at 50s of the first iteration');
|
||||
anim.currentTime = anim.effect.timing.duration * 2;
|
||||
anim.currentTime = anim.effect.getComputedTiming().duration * 2;
|
||||
assert_equals(getComputedStyle(div).filter,
|
||||
'sepia(2) contrast(3)',
|
||||
'Animated filter list at 0s of the third iteration');
|
||||
anim.currentTime += anim.effect.timing.duration / 2;
|
||||
anim.currentTime += anim.effect.getComputedTiming().duration / 2;
|
||||
assert_equals(getComputedStyle(div).filter,
|
||||
'sepia(2.5) contrast(3.5)',
|
||||
'Animated filter list at 50s of the third iteration');
|
||||
|
@ -448,15 +448,15 @@ test(t => {
|
|||
iterationComposite: 'accumulate' });
|
||||
anim.pause();
|
||||
|
||||
anim.currentTime = anim.effect.timing.duration / 2;
|
||||
anim.currentTime = anim.effect.getComputedTiming().duration / 2;
|
||||
assert_matrix_equals(getComputedStyle(div).transform,
|
||||
'matrix(0, 1, -1, 0, 0, 0)', // rotate(90deg)
|
||||
'Animated transform(rotate) style at 50s of the first iteration');
|
||||
anim.currentTime = anim.effect.timing.duration * 2;
|
||||
anim.currentTime = anim.effect.getComputedTiming().duration * 2;
|
||||
assert_matrix_equals(getComputedStyle(div).transform,
|
||||
'matrix(1, 0, 0, 1, 0, 0)', // rotate(360deg)
|
||||
'Animated transform(rotate) style at 0s of the third iteration');
|
||||
anim.currentTime += anim.effect.timing.duration / 2;
|
||||
anim.currentTime += anim.effect.getComputedTiming().duration / 2;
|
||||
assert_matrix_equals(getComputedStyle(div).transform,
|
||||
'matrix(0, 1, -1, 0, 0, 0)', // rotate(450deg)
|
||||
'Animated transform(rotate) style at 50s of the third iteration');
|
||||
|
@ -472,16 +472,16 @@ test(t => {
|
|||
iterationComposite: 'accumulate' });
|
||||
anim.pause();
|
||||
|
||||
anim.currentTime = anim.effect.timing.duration / 2;
|
||||
anim.currentTime = anim.effect.getComputedTiming().duration / 2;
|
||||
assert_matrix_equals(getComputedStyle(div).transform,
|
||||
'matrix(0.5, 0, 0, 0.5, 0, 0)', // scale(0.5)
|
||||
'Animated transform(scale) style at 50s of the first iteration');
|
||||
anim.currentTime = anim.effect.timing.duration * 2;
|
||||
anim.currentTime = anim.effect.getComputedTiming().duration * 2;
|
||||
assert_matrix_equals(getComputedStyle(div).transform,
|
||||
'matrix(0, 0, 0, 0, 0, 0)', // scale(0); scale(1) is an identity element,
|
||||
// not accumulated.
|
||||
'Animated transform(scale) style at 0s of the third iteration');
|
||||
anim.currentTime += anim.effect.timing.duration / 2;
|
||||
anim.currentTime += anim.effect.getComputedTiming().duration / 2;
|
||||
assert_matrix_equals(getComputedStyle(div).transform,
|
||||
'matrix(0.5, 0, 0, 0.5, 0, 0)', // scale(0.5); scale(1) an identity
|
||||
// element, not accumulated.
|
||||
|
@ -498,15 +498,15 @@ test(t => {
|
|||
iterationComposite: 'accumulate' });
|
||||
anim.pause();
|
||||
|
||||
anim.currentTime = anim.effect.timing.duration / 2;
|
||||
anim.currentTime = anim.effect.getComputedTiming().duration / 2;
|
||||
assert_matrix_equals(getComputedStyle(div).transform,
|
||||
'matrix(1.5, 0, 0, 1.5, 0, 0)', // scale(1.5)
|
||||
'Animated transform(scale) style at 50s of the first iteration');
|
||||
anim.currentTime = anim.effect.timing.duration * 2;
|
||||
anim.currentTime = anim.effect.getComputedTiming().duration * 2;
|
||||
assert_matrix_equals(getComputedStyle(div).transform,
|
||||
'matrix(3, 0, 0, 3, 0, 0)', // scale(1 + (2 -1) + (2 -1))
|
||||
'Animated transform(scale) style at 0s of the third iteration');
|
||||
anim.currentTime += anim.effect.timing.duration / 2;
|
||||
anim.currentTime += anim.effect.getComputedTiming().duration / 2;
|
||||
assert_matrix_equals(getComputedStyle(div).transform,
|
||||
'matrix(3.5, 0, 0, 3.5, 0, 0)', // (scale(3) + scale(4)) * 0.5
|
||||
'Animated transform(scale) style at 50s of the third iteration');
|
||||
|
@ -522,15 +522,15 @@ test(t => {
|
|||
iterationComposite: 'accumulate' });
|
||||
anim.pause();
|
||||
|
||||
anim.currentTime = anim.effect.timing.duration / 2;
|
||||
anim.currentTime = anim.effect.getComputedTiming().duration / 2;
|
||||
assert_matrix_equals(getComputedStyle(div).transform,
|
||||
'matrix(1, 0, 0, 1, 0, 0)', // scale(1)
|
||||
'Animated transform(scale) style at 50s of the first iteration');
|
||||
anim.currentTime = anim.effect.timing.duration * 2;
|
||||
anim.currentTime = anim.effect.getComputedTiming().duration * 2;
|
||||
assert_matrix_equals(getComputedStyle(div).transform,
|
||||
'matrix(2, 0, 0, 2, 0, 0)', // (scale(0) + scale(2-1)*2)
|
||||
'Animated transform(scale) style at 0s of the third iteration');
|
||||
anim.currentTime += anim.effect.timing.duration / 2;
|
||||
anim.currentTime += anim.effect.getComputedTiming().duration / 2;
|
||||
assert_matrix_equals(getComputedStyle(div).transform,
|
||||
'matrix(3, 0, 0, 3, 0, 0)', // (scale(2) + scale(4)) * 0.5
|
||||
'Animated transform(scale) style at 50s of the third iteration');
|
||||
|
@ -547,15 +547,15 @@ test(t => {
|
|||
iterationComposite: 'accumulate' });
|
||||
anim.pause();
|
||||
|
||||
anim.currentTime = anim.effect.timing.duration / 2;
|
||||
anim.currentTime = anim.effect.getComputedTiming().duration / 2;
|
||||
assert_matrix_equals(getComputedStyle(div).transform,
|
||||
'matrix(0, 1, -1, 0, 0, 5)', // rotate(90deg) translateX(5px)
|
||||
'Animated transform list at 50s of the first iteration');
|
||||
anim.currentTime = anim.effect.timing.duration * 2;
|
||||
anim.currentTime = anim.effect.getComputedTiming().duration * 2;
|
||||
assert_matrix_equals(getComputedStyle(div).transform,
|
||||
'matrix(1, 0, 0, 1, 20, 0)', // rotate(360deg) translateX(20px)
|
||||
'Animated transform list at 0s of the third iteration');
|
||||
anim.currentTime += anim.effect.timing.duration / 2;
|
||||
anim.currentTime += anim.effect.getComputedTiming().duration / 2;
|
||||
assert_matrix_equals(getComputedStyle(div).transform,
|
||||
'matrix(0, 1, -1, 0, 0, 25)', // rotate(450deg) translateX(25px)
|
||||
'Animated transform list at 50s of the third iteration');
|
||||
|
@ -572,16 +572,16 @@ test(t => {
|
|||
iterationComposite: 'accumulate' });
|
||||
anim.pause();
|
||||
|
||||
anim.currentTime = anim.effect.timing.duration / 2;
|
||||
anim.currentTime = anim.effect.getComputedTiming().duration / 2;
|
||||
assert_matrix_equals(getComputedStyle(div).transform,
|
||||
'matrix(2.5, 0, 0, 2.5, 15, 0)',
|
||||
'Animated transform of matrix function at 50s of the first iteration');
|
||||
anim.currentTime = anim.effect.timing.duration * 2;
|
||||
anim.currentTime = anim.effect.getComputedTiming().duration * 2;
|
||||
assert_matrix_equals(getComputedStyle(div).transform,
|
||||
// scale(2) + (scale(3-1)*2) + translateX(30px)*2
|
||||
'matrix(6, 0, 0, 6, 60, 0)',
|
||||
'Animated transform of matrix function at 0s of the third iteration');
|
||||
anim.currentTime += anim.effect.timing.duration / 2;
|
||||
anim.currentTime += anim.effect.getComputedTiming().duration / 2;
|
||||
assert_matrix_equals(getComputedStyle(div).transform,
|
||||
// from: matrix(6, 0, 0, 6, 60, 0)
|
||||
// to: matrix(7, 0, 0, 7, 90, 0)
|
||||
|
@ -601,20 +601,20 @@ test(t => {
|
|||
iterationComposite: 'accumulate' });
|
||||
anim.pause();
|
||||
|
||||
anim.currentTime = anim.effect.timing.duration / 2;
|
||||
anim.currentTime = anim.effect.getComputedTiming().duration / 2;
|
||||
assert_matrix_equals(getComputedStyle(div).transform,
|
||||
// Interpolate between matrix(2, 0, 0, 2, 0, 0) = translateX(0px) scale(2)
|
||||
// and matrix(3, 0, 0, 3, 30, 0) = scale(3) translateX(10px)
|
||||
'matrix(2.5, 0, 0, 2.5, 15, 0)',
|
||||
'Animated transform list at 50s of the first iteration');
|
||||
anim.currentTime = anim.effect.timing.duration * 2;
|
||||
anim.currentTime = anim.effect.getComputedTiming().duration * 2;
|
||||
assert_matrix_equals(getComputedStyle(div).transform,
|
||||
// 'from' and 'to' value are mismatched, so accumulate
|
||||
// matrix(2, 0, 0, 2, 0, 0) onto matrix(3, 0, 0, 3, 30, 0) * 2
|
||||
// = scale(2) + (scale(3-1)*2) + translateX(30px)*2
|
||||
'matrix(6, 0, 0, 6, 60, 0)',
|
||||
'Animated transform list at 0s of the third iteration');
|
||||
anim.currentTime += anim.effect.timing.duration / 2;
|
||||
anim.currentTime += anim.effect.getComputedTiming().duration / 2;
|
||||
assert_matrix_equals(getComputedStyle(div).transform,
|
||||
// Interpolate between matrix(6, 0, 0, 6, 60, 0)
|
||||
// and matrix(7, 0, 0, 7, 210, 0) = scale(7) translate(30px)
|
||||
|
@ -636,20 +636,20 @@ test(t => {
|
|||
iterationComposite: 'accumulate' });
|
||||
anim.pause();
|
||||
|
||||
anim.currentTime = anim.effect.timing.duration / 2;
|
||||
anim.currentTime = anim.effect.getComputedTiming().duration / 2;
|
||||
assert_matrix_equals(getComputedStyle(div).transform,
|
||||
// Interpolate between matrix(1, 0, 0, 1, 0, 0) = translateX(0px)
|
||||
// and matrix(2, 0, 0, 2, 20, 0) = scale(2) translateX(10px)
|
||||
'matrix(1.5, 0, 0, 1.5, 10, 0)',
|
||||
'Animated transform list at 50s of the first iteration');
|
||||
anim.currentTime = anim.effect.timing.duration * 2;
|
||||
anim.currentTime = anim.effect.getComputedTiming().duration * 2;
|
||||
assert_matrix_equals(getComputedStyle(div).transform,
|
||||
// 'from' and 'to' value are mismatched, so accumulate
|
||||
// matrix(1, 0, 0, 1, 0, 0) onto matrix(2, 0, 0, 2, 20, 0) * 2
|
||||
// = scale(1) + (scale(2-1)*2) + translateX(20px)*2
|
||||
'matrix(3, 0, 0, 3, 40, 0)',
|
||||
'Animated transform list at 0s of the third iteration');
|
||||
anim.currentTime += anim.effect.timing.duration / 2;
|
||||
anim.currentTime += anim.effect.getComputedTiming().duration / 2;
|
||||
assert_matrix_equals(getComputedStyle(div).transform,
|
||||
// Interpolate between matrix(3, 0, 0, 3, 40, 0)
|
||||
// and matrix(4, 0, 0, 4, 120, 0) =
|
||||
|
@ -670,17 +670,17 @@ test(t => {
|
|||
iterationComposite: 'accumulate' });
|
||||
anim.pause();
|
||||
|
||||
anim.currentTime = anim.effect.timing.duration / 2;
|
||||
anim.currentTime = anim.effect.getComputedTiming().duration / 2;
|
||||
assert_matrix_equals(getComputedStyle(div).transform,
|
||||
// translateX(none) -> translateX(10px) @ 50%
|
||||
'matrix(1, 0, 0, 1, 5, 0)',
|
||||
'Animated transform list at 50s of the first iteration');
|
||||
anim.currentTime = anim.effect.timing.duration * 2;
|
||||
anim.currentTime = anim.effect.getComputedTiming().duration * 2;
|
||||
assert_matrix_equals(getComputedStyle(div).transform,
|
||||
// translateX(10px * 2 + none) -> translateX(10px * 2 + 10px) @ 0%
|
||||
'matrix(1, 0, 0, 1, 20, 0)',
|
||||
'Animated transform list at 0s of the third iteration');
|
||||
anim.currentTime += anim.effect.timing.duration / 2;
|
||||
anim.currentTime += anim.effect.getComputedTiming().duration / 2;
|
||||
assert_matrix_equals(getComputedStyle(div).transform,
|
||||
// translateX(10px * 2 + none) -> translateX(10px * 2 + 10px) @ 50%
|
||||
'matrix(1, 0, 0, 1, 25, 0)',
|
||||
|
@ -704,16 +704,16 @@ test(t => {
|
|||
iterationComposite: 'accumulate' });
|
||||
anim.pause();
|
||||
|
||||
anim.currentTime = anim.effect.timing.duration / 2;
|
||||
anim.currentTime = anim.effect.getComputedTiming().duration / 2;
|
||||
assert_matrix_equals(getComputedStyle(div).transform,
|
||||
'matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 40, 1)',
|
||||
'Animated transform of matrix3d function at 50s of the first iteration');
|
||||
anim.currentTime = anim.effect.timing.duration * 2;
|
||||
anim.currentTime = anim.effect.getComputedTiming().duration * 2;
|
||||
assert_matrix_equals(getComputedStyle(div).transform,
|
||||
// translateZ(30px) + (translateZ(50px)*2)
|
||||
'matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 130, 1)',
|
||||
'Animated transform of matrix3d function at 0s of the third iteration');
|
||||
anim.currentTime += anim.effect.timing.duration / 2;
|
||||
anim.currentTime += anim.effect.getComputedTiming().duration / 2;
|
||||
assert_matrix_equals(getComputedStyle(div).transform,
|
||||
// from: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 130, 1)
|
||||
// to: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 150, 1)
|
||||
|
@ -736,11 +736,11 @@ test(t => {
|
|||
assert_matrix_equals(getComputedStyle(div).transform,
|
||||
'matrix(1, 0, 0, 1, 0, 0)', // Actually not rotated at all.
|
||||
'Animated transform of rotate3d function at 50s of the first iteration');
|
||||
anim.currentTime = anim.effect.timing.duration * 2;
|
||||
anim.currentTime = anim.effect.getComputedTiming().duration * 2;
|
||||
assert_matrix_equals(getComputedStyle(div).transform,
|
||||
rotate3dToMatrix3d(1, 1, 0, Math.PI), // 180deg
|
||||
'Animated transform of rotate3d function at 0s of the third iteration');
|
||||
anim.currentTime += anim.effect.timing.duration / 2;
|
||||
anim.currentTime += anim.effect.getComputedTiming().duration / 2;
|
||||
assert_matrix_equals(getComputedStyle(div).transform,
|
||||
rotate3dToMatrix3d(1, 1, 0, 225 * Math.PI / 180), //((270 + 180) * 0.5)deg
|
||||
'Animated transform of rotate3d function at 50s of the third iteration');
|
||||
|
@ -756,13 +756,13 @@ test(t => {
|
|||
iterationComposite: 'accumulate' });
|
||||
anim.pause();
|
||||
|
||||
anim.currentTime = anim.effect.timing.duration / 2;
|
||||
anim.currentTime = anim.effect.getComputedTiming().duration / 2;
|
||||
assert_equals(getComputedStyle(div).marginLeft, '15px',
|
||||
'Animated margin-left style at 50s of the first iteration');
|
||||
anim.currentTime = anim.effect.timing.duration * 2;
|
||||
anim.currentTime = anim.effect.getComputedTiming().duration * 2;
|
||||
assert_equals(getComputedStyle(div).marginLeft, '50px', // 10px + 20px + 20px
|
||||
'Animated margin-left style at 0s of the third iteration');
|
||||
anim.currentTime += anim.effect.timing.duration / 2;
|
||||
anim.currentTime += anim.effect.getComputedTiming().duration / 2;
|
||||
assert_equals(getComputedStyle(div).marginLeft, '55px', // (50px + 60px) * 0.5
|
||||
'Animated margin-left style at 50s of the third iteration');
|
||||
}, 'iteration composition starts with non-zero value animation');
|
||||
|
@ -777,15 +777,15 @@ test(t => {
|
|||
iterationComposite: 'accumulate' });
|
||||
anim.pause();
|
||||
|
||||
anim.currentTime = anim.effect.timing.duration / 2;
|
||||
anim.currentTime = anim.effect.getComputedTiming().duration / 2;
|
||||
assert_equals(getComputedStyle(div).marginLeft,
|
||||
'0px',
|
||||
'Animated margin-left style at 50s of the first iteration');
|
||||
anim.currentTime = anim.effect.timing.duration * 2;
|
||||
anim.currentTime = anim.effect.getComputedTiming().duration * 2;
|
||||
assert_equals(getComputedStyle(div).marginLeft,
|
||||
'-10px', // 10px + -10px + -10px
|
||||
'Animated margin-left style at 0s of the third iteration');
|
||||
anim.currentTime += anim.effect.timing.duration / 2;
|
||||
anim.currentTime += anim.effect.getComputedTiming().duration / 2;
|
||||
assert_equals(getComputedStyle(div).marginLeft,
|
||||
'-20px', // (-10px + -30px) * 0.5
|
||||
'Animated margin-left style at 50s of the third iteration');
|
||||
|
@ -801,17 +801,22 @@ test(t => {
|
|||
anim.pause();
|
||||
|
||||
anim.currentTime =
|
||||
anim.effect.timing.duration * 2 + anim.effect.timing.duration / 2;
|
||||
anim.effect.getComputedTiming().duration * 2 +
|
||||
anim.effect.getComputedTiming().duration / 2;
|
||||
assert_equals(getComputedStyle(div).marginLeft, '25px',
|
||||
'Animated style at 50s of the third iteration');
|
||||
|
||||
// double its duration.
|
||||
anim.effect.timing.duration = anim.effect.timing.duration * 2;
|
||||
anim.effect.updateTiming({
|
||||
duration: anim.effect.getComputedTiming().duration * 2
|
||||
});
|
||||
assert_equals(getComputedStyle(div).marginLeft, '12.5px',
|
||||
'Animated style at 25s of the first iteration');
|
||||
|
||||
// half of original.
|
||||
anim.effect.timing.duration = anim.effect.timing.duration / 4;
|
||||
anim.effect.updateTiming({
|
||||
duration: anim.effect.getComputedTiming().duration / 4
|
||||
});
|
||||
assert_equals(getComputedStyle(div).marginLeft, '50px',
|
||||
'Animated style at 50s of the fourth iteration');
|
||||
}, 'duration changes with an iteration composition operation of accumulate');
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
<script src="../../resources/easing-tests.js"></script>
|
||||
<script src="../../resources/keyframe-utils.js"></script>
|
||||
<script src="../../resources/keyframe-tests.js"></script>
|
||||
<script src="../../resources/timing-utils.js"></script>
|
||||
<script src="../../resources/timing-tests.js"></script>
|
||||
<body>
|
||||
<div id="log"></div>
|
||||
<iframe width="10" height="10" id="iframe"></iframe>
|
||||
|
@ -17,8 +19,7 @@
|
|||
// Tests on Element
|
||||
|
||||
test(t => {
|
||||
const div = createDiv(t);
|
||||
const anim = div.animate(null);
|
||||
const anim = createDiv(t).animate(null);
|
||||
assert_class_string(anim, 'Animation', 'Returned object is an Animation');
|
||||
}, 'Element.animate() creates an Animation object');
|
||||
|
||||
|
@ -57,26 +58,9 @@ test(t => {
|
|||
}, 'Element.animate() creates an Animation object with a KeyframeEffect'
|
||||
+ ' that is created in the relevant realm of the target element');
|
||||
|
||||
test(t => {
|
||||
const iframe = window.frames[0];
|
||||
const div = createDiv(t, iframe.document);
|
||||
const anim = div.animate(null);
|
||||
assert_equals(Object.getPrototypeOf(anim.effect.timing),
|
||||
iframe.AnimationEffectTiming.prototype,
|
||||
'The prototype of the created AnimationEffectTiming is that'
|
||||
+ ' defined on the relevant global for the target element');
|
||||
assert_not_equals(Object.getPrototypeOf(anim.effect.timing),
|
||||
AnimationEffectTiming.prototype,
|
||||
'The prototype of the created AnimationEffectTiming is NOT'
|
||||
+ ' that of the current global');
|
||||
}, 'Element.animate() creates an Animation object with a KeyframeEffect'
|
||||
+ ' whose AnimationEffectTiming object is created in the relevant realm'
|
||||
+ ' of the target element');
|
||||
|
||||
for (const subtest of gEmptyKeyframeListTests) {
|
||||
test(t => {
|
||||
const div = createDiv(t);
|
||||
const anim = div.animate(subtest, 2000);
|
||||
const anim = createDiv(t).animate(subtest, 2000);
|
||||
assert_not_equals(anim, null);
|
||||
}, 'Element.animate() accepts empty keyframe lists ' +
|
||||
`(input: ${JSON.stringify(subtest)})`);
|
||||
|
@ -84,8 +68,7 @@ for (const subtest of gEmptyKeyframeListTests) {
|
|||
|
||||
for (const subtest of gKeyframesTests) {
|
||||
test(t => {
|
||||
const div = createDiv(t);
|
||||
const anim = div.animate(subtest.input, 2000);
|
||||
const anim = createDiv(t).animate(subtest.input, 2000);
|
||||
assert_frame_lists_equal(anim.effect.getKeyframes(), subtest.output);
|
||||
}, `Element.animate() accepts ${subtest.desc}`);
|
||||
}
|
||||
|
@ -99,54 +82,101 @@ for (const subtest of gInvalidKeyframesTests) {
|
|||
}, `Element.animate() does not accept ${subtest.desc}`);
|
||||
}
|
||||
|
||||
test(t => {
|
||||
const anim = createDiv(t).animate(null, 2000);
|
||||
assert_equals(anim.effect.getTiming().duration, 2000);
|
||||
assert_default_timing_except(anim.effect, ['duration']);
|
||||
}, 'Element.animate() accepts a double as an options argument');
|
||||
|
||||
test(t => {
|
||||
const anim = createDiv(t).animate(null,
|
||||
{ duration: Infinity, fill: 'forwards' });
|
||||
assert_equals(anim.effect.getTiming().duration, Infinity);
|
||||
assert_equals(anim.effect.getTiming().fill, 'forwards');
|
||||
assert_default_timing_except(anim.effect, ['duration', 'fill']);
|
||||
}, 'Element.animate() accepts a KeyframeAnimationOptions argument');
|
||||
|
||||
test(t => {
|
||||
const anim = createDiv(t).animate(null);
|
||||
assert_default_timing_except(anim.effect, []);
|
||||
}, 'Element.animate() accepts an absent options argument');
|
||||
|
||||
for (const invalid of gBadDelayValues) {
|
||||
test(t => {
|
||||
assert_throws(new TypeError, () => {
|
||||
createDiv(t).animate(null, { delay: invalid });
|
||||
});
|
||||
}, `Element.animate() does not accept invalid delay value: ${invalid}`);
|
||||
}
|
||||
|
||||
test(t => {
|
||||
const anim = createDiv(t).animate(null, { duration: 'auto' });
|
||||
assert_equals(anim.effect.getTiming().duration, 'auto', 'set duration \'auto\'');
|
||||
assert_equals(anim.effect.getComputedTiming().duration, 0,
|
||||
'getComputedTiming() after set duration \'auto\'');
|
||||
}, 'Element.animate() accepts a duration of \'auto\' using a dictionary'
|
||||
+ ' object');
|
||||
|
||||
for (const invalid of gBadDurationValues) {
|
||||
if (typeof invalid === 'string' && !isNaN(parseFloat(invalid))) {
|
||||
continue;
|
||||
}
|
||||
test(t => {
|
||||
assert_throws(new TypeError, () => {
|
||||
createDiv(t).animate(null, invalid);
|
||||
});
|
||||
}, 'Element.animate() does not accept invalid duration value: '
|
||||
+ (typeof invalid === 'string' ? `"${invalid}"` : invalid));
|
||||
}
|
||||
|
||||
for (const invalid of gBadDurationValues) {
|
||||
test(t => {
|
||||
assert_throws(new TypeError, () => {
|
||||
createDiv(t).animate(null, { duration: invalid });
|
||||
});
|
||||
}, 'Element.animate() does not accept invalid duration value: '
|
||||
+ (typeof invalid === 'string' ? `"${invalid}"` : invalid)
|
||||
+ ' using a dictionary object');
|
||||
}
|
||||
|
||||
for (const invalidEasing of gInvalidEasings) {
|
||||
test(t => {
|
||||
const div = createDiv(t);
|
||||
assert_throws(new TypeError, () => {
|
||||
div.animate({ easing: invalidEasing }, 2000);
|
||||
createDiv(t).animate({ easing: invalidEasing }, 2000);
|
||||
});
|
||||
}, `Element.animate() does not accept invalid easing: '${invalidEasing}'`);
|
||||
}
|
||||
|
||||
test(t => {
|
||||
const div = createDiv(t);
|
||||
const anim = div.animate({ opacity: [ 0, 1 ] }, 2000);
|
||||
assert_equals(anim.effect.timing.duration, 2000);
|
||||
// Also check that unspecified parameters receive their default values
|
||||
assert_equals(anim.effect.timing.fill, 'auto');
|
||||
}, 'Element.animate() accepts a double as an options argument');
|
||||
for (const invalid of gBadIterationStartValues) {
|
||||
test(t => {
|
||||
assert_throws(new TypeError, () => {
|
||||
createDiv(t).animate(null, { iterationStart: invalid });
|
||||
});
|
||||
}, 'Element.animate() does not accept invalid iterationStart value: ' +
|
||||
invalid);
|
||||
}
|
||||
|
||||
for (const invalid of gBadIterationsValues) {
|
||||
test(t => {
|
||||
assert_throws(new TypeError, () => {
|
||||
createDiv(t).animate(null, { iterations: invalid });
|
||||
});
|
||||
}, 'Element.animate() does not accept invalid iterations value: ' +
|
||||
invalid);
|
||||
}
|
||||
|
||||
test(t => {
|
||||
const div = createDiv(t);
|
||||
const anim = div.animate({ opacity: [ 0, 1 ] },
|
||||
{ duration: Infinity, fill: 'forwards' });
|
||||
assert_equals(anim.effect.timing.duration, Infinity);
|
||||
assert_equals(anim.effect.timing.fill, 'forwards');
|
||||
// Also check that unspecified parameters receive their default values
|
||||
assert_equals(anim.effect.timing.direction, 'normal');
|
||||
}, 'Element.animate() accepts a KeyframeAnimationOptions argument');
|
||||
|
||||
test(t => {
|
||||
const div = createDiv(t);
|
||||
const anim = div.animate({ opacity: [ 0, 1 ] });
|
||||
assert_equals(anim.effect.timing.duration, 'auto');
|
||||
}, 'Element.animate() accepts an absent options argument');
|
||||
|
||||
test(t => {
|
||||
const div = createDiv(t);
|
||||
const anim = div.animate({ opacity: [ 0, 1 ] }, 2000);
|
||||
const anim = createDiv(t).animate(null, 2000);
|
||||
assert_equals(anim.id, '');
|
||||
}, 'Element.animate() correctly sets the id attribute when no id is specified');
|
||||
|
||||
test(t => {
|
||||
const div = createDiv(t);
|
||||
const anim = div.animate({ opacity: [ 0, 1 ] }, { id: 'test' });
|
||||
const anim = createDiv(t).animate(null, { id: 'test' });
|
||||
assert_equals(anim.id, 'test');
|
||||
}, 'Element.animate() correctly sets the id attribute');
|
||||
|
||||
test(t => {
|
||||
const div = createDiv(t);
|
||||
const anim = div.animate({ opacity: [ 0, 1 ] }, 2000);
|
||||
const anim = createDiv(t).animate(null, 2000);
|
||||
assert_equals(anim.timeline, document.timeline);
|
||||
}, 'Element.animate() correctly sets the Animation\'s timeline');
|
||||
|
||||
|
@ -157,7 +187,7 @@ async_test(t => {
|
|||
|
||||
iframe.addEventListener('load', t.step_func(() => {
|
||||
const div = createDiv(t, iframe.contentDocument);
|
||||
const anim = div.animate({ opacity: [ 0, 1 ] }, 2000);
|
||||
const anim = div.animate(null, 2000);
|
||||
assert_equals(anim.timeline, iframe.contentDocument.timeline);
|
||||
iframe.remove();
|
||||
t.done();
|
||||
|
@ -168,8 +198,7 @@ async_test(t => {
|
|||
'triggered on an element in a different document');
|
||||
|
||||
test(t => {
|
||||
const div = createDiv(t);
|
||||
const anim = div.animate({ opacity: [ 0, 1 ] }, 2000);
|
||||
const anim = createDiv(t).animate(null, 2000);
|
||||
assert_equals(anim.playState, 'running');
|
||||
}, 'Element.animate() calls play on the Animation');
|
||||
|
||||
|
|
|
@ -75,12 +75,14 @@ test(t => {
|
|||
assert_array_equals(div.getAnimations(), [],
|
||||
'Animation should not be returned when it is finished');
|
||||
|
||||
animation.effect.timing.duration += 100 * MS_PER_SEC;
|
||||
animation.effect.updateTiming({
|
||||
duration: animation.effect.getTiming().duration + 100 * MS_PER_SEC,
|
||||
});
|
||||
assert_array_equals(div.getAnimations(), [animation],
|
||||
'Animation should be returned after extending the'
|
||||
+ ' duration');
|
||||
|
||||
animation.effect.timing.duration = 0;
|
||||
animation.effect.updateTiming({ duration: 0 });
|
||||
assert_array_equals(div.getAnimations(), [],
|
||||
'Animation should not be returned after setting the'
|
||||
+ ' duration to zero');
|
||||
|
@ -91,13 +93,13 @@ test(t => {
|
|||
const div = createDiv(t);
|
||||
const animation = div.animate(null, 100 * MS_PER_SEC);
|
||||
|
||||
animation.effect.timing.endDelay = -200 * MS_PER_SEC;
|
||||
animation.effect.updateTiming({ endDelay: -200 * MS_PER_SEC });
|
||||
assert_array_equals(div.getAnimations(), [],
|
||||
'Animation should not be returned after setting a'
|
||||
+ ' negative end delay such that the end time is less'
|
||||
+ ' than the current time');
|
||||
|
||||
animation.effect.timing.endDelay = 100 * MS_PER_SEC;
|
||||
animation.effect.updateTiming({ endDelay: 100 * MS_PER_SEC });
|
||||
assert_array_equals(div.getAnimations(), [animation],
|
||||
'Animation should be returned after setting a positive'
|
||||
+ ' end delay such that the end time is more than the'
|
||||
|
@ -113,17 +115,17 @@ test(t => {
|
|||
assert_array_equals(div.getAnimations(), [],
|
||||
'Animation should not be returned when it is finished');
|
||||
|
||||
animation.effect.timing.iterations = 10;
|
||||
animation.effect.updateTiming({ iterations: 10 });
|
||||
assert_array_equals(div.getAnimations(), [animation],
|
||||
'Animation should be returned after inreasing the'
|
||||
+ ' number of iterations');
|
||||
|
||||
animation.effect.timing.iterations = 0;
|
||||
animation.effect.updateTiming({ iterations: 0 });
|
||||
assert_array_equals(div.getAnimations(), [],
|
||||
'Animations should not be returned after setting the'
|
||||
+ ' iteration count to zero');
|
||||
|
||||
animation.effect.timing.iterations = Infinity;
|
||||
animation.effect.updateTiming({ iterations: Infinity });
|
||||
assert_array_equals(div.getAnimations(), [animation],
|
||||
'Animation should be returned after inreasing the'
|
||||
+ ' number of iterations to infinity');
|
||||
|
|
|
@ -29,7 +29,7 @@ test(t => {
|
|||
const div = createDiv(t);
|
||||
const animation = div.animate({ marginLeft: ['100px', '200px'] },
|
||||
100 * MS_PER_SEC);
|
||||
animation.effect.timing.easing = 'linear';
|
||||
animation.effect.updateTiming({ easing: 'linear' });
|
||||
animation.cancel();
|
||||
assert_equals(getComputedStyle(div).marginLeft, '0px',
|
||||
'margin-left style is not animated after cancelling');
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
const gTarget = document.getElementById('target');
|
||||
|
||||
function createEffect() {
|
||||
return new KeyframeEffectReadOnly(gTarget, { opacity: [0, 1] });
|
||||
return new KeyframeEffect(gTarget, { opacity: [0, 1] });
|
||||
}
|
||||
|
||||
function createNull() {
|
||||
|
@ -82,10 +82,9 @@ for (const args of gTestArguments) {
|
|||
}
|
||||
|
||||
test(t => {
|
||||
const effect = new KeyframeEffectReadOnly(null,
|
||||
{ left: ['10px', '20px'] },
|
||||
{ duration: 10000,
|
||||
fill: 'forwards' });
|
||||
const effect = new KeyframeEffect(null,
|
||||
{ left: ['10px', '20px'] },
|
||||
{ duration: 10000, fill: 'forwards' });
|
||||
const anim = new Animation(effect, document.timeline);
|
||||
anim.pause();
|
||||
assert_equals(effect.getComputedTiming().progress, 0.0);
|
||||
|
@ -100,7 +99,7 @@ async_test(t => {
|
|||
|
||||
iframe.addEventListener('load', t.step_func(() => {
|
||||
const div = createDiv(t, iframe.contentDocument);
|
||||
const effect = new KeyframeEffectReadOnly(div, null, 10000);
|
||||
const effect = new KeyframeEffect(div, null, 10000);
|
||||
const anim = new Animation(effect);
|
||||
assert_equals(anim.timeline, document.timeline);
|
||||
iframe.remove();
|
||||
|
|
|
@ -14,7 +14,7 @@ test(t => {
|
|||
const anim = new Animation();
|
||||
assert_equals(anim.effect, null, 'initial effect is null');
|
||||
|
||||
const newEffect = new KeyframeEffectReadOnly(createDiv(t), null);
|
||||
const newEffect = new KeyframeEffect(createDiv(t), null);
|
||||
anim.effect = newEffect;
|
||||
assert_equals(anim.effect, newEffect, 'new effect is set');
|
||||
}, 'effect is set correctly.');
|
||||
|
|
|
@ -189,7 +189,7 @@ promise_test(t => {
|
|||
animation.currentTime = HALF_DUR;
|
||||
return animation.ready.then(() => {
|
||||
currentTimeBeforeShortening = animation.currentTime;
|
||||
animation.effect.timing.duration = QUARTER_DUR;
|
||||
animation.effect.updateTiming({ duration: QUARTER_DUR });
|
||||
// Below we use gotNextFrame to check that shortening of the animation
|
||||
// duration causes the finished promise to resolve, rather than it just
|
||||
// getting resolved on the next animation frame. This relies on the fact
|
||||
|
@ -206,7 +206,7 @@ promise_test(t => {
|
|||
assert_equals(animation.currentTime, currentTimeBeforeShortening,
|
||||
'currentTime should be unchanged when duration shortened');
|
||||
const previousFinishedPromise = animation.finished;
|
||||
animation.effect.timing.duration = 100 * MS_PER_SEC;
|
||||
animation.effect.updateTiming({ duration: 100 * MS_PER_SEC });
|
||||
assert_not_equals(animation.finished, previousFinishedPromise,
|
||||
'Finished promise should change after lengthening the ' +
|
||||
'duration causes the animation to become active');
|
||||
|
|
|
@ -10,11 +10,11 @@
|
|||
<script type="text/plain" id="Animation-IDL">
|
||||
enum AnimationPlayState { "idle", "pending", "running", "paused", "finished" };
|
||||
|
||||
[Constructor (optional AnimationEffectReadOnly? effect = null,
|
||||
[Constructor (optional AnimationEffect? effect = null,
|
||||
optional AnimationTimeline? timeline)]
|
||||
interface Animation : EventTarget {
|
||||
attribute DOMString id;
|
||||
attribute AnimationEffectReadOnly? effect;
|
||||
attribute AnimationEffect? effect;
|
||||
attribute AnimationTimeline? timeline;
|
||||
attribute double? startTime;
|
||||
attribute double? currentTime;
|
||||
|
|
|
@ -195,7 +195,5 @@ for (const stest of gEndTimeTests) {
|
|||
|
||||
}, `getComputedTiming().endTime for ${stest.desc}`);
|
||||
}
|
||||
|
||||
done();
|
||||
</script>
|
||||
</body>
|
|
@ -0,0 +1,475 @@
|
|||
<!doctype html>
|
||||
<meta charset=utf-8>
|
||||
<title>AnimationEffect.updateTiming</title>
|
||||
<link rel="help" href="https://drafts.csswg.org/web-animations-1/#dom-animationeffect-updatetiming">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="../../testcommon.js"></script>
|
||||
<script src="../../resources/easing-tests.js"></script>
|
||||
<script src="../../resources/timing-tests.js"></script>
|
||||
<body>
|
||||
<div id="log"></div>
|
||||
<script>
|
||||
'use strict';
|
||||
|
||||
// ------------------------------
|
||||
// delay
|
||||
// ------------------------------
|
||||
|
||||
test(t => {
|
||||
const anim = createDiv(t).animate(null, 100);
|
||||
anim.effect.updateTiming({ delay: 100 });
|
||||
assert_equals(anim.effect.getTiming().delay, 100, 'set delay 100');
|
||||
assert_equals(anim.effect.getComputedTiming().delay, 100,
|
||||
'getComputedTiming() after set delay 100');
|
||||
}, 'Allows setting the delay to a positive number');
|
||||
|
||||
test(t => {
|
||||
const anim = createDiv(t).animate(null, 100);
|
||||
anim.effect.updateTiming({ delay: -100 });
|
||||
assert_equals(anim.effect.getTiming().delay, -100, 'set delay -100');
|
||||
assert_equals(anim.effect.getComputedTiming().delay, -100,
|
||||
'getComputedTiming() after set delay -100');
|
||||
}, 'Allows setting the delay to a negative number');
|
||||
|
||||
test(t => {
|
||||
const anim = createDiv(t).animate(null, 100);
|
||||
anim.effect.updateTiming({ delay: 100 });
|
||||
assert_equals(anim.effect.getComputedTiming().progress, null);
|
||||
assert_equals(anim.effect.getComputedTiming().currentIteration, null);
|
||||
}, 'Allows setting the delay of an animation in progress: positive delay that'
|
||||
+ ' causes the animation to be no longer in-effect');
|
||||
|
||||
test(t => {
|
||||
const anim = createDiv(t).animate(null, { fill: 'both', duration: 100 });
|
||||
anim.effect.updateTiming({ delay: -50 });
|
||||
assert_equals(anim.effect.getComputedTiming().progress, 0.5);
|
||||
}, 'Allows setting the delay of an animation in progress: negative delay that'
|
||||
+ ' seeks into the active interval');
|
||||
|
||||
test(t => {
|
||||
const anim = createDiv(t).animate(null, { fill: 'both', duration: 100 });
|
||||
anim.effect.updateTiming({ delay: -100 });
|
||||
assert_equals(anim.effect.getComputedTiming().progress, 1);
|
||||
assert_equals(anim.effect.getComputedTiming().currentIteration, 0);
|
||||
}, 'Allows setting the delay of an animation in progress: large negative delay'
|
||||
+ ' that causes the animation to be finished');
|
||||
|
||||
for (const invalid of gBadDelayValues) {
|
||||
test(t => {
|
||||
const anim = createDiv(t).animate(null);
|
||||
assert_throws({ name: 'TypeError' }, () => {
|
||||
anim.effect.updateTiming({ delay: invalid });
|
||||
});
|
||||
}, `Throws when setting invalid delay value: ${invalid}`);
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------
|
||||
// endDelay
|
||||
// ------------------------------
|
||||
|
||||
test(t => {
|
||||
const anim = createDiv(t).animate(null, 2000);
|
||||
anim.effect.updateTiming({ endDelay: 123.45 });
|
||||
assert_time_equals_literal(anim.effect.getTiming().endDelay, 123.45,
|
||||
'set endDelay 123.45');
|
||||
assert_time_equals_literal(anim.effect.getComputedTiming().endDelay, 123.45,
|
||||
'getComputedTiming() after set endDelay 123.45');
|
||||
}, 'Allows setting the endDelay to a positive number');
|
||||
|
||||
test(t => {
|
||||
const anim = createDiv(t).animate(null, 2000);
|
||||
anim.effect.updateTiming({ endDelay: -1000 });
|
||||
assert_equals(anim.effect.getTiming().endDelay, -1000, 'set endDelay -1000');
|
||||
assert_equals(anim.effect.getComputedTiming().endDelay, -1000,
|
||||
'getComputedTiming() after set endDelay -1000');
|
||||
}, 'Allows setting the endDelay to a negative number');
|
||||
|
||||
test(t => {
|
||||
const anim = createDiv(t).animate(null, 2000);
|
||||
assert_throws({ name: 'TypeError' }, () => {
|
||||
anim.effect.updateTiming({ endDelay: Infinity });
|
||||
});
|
||||
}, 'Throws when setting the endDelay to infinity');
|
||||
|
||||
test(t => {
|
||||
const anim = createDiv(t).animate(null, 2000);
|
||||
assert_throws({ name: 'TypeError' }, () => {
|
||||
anim.effect.updateTiming({ endDelay: -Infinity });
|
||||
});
|
||||
}, 'Throws when setting the endDelay to negative infinity');
|
||||
|
||||
|
||||
// ------------------------------
|
||||
// fill
|
||||
// ------------------------------
|
||||
|
||||
for (const fill of ['none', 'forwards', 'backwards', 'both']) {
|
||||
test(t => {
|
||||
const anim = createDiv(t).animate(null, 100);
|
||||
anim.effect.updateTiming({ fill });
|
||||
assert_equals(anim.effect.getTiming().fill, fill, 'set fill ' + fill);
|
||||
assert_equals(anim.effect.getComputedTiming().fill, fill,
|
||||
'getComputedTiming() after set fill ' + fill);
|
||||
}, `Allows setting the fill to '${fill}'`);
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------
|
||||
// iterationStart
|
||||
// ------------------------------
|
||||
|
||||
test(t => {
|
||||
const anim = createDiv(t).animate(null,
|
||||
{ iterationStart: 0.2,
|
||||
iterations: 1,
|
||||
fill: 'both',
|
||||
duration: 100,
|
||||
delay: 1 });
|
||||
anim.effect.updateTiming({ iterationStart: 2.5 });
|
||||
assert_time_equals_literal(anim.effect.getComputedTiming().progress, 0.5);
|
||||
assert_equals(anim.effect.getComputedTiming().currentIteration, 2);
|
||||
}, 'Allows setting the iterationStart of an animation in progress:'
|
||||
+ ' backwards-filling');
|
||||
|
||||
test(t => {
|
||||
const anim = createDiv(t).animate(null,
|
||||
{ iterationStart: 0.2,
|
||||
iterations: 1,
|
||||
fill: 'both',
|
||||
duration: 100,
|
||||
delay: 0 });
|
||||
anim.effect.updateTiming({ iterationStart: 2.5 });
|
||||
assert_time_equals_literal(anim.effect.getComputedTiming().progress, 0.5);
|
||||
assert_equals(anim.effect.getComputedTiming().currentIteration, 2);
|
||||
}, 'Allows setting the iterationStart of an animation in progress:'
|
||||
+ ' active phase');
|
||||
|
||||
test(t => {
|
||||
const anim = createDiv(t).animate(null,
|
||||
{ iterationStart: 0.2,
|
||||
iterations: 1,
|
||||
fill: 'both',
|
||||
duration: 100,
|
||||
delay: 0 });
|
||||
anim.finish();
|
||||
anim.effect.updateTiming({ iterationStart: 2.5 });
|
||||
assert_time_equals_literal(anim.effect.getComputedTiming().progress, 0.5);
|
||||
assert_equals(anim.effect.getComputedTiming().currentIteration, 3);
|
||||
}, 'Allows setting the iterationStart of an animation in progress:'
|
||||
+ ' forwards-filling');
|
||||
|
||||
for (const invalid of gBadIterationStartValues) {
|
||||
test(t => {
|
||||
const anim = createDiv(t).animate(null);
|
||||
assert_throws({ name: 'TypeError' }, () => {
|
||||
anim.effect.updateTiming({ iterationStart: invalid });
|
||||
}, `setting ${invalid}`);
|
||||
}, `Throws when setting invalid iterationStart value: ${invalid}`);
|
||||
}
|
||||
|
||||
// ------------------------------
|
||||
// iterations
|
||||
// ------------------------------
|
||||
|
||||
test(t => {
|
||||
const anim = createDiv(t).animate(null, 2000);
|
||||
anim.effect.updateTiming({ iterations: 2 });
|
||||
assert_equals(anim.effect.getTiming().iterations, 2, 'set duration 2');
|
||||
assert_equals(anim.effect.getComputedTiming().iterations, 2,
|
||||
'getComputedTiming() after set iterations 2');
|
||||
}, 'Allows setting iterations to a double value');
|
||||
|
||||
test(t => {
|
||||
const anim = createDiv(t).animate(null, 2000);
|
||||
anim.effect.updateTiming({ iterations: Infinity });
|
||||
assert_equals(anim.effect.getTiming().iterations, Infinity,
|
||||
'set duration Infinity');
|
||||
assert_equals(anim.effect.getComputedTiming().iterations, Infinity,
|
||||
'getComputedTiming() after set iterations Infinity');
|
||||
}, 'Allows setting iterations to infinity');
|
||||
|
||||
for (const invalid of gBadIterationsValues) {
|
||||
test(t => {
|
||||
const anim = createDiv(t).animate(null);
|
||||
assert_throws({ name: 'TypeError' }, () => {
|
||||
anim.effect.updateTiming({ iterations: invalid });
|
||||
});
|
||||
}, `Throws when setting invalid iterations value: ${invalid}`);
|
||||
}
|
||||
|
||||
test(t => {
|
||||
const anim = createDiv(t).animate(null, { duration: 100000, fill: 'both' });
|
||||
|
||||
anim.finish();
|
||||
|
||||
assert_equals(anim.effect.getComputedTiming().progress, 1,
|
||||
'progress when animation is finished');
|
||||
assert_equals(anim.effect.getComputedTiming().currentIteration, 0,
|
||||
'current iteration when animation is finished');
|
||||
|
||||
anim.effect.updateTiming({ iterations: 2 });
|
||||
|
||||
assert_time_equals_literal(anim.effect.getComputedTiming().progress,
|
||||
0,
|
||||
'progress after adding an iteration');
|
||||
assert_time_equals_literal(anim.effect.getComputedTiming().currentIteration,
|
||||
1,
|
||||
'current iteration after adding an iteration');
|
||||
|
||||
anim.effect.updateTiming({ iterations: 0 });
|
||||
|
||||
assert_equals(anim.effect.getComputedTiming().progress, 0,
|
||||
'progress after setting iterations to zero');
|
||||
assert_equals(anim.effect.getComputedTiming().currentIteration, 0,
|
||||
'current iteration after setting iterations to zero');
|
||||
|
||||
anim.effect.updateTiming({ iterations: Infinity });
|
||||
|
||||
assert_equals(anim.effect.getComputedTiming().progress, 0,
|
||||
'progress after setting iterations to Infinity');
|
||||
assert_equals(anim.effect.getComputedTiming().currentIteration, 1,
|
||||
'current iteration after setting iterations to Infinity');
|
||||
}, 'Allows setting the iterations of an animation in progress');
|
||||
|
||||
|
||||
// ------------------------------
|
||||
// duration
|
||||
// ------------------------------
|
||||
|
||||
for (const duration of gGoodDurationValues) {
|
||||
test(t => {
|
||||
const anim = createDiv(t).animate(null, 2000);
|
||||
anim.effect.updateTiming({ duration: duration.specified });
|
||||
if (typeof duration.specified === 'number') {
|
||||
assert_time_equals_literal(anim.effect.getTiming().duration,
|
||||
duration.specified,
|
||||
'Updates specified duration');
|
||||
} else {
|
||||
assert_equals(anim.effect.getTiming().duration, duration.specified,
|
||||
'Updates specified duration');
|
||||
}
|
||||
assert_time_equals_literal(anim.effect.getComputedTiming().duration,
|
||||
duration.computed,
|
||||
'Updates computed duration');
|
||||
}, `Allows setting the duration to ${duration.specified}`);
|
||||
}
|
||||
|
||||
for (const invalid of gBadDurationValues) {
|
||||
test(t => {
|
||||
assert_throws(new TypeError, () => {
|
||||
createDiv(t).animate(null, { duration: invalid });
|
||||
});
|
||||
}, 'Throws when setting invalid duration: '
|
||||
+ (typeof invalid === 'string' ? `"${invalid}"` : invalid));
|
||||
}
|
||||
|
||||
test(t => {
|
||||
const anim = createDiv(t).animate(null, { duration: 100000, fill: 'both' });
|
||||
anim.finish();
|
||||
assert_equals(anim.effect.getComputedTiming().progress, 1,
|
||||
'progress when animation is finished');
|
||||
anim.effect.updateTiming({ duration: anim.effect.getTiming().duration * 2 });
|
||||
assert_time_equals_literal(anim.effect.getComputedTiming().progress, 0.5,
|
||||
'progress after doubling the duration');
|
||||
anim.effect.updateTiming({ duration: 0 });
|
||||
assert_equals(anim.effect.getComputedTiming().progress, 1,
|
||||
'progress after setting duration to zero');
|
||||
anim.effect.updateTiming({ duration: 'auto' });
|
||||
assert_equals(anim.effect.getComputedTiming().progress, 1,
|
||||
'progress after setting duration to \'auto\'');
|
||||
}, 'Allows setting the duration of an animation in progress');
|
||||
|
||||
promise_test(t => {
|
||||
const anim = createDiv(t).animate(null, 100 * MS_PER_SEC);
|
||||
return anim.ready.then(() => {
|
||||
const originalStartTime = anim.startTime;
|
||||
const originalCurrentTime = anim.currentTime;
|
||||
assert_time_equals_literal(
|
||||
anim.effect.getComputedTiming().duration,
|
||||
100 * MS_PER_SEC,
|
||||
'Initial duration should be as set on KeyframeEffect'
|
||||
);
|
||||
|
||||
anim.effect.updateTiming({ duration: 200 * MS_PER_SEC });
|
||||
assert_time_equals_literal(
|
||||
anim.effect.getComputedTiming().duration,
|
||||
200 * MS_PER_SEC,
|
||||
'Effect duration should have been updated'
|
||||
);
|
||||
assert_times_equal(anim.startTime, originalStartTime,
|
||||
'startTime should be unaffected by changing effect ' +
|
||||
'duration');
|
||||
assert_times_equal(anim.currentTime, originalCurrentTime,
|
||||
'currentTime should be unaffected by changing effect ' +
|
||||
'duration');
|
||||
});
|
||||
}, 'Allows setting the duration of an animation in progress such that the' +
|
||||
' the start and current time do not change');
|
||||
|
||||
|
||||
// ------------------------------
|
||||
// direction
|
||||
// ------------------------------
|
||||
|
||||
test(t => {
|
||||
const anim = createDiv(t).animate(null, 2000);
|
||||
|
||||
const directions = ['normal', 'reverse', 'alternate', 'alternate-reverse'];
|
||||
for (const direction of directions) {
|
||||
anim.effect.updateTiming({ direction: direction });
|
||||
assert_equals(anim.effect.getTiming().direction, direction,
|
||||
`set direction to ${direction}`);
|
||||
}
|
||||
}, 'Allows setting the direction to each of the possible keywords');
|
||||
|
||||
test(t => {
|
||||
const anim = createDiv(t).animate(null, {
|
||||
duration: 10000,
|
||||
direction: 'normal',
|
||||
});
|
||||
anim.currentTime = 7000;
|
||||
assert_time_equals_literal(anim.effect.getComputedTiming().progress, 0.7,
|
||||
'progress before updating direction');
|
||||
|
||||
anim.effect.updateTiming({ direction: 'reverse' });
|
||||
|
||||
assert_time_equals_literal(anim.effect.getComputedTiming().progress, 0.3,
|
||||
'progress after updating direction');
|
||||
}, 'Allows setting the direction of an animation in progress from \'normal\' to'
|
||||
+ ' \'reverse\'');
|
||||
|
||||
test(t => {
|
||||
const anim = createDiv(t).animate(null,
|
||||
{ duration: 10000, direction: 'normal' });
|
||||
assert_equals(anim.effect.getComputedTiming().progress, 0,
|
||||
'progress before updating direction');
|
||||
|
||||
anim.effect.updateTiming({ direction: 'reverse' });
|
||||
|
||||
assert_equals(anim.effect.getComputedTiming().progress, 1,
|
||||
'progress after updating direction');
|
||||
}, 'Allows setting the direction of an animation in progress from \'normal\' to'
|
||||
+ ' \'reverse\' while at start of active interval');
|
||||
|
||||
test(t => {
|
||||
const anim = createDiv(t).animate(null,
|
||||
{ fill: 'backwards',
|
||||
duration: 10000,
|
||||
delay: 10000,
|
||||
direction: 'normal' });
|
||||
assert_equals(anim.effect.getComputedTiming().progress, 0,
|
||||
'progress before updating direction');
|
||||
|
||||
anim.effect.updateTiming({ direction: 'reverse' });
|
||||
|
||||
assert_equals(anim.effect.getComputedTiming().progress, 1,
|
||||
'progress after updating direction');
|
||||
}, 'Allows setting the direction of an animation in progress from \'normal\' to'
|
||||
+ ' \'reverse\' while filling backwards');
|
||||
|
||||
test(t => {
|
||||
const anim = createDiv(t).animate(null,
|
||||
{ iterations: 2,
|
||||
duration: 10000,
|
||||
direction: 'normal' });
|
||||
anim.currentTime = 17000;
|
||||
assert_time_equals_literal(anim.effect.getComputedTiming().progress, 0.7,
|
||||
'progress before updating direction');
|
||||
|
||||
anim.effect.updateTiming({ direction: 'alternate' });
|
||||
|
||||
assert_time_equals_literal(anim.effect.getComputedTiming().progress, 0.3,
|
||||
'progress after updating direction');
|
||||
}, 'Allows setting the direction of an animation in progress from \'normal\' to'
|
||||
+ ' \'alternate\'');
|
||||
|
||||
test(t => {
|
||||
const anim = createDiv(t).animate(null,
|
||||
{ iterations: 2,
|
||||
duration: 10000,
|
||||
direction: 'alternate' });
|
||||
anim.currentTime = 17000;
|
||||
assert_time_equals_literal(anim.effect.getComputedTiming().progress, 0.3,
|
||||
'progress before updating direction');
|
||||
|
||||
anim.effect.updateTiming({ direction: 'alternate-reverse' });
|
||||
|
||||
assert_time_equals_literal(anim.effect.getComputedTiming().progress, 0.7,
|
||||
'progress after updating direction');
|
||||
}, 'Allows setting the direction of an animation in progress from \'alternate\''
|
||||
+ ' to \'alternate-reverse\'');
|
||||
|
||||
|
||||
// ------------------------------
|
||||
// easing
|
||||
// ------------------------------
|
||||
|
||||
function assert_progress(animation, currentTime, easingFunction) {
|
||||
animation.currentTime = currentTime;
|
||||
const portion = currentTime / animation.effect.getTiming().duration;
|
||||
assert_approx_equals(animation.effect.getComputedTiming().progress,
|
||||
easingFunction(portion),
|
||||
0.01,
|
||||
'The progress of the animation should be approximately'
|
||||
+ ` ${easingFunction(portion)} at ${currentTime}ms`);
|
||||
}
|
||||
|
||||
for (const options of gEasingTests) {
|
||||
test(t => {
|
||||
const target = createDiv(t);
|
||||
const anim = target.animate(null,
|
||||
{ duration: 1000 * MS_PER_SEC,
|
||||
fill: 'forwards' });
|
||||
anim.effect.updateTiming({ easing: options.easing });
|
||||
assert_equals(anim.effect.getTiming().easing,
|
||||
options.serialization || options.easing);
|
||||
|
||||
const easing = options.easingFunction;
|
||||
assert_progress(anim, 0, easing);
|
||||
assert_progress(anim, 250 * MS_PER_SEC, easing);
|
||||
assert_progress(anim, 500 * MS_PER_SEC, easing);
|
||||
assert_progress(anim, 750 * MS_PER_SEC, easing);
|
||||
assert_progress(anim, 1000 * MS_PER_SEC, easing);
|
||||
}, `Allows setting the easing to a ${options.desc}`);
|
||||
}
|
||||
|
||||
for (const easing of gRoundtripEasings) {
|
||||
test(t => {
|
||||
const anim = createDiv(t).animate(null);
|
||||
anim.effect.updateTiming({ easing: easing });
|
||||
assert_equals(anim.effect.getTiming().easing, easing);
|
||||
}, `Updates the specified value when setting the easing to '${easing}'`);
|
||||
}
|
||||
|
||||
test(t => {
|
||||
const delay = 1000 * MS_PER_SEC;
|
||||
|
||||
const target = createDiv(t);
|
||||
const anim = target.animate(null,
|
||||
{ duration: 1000 * MS_PER_SEC,
|
||||
fill: 'both',
|
||||
delay: delay,
|
||||
easing: 'steps(2, start)' });
|
||||
|
||||
anim.effect.updateTiming({ easing: 'steps(2, end)' });
|
||||
assert_equals(anim.effect.getComputedTiming().progress, 0,
|
||||
'easing replace to steps(2, end) at before phase');
|
||||
|
||||
anim.currentTime = delay + 750 * MS_PER_SEC;
|
||||
assert_equals(anim.effect.getComputedTiming().progress, 0.5,
|
||||
'change currentTime to active phase');
|
||||
|
||||
anim.effect.updateTiming({ easing: 'steps(2, start)' });
|
||||
assert_equals(anim.effect.getComputedTiming().progress, 1,
|
||||
'easing replace to steps(2, start) at active phase');
|
||||
|
||||
anim.currentTime = delay + 1500 * MS_PER_SEC;
|
||||
anim.effect.updateTiming({ easing: 'steps(2, end)' });
|
||||
assert_equals(anim.effect.getComputedTiming().progress, 1,
|
||||
'easing replace to steps(2, end) again at after phase');
|
||||
}, 'Allows setting the easing of an animation in progress');
|
||||
|
||||
</script>
|
||||
</body>
|
|
@ -1,78 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset=utf-8>
|
||||
<title>AnimationEffectTiming.delay</title>
|
||||
<link rel="help" href="https://drafts.csswg.org/web-animations/#dom-animationeffecttiming-delay">
|
||||
<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(t => {
|
||||
const anim = createDiv(t).animate(null);
|
||||
assert_equals(anim.effect.timing.delay, 0);
|
||||
}, 'Has the default value 0');
|
||||
|
||||
test(t => {
|
||||
const div = createDiv(t);
|
||||
const anim = div.animate({ opacity: [ 0, 1 ] }, 100);
|
||||
anim.effect.timing.delay = 100;
|
||||
assert_equals(anim.effect.timing.delay, 100, 'set delay 100');
|
||||
assert_equals(anim.effect.getComputedTiming().delay, 100,
|
||||
'getComputedTiming() after set delay 100');
|
||||
}, 'Can be set to a positive number');
|
||||
|
||||
test(t => {
|
||||
const div = createDiv(t);
|
||||
const anim = div.animate({ opacity: [ 0, 1 ] }, 100);
|
||||
anim.effect.timing.delay = -100;
|
||||
assert_equals(anim.effect.timing.delay, -100, 'set delay -100');
|
||||
assert_equals(anim.effect.getComputedTiming().delay, -100,
|
||||
'getComputedTiming() after set delay -100');
|
||||
}, 'Can be set to a negative number');
|
||||
|
||||
test(t => {
|
||||
const div = createDiv(t);
|
||||
const anim = div.animate({ opacity: [ 0, 1 ] }, 100);
|
||||
anim.effect.timing.delay = 100;
|
||||
assert_equals(anim.effect.getComputedTiming().progress, null);
|
||||
assert_equals(anim.effect.getComputedTiming().currentIteration, null);
|
||||
}, 'Can set a positive delay on an animation without a backwards fill to'
|
||||
+ ' make it no longer active');
|
||||
|
||||
test(t => {
|
||||
const div = createDiv(t);
|
||||
const anim = div.animate({ opacity: [ 0, 1 ] },
|
||||
{ fill: 'both',
|
||||
duration: 100 });
|
||||
anim.effect.timing.delay = -50;
|
||||
assert_equals(anim.effect.getComputedTiming().progress, 0.5);
|
||||
}, 'Can set a negative delay to seek into the active interval');
|
||||
|
||||
test(t => {
|
||||
const div = createDiv(t);
|
||||
const anim = div.animate({ opacity: [ 0, 1 ] },
|
||||
{ fill: 'both',
|
||||
duration: 100 });
|
||||
anim.effect.timing.delay = -100;
|
||||
assert_equals(anim.effect.getComputedTiming().progress, 1);
|
||||
assert_equals(anim.effect.getComputedTiming().currentIteration, 0);
|
||||
}, 'Can set a large negative delay to finishing an animation');
|
||||
|
||||
test(t => {
|
||||
const div = createDiv(t);
|
||||
const anim = div.animate(null);
|
||||
for (let invalid of [NaN, Infinity]) {
|
||||
assert_throws({ name: 'TypeError' }, () => {
|
||||
anim.effect.timing.delay = invalid;
|
||||
}, `setting ${invalid}`);
|
||||
assert_throws({ name: 'TypeError' }, () => {
|
||||
div.animate({}, { delay: invalid });
|
||||
}, `animate() with ${invalid}`);
|
||||
}
|
||||
}, 'Throws when setting invalid values');
|
||||
|
||||
</script>
|
||||
</body>
|
|
@ -1,108 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset=utf-8>
|
||||
<title>AnimationEffectTiming.direction</title>
|
||||
<link rel="help" href="https://drafts.csswg.org/web-animations/#dom-animationeffecttiming-direction">
|
||||
<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(t => {
|
||||
const anim = createDiv(t).animate(null);
|
||||
assert_equals(anim.effect.timing.direction, 'normal');
|
||||
}, 'Has the default value \'normal\'');
|
||||
|
||||
test(t => {
|
||||
const div = createDiv(t);
|
||||
const anim = div.animate({ opacity: [ 0, 1 ] }, 2000);
|
||||
|
||||
const directions = ['normal', 'reverse', 'alternate', 'alternate-reverse'];
|
||||
for (const direction of directions) {
|
||||
anim.effect.timing.direction = direction;
|
||||
assert_equals(anim.effect.timing.direction, direction,
|
||||
`set direction to ${direction}`);
|
||||
}
|
||||
}, 'Can be set to each of the possible keywords');
|
||||
|
||||
test(t => {
|
||||
const div = createDiv(t);
|
||||
const anim = div.animate(null, { duration: 10000, direction: 'normal' });
|
||||
anim.currentTime = 7000;
|
||||
assert_time_equals_literal(anim.effect.getComputedTiming().progress, 0.7,
|
||||
'progress before updating direction');
|
||||
|
||||
anim.effect.timing.direction = 'reverse';
|
||||
|
||||
assert_time_equals_literal(anim.effect.getComputedTiming().progress, 0.3,
|
||||
'progress after updating direction');
|
||||
}, 'Can be changed from \'normal\' to \'reverse\' while in progress');
|
||||
|
||||
test(t => {
|
||||
const div = createDiv(t);
|
||||
const anim = div.animate({ opacity: [ 0, 1 ] },
|
||||
{ duration: 10000,
|
||||
direction: 'normal' });
|
||||
assert_equals(anim.effect.getComputedTiming().progress, 0,
|
||||
'progress before updating direction');
|
||||
|
||||
anim.effect.timing.direction = 'reverse';
|
||||
|
||||
assert_equals(anim.effect.getComputedTiming().progress, 1,
|
||||
'progress after updating direction');
|
||||
}, 'Can be changed from \'normal\' to \'reverse\' while at start of active'
|
||||
+ ' interval');
|
||||
|
||||
test(t => {
|
||||
const div = createDiv(t);
|
||||
const anim = div.animate({ opacity: [ 0, 1 ] },
|
||||
{ fill: 'backwards',
|
||||
duration: 10000,
|
||||
delay: 10000,
|
||||
direction: 'normal' });
|
||||
assert_equals(anim.effect.getComputedTiming().progress, 0,
|
||||
'progress before updating direction');
|
||||
|
||||
anim.effect.timing.direction = 'reverse';
|
||||
|
||||
assert_equals(anim.effect.getComputedTiming().progress, 1,
|
||||
'progress after updating direction');
|
||||
}, 'Can be changed from \'normal\' to \'reverse\' while filling backwards');
|
||||
|
||||
test(t => {
|
||||
const div = createDiv(t);
|
||||
const anim = div.animate({ opacity: [ 0, 1 ] },
|
||||
{ iterations: 2,
|
||||
duration: 10000,
|
||||
direction: 'normal' });
|
||||
anim.currentTime = 17000;
|
||||
assert_time_equals_literal(anim.effect.getComputedTiming().progress, 0.7,
|
||||
'progress before updating direction');
|
||||
|
||||
anim.effect.timing.direction = 'alternate';
|
||||
|
||||
assert_time_equals_literal(anim.effect.getComputedTiming().progress, 0.3,
|
||||
'progress after updating direction');
|
||||
}, 'Can be changed from \'normal\' to \'alternate\' while in progress');
|
||||
|
||||
test(t => {
|
||||
const div = createDiv(t);
|
||||
const anim = div.animate({ opacity: [ 0, 1 ] },
|
||||
{ iterations: 2,
|
||||
duration: 10000,
|
||||
direction: 'alternate' });
|
||||
anim.currentTime = 17000;
|
||||
assert_time_equals_literal(anim.effect.getComputedTiming().progress, 0.3,
|
||||
'progress before updating direction');
|
||||
|
||||
anim.effect.timing.direction = 'alternate-reverse';
|
||||
|
||||
assert_time_equals_literal(anim.effect.getComputedTiming().progress, 0.7,
|
||||
'progress after updating direction');
|
||||
}, 'Can be changed from \'alternate\' to \'alternate-reverse\' while in'
|
||||
+ ' progress');
|
||||
|
||||
</script>
|
||||
</body>
|
|
@ -1,190 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset=utf-8>
|
||||
<title>AnimationEffectTiming.duration</title>
|
||||
<link rel="help" href="https://drafts.csswg.org/web-animations/#dom-animationeffecttiming-duration">
|
||||
<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(t => {
|
||||
const anim = createDiv(t).animate(null);
|
||||
assert_equals(anim.effect.timing.duration, 'auto');
|
||||
}, 'Has the default value \'auto\'');
|
||||
|
||||
test(t => {
|
||||
const div = createDiv(t);
|
||||
const anim = div.animate({ opacity: [ 0, 1 ] }, 2000);
|
||||
anim.effect.timing.duration = 123.45;
|
||||
assert_time_equals_literal(anim.effect.timing.duration, 123.45,
|
||||
'set duration 123.45');
|
||||
assert_time_equals_literal(anim.effect.getComputedTiming().duration, 123.45,
|
||||
'getComputedTiming() after set duration 123.45');
|
||||
}, 'Can be set to a double value');
|
||||
|
||||
test(t => {
|
||||
const div = createDiv(t);
|
||||
const anim = div.animate({ opacity: [ 0, 1 ] }, 2000);
|
||||
anim.effect.timing.duration = 'auto';
|
||||
assert_equals(anim.effect.timing.duration, 'auto', 'set duration \'auto\'');
|
||||
assert_equals(anim.effect.getComputedTiming().duration, 0,
|
||||
'getComputedTiming() after set duration \'auto\'');
|
||||
}, 'Can be set to the string \'auto\'');
|
||||
|
||||
test(t => {
|
||||
const div = createDiv(t);
|
||||
const anim = div.animate({ opacity: [ 0, 1 ] }, { duration: 'auto' });
|
||||
assert_equals(anim.effect.timing.duration, 'auto', 'set duration \'auto\'');
|
||||
assert_equals(anim.effect.getComputedTiming().duration, 0,
|
||||
'getComputedTiming() after set duration \'auto\'');
|
||||
}, 'Can be set to \'auto\' using a dictionary object');
|
||||
|
||||
test(t => {
|
||||
const div = createDiv(t);
|
||||
const anim = div.animate({ opacity: [ 0, 1 ] }, 2000);
|
||||
anim.effect.timing.duration = Infinity;
|
||||
assert_equals(anim.effect.timing.duration, Infinity, 'set duration Infinity');
|
||||
assert_equals(anim.effect.getComputedTiming().duration, Infinity,
|
||||
'getComputedTiming() after set duration Infinity');
|
||||
}, 'Can be set to Infinity');
|
||||
|
||||
test(t => {
|
||||
const div = createDiv(t);
|
||||
assert_throws({ name: 'TypeError' }, () => {
|
||||
div.animate({ opacity: [ 0, 1 ] }, -1);
|
||||
});
|
||||
}, 'animate() throws when passed a negative number');
|
||||
|
||||
test(t => {
|
||||
const div = createDiv(t);
|
||||
assert_throws({ name: 'TypeError' }, () => {
|
||||
div.animate({ opacity: [ 0, 1 ] }, -Infinity);
|
||||
});
|
||||
}, 'animate() throws when passed negative Infinity');
|
||||
|
||||
test(t => {
|
||||
const div = createDiv(t);
|
||||
assert_throws({ name: 'TypeError' }, () => {
|
||||
div.animate({ opacity: [ 0, 1 ] }, NaN);
|
||||
});
|
||||
}, 'animate() throws when passed a NaN value');
|
||||
|
||||
test(t => {
|
||||
const div = createDiv(t);
|
||||
assert_throws({ name: 'TypeError' }, () => {
|
||||
div.animate({ opacity: [ 0, 1 ] }, { duration: -1 });
|
||||
});
|
||||
}, 'animate() throws when passed a negative number using a dictionary object');
|
||||
|
||||
test(t => {
|
||||
const div = createDiv(t);
|
||||
assert_throws({ name: 'TypeError' }, () => {
|
||||
div.animate({ opacity: [ 0, 1 ] }, { duration: -Infinity });
|
||||
});
|
||||
}, 'animate() throws when passed negative Infinity using a dictionary object');
|
||||
|
||||
test(t => {
|
||||
const div = createDiv(t);
|
||||
assert_throws({ name: 'TypeError' }, () => {
|
||||
div.animate({ opacity: [ 0, 1 ] }, { duration: NaN });
|
||||
});
|
||||
}, 'animate() throws when passed a NaN value using a dictionary object');
|
||||
|
||||
test(t => {
|
||||
const div = createDiv(t);
|
||||
assert_throws({ name: 'TypeError' }, () => {
|
||||
div.animate({ opacity: [ 0, 1 ] }, { duration: 'abc' });
|
||||
});
|
||||
}, 'animate() throws when passed a string other than \'auto\' using a'
|
||||
+ ' dictionary object');
|
||||
|
||||
test(t => {
|
||||
const div = createDiv(t);
|
||||
assert_throws({ name: 'TypeError' }, () => {
|
||||
div.animate({ opacity: [ 0, 1 ] }, { duration: '100' });
|
||||
});
|
||||
}, 'animate() throws when passed a string containing a number using a'
|
||||
+ ' dictionary object');
|
||||
|
||||
test(t => {
|
||||
const div = createDiv(t);
|
||||
const anim = div.animate({ opacity: [ 0, 1 ] }, 2000);
|
||||
assert_throws({ name: 'TypeError' }, () => {
|
||||
anim.effect.timing.duration = -1;
|
||||
});
|
||||
}, 'Throws when setting a negative number');
|
||||
|
||||
test(t => {
|
||||
const div = createDiv(t);
|
||||
const anim = div.animate({ opacity: [ 0, 1 ] }, 2000);
|
||||
assert_throws({ name: 'TypeError' }, () => {
|
||||
anim.effect.timing.duration = -Infinity;
|
||||
});
|
||||
}, 'Throws when setting negative infinity');
|
||||
|
||||
test(t => {
|
||||
const div = createDiv(t);
|
||||
const anim = div.animate({ opacity: [ 0, 1 ] }, 2000);
|
||||
assert_throws({ name: 'TypeError' }, () => {
|
||||
anim.effect.timing.duration = NaN;
|
||||
});
|
||||
}, 'Throws when setting a NaN value');
|
||||
|
||||
test(t => {
|
||||
const div = createDiv(t);
|
||||
const anim = div.animate({ opacity: [ 0, 1 ] }, 2000);
|
||||
assert_throws({ name: 'TypeError' }, () => {
|
||||
anim.effect.timing.duration = 'abc';
|
||||
});
|
||||
}, 'Throws when setting a string other than \'auto\'');
|
||||
|
||||
test(t => {
|
||||
const div = createDiv(t);
|
||||
const anim = div.animate({ opacity: [ 0, 1 ] }, 2000);
|
||||
assert_throws({ name: 'TypeError' }, () => {
|
||||
anim.effect.timing.duration = '100';
|
||||
});
|
||||
}, 'Throws when setting a string containing a number');
|
||||
|
||||
promise_test(t => {
|
||||
const anim = createDiv(t).animate(null, 100 * MS_PER_SEC);
|
||||
return anim.ready.then(() => {
|
||||
const originalStartTime = anim.startTime;
|
||||
const originalCurrentTime = anim.currentTime;
|
||||
assert_equals(anim.effect.getComputedTiming().duration, 100 * MS_PER_SEC,
|
||||
'Initial duration should be as set on KeyframeEffect');
|
||||
|
||||
anim.effect.timing.duration = 200 * MS_PER_SEC;
|
||||
assert_equals(anim.effect.getComputedTiming().duration, 200 * MS_PER_SEC,
|
||||
'Effect duration should have been updated');
|
||||
assert_times_equal(anim.startTime, originalStartTime,
|
||||
'startTime should be unaffected by changing effect ' +
|
||||
'duration');
|
||||
assert_times_equal(anim.currentTime, originalCurrentTime,
|
||||
'currentTime should be unaffected by changing effect ' +
|
||||
'duration');
|
||||
});
|
||||
}, 'Extending an effect\'s duration does not change the start or current time');
|
||||
|
||||
test(t => {
|
||||
const div = createDiv(t);
|
||||
const anim = div.animate(null, { duration: 100000, fill: 'both' });
|
||||
anim.finish();
|
||||
assert_equals(anim.effect.getComputedTiming().progress, 1,
|
||||
'progress when animation is finished');
|
||||
anim.effect.timing.duration *= 2;
|
||||
assert_time_equals_literal(anim.effect.getComputedTiming().progress, 0.5,
|
||||
'progress after doubling the duration');
|
||||
anim.effect.timing.duration = 0;
|
||||
assert_equals(anim.effect.getComputedTiming().progress, 1,
|
||||
'progress after setting duration to zero');
|
||||
anim.effect.timing.duration = 'auto';
|
||||
assert_equals(anim.effect.getComputedTiming().progress, 1,
|
||||
'progress after setting duration to \'auto\'');
|
||||
}, 'Can be updated while the animation is in progress');
|
||||
|
||||
</script>
|
||||
</body>
|
|
@ -1,96 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset=utf-8>
|
||||
<title>AnimationEffectTiming.easing</title>
|
||||
<link rel="help" href="https://drafts.csswg.org/web-animations/#dom-animationeffecttiming-easing">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="../../testcommon.js"></script>
|
||||
<script src="../../resources/easing-tests.js"></script>
|
||||
<body>
|
||||
<div id="log"></div>
|
||||
<script>
|
||||
'use strict';
|
||||
|
||||
test(t => {
|
||||
const anim = createDiv(t).animate(null);
|
||||
assert_equals(anim.effect.timing.easing, 'linear');
|
||||
}, 'Has the default value \'linear\'');
|
||||
|
||||
function assert_progress(animation, currentTime, easingFunction) {
|
||||
animation.currentTime = currentTime;
|
||||
const portion = currentTime / animation.effect.timing.duration;
|
||||
assert_approx_equals(animation.effect.getComputedTiming().progress,
|
||||
easingFunction(portion),
|
||||
0.01,
|
||||
'The progress of the animation should be approximately'
|
||||
+ ` ${easingFunction(portion)} at ${currentTime}ms`);
|
||||
}
|
||||
|
||||
for (const options of gEasingTests) {
|
||||
test(t => {
|
||||
const target = createDiv(t);
|
||||
const anim = target.animate([ { opacity: 0 }, { opacity: 1 } ],
|
||||
{ duration: 1000 * MS_PER_SEC,
|
||||
fill: 'forwards' });
|
||||
anim.effect.timing.easing = options.easing;
|
||||
assert_equals(anim.effect.timing.easing,
|
||||
options.serialization || options.easing);
|
||||
|
||||
const easing = options.easingFunction;
|
||||
assert_progress(anim, 0, easing);
|
||||
assert_progress(anim, 250 * MS_PER_SEC, easing);
|
||||
assert_progress(anim, 500 * MS_PER_SEC, easing);
|
||||
assert_progress(anim, 750 * MS_PER_SEC, easing);
|
||||
assert_progress(anim, 1000 * MS_PER_SEC, easing);
|
||||
}, options.desc);
|
||||
}
|
||||
|
||||
for (const invalidEasing of gInvalidEasings) {
|
||||
test(t => {
|
||||
const div = createDiv(t);
|
||||
const anim = div.animate({ opacity: [ 0, 1 ] }, 100 * MS_PER_SEC);
|
||||
assert_throws({ name: 'TypeError' },
|
||||
() => {
|
||||
anim.effect.timing.easing = invalidEasing;
|
||||
});
|
||||
}, `Throws on invalid easing: '${invalidEasing}'`);
|
||||
}
|
||||
|
||||
for (const easing of gRoundtripEasings) {
|
||||
test(t => {
|
||||
const anim = createDiv(t).animate(null);
|
||||
anim.effect.timing.easing = easing;
|
||||
assert_equals(anim.effect.timing.easing, easing);
|
||||
}, `Canonical easing '${easing}' is returned as set`);
|
||||
}
|
||||
|
||||
test(t => {
|
||||
const delay = 1000 * MS_PER_SEC;
|
||||
|
||||
const target = createDiv(t);
|
||||
const anim = target.animate([ { opacity: 0 }, { opacity: 1 } ],
|
||||
{ duration: 1000 * MS_PER_SEC,
|
||||
fill: 'both',
|
||||
delay: delay,
|
||||
easing: 'steps(2, start)' });
|
||||
|
||||
anim.effect.timing.easing = 'steps(2, end)';
|
||||
assert_equals(anim.effect.getComputedTiming().progress, 0,
|
||||
'easing replace to steps(2, end) at before phase');
|
||||
|
||||
anim.currentTime = delay + 750 * MS_PER_SEC;
|
||||
assert_equals(anim.effect.getComputedTiming().progress, 0.5,
|
||||
'change currentTime to active phase');
|
||||
|
||||
anim.effect.timing.easing = 'steps(2, start)';
|
||||
assert_equals(anim.effect.getComputedTiming().progress, 1,
|
||||
'easing replace to steps(2, start) at active phase');
|
||||
|
||||
anim.currentTime = delay + 1500 * MS_PER_SEC;
|
||||
anim.effect.timing.easing = 'steps(2, end)';
|
||||
assert_equals(anim.effect.getComputedTiming().progress, 1,
|
||||
'easing replace to steps(2, end) again at after phase');
|
||||
}, 'Allows the easing to be changed while the animation is in progress');
|
||||
|
||||
</script>
|
||||
</body>
|
|
@ -1,89 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset=utf-8>
|
||||
<title>AnimationEffectTiming.endDelay</title>
|
||||
<link rel="help" href="https://drafts.csswg.org/web-animations/#dom-animationeffecttiming-enddelay">
|
||||
<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(t => {
|
||||
const anim = createDiv(t).animate(null);
|
||||
assert_equals(anim.effect.timing.endDelay, 0);
|
||||
}, 'Has the default value 0');
|
||||
|
||||
test(t => {
|
||||
const div = createDiv(t);
|
||||
const anim = div.animate({ opacity: [ 0, 1 ] }, 2000);
|
||||
anim.effect.timing.endDelay = 123.45;
|
||||
assert_time_equals_literal(anim.effect.timing.endDelay, 123.45,
|
||||
'set endDelay 123.45');
|
||||
assert_time_equals_literal(anim.effect.getComputedTiming().endDelay, 123.45,
|
||||
'getComputedTiming() after set endDelay 123.45');
|
||||
}, 'Can be set to a positive number');
|
||||
|
||||
test(t => {
|
||||
const div = createDiv(t);
|
||||
const anim = div.animate({ opacity: [ 0, 1 ] }, 2000);
|
||||
anim.effect.timing.endDelay = -1000;
|
||||
assert_equals(anim.effect.timing.endDelay, -1000, 'set endDelay -1000');
|
||||
assert_equals(anim.effect.getComputedTiming().endDelay, -1000,
|
||||
'getComputedTiming() after set endDelay -1000');
|
||||
}, 'Can be set to a negative number');
|
||||
|
||||
test(t => {
|
||||
const div = createDiv(t);
|
||||
const anim = div.animate({ opacity: [ 0, 1 ] }, 2000);
|
||||
assert_throws({ name: 'TypeError' }, () => {
|
||||
anim.effect.timing.endDelay = Infinity;
|
||||
}, 'we can not assign Infinity to timing.endDelay');
|
||||
}, 'Throws when setting infinity');
|
||||
|
||||
test(t => {
|
||||
const div = createDiv(t);
|
||||
const anim = div.animate({ opacity: [ 0, 1 ] }, 2000);
|
||||
assert_throws({ name: 'TypeError' }, () => {
|
||||
anim.effect.timing.endDelay = -Infinity;
|
||||
}, 'we can not assign negative Infinity to timing.endDelay');
|
||||
}, 'Throws when setting negative infinity');
|
||||
|
||||
async_test(t => {
|
||||
const div = createDiv(t);
|
||||
const anim = div.animate({ opacity: [ 0, 1 ] },
|
||||
{ duration: 100000, endDelay: 50000 });
|
||||
anim.onfinish = t.step_func(event => {
|
||||
assert_unreached('finish event should not be fired');
|
||||
});
|
||||
|
||||
anim.ready.then(() => {
|
||||
anim.currentTime = 100000;
|
||||
return waitForAnimationFrames(2);
|
||||
}).then(t.step_func(() => {
|
||||
t.done();
|
||||
}));
|
||||
}, 'finish event is not fired at the end of the active interval when the'
|
||||
+ ' endDelay has not expired');
|
||||
|
||||
async_test(t => {
|
||||
const div = createDiv(t);
|
||||
const anim = div.animate({ opacity: [ 0, 1 ] },
|
||||
{ duration: 100000, endDelay: 30000 });
|
||||
anim.ready.then(() => {
|
||||
anim.currentTime = 110000; // during endDelay
|
||||
anim.onfinish = t.step_func(event => {
|
||||
assert_unreached('onfinish event should not be fired during endDelay');
|
||||
});
|
||||
return waitForAnimationFrames(2);
|
||||
}).then(t.step_func(() => {
|
||||
anim.onfinish = t.step_func(event => {
|
||||
t.done();
|
||||
});
|
||||
anim.currentTime = 130000; // after endTime
|
||||
}));
|
||||
}, 'finish event is fired after the endDelay has expired');
|
||||
|
||||
</script>
|
||||
</body>
|
|
@ -1,30 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset=utf-8>
|
||||
<title>AnimationEffectTiming.fill</title>
|
||||
<link rel="help" href="https://drafts.csswg.org/web-animations/#dom-animationeffecttiming-fill">
|
||||
<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(t => {
|
||||
const anim = createDiv(t).animate(null);
|
||||
assert_equals(anim.effect.timing.fill, 'auto');
|
||||
}, 'Has the default value \'auto\'');
|
||||
|
||||
for (const fill of ['none', 'forwards', 'backwards', 'both']) {
|
||||
test(t => {
|
||||
const div = createDiv(t);
|
||||
const anim = div.animate({ opacity: [ 0, 1 ] }, 100);
|
||||
anim.effect.timing.fill = fill;
|
||||
assert_equals(anim.effect.timing.fill, fill, 'set fill ' + fill);
|
||||
assert_equals(anim.effect.getComputedTiming().fill, fill,
|
||||
'getComputedTiming() after set fill ' + fill);
|
||||
}, `Can set fill to ${fill}`);
|
||||
}
|
||||
|
||||
</script>
|
||||
</body>
|
|
@ -1,80 +0,0 @@
|
|||
<!doctype html>
|
||||
<meta charset=utf-8>
|
||||
<title>AnimationEffectTiming and AnimationEffectTimingReadOnly IDL</title>
|
||||
<link rel="help"
|
||||
href="https://drafts.csswg.org/web-animations/#animationeffecttiming">
|
||||
<link rel="help"
|
||||
href="https://drafts.csswg.org/web-animations/#animationeffecttimingreadonly">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/resources/WebIDLParser.js"></script>
|
||||
<script src="/resources/idlharness.js"></script>
|
||||
<div id="log"></div>
|
||||
<script type="text/plain" id="AnimationEffectTimingReadOnly-IDL">
|
||||
enum FillMode { "none", "forwards", "backwards", "both", "auto" };
|
||||
enum PlaybackDirection {
|
||||
"normal",
|
||||
"reverse",
|
||||
"alternate",
|
||||
"alternate-reverse"
|
||||
};
|
||||
|
||||
dictionary AnimationEffectTimingProperties {
|
||||
double delay = 0.0;
|
||||
double endDelay = 0.0;
|
||||
FillMode fill = "auto";
|
||||
double iterationStart = 0.0;
|
||||
unrestricted double iterations = 1.0;
|
||||
(unrestricted double or DOMString) duration = "auto";
|
||||
PlaybackDirection direction = "normal";
|
||||
DOMString easing = "linear";
|
||||
};
|
||||
|
||||
[Exposed=Window]
|
||||
interface AnimationEffectTimingReadOnly {
|
||||
readonly attribute double delay;
|
||||
readonly attribute double endDelay;
|
||||
readonly attribute FillMode fill;
|
||||
readonly attribute double iterationStart;
|
||||
readonly attribute unrestricted double iterations;
|
||||
readonly attribute (unrestricted double or DOMString) duration;
|
||||
readonly attribute PlaybackDirection direction;
|
||||
readonly attribute DOMString easing;
|
||||
};
|
||||
</script>
|
||||
<script type="text/plain" id="AnimationEffectTiming-IDL">
|
||||
[Exposed=Window]
|
||||
interface AnimationEffectTiming : AnimationEffectTimingReadOnly {
|
||||
inherit attribute double delay;
|
||||
inherit attribute double endDelay;
|
||||
inherit attribute FillMode fill;
|
||||
inherit attribute double iterationStart;
|
||||
inherit attribute unrestricted double iterations;
|
||||
inherit attribute (unrestricted double or DOMString) duration;
|
||||
inherit attribute PlaybackDirection direction;
|
||||
inherit attribute DOMString easing;
|
||||
};
|
||||
</script>
|
||||
<script>
|
||||
'use strict';
|
||||
|
||||
const idlArray = new IdlArray();
|
||||
|
||||
idlArray.add_idls(
|
||||
document.getElementById('AnimationEffectTimingReadOnly-IDL').textContent
|
||||
);
|
||||
idlArray.add_idls(
|
||||
document.getElementById('AnimationEffectTiming-IDL').textContent
|
||||
);
|
||||
|
||||
idlArray.add_objects({
|
||||
AnimationEffectTiming: [
|
||||
'(new KeyframeEffect(null, null)).timing'
|
||||
],
|
||||
AnimationEffectTimingReadOnly: [
|
||||
'(new KeyframeEffectReadOnly(null, null)).timing'
|
||||
],
|
||||
});
|
||||
idlArray.test();
|
||||
|
||||
</script>
|
|
@ -1,72 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset=utf-8>
|
||||
<title>AnimationEffectTiming.iterationStart</title>
|
||||
<link rel="help" href="https://drafts.csswg.org/web-animations/#dom-animationeffecttiming-iterationstart">
|
||||
<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(t => {
|
||||
const anim = createDiv(t).animate(null);
|
||||
assert_equals(anim.effect.timing.iterationStart, 0);
|
||||
}, 'Has the default value 0');
|
||||
|
||||
test(t => {
|
||||
const div = createDiv(t);
|
||||
const anim = div.animate({ opacity: [ 0, 1 ] },
|
||||
{ iterationStart: 0.2,
|
||||
iterations: 1,
|
||||
fill: 'both',
|
||||
duration: 100,
|
||||
delay: 1 });
|
||||
anim.effect.timing.iterationStart = 2.5;
|
||||
assert_time_equals_literal(anim.effect.getComputedTiming().progress, 0.5);
|
||||
assert_equals(anim.effect.getComputedTiming().currentIteration, 2);
|
||||
}, 'Changing the value updates computed timing when backwards-filling');
|
||||
|
||||
test(t => {
|
||||
const div = createDiv(t);
|
||||
const anim = div.animate({ opacity: [ 0, 1 ] },
|
||||
{ iterationStart: 0.2,
|
||||
iterations: 1,
|
||||
fill: 'both',
|
||||
duration: 100,
|
||||
delay: 0 });
|
||||
anim.effect.timing.iterationStart = 2.5;
|
||||
assert_time_equals_literal(anim.effect.getComputedTiming().progress, 0.5);
|
||||
assert_equals(anim.effect.getComputedTiming().currentIteration, 2);
|
||||
}, 'Changing the value updates computed timing during the active phase');
|
||||
|
||||
test(t => {
|
||||
const div = createDiv(t);
|
||||
const anim = div.animate({ opacity: [ 0, 1 ] },
|
||||
{ iterationStart: 0.2,
|
||||
iterations: 1,
|
||||
fill: 'both',
|
||||
duration: 100,
|
||||
delay: 0 });
|
||||
anim.finish();
|
||||
anim.effect.timing.iterationStart = 2.5;
|
||||
assert_time_equals_literal(anim.effect.getComputedTiming().progress, 0.5);
|
||||
assert_equals(anim.effect.getComputedTiming().currentIteration, 3);
|
||||
}, 'Changing the value updates computed timing when forwards-filling');
|
||||
|
||||
test(t => {
|
||||
const div = createDiv(t);
|
||||
const anim = div.animate(null);
|
||||
for (let invalid of [-1, NaN, Infinity]) {
|
||||
assert_throws({ name: 'TypeError' }, () => {
|
||||
anim.effect.timing.iterationStart = invalid;
|
||||
}, `setting ${invalid}`);
|
||||
assert_throws({ name: 'TypeError' }, () => {
|
||||
div.animate({}, { iterationStart: invalid });
|
||||
}, `animate() with ${invalid}`);
|
||||
}
|
||||
}, 'Throws when setting invalid values');
|
||||
|
||||
</script>
|
||||
</body>
|
|
@ -1,96 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset=utf-8>
|
||||
<title>AnimationEffectTiming.iterations</title>
|
||||
<link rel="help" href="https://drafts.csswg.org/web-animations/#dom-animationeffecttiming-iterations">
|
||||
<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(t => {
|
||||
const anim = createDiv(t).animate(null);
|
||||
assert_equals(anim.effect.timing.iterations, 1);
|
||||
}, 'Has the default value 1');
|
||||
|
||||
test(t => {
|
||||
const div = createDiv(t);
|
||||
const anim = div.animate({ opacity: [ 0, 1 ] }, 2000);
|
||||
anim.effect.timing.iterations = 2;
|
||||
assert_equals(anim.effect.timing.iterations, 2, 'set duration 2');
|
||||
assert_equals(anim.effect.getComputedTiming().iterations, 2,
|
||||
'getComputedTiming() after set iterations 2');
|
||||
}, 'Can be set to a double value');
|
||||
|
||||
test(t => {
|
||||
const div = createDiv(t);
|
||||
const anim = div.animate({ opacity: [ 0, 1 ] }, 2000);
|
||||
anim.effect.timing.iterations = Infinity;
|
||||
assert_equals(anim.effect.timing.iterations, Infinity, 'set duration Infinity');
|
||||
assert_equals(anim.effect.getComputedTiming().iterations, Infinity,
|
||||
'getComputedTiming() after set iterations Infinity');
|
||||
}, 'Can be set to infinity');
|
||||
|
||||
test(t => {
|
||||
const div = createDiv(t);
|
||||
const anim = div.animate({ opacity: [ 0, 1 ] }, 2000);
|
||||
assert_throws({ name: 'TypeError' }, () => {
|
||||
anim.effect.timing.iterations = -1;
|
||||
});
|
||||
}, 'Throws when setting a negative number');
|
||||
|
||||
test(t => {
|
||||
const div = createDiv(t);
|
||||
const anim = div.animate({ opacity: [ 0, 1 ] }, 2000);
|
||||
assert_throws({ name: 'TypeError' }, () => {
|
||||
anim.effect.timing.iterations = -Infinity;
|
||||
});
|
||||
}, 'Throws when setting negative infinity');
|
||||
|
||||
test(t => {
|
||||
const div = createDiv(t);
|
||||
const anim = div.animate({ opacity: [ 0, 1 ] }, 2000);
|
||||
assert_throws({ name: 'TypeError' }, () => {
|
||||
anim.effect.timing.iterations = NaN;
|
||||
});
|
||||
}, 'Throws when setting a NaN value');
|
||||
|
||||
test(t => {
|
||||
const div = createDiv(t);
|
||||
const anim = div.animate(null, { duration: 100000, fill: 'both' });
|
||||
|
||||
anim.finish();
|
||||
|
||||
assert_equals(anim.effect.getComputedTiming().progress, 1,
|
||||
'progress when animation is finished');
|
||||
assert_equals(anim.effect.getComputedTiming().currentIteration, 0,
|
||||
'current iteration when animation is finished');
|
||||
|
||||
anim.effect.timing.iterations = 2;
|
||||
|
||||
assert_time_equals_literal(anim.effect.getComputedTiming().progress,
|
||||
0,
|
||||
'progress after adding an iteration');
|
||||
assert_time_equals_literal(anim.effect.getComputedTiming().currentIteration,
|
||||
1,
|
||||
'current iteration after adding an iteration');
|
||||
|
||||
anim.effect.timing.iterations = 0;
|
||||
|
||||
assert_equals(anim.effect.getComputedTiming().progress, 0,
|
||||
'progress after setting iterations to zero');
|
||||
assert_equals(anim.effect.getComputedTiming().currentIteration, 0,
|
||||
'current iteration after setting iterations to zero');
|
||||
|
||||
anim.effect.timing.iterations = Infinity;
|
||||
|
||||
assert_equals(anim.effect.getComputedTiming().progress, 0,
|
||||
'progress after setting iterations to Infinity');
|
||||
assert_equals(anim.effect.getComputedTiming().currentIteration, 1,
|
||||
'current iteration after setting iterations to Infinity');
|
||||
}, 'Can be updated while the animation is in progress');
|
||||
|
||||
</script>
|
||||
</body>
|
|
@ -42,7 +42,7 @@ test(t => {
|
|||
}, 'Test the order of document.getAnimations with script generated animations')
|
||||
|
||||
test(t => {
|
||||
const effect = new KeyframeEffectReadOnly(null, gKeyFrames, 100 * MS_PER_SEC);
|
||||
const effect = new KeyframeEffect(null, gKeyFrames, 100 * MS_PER_SEC);
|
||||
const anim = new Animation(effect, document.timeline);
|
||||
anim.play();
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset=utf-8>
|
||||
<title>KeyframeEffect and KeyframeEffectReadOnly constructor</title>
|
||||
<title>KeyframeEffect constructor</title>
|
||||
<link rel="help"
|
||||
href="https://drafts.csswg.org/web-animations/#dom-keyframeeffect-keyframeeffect">
|
||||
<link rel="help"
|
||||
|
@ -21,49 +21,48 @@ const target = document.getElementById('target');
|
|||
|
||||
test(t => {
|
||||
for (const frames of gEmptyKeyframeListTests) {
|
||||
assert_equals(new KeyframeEffectReadOnly(target, frames)
|
||||
.getKeyframes().length,
|
||||
assert_equals(new KeyframeEffect(target, frames).getKeyframes().length,
|
||||
0, `number of frames for ${JSON.stringify(frames)}`);
|
||||
}
|
||||
}, 'A KeyframeEffectReadOnly can be constructed with no frames');
|
||||
}, 'A KeyframeEffect can be constructed with no frames');
|
||||
|
||||
test(t => {
|
||||
for (const subtest of gEasingParsingTests) {
|
||||
const easing = subtest[0];
|
||||
const expected = subtest[1];
|
||||
const effect = new KeyframeEffectReadOnly(target, {
|
||||
const effect = new KeyframeEffect(target, {
|
||||
left: ['10px', '20px']
|
||||
}, { easing: easing });
|
||||
assert_equals(effect.timing.easing, expected,
|
||||
assert_equals(effect.getTiming().easing, expected,
|
||||
`resulting easing for '${easing}'`);
|
||||
}
|
||||
}, 'easing values are parsed correctly when passed to the ' +
|
||||
'KeyframeEffectReadOnly constructor in KeyframeEffectOptions');
|
||||
'KeyframeEffect constructor in KeyframeEffectOptions');
|
||||
|
||||
test(t => {
|
||||
for (const invalidEasing of gInvalidEasings) {
|
||||
assert_throws(new TypeError, () => {
|
||||
new KeyframeEffectReadOnly(target, null, { easing: invalidEasing });
|
||||
new KeyframeEffect(target, null, { easing: invalidEasing });
|
||||
}, `TypeError is thrown for easing '${invalidEasing}'`);
|
||||
}
|
||||
}, 'Invalid easing values are correctly rejected when passed to the ' +
|
||||
'KeyframeEffectReadOnly constructor in KeyframeEffectOptions');
|
||||
'KeyframeEffect constructor in KeyframeEffectOptions');
|
||||
|
||||
test(t => {
|
||||
const getKeyframe =
|
||||
composite => ({ left: [ '10px', '20px' ], composite: composite });
|
||||
for (const composite of gGoodKeyframeCompositeValueTests) {
|
||||
const effect = new KeyframeEffectReadOnly(target, getKeyframe(composite));
|
||||
const effect = new KeyframeEffect(target, getKeyframe(composite));
|
||||
assert_equals(effect.getKeyframes()[0].composite, composite,
|
||||
`resulting composite for '${composite}'`);
|
||||
}
|
||||
for (const composite of gBadKeyframeCompositeValueTests) {
|
||||
assert_throws(new TypeError, () => {
|
||||
new KeyframeEffectReadOnly(target, getKeyframe(composite));
|
||||
new KeyframeEffect(target, getKeyframe(composite));
|
||||
});
|
||||
}
|
||||
}, 'composite values are parsed correctly when passed to the ' +
|
||||
'KeyframeEffectReadOnly constructor in property-indexed keyframes');
|
||||
'KeyframeEffect constructor in property-indexed keyframes');
|
||||
|
||||
test(t => {
|
||||
const getKeyframes = composite =>
|
||||
|
@ -72,29 +71,29 @@ test(t => {
|
|||
{ offset: 1, left: '20px' }
|
||||
];
|
||||
for (const composite of gGoodKeyframeCompositeValueTests) {
|
||||
const effect = new KeyframeEffectReadOnly(target, getKeyframes(composite));
|
||||
const effect = new KeyframeEffect(target, getKeyframes(composite));
|
||||
assert_equals(effect.getKeyframes()[0].composite, composite,
|
||||
`resulting composite for '${composite}'`);
|
||||
}
|
||||
for (const composite of gBadKeyframeCompositeValueTests) {
|
||||
assert_throws(new TypeError, () => {
|
||||
new KeyframeEffectReadOnly(target, getKeyframes(composite));
|
||||
new KeyframeEffect(target, getKeyframes(composite));
|
||||
});
|
||||
}
|
||||
}, 'composite values are parsed correctly when passed to the ' +
|
||||
'KeyframeEffectReadOnly constructor in regular keyframes');
|
||||
'KeyframeEffect constructor in regular keyframes');
|
||||
|
||||
test(t => {
|
||||
for (const composite of gGoodOptionsCompositeValueTests) {
|
||||
const effect = new KeyframeEffectReadOnly(target, {
|
||||
const effect = new KeyframeEffect(target, {
|
||||
left: ['10px', '20px']
|
||||
}, { composite: composite });
|
||||
}, { composite });
|
||||
assert_equals(effect.getKeyframes()[0].composite, null,
|
||||
`resulting composite for '${composite}'`);
|
||||
}
|
||||
for (const composite of gBadOptionsCompositeValueTests) {
|
||||
assert_throws(new TypeError, () => {
|
||||
new KeyframeEffectReadOnly(target, {
|
||||
new KeyframeEffect(target, {
|
||||
left: ['10px', '20px']
|
||||
}, { composite: composite });
|
||||
});
|
||||
|
@ -104,32 +103,30 @@ test(t => {
|
|||
|
||||
for (const subtest of gKeyframesTests) {
|
||||
test(t => {
|
||||
const effect = new KeyframeEffectReadOnly(target, subtest.input);
|
||||
const effect = new KeyframeEffect(target, subtest.input);
|
||||
assert_frame_lists_equal(effect.getKeyframes(), subtest.output);
|
||||
}, `A KeyframeEffectReadOnly can be constructed with ${subtest.desc}`);
|
||||
}, `A KeyframeEffect can be constructed with ${subtest.desc}`);
|
||||
|
||||
test(t => {
|
||||
const effect = new KeyframeEffectReadOnly(target, subtest.input);
|
||||
const secondEffect =
|
||||
new KeyframeEffectReadOnly(target, effect.getKeyframes());
|
||||
const effect = new KeyframeEffect(target, subtest.input);
|
||||
const secondEffect = new KeyframeEffect(target, effect.getKeyframes());
|
||||
assert_frame_lists_equal(secondEffect.getKeyframes(),
|
||||
effect.getKeyframes());
|
||||
}, `A KeyframeEffectReadOnly constructed with ${subtest.desc} roundtrips`);
|
||||
}, `A KeyframeEffect constructed with ${subtest.desc} roundtrips`);
|
||||
}
|
||||
|
||||
for (const subtest of gInvalidKeyframesTests) {
|
||||
test(t => {
|
||||
assert_throws(new TypeError, () => {
|
||||
new KeyframeEffectReadOnly(target, subtest.input);
|
||||
new KeyframeEffect(target, subtest.input);
|
||||
});
|
||||
}, `KeyframeEffectReadOnly constructor throws with ${subtest.desc}`);
|
||||
}, `KeyframeEffect constructor throws with ${subtest.desc}`);
|
||||
}
|
||||
|
||||
test(t => {
|
||||
const effect = new KeyframeEffectReadOnly(target,
|
||||
{ left: ['10px', '20px'] });
|
||||
const effect = new KeyframeEffect(target, { left: ['10px', '20px'] });
|
||||
|
||||
const timing = effect.timing;
|
||||
const timing = effect.getTiming();
|
||||
assert_equals(timing.delay, 0, 'default delay');
|
||||
assert_equals(timing.endDelay, 0, 'default endDelay');
|
||||
assert_equals(timing.fill, 'auto', 'default fill');
|
||||
|
@ -142,14 +139,12 @@ test(t => {
|
|||
assert_equals(effect.composite, 'replace', 'default composite');
|
||||
assert_equals(effect.iterationComposite, 'replace',
|
||||
'default iterationComposite');
|
||||
}, 'A KeyframeEffectReadOnly constructed without any ' +
|
||||
'KeyframeEffectOptions object');
|
||||
}, 'A KeyframeEffect constructed without any KeyframeEffectOptions object');
|
||||
|
||||
for (const subtest of gKeyframeEffectOptionTests) {
|
||||
test(t => {
|
||||
const effect = new KeyframeEffectReadOnly(target,
|
||||
{ left: ['10px', '20px'] },
|
||||
subtest.input);
|
||||
const effect = new KeyframeEffect(target, { left: ['10px', '20px'] },
|
||||
subtest.input);
|
||||
|
||||
// Helper function to provide default expected values when the test does
|
||||
// not supply them.
|
||||
|
@ -157,7 +152,7 @@ for (const subtest of gKeyframeEffectOptionTests) {
|
|||
return field in subtest.expected ? subtest.expected[field] : defaultValue;
|
||||
};
|
||||
|
||||
const timing = effect.timing;
|
||||
const timing = effect.getTiming();
|
||||
assert_equals(timing.delay, expected('delay', 0),
|
||||
'timing delay');
|
||||
assert_equals(timing.fill, expected('fill', 'auto'),
|
||||
|
@ -169,27 +164,24 @@ for (const subtest of gKeyframeEffectOptionTests) {
|
|||
assert_equals(timing.direction, expected('direction', 'normal'),
|
||||
'timing direction');
|
||||
|
||||
}, `A KeyframeEffectReadOnly constructed by ${subtest.desc}`);
|
||||
}, `A KeyframeEffect constructed by ${subtest.desc}`);
|
||||
}
|
||||
|
||||
for (const subtest of gInvalidKeyframeEffectOptionTests) {
|
||||
test(t => {
|
||||
assert_throws(new TypeError, () => {
|
||||
new KeyframeEffectReadOnly(target,
|
||||
{ left: ['10px', '20px'] },
|
||||
subtest.input);
|
||||
new KeyframeEffect(target, { left: ['10px', '20px'] }, subtest.input);
|
||||
});
|
||||
}, `Invalid KeyframeEffectReadOnly option by ${subtest.desc}`);
|
||||
}, `Invalid KeyframeEffect option by ${subtest.desc}`);
|
||||
}
|
||||
|
||||
test(t => {
|
||||
const effect = new KeyframeEffectReadOnly(null,
|
||||
{ left: ['10px', '20px'] },
|
||||
{ duration: 100 * MS_PER_SEC,
|
||||
fill: 'forwards' });
|
||||
const effect = new KeyframeEffect(null, { left: ['10px', '20px'] },
|
||||
{ duration: 100 * MS_PER_SEC,
|
||||
fill: 'forwards' });
|
||||
assert_equals(effect.target, null,
|
||||
'Effect created with null target has correct target');
|
||||
}, 'A KeyframeEffectReadOnly constructed with null target');
|
||||
}, 'A KeyframeEffect constructed with null target');
|
||||
|
||||
test(t => {
|
||||
const test_error = { name: 'test' };
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset=utf-8>
|
||||
<title>KeyframeEffect and KeyframeEffectReadOnly copy constructor</title>
|
||||
<title>KeyframeEffect copy constructor</title>
|
||||
<link rel="help"
|
||||
href="https://drafts.csswg.org/web-animations/#dom-keyframeeffect-keyframeeffect-source">
|
||||
<link rel="help"
|
||||
|
@ -14,21 +14,21 @@
|
|||
'use strict';
|
||||
|
||||
test(t => {
|
||||
const effect = new KeyframeEffectReadOnly(createDiv(t), null);
|
||||
const copiedEffect = new KeyframeEffectReadOnly(effect);
|
||||
const effect = new KeyframeEffect(createDiv(t), null);
|
||||
const copiedEffect = new KeyframeEffect(effect);
|
||||
assert_equals(copiedEffect.target, effect.target, 'same target');
|
||||
}, 'Copied KeyframeEffectReadOnly has the same target');
|
||||
}, 'Copied KeyframeEffect has the same target');
|
||||
|
||||
test(t => {
|
||||
const effect =
|
||||
new KeyframeEffectReadOnly(null,
|
||||
[ { marginLeft: '0px' },
|
||||
{ marginLeft: '-20px', easing: 'ease-in',
|
||||
offset: 0.1 },
|
||||
{ marginLeft: '100px', easing: 'ease-out' },
|
||||
{ marginLeft: '50px' } ]);
|
||||
new KeyframeEffect(null,
|
||||
[ { marginLeft: '0px' },
|
||||
{ marginLeft: '-20px', easing: 'ease-in',
|
||||
offset: 0.1 },
|
||||
{ marginLeft: '100px', easing: 'ease-out' },
|
||||
{ marginLeft: '50px' } ]);
|
||||
|
||||
const copiedEffect = new KeyframeEffectReadOnly(effect);
|
||||
const copiedEffect = new KeyframeEffect(effect);
|
||||
const keyframesA = effect.getKeyframes();
|
||||
const keyframesB = copiedEffect.getKeyframes();
|
||||
assert_equals(keyframesA.length, keyframesB.length, 'same keyframes length');
|
||||
|
@ -50,34 +50,33 @@ test(t => {
|
|||
assert_equals(keyframesA[i].marginLeft, keyframesB[i].marginLeft,
|
||||
`Keyframe ${i} has the same property value pair`);
|
||||
}
|
||||
}, 'Copied KeyframeEffectReadOnly has the same keyframes');
|
||||
}, 'Copied KeyframeEffect has the same keyframes');
|
||||
|
||||
test(t => {
|
||||
const effect =
|
||||
new KeyframeEffectReadOnly(null, null,
|
||||
{ iterationComposite: 'accumulate' });
|
||||
new KeyframeEffect(null, null, { iterationComposite: 'accumulate' });
|
||||
|
||||
const copiedEffect = new KeyframeEffectReadOnly(effect);
|
||||
const copiedEffect = new KeyframeEffect(effect);
|
||||
assert_equals(copiedEffect.iterationComposite, effect.iterationComposite,
|
||||
'same iterationCompositeOperation');
|
||||
assert_equals(copiedEffect.composite, effect.composite,
|
||||
'same compositeOperation');
|
||||
}, 'Copied KeyframeEffectReadOnly has the same KeyframeEffectOptions');
|
||||
}, 'Copied KeyframeEffect has the same KeyframeEffectOptions');
|
||||
|
||||
test(t => {
|
||||
const effect = new KeyframeEffectReadOnly(null, null,
|
||||
{ duration: 100 * MS_PER_SEC,
|
||||
delay: -1 * MS_PER_SEC,
|
||||
endDelay: 2 * MS_PER_SEC,
|
||||
fill: 'forwards',
|
||||
iterationStart: 2,
|
||||
iterations: 20,
|
||||
easing: 'ease-out',
|
||||
direction: 'alternate' } );
|
||||
const effect = new KeyframeEffect(null, null,
|
||||
{ duration: 100 * MS_PER_SEC,
|
||||
delay: -1 * MS_PER_SEC,
|
||||
endDelay: 2 * MS_PER_SEC,
|
||||
fill: 'forwards',
|
||||
iterationStart: 2,
|
||||
iterations: 20,
|
||||
easing: 'ease-out',
|
||||
direction: 'alternate' } );
|
||||
|
||||
const copiedEffect = new KeyframeEffectReadOnly(effect);
|
||||
const timingA = effect.timing;
|
||||
const timingB = copiedEffect.timing;
|
||||
const copiedEffect = new KeyframeEffect(effect);
|
||||
const timingA = effect.getTiming();
|
||||
const timingB = copiedEffect.getTiming();
|
||||
assert_not_equals(timingA, timingB, 'different timing objects');
|
||||
assert_equals(timingA.delay, timingB.delay, 'same delay');
|
||||
assert_equals(timingA.endDelay, timingB.endDelay, 'same endDelay');
|
||||
|
@ -88,19 +87,7 @@ test(t => {
|
|||
assert_equals(timingA.duration, timingB.duration, 'same duration');
|
||||
assert_equals(timingA.direction, timingB.direction, 'same direction');
|
||||
assert_equals(timingA.easing, timingB.easing, 'same easing');
|
||||
}, 'Copied KeyframeEffectReadOnly has the same timing content');
|
||||
|
||||
test(t => {
|
||||
const effect = new KeyframeEffectReadOnly(createDiv(t), null);
|
||||
assert_equals(effect.constructor.name, 'KeyframeEffectReadOnly');
|
||||
assert_equals(effect.timing.constructor.name,
|
||||
'AnimationEffectTimingReadOnly');
|
||||
|
||||
// Make a mutable copy
|
||||
const copiedEffect = new KeyframeEffect(effect);
|
||||
assert_equals(copiedEffect.constructor.name, 'KeyframeEffect');
|
||||
assert_equals(copiedEffect.timing.constructor.name, 'AnimationEffectTiming');
|
||||
}, 'KeyframeEffect constructed from a KeyframeEffectReadOnly is mutable');
|
||||
}, 'Copied KeyframeEffect has the same timing content');
|
||||
|
||||
</script>
|
||||
</body>
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
<script src="/resources/WebIDLParser.js"></script>
|
||||
<script src="/resources/idlharness.js"></script>
|
||||
<div id="log"></div>
|
||||
<script type="text/plain" id="AnimationEffectTimingReadOnly-IDL">
|
||||
<script type="text/plain" id="AnimationEffect-IDL">
|
||||
enum FillMode { "none", "forwards", "backwards", "both", "auto" };
|
||||
enum PlaybackDirection {
|
||||
"normal",
|
||||
|
@ -18,7 +18,7 @@ enum PlaybackDirection {
|
|||
"alternate-reverse"
|
||||
};
|
||||
|
||||
dictionary AnimationEffectTimingProperties {
|
||||
dictionary EffectTiming {
|
||||
double delay = 0.0;
|
||||
double endDelay = 0.0;
|
||||
FillMode fill = "auto";
|
||||
|
@ -29,38 +29,37 @@ dictionary AnimationEffectTimingProperties {
|
|||
DOMString easing = "linear";
|
||||
};
|
||||
|
||||
[Exposed=Window]
|
||||
interface AnimationEffectTimingReadOnly {
|
||||
readonly attribute double delay;
|
||||
readonly attribute double endDelay;
|
||||
readonly attribute FillMode fill;
|
||||
readonly attribute double iterationStart;
|
||||
readonly attribute unrestricted double iterations;
|
||||
readonly attribute (unrestricted double or DOMString) duration;
|
||||
readonly attribute PlaybackDirection direction;
|
||||
readonly attribute DOMString easing;
|
||||
dictionary OptionalEffectTiming {
|
||||
double delay;
|
||||
double endDelay;
|
||||
FillMode fill;
|
||||
double iterationStart;
|
||||
unrestricted double iterations;
|
||||
(unrestricted double or DOMString) duration;
|
||||
PlaybackDirection direction;
|
||||
DOMString easing;
|
||||
};
|
||||
</script>
|
||||
<script type="text/plain" id="AnimationEffectReadOnly-IDL">
|
||||
dictionary ComputedTimingProperties : AnimationEffectTimingProperties {
|
||||
unrestricted double endTime;
|
||||
unrestricted double activeDuration;
|
||||
double? localTime;
|
||||
double? progress;
|
||||
unrestricted double? currentIteration;
|
||||
|
||||
dictionary ComputedEffectTiming : EffectTiming {
|
||||
unrestricted double endTime = 0.0;
|
||||
unrestricted double activeDuration = 0.0;
|
||||
double? localTime = null;
|
||||
double? progress = null;
|
||||
unrestricted double? currentIteration = null;
|
||||
};
|
||||
|
||||
[Exposed=Window]
|
||||
interface AnimationEffectReadOnly {
|
||||
readonly attribute AnimationEffectTimingReadOnly timing;
|
||||
ComputedTimingProperties getComputedTiming();
|
||||
interface AnimationEffect {
|
||||
EffectTiming getTiming();
|
||||
ComputedEffectTiming getComputedTiming();
|
||||
void updateTiming(optional OptionalEffectTiming timing);
|
||||
};
|
||||
</script>
|
||||
<script type="text/plain" id="KeyframeEffectReadOnly-IDL">
|
||||
<script type="text/plain" id="KeyframeEffect-IDL">
|
||||
enum IterationCompositeOperation { "replace", "accumulate" };
|
||||
enum CompositeOperation { "replace", "add", "accumulate" };
|
||||
|
||||
dictionary KeyframeEffectOptions : AnimationEffectTimingProperties {
|
||||
dictionary KeyframeEffectOptions : EffectTiming {
|
||||
IterationCompositeOperation iterationComposite = "replace";
|
||||
CompositeOperation composite = "replace";
|
||||
};
|
||||
|
@ -69,24 +68,13 @@ dictionary KeyframeEffectOptions : AnimationEffectTimingProperties {
|
|||
Constructor ((Element or CSSPseudoElement)? target,
|
||||
object? keyframes,
|
||||
optional (unrestricted double or KeyframeEffectOptions) options),
|
||||
Constructor (KeyframeEffectReadOnly source)]
|
||||
interface KeyframeEffectReadOnly : AnimationEffectReadOnly {
|
||||
readonly attribute (Element or CSSPseudoElement)? target;
|
||||
readonly attribute IterationCompositeOperation iterationComposite;
|
||||
readonly attribute CompositeOperation composite;
|
||||
Constructor (KeyframeEffect source)]
|
||||
interface KeyframeEffect : AnimationEffect {
|
||||
attribute (Element or CSSPseudoElement)? target;
|
||||
attribute IterationCompositeOperation iterationComposite;
|
||||
attribute CompositeOperation composite;
|
||||
|
||||
sequence<object> getKeyframes ();
|
||||
};
|
||||
</script>
|
||||
<script type="text/plain" id="KeyframeEffect-IDL">
|
||||
[Exposed=Window,
|
||||
Constructor ((Element or CSSPseudoElement)? target,
|
||||
object? keyframes,
|
||||
optional (unrestricted double or KeyframeEffectOptions) options),
|
||||
Constructor (KeyframeEffectReadOnly source)]
|
||||
interface KeyframeEffect : KeyframeEffectReadOnly {
|
||||
inherit attribute (Element or CSSPseudoElement)? target;
|
||||
inherit attribute IterationCompositeOperation iterationComposite;
|
||||
inherit attribute CompositeOperation composite;
|
||||
void setKeyframes (object? keyframes);
|
||||
};
|
||||
</script>
|
||||
|
@ -98,20 +86,13 @@ const idlArray = new IdlArray();
|
|||
idlArray.add_untested_idls('interface CSSPseudoElement {};');
|
||||
idlArray.add_untested_idls('interface Element {};');
|
||||
idlArray.add_untested_idls(
|
||||
document.getElementById('AnimationEffectTimingReadOnly-IDL').textContent
|
||||
);
|
||||
idlArray.add_idls(
|
||||
document.getElementById('AnimationEffectReadOnly-IDL').textContent
|
||||
);
|
||||
idlArray.add_idls(
|
||||
document.getElementById('KeyframeEffectReadOnly-IDL').textContent
|
||||
document.getElementById('AnimationEffect-IDL').textContent
|
||||
);
|
||||
idlArray.add_idls(
|
||||
document.getElementById('KeyframeEffect-IDL').textContent
|
||||
);
|
||||
idlArray.add_objects({
|
||||
KeyframeEffect: ['new KeyframeEffect(null, null)'],
|
||||
KeyframeEffectReadOnly: ['new KeyframeEffectReadOnly(null, null)'],
|
||||
});
|
||||
|
||||
idlArray.test();
|
||||
|
|
|
@ -19,7 +19,8 @@ test(t => {
|
|||
anim.pause();
|
||||
|
||||
anim.currentTime =
|
||||
anim.effect.timing.duration * 2 + anim.effect.timing.duration / 2;
|
||||
anim.effect.getComputedTiming().duration * 2 +
|
||||
anim.effect.getComputedTiming().duration / 2;
|
||||
assert_equals(getComputedStyle(div).marginLeft, '25px',
|
||||
'Animated style at 50s of the third iteration');
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
'use strict';
|
||||
|
||||
// This file only tests the KeyframeEffect constructor since it is
|
||||
// assumed that the implementation of the KeyframeEffectReadOnly constructor,
|
||||
// assumed that the implementation of the KeyframeEffect constructor,
|
||||
// Animatable.animate() method, and KeyframeEffect.setKeyframes() method will
|
||||
// all share common machinery and it is not necessary to test each method.
|
||||
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
'use strict';
|
||||
|
||||
// =================================
|
||||
//
|
||||
// Common timing parameter test data
|
||||
//
|
||||
// =================================
|
||||
|
||||
|
||||
// ------------------------------
|
||||
// Delay values
|
||||
// ------------------------------
|
||||
|
||||
const gBadDelayValues = [
|
||||
NaN, Infinity, -Infinity
|
||||
];
|
||||
|
||||
// ------------------------------
|
||||
// Duration values
|
||||
// ------------------------------
|
||||
|
||||
const gGoodDurationValues = [
|
||||
{ specified: 123.45, computed: 123.45 },
|
||||
{ specified: 'auto', computed: 0 },
|
||||
{ specified: Infinity, computed: Infinity },
|
||||
];
|
||||
|
||||
const gBadDurationValues = [
|
||||
-1, NaN, -Infinity, 'abc', '100'
|
||||
];
|
||||
|
||||
// ------------------------------
|
||||
// iterationStart values
|
||||
// ------------------------------
|
||||
|
||||
const gBadIterationStartValues = [
|
||||
-1, NaN, Infinity, -Infinity
|
||||
];
|
||||
|
||||
// ------------------------------
|
||||
// iterations values
|
||||
// ------------------------------
|
||||
|
||||
const gBadIterationsValues = [
|
||||
-1, -Infinity, NaN
|
||||
];
|
|
@ -0,0 +1,39 @@
|
|||
'use strict';
|
||||
|
||||
// =======================================
|
||||
//
|
||||
// Utility functions for testing timing
|
||||
//
|
||||
// =======================================
|
||||
|
||||
|
||||
// ------------------------------
|
||||
// Helper functions
|
||||
// ------------------------------
|
||||
|
||||
// Utility function to check that a subset of timing properties have their
|
||||
// default values.
|
||||
function assert_default_timing_except(effect, propertiesToSkip) {
|
||||
const defaults = {
|
||||
delay: 0,
|
||||
endDelay: 0,
|
||||
fill: 'auto',
|
||||
iterationStart: 0,
|
||||
iterations: 1,
|
||||
duration: 'auto',
|
||||
direction: 'normal',
|
||||
easing: 'linear',
|
||||
};
|
||||
|
||||
for (const prop of Object.keys(defaults)) {
|
||||
if (propertiesToSkip.includes(prop)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
assert_equals(
|
||||
effect.getTiming()[prop],
|
||||
defaults[prop],
|
||||
`${prop} parameter has default value:`
|
||||
);
|
||||
}
|
||||
}
|
|
@ -29,7 +29,11 @@ if (!window.assert_times_equal) {
|
|||
// a time value based on its precision requirements with a fixed value.
|
||||
if (!window.assert_time_equals_literal) {
|
||||
window.assert_time_equals_literal = (actual, expected, description) => {
|
||||
assert_approx_equals(actual, expected, TIME_PRECISION, description);
|
||||
if (Math.abs(expected) === Infinity) {
|
||||
assert_equals(actual, expected, description);
|
||||
} else {
|
||||
assert_approx_equals(actual, expected, TIME_PRECISION, description);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -283,4 +287,4 @@ function assert_rotate3d_equals(actual, expected, description) {
|
|||
assert_approx_equals(actualRotationVector[i], expectedRotationVector[i], 0.0001,
|
||||
`expected ${expected} but got ${actual}: ${description}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ function assert_phase_at_time(animation, phase, 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';
|
||||
animation.effect.updateTiming({ fill: 'none' });
|
||||
assert_not_equals(animation.effect.getComputedTiming().progress, null,
|
||||
'Animation effect is in active phase when current time'
|
||||
+ ` is ${currentTime}ms`);
|
||||
|
@ -31,15 +31,15 @@ function assert_phase_at_time(animation, phase, currentTime) {
|
|||
// 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';
|
||||
animation.effect.updateTiming({ 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';
|
||||
animation.effect.updateTiming({
|
||||
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`
|
||||
|
|
|
@ -196,7 +196,7 @@ promise_test(async t => {
|
|||
}, 'Finishing an animation resolves the finished promise synchronously');
|
||||
|
||||
promise_test(async t => {
|
||||
const effect = new KeyframeEffectReadOnly(null, null, 100 * MS_PER_SEC);
|
||||
const effect = new KeyframeEffect(null, null, 100 * MS_PER_SEC);
|
||||
const animation = new Animation(effect, document.timeline);
|
||||
let resolvedFinished = false;
|
||||
animation.finished.then(() => {
|
||||
|
|
|
@ -36,9 +36,9 @@ promise_test(async t => {
|
|||
anim.pause();
|
||||
assert_true(anim.pending);
|
||||
|
||||
anim.effect = new KeyframeEffectReadOnly(createDiv(t),
|
||||
{ marginLeft: [ '0px', '100px' ] },
|
||||
100 * MS_PER_SEC);
|
||||
anim.effect = new KeyframeEffect(createDiv(t),
|
||||
{ marginLeft: [ '0px', '100px' ] },
|
||||
100 * MS_PER_SEC);
|
||||
assert_true(anim.pending);
|
||||
await anim.ready;
|
||||
|
||||
|
@ -52,9 +52,9 @@ promise_test(async t => {
|
|||
anim.play();
|
||||
assert_true(anim.pending);
|
||||
|
||||
anim.effect = new KeyframeEffectReadOnly(createDiv(t),
|
||||
{ marginLeft: [ '0px', '100px' ] },
|
||||
100 * MS_PER_SEC);
|
||||
anim.effect = new KeyframeEffect(createDiv(t),
|
||||
{ marginLeft: [ '0px', '100px' ] },
|
||||
100 * MS_PER_SEC);
|
||||
assert_true(anim.pending);
|
||||
await anim.ready;
|
||||
|
||||
|
|
|
@ -141,7 +141,9 @@ promise_test(async t => {
|
|||
'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;
|
||||
anim.effect.updateTiming({
|
||||
duration: anim.effect.getComputedTiming().duration * 2,
|
||||
});
|
||||
await waitForNextFrame();
|
||||
|
||||
assert_greater_than(anim.currentTime, 100 * MS_PER_SEC,
|
||||
|
@ -247,7 +249,7 @@ promise_test(async t => {
|
|||
anim.cancel();
|
||||
// Trigger a change that will cause the "update the finished state"
|
||||
// procedure to run.
|
||||
anim.effect.timing.duration = 200 * MS_PER_SEC;
|
||||
anim.effect.updateTiming({ 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
|
||||
|
@ -273,7 +275,7 @@ test(t => {
|
|||
// 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;
|
||||
anim.effect.updateTiming({ 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');
|
||||
|
@ -289,7 +291,7 @@ promise_test(async t => {
|
|||
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;
|
||||
anim.effect.updateTiming({ duration: 200 * MS_PER_SEC });
|
||||
await waitForAnimationFrames(1);
|
||||
|
||||
assert_equals(anim.currentTime, 150 * MS_PER_SEC,
|
||||
|
@ -348,7 +350,7 @@ promise_test(async t => {
|
|||
}, 'Finish notification steps run when the animation completes normally');
|
||||
|
||||
promise_test(async t => {
|
||||
const effect = new KeyframeEffectReadOnly(null, null, 1);
|
||||
const effect = new KeyframeEffect(null, null, 1);
|
||||
const animation = new Animation(effect, document.timeline);
|
||||
animation.play();
|
||||
await animation.ready;
|
||||
|
@ -417,5 +419,38 @@ async_test(t => {
|
|||
};
|
||||
}, 'Animation finish event is fired again after replaying from start');
|
||||
|
||||
async_test(t => {
|
||||
const anim = createDiv(t).animate(null,
|
||||
{ duration: 100000, endDelay: 50000 });
|
||||
anim.onfinish = t.step_func(event => {
|
||||
assert_unreached('finish event should not be fired');
|
||||
});
|
||||
|
||||
anim.ready.then(() => {
|
||||
anim.currentTime = 100000;
|
||||
return waitForAnimationFrames(2);
|
||||
}).then(t.step_func(() => {
|
||||
t.done();
|
||||
}));
|
||||
}, 'finish event is not fired at the end of the active interval when the'
|
||||
+ ' endDelay has not expired');
|
||||
|
||||
async_test(t => {
|
||||
const anim = createDiv(t).animate(null,
|
||||
{ duration: 100000, endDelay: 30000 });
|
||||
anim.ready.then(() => {
|
||||
anim.currentTime = 110000; // during endDelay
|
||||
anim.onfinish = t.step_func(event => {
|
||||
assert_unreached('onfinish event should not be fired during endDelay');
|
||||
});
|
||||
return waitForAnimationFrames(2);
|
||||
}).then(t.step_func(() => {
|
||||
anim.onfinish = t.step_func(event => {
|
||||
t.done();
|
||||
});
|
||||
anim.currentTime = 130000; // after endTime
|
||||
}));
|
||||
}, 'finish event is fired after the endDelay has expired');
|
||||
|
||||
</script>
|
||||
</body>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue