author | Hiroyuki Ikezoe <hiikezoe@mozilla-japan.org> |
Fri, 14 Oct 2016 07:58:32 +0900 | |
changeset 317814 | 8a34e43924f5e269579145231f6f3c43a6e812e2 |
parent 317813 | 2664c275c9d5e056282c3b7670dc3179c5e71cb6 |
child 317815 | 617c4ce41eb287953e9dbf8c073446aafe835dc8 |
push id | 30817 |
push user | cbook@mozilla.com |
push date | Fri, 14 Oct 2016 09:56:08 +0000 |
treeherder | mozilla-central@a71215ad8ab8 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | boris |
bugs | 1283754 |
milestone | 52.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/dom/animation/test/chrome.ini +++ b/dom/animation/test/chrome.ini @@ -7,11 +7,12 @@ support-files = [chrome/test_animate_xrays.html] # file_animate_xrays.html needs to go in mochitest.ini since it is served # over HTTP [chrome/test_animation_observers.html] [chrome/test_animation_performance_warning.html] [chrome/test_animation_properties.html] [chrome/test_generated_content_getAnimations.html] +[chrome/test_observers_for_script_animation.html] [chrome/test_restyles.html] [chrome/test_running_on_compositor.html] skip-if = buildapp == 'b2g'
--- a/dom/animation/test/chrome/test_animation_observers.html +++ b/dom/animation/test/chrome/test_animation_observers.html @@ -1517,193 +1517,55 @@ addAsyncAnimTest("tree_ordering", { obse div.classList.remove("before"); div.classList.remove("after"); div.style = ""; childA.remove(); childB.remove(); extraStyle.remove(); }); -[ div, pseudoTarget ].forEach(function(target) { - addAsyncAnimTest("change_duration_and_currenttime", - { observe: div, subtree: true }, function*() { - var anim = target.animate({ opacity: [ 0, 1 ] }, 200 * MS_PER_SEC); - - yield waitForFrame(); - assert_records([{ added: [anim], changed: [], removed: [] }], - "records after animation is added"); - - anim.effect.timing.duration = 100 * MS_PER_SEC; - yield waitForFrame(); - assert_records([{ added: [], changed: [anim], removed: [] }], - "records after duration is changed"); - - anim.effect.timing.duration = 100 * MS_PER_SEC; - yield waitForFrame(); - assert_records([], "records after assigning same value"); - - anim.currentTime = anim.effect.timing.duration * 2; - anim.finish(); - yield waitForFrame(); - assert_records([{ added: [], changed: [], removed: [anim] }], - "records after animation end"); - - anim.effect.timing.duration = anim.effect.timing.duration * 3; - yield waitForFrame(); - assert_records([{ added: [anim], changed: [], removed: [] }], - "records after animation restarted"); - - anim.effect.timing.duration = "auto"; - yield waitForFrame(); - assert_records([{ added: [], changed: [], removed: [anim] }], - "records after duration set \"auto\""); - - anim.effect.timing.duration = "auto"; - yield waitForFrame(); - assert_records([], "records after assigning same value \"auto\""); - - anim.cancel(); - yield waitForFrame(); - }); -}); - -addAsyncAnimTest("change_enddelay_and_currenttime", +addAsyncAnimTest("change_duration_and_currenttime", { observe: div, subtree: true }, function*() { - var anim = div.animate({ opacity: [ 0, 1 ] }, { duration: 100 * MS_PER_SEC }); + var anim = pseudoTarget.animate({ opacity: [ 0, 1 ] }, 200 * MS_PER_SEC); yield waitForFrame(); assert_records([{ added: [anim], changed: [], removed: [] }], "records after animation is added"); - anim.effect.timing.endDelay = 10 * MS_PER_SEC; + anim.effect.timing.duration = 100 * MS_PER_SEC; yield waitForFrame(); assert_records([{ added: [], changed: [anim], removed: [] }], - "records after endDelay is changed"); + "records after duration is changed"); - anim.effect.timing.endDelay = 10 * MS_PER_SEC; + anim.effect.timing.duration = 100 * MS_PER_SEC; yield waitForFrame(); assert_records([], "records after assigning same value"); - anim.currentTime = 109 * MS_PER_SEC; - yield waitForFrame(); - assert_records([{ added: [], changed: [], removed: [anim] }], - "records after currentTime during endDelay"); - - anim.effect.timing.endDelay = -110 * MS_PER_SEC; - yield waitForFrame(); - assert_records([], "records after assigning negative value"); - - anim.cancel(); - yield waitForFrame(); -}); - -addAsyncAnimTest("change_enddelay_and_currenttime", - { observe: div, subtree: true }, function*() { - var anim = div.animate({ opacity: [ 0, 1 ] }, - { duration: 100 * MS_PER_SEC, - endDelay: -100 * MS_PER_SEC }); - yield waitForFrame(); - assert_records([], "records after animation is added"); -}); - -addAsyncAnimTest("change_iterations", - { observe: div, subtree: true }, function*() { - var anim = div.animate({ opacity: [ 0, 1 ] }, 100 * MS_PER_SEC); - - yield waitForFrame(); - assert_records([{ added: [anim], changed: [], removed: [] }], - "records after animation is added"); - - anim.effect.timing.iterations = 2; - yield waitForFrame(); - assert_records([{ added: [], changed: [anim], removed: [] }], - "records after iterations is changed"); - - anim.effect.timing.iterations = 2; - yield waitForFrame(); - assert_records([], "records after assigning same value"); - - anim.effect.timing.iterations = 0; + anim.currentTime = anim.effect.timing.duration * 2; + anim.finish(); yield waitForFrame(); assert_records([{ added: [], changed: [], removed: [anim] }], "records after animation end"); - anim.effect.timing.iterations = Infinity; + anim.effect.timing.duration = anim.effect.timing.duration * 3; yield waitForFrame(); assert_records([{ added: [anim], changed: [], removed: [] }], "records after animation restarted"); - anim.cancel(); + anim.effect.timing.duration = "auto"; yield waitForFrame(); assert_records([{ added: [], changed: [], removed: [anim] }], - "records after animation end"); -}); + "records after duration set \"auto\""); -addAsyncAnimTest("change_delay", - { observe: div, subtree: true }, function*() { - var anim = div.animate({ opacity: [ 0, 1 ] }, 100000); - - yield waitForFrame(); - assert_records([{ added: [anim], changed: [], removed: [] }], - "records after animation is added"); - - anim.effect.timing.delay = 100; + anim.effect.timing.duration = "auto"; yield waitForFrame(); - assert_records([{ added: [], changed: [anim], removed: [] }], - "records after delay is changed"); - - anim.effect.timing.delay = 100; - yield waitForFrame(); - assert_records([], "records after assigning same value"); - - anim.effect.timing.delay = -100000; - yield waitForFrame(); - assert_records([{ added: [], changed: [], removed: [anim] }], - "records after animation end"); - - anim.effect.timing.delay = 0; - yield waitForFrame(); - assert_records([{ added: [anim], changed: [], removed: [] }], - "records after animation restarted"); + assert_records([], "records after assigning same value \"auto\""); anim.cancel(); yield waitForFrame(); - assert_records([{ added: [], changed: [], removed: [anim] }], - "records after animation end"); -}); - -addAsyncAnimTest("change_easing", - { observe: div, subtree: true }, function*() { - var anim = div.animate({ opacity: [ 0, 1 ] }, - { duration: 100 * MS_PER_SEC, - easing: "steps(2, start)" }); - - yield waitForFrame(); - assert_records([{ added: [anim], changed: [], removed: [] }], - "records after animation is added"); - - anim.effect.timing.easing = "steps(2, end)"; - yield waitForFrame(); - assert_records([{ added: [], changed: [anim], removed: [] }], - "records after easing is changed"); - - anim.effect.timing.easing = "steps(2, end)"; - yield waitForFrame(); - assert_records([], "records after assigning same value"); - - anim.cancel(); - yield waitForFrame(); -}); - -addAsyncAnimTest("negative_delay_in_constructor", - { observe: div, subtree: true }, function*() { - var anim = div.animate({ opacity: [ 0, 1 ] }, - { duration: 100, delay: -100 }); - yield waitForFrame(); - assert_records([], "records after assigning negative value"); }); addAsyncAnimTest("exclude_animations_targeting_pseudo_elements", { observe: div, subtree: false }, function*() { var anim = div.animate({ opacity: [ 0, 1 ] }, { duration: 100 * MS_PER_SEC }); var pAnim = pseudoTarget.animate({ opacity: [ 0, 1 ] }, { duration: 100 * MS_PER_SEC }); @@ -1714,260 +1576,16 @@ addAsyncAnimTest("exclude_animations_tar anim.finish(); pAnim.finish(); yield waitForFrame(); assert_records([{ added: [], changed: [], removed: [anim] }], "records after animation is finished"); }); -addAsyncAnimTest("create_animation_without_target", - { observe: document, subtree: true }, function*() { - var effect = new KeyframeEffectReadOnly(null, - { opacity: [ 0, 1 ] }, - { duration: 10000 }); - var anim = new Animation(effect, document.timeline); - anim.play(); - yield waitForFrame(); - assert_records([], "no records after animation is added"); - - anim.cancel(); - yield waitForFrame(); - assert_records([], "no records after animation is removed"); -}); - -addAsyncAnimTest("set_animation_target", - { observe: document, subtree: true }, function*() { - var anim = div.animate({ opacity: [ 0, 1 ] }, - { duration: 100 * MS_PER_SEC }); - - yield waitForFrame(); - assert_records([{ added: [anim], changed: [], removed: [] }], - "records after animation is added"); - - anim.effect.target = null; - yield waitForFrame(); - assert_records([{ added: [], changed: [], removed: [anim] }], - "records after setting null"); - - anim.effect.target = div; - yield waitForFrame(); - assert_records([{ added: [anim], changed: [], removed: [] }], - "records after setting a target"); - - var newTarget = document.createElement("div"); - document.body.appendChild(newTarget); - anim.effect.target = newTarget; - yield waitForFrame(); - assert_records([{ added: [], changed: [], removed: [anim] }, - { added: [anim], changed: [], removed: [] }], - "records after setting a different target"); - - anim.cancel(); - yield waitForFrame(); - assert_records([{ added: [], changed: [], removed: [anim] }], - "records after animation ends"); - - newTarget.remove(); -}); - -addAsyncAnimTest("set_redundant_animation_target", - { observe: div, subtree: true }, function*() { - var anim = div.animate({ opacity: [ 0, 1 ] }, - { duration: 100 * MS_PER_SEC }); - yield waitForFrame(); - assert_records([{ added: [anim], changed: [], removed: [] }], - "records after animation is added"); - - anim.effect.target = div; - yield waitForFrame(); - assert_records([], "no records after setting the same target"); - - anim.effect.target = null; - yield waitForFrame(); - assert_records([{ added: [], changed: [], removed: [anim] }], - "records after setting null"); - - anim.effect.target = null; - yield waitForFrame(); - assert_records([], "records after setting redundant null"); - - anim.cancel(); - yield waitForFrame(); -}); - -addAsyncAnimTest("set_null_animation_effect", - { observe: div, subtree: true }, function*() { - var anim = div.animate({ opacity: [ 0, 1 ] }, - { duration: 100 * MS_PER_SEC }); - yield waitForFrame(); - assert_records([{ added: [anim], changed: [], removed: [] }], - "records after animation is added"); - - anim.effect = null; - yield waitForFrame(); - assert_records([{ added: [], changed: [], removed: [anim] }], - "records after animation is removed"); - - anim.cancel(); - yield waitForFrame(); -}); - -addAsyncAnimTest("set_effect_on_null_effect_animation", - { observe: div, subtree: true }, function*() { - var anim = new Animation(); - anim.play(); - anim.effect = new KeyframeEffect(div, { opacity: [ 0, 1 ] }, - 100 * MS_PER_SEC); - yield waitForFrame(); - assert_records([{ added: [anim], changed: [], removed: [] }], - "records after animation is added"); - - anim.cancel(); - yield waitForFrame(); -}); - -addAsyncAnimTest("replace_effect_targeting_on_the_same_element", - { observe: div, subtree: true }, function*() { - var anim = div.animate({ marginLeft: [ "0px", "100px" ] }, - 100 * MS_PER_SEC); - yield waitForFrame(); - assert_records([{ added: [anim], changed: [], removed: [] }], - "records after animation is added"); - - anim.effect = new KeyframeEffect(div, { opacity: [ 0, 1 ] }, - 100 * MS_PER_SEC); - yield waitForFrame(); - assert_records([{ added: [], changed: [anim], removed: [] }], - "records after replace effects"); - - anim.cancel(); - yield waitForFrame(); -}); - -addAsyncAnimTest("replace_effect_targeting_on_the_same_element_not_in_effect", - { observe: div, subtree: true }, function*() { - var anim = div.animate({ marginLeft: [ "0px", "100px" ] }, - 100 * MS_PER_SEC); - yield waitForFrame(); - assert_records([{ added: [anim], changed: [], removed: [] }], - "records after animation is added"); - - anim.currentTime = 60 * MS_PER_SEC; - yield waitForFrame(); - assert_records([{ added: [], changed: [anim], removed: [] }], - "records after animation is changed"); - - anim.effect = new KeyframeEffect(div, { opacity: [ 0, 1 ] }, - 50 * MS_PER_SEC); - yield waitForFrame(); - assert_records([{ added: [], changed: [], removed: [anim] }], - "records after replacing effects"); - - anim.cancel(); - yield waitForFrame(); -}); - -addAsyncAnimTest("set_effect_with_previous_animation", - { observe: div, subtree: true }, function*() { - var child = document.createElement("div"); - div.appendChild(child); - - var anim1 = div.animate({ marginLeft: [ "0px", "50px" ] }, - 100 * MS_PER_SEC); - var anim2 = child.animate({ marginLeft: [ "0px", "100px" ] }, - 50 * MS_PER_SEC); - yield waitForFrame(); - assert_records([{ added: [anim1], changed: [], removed: [] }, - { added: [anim2], changed: [], removed: [] }], - "records after animation is added"); - - // After setting a new effect, we remove the current animation, anim1, because - // it is no longer attached to |div|, and then remove the previous animation, - // anim2. Finally, add back the anim1 which is in effect on |child| now. - // In addition, we sort them by tree order and they are batched. - anim1.effect = anim2.effect; - yield waitForFrame(); - assert_records([{ added: [], changed: [], removed: [anim1] }, // div - { added: [anim1], changed: [], removed: [anim2] }], // child - "records after animation effects are changed"); - - anim1.cancel(); - anim2.cancel(); - child.remove(); - yield waitForFrame(); -}); - -addAsyncAnimTest("set_spacing", - { observe: div, subtree: true }, function*() { - var anim = div.animate([ { marginLeft: "0px" }, - { marginLeft: "-20px" }, - { marginLeft: "100px" }, - { marginLeft: "50px" } ], - { duration: 100 * MS_PER_SEC }); - yield waitForFrame(); - assert_records([{ added: [anim], changed: [], removed: [] }], - "records after animation is added"); - - anim.effect.spacing = "paced(margin-left)"; - yield waitForFrame(); - assert_records([{ added: [], changed: [anim], removed: [] }], - "records after animation is changed"); - - anim.cancel(); - yield waitForFrame(); - assert_records([{ added: [], changed: [], removed: [anim] }], - "records after animation end"); -}); - -addAsyncAnimTest("set_spacing_on_a_non-animatable_property", - { observe: div, subtree: true }, function*() { - var anim = div.animate([ { marginLeft: "0px" }, - { marginLeft: "-20px" }, - { marginLeft: "100px" }, - { marginLeft: "50px" } ], - { duration: 100 * MS_PER_SEC, - spacing: "paced(margin-left)" }); - yield waitForFrame(); - assert_records([{ added: [anim], changed: [], removed: [] }], - "records after animation is added"); - - anim.effect.spacing = "paced(animation-duration)"; - yield waitForFrame(); - assert_records([{ added: [], changed: [anim], removed: [] }], - "records after setting a non-animatable paced property"); - - anim.cancel(); - yield waitForFrame(); - assert_records([{ added: [], changed: [], removed: [anim] }], - "records after animation end"); -}); - -addAsyncAnimTest("set_the_same_spacing", - { observe: div, subtree: true }, function*() { - var anim = div.animate([ { marginLeft: "0px" }, - { marginLeft: "-20px" }, - { marginLeft: "100px" }, - { marginLeft: "50px" } ], - { duration: 100 * MS_PER_SEC, - spacing: "paced(margin-left)" }); - yield waitForFrame(); - assert_records([{ added: [anim], changed: [], removed: [] }], - "records after animation is added"); - - anim.effect.spacing = "paced(margin-left)"; - yield waitForFrame(); - assert_records([], "no record after setting the same spacing"); - - anim.cancel(); - yield waitForFrame(); - assert_records([{ added: [], changed: [], removed: [anim] }], - "records after animation end"); -}); - // Run the tests. SimpleTest.requestLongerTimeout(2); SimpleTest.waitForExplicitFinish(); runAllAsyncTests().then(function() { SimpleTest.finish(); }, function(aError) { ok(false, "Something failed: " + aError);
new file mode 100644 --- /dev/null +++ b/dom/animation/test/chrome/test_observers_for_script_animation.html @@ -0,0 +1,433 @@ +<!DOCTYPE html> +<meta charset=utf-8> +<title> +Test chrome-only MutationObserver animation notifications for script +animations +</title> +<script type="application/javascript" src="../testharness.js"></script> +<script type="application/javascript" src="../testharnessreport.js"></script> +<script type="application/javascript" src="../testcommon.js"></script> +<div id="log"></div> +<script> + +function assert_record_list(actual, expected, desc, index, listName) { + assert_equals(actual.length, expected.length, + `${desc} - record[${index}].${listName} length`); + if (actual.length != expected.length) { + return; + } + for (var i = 0; i < actual.length; i++) { + assert_not_equals(actual.indexOf(expected[i]), -1, + `${desc} - record[${index}].${listName} contains expected Animation`); + } +} + +function assert_equals_records(actual, expected, desc) { + assert_equals(actual.length, expected.length, `${desc} - number of records`); + if (actual.length != expected.length) { + return; + } + for (var i = 0; i < actual.length; i++) { + assert_record_list(actual[i].addedAnimations, + expected[i].added, desc, i, "addedAnimations"); + assert_record_list(actual[i].changedAnimations, + expected[i].changed, desc, i, "changedAnimations"); + assert_record_list(actual[i].removedAnimations, + expected[i].removed, desc, i, "removedAnimations"); + } +} + +test(t => { + var div = addDiv(t); + var observer = setupSynchronousObserver(t, div, false); + + var anim = div.animate({ opacity: [ 0, 1 ] }, 200 * MS_PER_SEC); + + assert_equals_records(observer.takeRecords(), + [{ added: [anim], changed: [], removed: [] }], + "records after animation is added"); + + anim.effect.timing.duration = 100 * MS_PER_SEC; + assert_equals_records(observer.takeRecords(), + [{ added: [], changed: [anim], removed: [] }], + "records after duration is changed"); + + anim.effect.timing.duration = 100 * MS_PER_SEC; + assert_equals_records(observer.takeRecords(), + [], "records after assigning same value"); + + anim.currentTime = anim.effect.timing.duration * 2; + anim.finish(); + assert_equals_records(observer.takeRecords(), + [{ added: [], changed: [], removed: [anim] }], + "records after animation end"); + + anim.effect.timing.duration = anim.effect.timing.duration * 3; + assert_equals_records(observer.takeRecords(), + [{ added: [anim], changed: [], removed: [] }], + "records after animation restarted"); + + anim.effect.timing.duration = "auto"; + assert_equals_records(observer.takeRecords(), + [{ added: [], changed: [], removed: [anim] }], + "records after duration set \"auto\""); + + anim.effect.timing.duration = "auto"; + assert_equals_records(observer.takeRecords(), + [], "records after assigning same value \"auto\""); +}, "change_duration_and_currenttime"); + +test(t => { + var div = addDiv(t); + var observer = setupSynchronousObserver(t, div, false); + + var anim = div.animate({ opacity: [ 0, 1 ] }, 100 * MS_PER_SEC); + + assert_equals_records(observer.takeRecords(), + [{ added: [anim], changed: [], removed: [] }], + "records after animation is added"); + + anim.effect.timing.endDelay = 10 * MS_PER_SEC; + assert_equals_records(observer.takeRecords(), + [{ added: [], changed: [anim], removed: [] }], + "records after endDelay is changed"); + + anim.effect.timing.endDelay = 10 * MS_PER_SEC; + assert_equals_records(observer.takeRecords(), + [], "records after assigning same value"); + + anim.currentTime = 109 * MS_PER_SEC; + assert_equals_records(observer.takeRecords(), + [{ added: [], changed: [], removed: [anim] }], + "records after currentTime during endDelay"); + + anim.effect.timing.endDelay = -110 * MS_PER_SEC; + assert_equals_records(observer.takeRecords(), + [], "records after assigning negative value"); +}, "change_enddelay_and_currenttime"); + +test(t => { + var div = addDiv(t); + var observer = setupSynchronousObserver(t, div, false); + + var anim = div.animate({ opacity: [ 0, 1 ] }, + { duration: 100 * MS_PER_SEC, + endDelay: -100 * MS_PER_SEC }); + assert_equals_records(observer.takeRecords(), + [], "records after animation is added"); +}, "zero_end_time"); + +test(t => { + var div = addDiv(t); + var observer = setupSynchronousObserver(t, div, false); + + var anim = div.animate({ opacity: [ 0, 1 ] }, 100 * MS_PER_SEC); + + assert_equals_records(observer.takeRecords(), + [{ added: [anim], changed: [], removed: [] }], + "records after animation is added"); + + anim.effect.timing.iterations = 2; + assert_equals_records(observer.takeRecords(), + [{ added: [], changed: [anim], removed: [] }], + "records after iterations is changed"); + + anim.effect.timing.iterations = 2; + assert_equals_records(observer.takeRecords(), + [], "records after assigning same value"); + + anim.effect.timing.iterations = 0; + assert_equals_records(observer.takeRecords(), + [{ added: [], changed: [], removed: [anim] }], + "records after animation end"); + + anim.effect.timing.iterations = Infinity; + assert_equals_records(observer.takeRecords(), + [{ added: [anim], changed: [], removed: [] }], + "records after animation restarted"); +}, "change_iterations"); + +test(t => { + var div = addDiv(t); + var observer = setupSynchronousObserver(t, div, false); + + var anim = div.animate({ opacity: [ 0, 1 ] }, 100 * MS_PER_SEC); + + assert_equals_records(observer.takeRecords(), + [{ added: [anim], changed: [], removed: [] }], + "records after animation is added"); + + anim.effect.timing.delay = 100; + assert_equals_records(observer.takeRecords(), + [{ added: [], changed: [anim], removed: [] }], + "records after delay is changed"); + + anim.effect.timing.delay = 100; + assert_equals_records(observer.takeRecords(), + [], "records after assigning same value"); + + anim.effect.timing.delay = -100 * MS_PER_SEC; + assert_equals_records(observer.takeRecords(), + [{ added: [], changed: [], removed: [anim] }], + "records after animation end"); + + anim.effect.timing.delay = 0; + assert_equals_records(observer.takeRecords(), + [{ added: [anim], changed: [], removed: [] }], + "records after animation restarted"); +}, "change_delay"); + +test(t => { + var div = addDiv(t); + var observer = setupSynchronousObserver(t, div, false); + + var anim = div.animate({ opacity: [ 0, 1 ] }, + { duration: 100 * MS_PER_SEC, + easing: "steps(2, start)" }); + + assert_equals_records(observer.takeRecords(), + [{ added: [anim], changed: [], removed: [] }], + "records after animation is added"); + + anim.effect.timing.easing = "steps(2, end)"; + assert_equals_records(observer.takeRecords(), + [{ added: [], changed: [anim], removed: [] }], + "records after easing is changed"); + + anim.effect.timing.easing = "steps(2, end)"; + assert_equals_records(observer.takeRecords(), + [], "records after assigning same value"); +}, "change_easing"); + +test(t => { + var div = addDiv(t); + var observer = setupSynchronousObserver(t, div, false); + + var anim = div.animate({ opacity: [ 0, 1 ] }, + { duration: 100, delay: -100 }); + assert_equals_records(observer.takeRecords(), + [], "records after assigning negative value"); +}, "negative_delay_in_constructor"); + +test(t => { + var div = addDiv(t); + var observer = setupSynchronousObserver(t, div, false); + + var effect = new KeyframeEffectReadOnly(null, + { opacity: [ 0, 1 ] }, + { duration: 100 * MS_PER_SEC }); + var anim = new Animation(effect, document.timeline); + anim.play(); + assert_equals_records(observer.takeRecords(), + [], "no records after animation is added"); +}, "create_animation_without_target"); + +test(t => { + var div = addDiv(t); + var observer = setupSynchronousObserver(t, document, true); + + var anim = div.animate({ opacity: [ 0, 1 ] }, + { duration: 100 * MS_PER_SEC }); + + var newTarget = document.createElement("div"); + + assert_equals_records(observer.takeRecords(), + [{ added: [anim], changed: [], removed: [] }], + "records after animation is added"); + + anim.effect.target = null; + assert_equals_records(observer.takeRecords(), + [{ added: [], changed: [], removed: [anim] }], + "records after setting null"); + + anim.effect.target = div; + assert_equals_records(observer.takeRecords(), + [{ added: [anim], changed: [], removed: [] }], + "records after setting a target"); + + anim.effect.target = addDiv(t); + assert_equals_records(observer.takeRecords(), + [{ added: [], changed: [], removed: [anim] }, + { added: [anim], changed: [], removed: [] }], + "records after setting a different target"); +}, "set_animation_target"); + +test(t => { + var div = addDiv(t); + var observer = setupSynchronousObserver(t, div, false); + + var anim = div.animate({ opacity: [ 0, 1 ] }, + { duration: 100 * MS_PER_SEC }); + assert_equals_records(observer.takeRecords(), + [{ added: [anim], changed: [], removed: [] }], + "records after animation is added"); + + anim.effect.target = div; + assert_equals_records(observer.takeRecords(), + [], "no records after setting the same target"); + + anim.effect.target = null; + assert_equals_records(observer.takeRecords(), + [{ added: [], changed: [], removed: [anim] }], + "records after setting null"); + + anim.effect.target = null; + assert_equals_records(observer.takeRecords(), + [], "records after setting redundant null"); +}, "set_redundant_animation_target"); + +test(t => { + var div = addDiv(t); + var observer = setupSynchronousObserver(t, div, false); + + var anim = div.animate({ opacity: [ 0, 1 ] }, + { duration: 100 * MS_PER_SEC }); + assert_equals_records(observer.takeRecords(), + [{ added: [anim], changed: [], removed: [] }], + "records after animation is added"); + + anim.effect = null; + assert_equals_records(observer.takeRecords(), + [{ added: [], changed: [], removed: [anim] }], + "records after animation is removed"); +}, "set_null_animation_effect"); + +test(t => { + var div = addDiv(t); + var observer = setupSynchronousObserver(t, div, false); + + var anim = new Animation(); + anim.play(); + anim.effect = new KeyframeEffect(div, { opacity: [ 0, 1 ] }, + 100 * MS_PER_SEC); + assert_equals_records(observer.takeRecords(), + [{ added: [anim], changed: [], removed: [] }], + "records after animation is added"); +}, "set_effect_on_null_effect_animation"); + +test(t => { + var div = addDiv(t); + var observer = setupSynchronousObserver(t, div, false); + + var anim = div.animate({ marginLeft: [ "0px", "100px" ] }, + 100 * MS_PER_SEC); + assert_equals_records(observer.takeRecords(), + [{ added: [anim], changed: [], removed: [] }], + "records after animation is added"); + + anim.effect = new KeyframeEffect(div, { opacity: [ 0, 1 ] }, + 100 * MS_PER_SEC); + assert_equals_records(observer.takeRecords(), + [{ added: [], changed: [anim], removed: [] }], + "records after replace effects"); +}, "replace_effect_targeting_on_the_same_element"); + +test(t => { + var div = addDiv(t); + var observer = setupSynchronousObserver(t, div, false); + + var anim = div.animate({ marginLeft: [ "0px", "100px" ] }, + 100 * MS_PER_SEC); + assert_equals_records(observer.takeRecords(), + [{ added: [anim], changed: [], removed: [] }], + "records after animation is added"); + + anim.currentTime = 60 * MS_PER_SEC; + assert_equals_records(observer.takeRecords(), + [{ added: [], changed: [anim], removed: [] }], + "records after animation is changed"); + + anim.effect = new KeyframeEffect(div, { opacity: [ 0, 1 ] }, + 50 * MS_PER_SEC); + assert_equals_records(observer.takeRecords(), + [{ added: [], changed: [], removed: [anim] }], + "records after replacing effects"); +}, "replace_effect_targeting_on_the_same_element_not_in_effect"); + +test(t => { + var div = addDiv(t); + var observer = setupSynchronousObserver(t, div, true); + + var child = document.createElement("div"); + div.appendChild(child); + + var anim1 = div.animate({ marginLeft: [ "0px", "50px" ] }, + 100 * MS_PER_SEC); + var anim2 = child.animate({ marginLeft: [ "0px", "100px" ] }, + 50 * MS_PER_SEC); + assert_equals_records(observer.takeRecords(), + [{ added: [anim1], changed: [], removed: [] }, + { added: [anim2], changed: [], removed: [] }], + "records after animation is added"); + + // After setting a new effect, we remove the current animation, anim1, + // because it is no longer attached to |div|, and then remove the previous + // animation, anim2. Finally, add back the anim1 which is in effect on + // |child| now. In addition, we sort them by tree order and they are + // batched. + anim1.effect = anim2.effect; + assert_equals_records(observer.takeRecords(), + [{ added: [], changed: [], removed: [anim1] }, // div + { added: [anim1], changed: [], removed: [anim2] }], // child + "records after animation effects are changed"); +}, "set_effect_with_previous_animation"); + +test(t => { + var div = addDiv(t); + var observer = setupSynchronousObserver(t, div, false); + + var anim = div.animate([ { marginLeft: "0px" }, + { marginLeft: "-20px" }, + { marginLeft: "100px" }, + { marginLeft: "50px" } ], + { duration: 100 * MS_PER_SEC }); + assert_equals_records(observer.takeRecords(), + [{ added: [anim], changed: [], removed: [] }], + "records after animation is added"); + + anim.effect.spacing = "paced(margin-left)"; + assert_equals_records(observer.takeRecords(), + [{ added: [], changed: [anim], removed: [] }], + "records after animation is changed"); +}, "set_spacing"); + +test(t => { + var div = addDiv(t); + var observer = setupSynchronousObserver(t, div, false); + + var anim = div.animate([ { marginLeft: "0px" }, + { marginLeft: "-20px" }, + { marginLeft: "100px" }, + { marginLeft: "50px" } ], + { duration: 100 * MS_PER_SEC, + spacing: "paced(margin-left)" }); + assert_equals_records(observer.takeRecords(), + [{ added: [anim], changed: [], removed: [] }], + "records after animation is added"); + + anim.effect.spacing = "paced(animation-duration)"; + assert_equals_records(observer.takeRecords(), + [{ added: [], changed: [anim], removed: [] }], + "records after setting a non-animatable paced property"); +}, "set_spacing_on_a_non-animatable_property"); + +test(t => { + var div = addDiv(t); + var observer = setupSynchronousObserver(t, div, false); + + var anim = div.animate([ { marginLeft: "0px" }, + { marginLeft: "-20px" }, + { marginLeft: "100px" }, + { marginLeft: "50px" } ], + { duration: 100 * MS_PER_SEC, + spacing: "paced(margin-left)" }); + assert_equals_records(observer.takeRecords(), + [{ added: [anim], changed: [], removed: [] }], + "records after animation is added"); + + anim.effect.spacing = "paced(margin-left)"; + assert_equals_records(observer.takeRecords(), + [], "no record after setting the same spacing"); +}, "set_the_same_spacing"); + +</script>