Bug 1049975 - Part 10: Test for writable effect.
MozReview-Commit-ID: 2hMY2barRb9
new file mode 100644
--- /dev/null
+++ b/dom/animation/test/css-transitions/file_setting-effect.html
@@ -0,0 +1,91 @@
+<!doctype html>
+<meta charset=utf-8>
+<script src='../testcommon.js'></script>
+<body>
+<script>
+'use strict';
+
+promise_test(function(t) {
+ var div = addDiv(t);
+ div.style.left = '0px';
+
+ div.style.transition = 'left 100s';
+ flushComputedStyle(div);
+ div.style.left = '100px';
+
+ var transition = div.getAnimations()[0];
+ return transition.ready.then(function() {
+ transition.currentTime = 50 * MS_PER_SEC;
+ transition.effect = null;
+ assert_equals(transition.transitionProperty, 'left');
+ assert_equals(transition.playState, 'finished');
+ assert_equals(window.getComputedStyle(div).left, '100px');
+ });
+}, 'Test for removing a transition effect');
+
+promise_test(function(t) {
+ var div = addDiv(t);
+ div.style.left = '0px';
+
+ div.style.transition = 'left 100s';
+ flushComputedStyle(div);
+ div.style.left = '100px';
+
+ var transition = div.getAnimations()[0];
+ return transition.ready.then(function() {
+ transition.currentTime = 50 * MS_PER_SEC;
+ transition.effect = new KeyframeEffect(div,
+ { marginLeft: [ '0px' , '100px'] },
+ 100 * MS_PER_SEC);
+ assert_equals(transition.transitionProperty, 'left');
+ assert_equals(transition.playState, 'running');
+ assert_equals(window.getComputedStyle(div).left, '100px');
+ assert_equals(window.getComputedStyle(div).marginLeft, '50px');
+ });
+}, 'Test for replacing the transition effect by a new keyframe effect');
+
+promise_test(function(t) {
+ var div = addDiv(t);
+ div.style.left = '0px';
+ div.style.width = '0px';
+
+ div.style.transition = 'left 100s';
+ flushComputedStyle(div);
+ div.style.left = '100px';
+
+ var transition = div.getAnimations()[0];
+ return transition.ready.then(function() {
+ transition.currentTime = 50 * MS_PER_SEC;
+ transition.effect = new KeyframeEffect(div,
+ { marginLeft: [ '0px' , '100px'] },
+ 20 * MS_PER_SEC);
+ assert_equals(transition.playState, 'finished');
+ });
+}, 'Test for setting a new keyframe effect with a shorter duration');
+
+promise_test(function(t) {
+ var div = addDiv(t);
+ div.style.left = '0px';
+ div.style.width = '0px';
+
+ div.style.transition = 'left 100s';
+ flushComputedStyle(div);
+ div.style.left = '100px';
+
+ var transition = div.getAnimations()[0];
+ assert_equals(transition.playState, 'pending');
+
+ transition.effect = new KeyframeEffect(div,
+ { marginLeft: [ '0px' , '100px'] },
+ 100 * MS_PER_SEC);
+ assert_equals(transition.transitionProperty, 'left');
+ assert_equals(transition.playState, 'pending');
+
+ return transition.ready.then(function() {
+ assert_equals(transition.playState, 'running');
+ });
+}, 'Test for setting a new keyframe effect to a pending transition');
+
+done();
+</script>
+</body>
new file mode 100644
--- /dev/null
+++ b/dom/animation/test/css-transitions/test_setting-effect.html
@@ -0,0 +1,14 @@
+<!doctype html>
+<meta charset=utf-8>
+<script src='/resources/testharness.js'></script>
+<script src='/resources/testharnessreport.js'></script>
+<div id='log'></div>
+<script>
+'use strict';
+setup({explicit_done: true});
+SpecialPowers.pushPrefEnv(
+ { 'set': [['dom.animations-api.core.enabled', true]]},
+ function() {
+ window.open('file_setting-effect.html');
+ });
+</script>
--- a/dom/animation/test/mochitest.ini
+++ b/dom/animation/test/mochitest.ini
@@ -29,28 +29,30 @@ support-files =
css-transitions/file_animation-ready.html
css-transitions/file_animation-starttime.html
css-transitions/file_csstransition-transitionproperty.html
css-transitions/file_document-get-animations.html
css-transitions/file_effect-target.html
css-transitions/file_element-get-animations.html
css-transitions/file_keyframeeffect-getkeyframes.html
css-transitions/file_pseudoElement-get-animations.html
+ css-transitions/file_setting-effect.html
document-timeline/file_document-timeline.html
mozilla/file_cubic_bezier_limits.html
mozilla/file_deferred_start.html
mozilla/file_disabled_properties.html
mozilla/file_document-timeline-origin-time-range.html
mozilla/file_hide_and_show.html
mozilla/file_partial_keyframes.html
mozilla/file_spacing_property_order.html
mozilla/file_transform_limits.html
mozilla/file_underlying-discrete-value.html
style/file_animation-seeking-with-current-time.html
style/file_animation-seeking-with-start-time.html
+ style/file_animation-setting-effect.html
testcommon.js
[css-animations/test_animations-dynamic-changes.html]
[css-animations/test_animation-cancel.html]
[css-animations/test_animation-computed-timing.html]
[css-animations/test_animation-currenttime.html]
[css-animations/test_animation-finish.html]
[css-animations/test_animation-finished.html]
@@ -76,24 +78,26 @@ skip-if = buildapp == 'mulet'
[css-transitions/test_animation-starttime.html]
[css-transitions/test_csstransition-transitionproperty.html]
[css-transitions/test_document-get-animations.html]
[css-transitions/test_effect-target.html]
[css-transitions/test_element-get-animations.html]
skip-if = buildapp == 'mulet'
[css-transitions/test_keyframeeffect-getkeyframes.html]
[css-transitions/test_pseudoElement-get-animations.html]
+[css-transitions/test_setting-effect.html]
[document-timeline/test_document-timeline.html]
[document-timeline/test_request_animation_frame.html]
skip-if = buildapp == 'mulet'
[mozilla/test_cubic_bezier_limits.html]
[mozilla/test_deferred_start.html]
skip-if = (toolkit == 'gonk' && debug)
[mozilla/test_disabled_properties.html]
[mozilla/test_document-timeline-origin-time-range.html]
[mozilla/test_hide_and_show.html]
[mozilla/test_partial_keyframes.html]
[mozilla/test_set-easing.html]
[mozilla/test_spacing_property_order.html]
[mozilla/test_transform_limits.html]
[mozilla/test_underlying-discrete-value.html]
[style/test_animation-seeking-with-current-time.html]
[style/test_animation-seeking-with-start-time.html]
+[style/test_animation-setting-effect.html]
new file mode 100644
--- /dev/null
+++ b/dom/animation/test/style/file_animation-setting-effect.html
@@ -0,0 +1,125 @@
+<!doctype html>
+<html>
+ <head>
+ <meta charset=utf-8>
+ <title>Tests for setting effects by using Animation.effect</title>
+ <script src='../testcommon.js'></script>
+ </head>
+ <body>
+ <script type='text/javascript'>
+
+'use strict';
+
+test(function(t) {
+ var target = addDiv(t);
+ var anim = new Animation();
+ anim.effect = new KeyframeEffectReadOnly(target,
+ { marginLeft: [ '0px', '100px' ] },
+ 100 * MS_PER_SEC);
+ anim.currentTime = 50 * MS_PER_SEC;
+ assert_equals(getComputedStyle(target).marginLeft, '50px');
+}, 'After setting target effect on an animation with null effect, the ' +
+ 'animation still works');
+
+test(function(t) {
+ var target = addDiv(t);
+ target.style.marginLeft = '10px';
+ var anim = target.animate({ marginLeft: [ '0px', '100px' ] },
+ 100 * MS_PER_SEC);
+ anim.currentTime = 50 * MS_PER_SEC;
+ assert_equals(getComputedStyle(target).marginLeft, '50px');
+
+ anim.effect = null;
+ assert_equals(getComputedStyle(target).marginLeft, '10px');
+}, 'After setting null target effect, the computed style of the target ' +
+ 'element becomes the initial value');
+
+test(function(t) {
+ var target = addDiv(t);
+ var animA = target.animate({ marginLeft: [ '0px', '100px' ] },
+ 100 * MS_PER_SEC);
+ var animB = new Animation();
+ animA.currentTime = 50 * MS_PER_SEC;
+ animB.currentTime = 20 * MS_PER_SEC;
+ assert_equals(getComputedStyle(target).marginLeft, '50px',
+ 'original computed style of the target element');
+
+ animB.effect = animA.effect;
+ assert_equals(getComputedStyle(target).marginLeft, '20px',
+ 'new computed style of the target element');
+}, 'After setting the target effect from an existing animation, the computed ' +
+ 'style of the target effect should reflect the time of the updated ' +
+ 'animation.');
+
+test(function(t) {
+ var target = addDiv(t);
+ target.style.marginTop = '-10px';
+ var animA = target.animate({ marginLeft: [ '0px', '100px' ] },
+ 100 * MS_PER_SEC);
+ var animB = target.animate({ marginTop: [ '0px', '100px' ] },
+ 50 * MS_PER_SEC);
+ animA.currentTime = 50 * MS_PER_SEC;
+ animB.currentTime = 10 * MS_PER_SEC;
+ assert_equals(getComputedStyle(target).marginLeft, '50px',
+ 'original margin-left of the target element');
+ assert_equals(getComputedStyle(target).marginTop, '20px',
+ 'original margin-top of the target element');
+
+ animB.effect = animA.effect;
+ assert_equals(getComputedStyle(target).marginLeft, '10px',
+ 'new margin-left of the target element');
+ assert_equals(getComputedStyle(target).marginTop, '-10px',
+ 'new margin-top of the target element');
+}, 'After setting target effect with an animation to another animation which ' +
+ 'also has an target effect and both animation effects target to the same ' +
+ 'element, the computed style of this element should reflect the time and ' +
+ 'effect of the animation that was set');
+
+test(function(t) {
+ var targetA = addDiv(t);
+ var targetB = addDiv(t);
+ targetB.style.marginLeft = '-10px';
+ var animA = targetA.animate({ marginLeft: [ '0px', '100px' ] },
+ 100 * MS_PER_SEC);
+ var animB = targetB.animate({ marginLeft: [ '0px', '100px' ] },
+ 50 * MS_PER_SEC);
+ animA.currentTime = 50 * MS_PER_SEC;
+ animB.currentTime = 10 * MS_PER_SEC;
+ assert_equals(getComputedStyle(targetA).marginLeft, '50px',
+ 'original margin-left of the first element');
+ assert_equals(getComputedStyle(targetB).marginLeft, '20px',
+ 'original margin-left of the second element');
+
+ animB.effect = animA.effect;
+ assert_equals(getComputedStyle(targetA).marginLeft, '10px',
+ 'new margin-left of the first element');
+ assert_equals(getComputedStyle(targetB).marginLeft, '-10px',
+ 'new margin-left of the second element');
+}, 'After setting target effect with an animation to another animation which ' +
+ 'also has an target effect and these animation effects target to ' +
+ 'different elements, the computed styles of the two elements should ' +
+ 'reflect the time and effect of the animation that was set');
+
+test(function(t) {
+ var target = addDiv(t);
+ var animA = target.animate({ marginLeft: [ '0px', '100px' ] },
+ 50 * MS_PER_SEC);
+ var animB = target.animate({ marginTop: [ '0px', '50px' ] },
+ 100 * MS_PER_SEC);
+ animA.currentTime = 20 * MS_PER_SEC;
+ animB.currentTime = 30 * MS_PER_SEC;
+ assert_equals(getComputedStyle(target).marginLeft, '40px');
+ assert_equals(getComputedStyle(target).marginTop, '15px');
+
+ var effectA = animA.effect;
+ animA.effect = animB.effect;
+ animB.effect = effectA;
+ assert_equals(getComputedStyle(target).marginLeft, '60px');
+ assert_equals(getComputedStyle(target).marginTop, '10px');
+}, 'After swapping effects of two playing animations, both animations are ' +
+ 'still running with the same current time');
+
+done();
+ </script>
+ </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/dom/animation/test/style/test_animation-setting-effect.html
@@ -0,0 +1,15 @@
+<!doctype html>
+<meta charset=utf-8>
+<script src='/resources/testharness.js'></script>
+<script src='/resources/testharnessreport.js'></script>
+<div id='log'></div>
+<script>
+'use strict';
+setup({explicit_done: true});
+SpecialPowers.pushPrefEnv(
+ { 'set': [['dom.animations-api.core.enabled', true]]},
+ function() {
+ window.open('file_animation-setting-effect.html');
+ });
+</script>
+</html>
--- a/testing/web-platform/meta/MANIFEST.json
+++ b/testing/web-platform/meta/MANIFEST.json
@@ -37663,22 +37663,34 @@
}
],
"html/semantics/forms/the-form-element/form-submission-sandbox.html": [
{
"path": "html/semantics/forms/the-form-element/form-submission-sandbox.html",
"url": "/html/semantics/forms/the-form-element/form-submission-sandbox.html"
}
],
+ "web-animations/interfaces/Animation/effect.html": [
+ {
+ "path": "web-animations/interfaces/Animation/effect.html",
+ "url": "/web-animations/interfaces/Animation/effect.html"
+ }
+ ],
"web-animations/timing-model/animation-effects/phases-and-states.html": [
{
"path": "web-animations/timing-model/animation-effects/phases-and-states.html",
"url": "/web-animations/timing-model/animation-effects/phases-and-states.html"
}
],
+ "web-animations/timing-model/animations/set-the-target-effect-of-an-animation.html": [
+ {
+ "path": "web-animations/timing-model/animations/set-the-target-effect-of-an-animation.html",
+ "url": "/web-animations/timing-model/animations/set-the-target-effect-of-an-animation.html"
+ }
+ ],
"web-animations/timing-model/animations/updating-the-finished-state.html": [
{
"path": "web-animations/timing-model/animations/updating-the-finished-state.html",
"url": "/web-animations/timing-model/animations/updating-the-finished-state.html"
}
]
}
},
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/web-animations/interfaces/Animation/effect.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Animation.effect tests</title>
+<link rel="help" href="https://w3c.github.io/web-animations/#dom-animation-effect">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../../testcommon.js"></script>
+<link rel="stylesheet" href="/resources/testharness.css">
+<body>
+<div id="log"></div>
+<script>
+"use strict";
+
+test(function(t) {
+ var anim = new Animation();
+ assert_equals(anim.effect, null, "initial effect is null");
+
+ var newEffect = new KeyframeEffectReadOnly(createDiv(t), null);
+ anim.effect = newEffect;
+ assert_equals(anim.effect, newEffect, "new effect is set");
+}, "effect is set correctly.");
+
+</script>
+</body>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/web-animations/timing-model/animations/set-the-target-effect-of-an-animation.html
@@ -0,0 +1,95 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Setting the target effect tests</title>
+<link rel='help' href='https://w3c.github.io/web-animations/#setting-the-target-effect'>
+<script src='/resources/testharness.js'></script>
+<script src='/resources/testharnessreport.js'></script>
+<script src='../../testcommon.js'></script>
+<body>
+<div id='log'></div>
+<script>
+'use strict';
+
+promise_test(function(t) {
+ var anim = createDiv(t).animate({ marginLeft: [ '0px', '100px' ] },
+ 100 * MS_PER_SEC);
+ assert_equals(anim.playState, 'pending');
+
+ var retPromise = anim.ready.then(function() {
+ assert_unreached('ready promise is fulfilled');
+ }).catch(function(err) {
+ assert_equals(err.name, 'AbortError',
+ 'ready promise is rejected with AbortError');
+ });
+
+ anim.effect = null;
+ assert_equals(anim.playState, 'paused');
+
+ return retPromise;
+}, 'If new effect is null and old effect is not null, we reset the pending ' +
+ 'tasks and ready promise is rejected');
+
+promise_test(function(t) {
+ var anim = new Animation();
+ anim.pause();
+ assert_equals(anim.playState, 'pending');
+
+ anim.effect = new KeyframeEffectReadOnly(createDiv(t),
+ { marginLeft: [ '0px', '100px' ] },
+ 100 * MS_PER_SEC);
+ assert_equals(anim.playState, 'pending');
+
+ return anim.ready.then(function() {
+ assert_equals(anim.playState, 'paused');
+ });
+}, 'If animation has a pending pause task, reschedule that task to run ' +
+ 'as soon as animation is ready.');
+
+promise_test(function(t) {
+ var anim = new Animation();
+ anim.play();
+ assert_equals(anim.playState, 'pending');
+
+ anim.effect = new KeyframeEffectReadOnly(createDiv(t),
+ { marginLeft: [ '0px', '100px' ] },
+ 100 * MS_PER_SEC);
+ assert_equals(anim.playState, 'pending');
+
+ return anim.ready.then(function() {
+ assert_equals(anim.playState, 'running');
+ });
+}, 'If animation has a pending play task, reschedule that task to run ' +
+ 'as soon as animation is ready to play new effect.');
+
+promise_test(function(t) {
+ var animA = createDiv(t).animate({ marginLeft: [ '0px', '100px' ] },
+ 100 * MS_PER_SEC);
+ var animB = new Animation();
+
+ return animA.ready.then(function() {
+ animB.effect = animA.effect;
+ assert_equals(animA.effect, null);
+ assert_equals(animA.playState, 'finished');
+ });
+}, 'When setting the effect of an animation to the effect of an existing ' +
+ 'animation, the existing animation\'s target effect should be set to null.');
+
+test(function(t) {
+ var animA = createDiv(t).animate({ marginLeft: [ '0px', '100px' ] },
+ 100 * MS_PER_SEC);
+ var animB = new Animation();
+ var effect = animA.effect;
+ animA.currentTime = 50 * MS_PER_SEC;
+ animB.currentTime = 20 * MS_PER_SEC;
+ assert_equals(effect.getComputedTiming().progress, 0.5,
+ 'Original timing comes from first animation');
+ animB.effect = effect;
+ assert_equals(effect.getComputedTiming().progress, 0.2,
+ 'After setting the effect on a different animation, ' +
+ 'it uses the new animation\'s timing');
+}, 'After setting the target effect of animation to the target effect of an ' +
+ 'existing animation, the target effect\'s timing is updated to reflect ' +
+ 'the current time of the new animation.');
+
+</script>
+</body>