mirror of
https://github.com/servo/servo.git
synced 2025-07-01 12:33:40 +01:00
221 lines
7.9 KiB
HTML
221 lines
7.9 KiB
HTML
<!DOCTYPE html>
|
|
<meta charset=utf-8>
|
|
<title>Animatable.animate</title>
|
|
<link rel="help" href="https://drafts.csswg.org/web-animations/#dom-animatable-animate">
|
|
<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/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>
|
|
<script>
|
|
'use strict';
|
|
|
|
// Tests on Element
|
|
|
|
test(t => {
|
|
const anim = createDiv(t).animate(null);
|
|
assert_class_string(anim, 'Animation', 'Returned object is an Animation');
|
|
}, 'Element.animate() creates an Animation object');
|
|
|
|
test(t => {
|
|
const iframe = window.frames[0];
|
|
const div = createDiv(t, iframe.document);
|
|
const anim = Element.prototype.animate.call(div, null);
|
|
assert_equals(Object.getPrototypeOf(anim), iframe.Animation.prototype,
|
|
'The prototype of the created Animation is that defined on'
|
|
+ ' the relevant global for the target element');
|
|
assert_not_equals(Object.getPrototypeOf(anim), Animation.prototype,
|
|
'The prototype of the created Animation is NOT that of'
|
|
+ ' the current global');
|
|
}, 'Element.animate() creates an Animation object in the relevant realm of'
|
|
+ ' the target element');
|
|
|
|
test(t => {
|
|
const div = createDiv(t);
|
|
const anim = Element.prototype.animate.call(div, null);
|
|
assert_class_string(anim.effect, 'KeyframeEffect',
|
|
'Returned Animation has a KeyframeEffect');
|
|
}, 'Element.animate() creates an Animation object with a KeyframeEffect');
|
|
|
|
test(t => {
|
|
const iframe = window.frames[0];
|
|
const div = createDiv(t, iframe.document);
|
|
const anim = Element.prototype.animate.call(div, null);
|
|
assert_equals(Object.getPrototypeOf(anim.effect),
|
|
iframe.KeyframeEffect.prototype,
|
|
'The prototype of the created KeyframeEffect is that defined on'
|
|
+ ' the relevant global for the target element');
|
|
assert_not_equals(Object.getPrototypeOf(anim.effect),
|
|
KeyframeEffect.prototype,
|
|
'The prototype of the created KeyframeEffect is NOT that of'
|
|
+ ' the current global');
|
|
}, 'Element.animate() creates an Animation object with a KeyframeEffect'
|
|
+ ' that is created in the relevant realm of the target element');
|
|
|
|
for (const subtest of gEmptyKeyframeListTests) {
|
|
test(t => {
|
|
const anim = createDiv(t).animate(subtest, 2000);
|
|
assert_not_equals(anim, null);
|
|
}, 'Element.animate() accepts empty keyframe lists ' +
|
|
`(input: ${JSON.stringify(subtest)})`);
|
|
}
|
|
|
|
for (const subtest of gKeyframesTests) {
|
|
test(t => {
|
|
const anim = createDiv(t).animate(subtest.input, 2000);
|
|
assert_frame_lists_equal(anim.effect.getKeyframes(), subtest.output);
|
|
}, `Element.animate() accepts ${subtest.desc}`);
|
|
}
|
|
|
|
for (const subtest of gInvalidKeyframesTests) {
|
|
test(t => {
|
|
const div = createDiv(t);
|
|
assert_throws(new TypeError, () => {
|
|
div.animate(subtest.input, 2000);
|
|
});
|
|
}, `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 => {
|
|
assert_throws(new TypeError, () => {
|
|
createDiv(t).animate({ easing: invalidEasing }, 2000);
|
|
});
|
|
}, `Element.animate() does not accept invalid easing: '${invalidEasing}'`);
|
|
}
|
|
|
|
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 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 anim = createDiv(t).animate(null, { id: 'test' });
|
|
assert_equals(anim.id, 'test');
|
|
}, 'Element.animate() correctly sets the id attribute');
|
|
|
|
test(t => {
|
|
const anim = createDiv(t).animate(null, 2000);
|
|
assert_equals(anim.timeline, document.timeline);
|
|
}, 'Element.animate() correctly sets the Animation\'s timeline');
|
|
|
|
async_test(t => {
|
|
const iframe = document.createElement('iframe');
|
|
iframe.width = 10;
|
|
iframe.height = 10;
|
|
|
|
iframe.addEventListener('load', t.step_func(() => {
|
|
const div = createDiv(t, iframe.contentDocument);
|
|
const anim = div.animate(null, 2000);
|
|
assert_equals(anim.timeline, iframe.contentDocument.timeline);
|
|
iframe.remove();
|
|
t.done();
|
|
}));
|
|
|
|
document.body.appendChild(iframe);
|
|
}, 'Element.animate() correctly sets the Animation\'s timeline when ' +
|
|
'triggered on an element in a different document');
|
|
|
|
test(t => {
|
|
const anim = createDiv(t).animate(null, 2000);
|
|
assert_equals(anim.playState, 'running');
|
|
}, 'Element.animate() calls play on the Animation');
|
|
|
|
// Tests on CSSPseudoElement
|
|
|
|
test(t => {
|
|
const pseudoTarget = getPseudoElement(t, 'before');
|
|
const anim = pseudoTarget.animate(null);
|
|
assert_class_string(anim, 'Animation', 'The returned object is an Animation');
|
|
}, 'CSSPseudoElement.animate() creates an Animation object');
|
|
|
|
test(t => {
|
|
const pseudoTarget = getPseudoElement(t, 'before');
|
|
const anim = pseudoTarget.animate(null);
|
|
assert_equals(anim.effect.target, pseudoTarget,
|
|
'The returned Animation targets to the correct object');
|
|
}, 'CSSPseudoElement.animate() creates an Animation object targeting ' +
|
|
'to the correct CSSPseudoElement object');
|
|
</script>
|
|
</body>
|