| <!doctype html> |
| <meta charset="utf-8"> |
| <title>Remove and add an animation element while the animation is repeating</title> |
| <script src="/resources/testharness.js"></script> |
| <script src="/resources/testharnessreport.js"></script> |
| <svg> |
| <animate id="anim" attributeName="visibility" to="visible" begin="0s" dur="2s" repeatCount="4"/> |
| <rect x="0" y="0" width="50" height="50" fill="lime"> |
| <set attributeName="fill" to="red" begin="anim.repeat(0)"/> |
| </rect> |
| <rect x="50" y="0" width="50" height="50" fill="red"> |
| <set attributeName="fill" to="lime" begin="anim.repeat(1)"/> |
| </rect> |
| <rect x="0" y="50" width="50" height="50" fill="red"> |
| <set attributeName="fill" to="lime" begin="anim.repeat(2)"/> |
| </rect> |
| <rect x="50" y="50" width="50" height="50" fill="red"> |
| <set attributeName="fill" to="lime" begin="anim.repeat(3)"/> |
| </rect> |
| </svg> |
| <script> |
| function recreate(anim) { |
| anim.parentNode.removeChild(anim); |
| return document.querySelector('svg').appendChild(anim.cloneNode()); |
| } |
| |
| function waitFrame() { |
| return new Promise(resolve => { |
| window.requestAnimationFrame(resolve); |
| }); |
| } |
| |
| function checkSetElements(setElements, expected) { |
| let fillValues = Array.from(setElements).map(set => { |
| return getComputedStyle(set.targetElement, '').fill; |
| }); |
| let remappedExpected = expected.map(color => { |
| const colorMap = {'red': 'rgb(255, 0, 0)', 'lime': 'rgb(0, 255, 0)'}; |
| return colorMap[color]; |
| }) |
| assert_array_equals(fillValues, remappedExpected); |
| } |
| |
| promise_test(t => { |
| let svg = document.querySelector('svg'); |
| let anim = document.getElementById('anim'); |
| let animWatcher = new EventWatcher(t, anim, ['beginEvent', 'repeatEvent']); |
| // Wait for #anims 'beginEvent' and then step through the |
| // 'repeatEvents' one at a time. |
| let stepsPromise = animWatcher.wait_for('beginEvent').then(() => { |
| checkSetElements(setElements, ['lime', 'red', 'red', 'red']); |
| svg.setCurrentTime(1.999); |
| return animWatcher.wait_for('repeatEvent'); |
| }).then(() => { |
| return waitFrame(); |
| }).then(() => { |
| checkSetElements(setElements, ['lime', 'lime', 'red', 'red']); |
| svg.setCurrentTime(2.999); |
| return waitFrame(); |
| }).then(() => { |
| checkSetElements(setElements, ['lime', 'lime', 'red', 'red']); |
| svg.setCurrentTime(3.999); |
| return animWatcher.wait_for('repeatEvent'); |
| }).then(() => { |
| return waitFrame(); |
| }).then(() => { |
| checkSetElements(setElements, ['lime', 'lime', 'lime', 'red']); |
| let newAnim = recreate(anim); |
| let animWatcher = new EventWatcher(t, newAnim, ['repeatEvent']); |
| svg.setCurrentTime(5.999); |
| return animWatcher.wait_for('repeatEvent'); |
| }).then(() => { |
| return waitFrame(); |
| }).then(() => { |
| checkSetElements(setElements, ['lime', 'lime', 'lime', 'lime']); |
| }); |
| let setElements = document.getElementsByTagName('set'); |
| let setBeginWatchers = Array.from(setElements).map(element => { |
| return new EventWatcher(t, element, 'beginEvent'); |
| }); |
| // Expect 'beginEvent' to be dispatched once for all but the first 'set' element. |
| let setPromises = setBeginWatchers.slice(1).map(watcher => { |
| return watcher.wait_for('beginEvent').then(evt => { |
| let target = evt.target.targetElement; |
| assert_equals(getComputedStyle(target, '').fill, 'rgb(0, 255, 0)'); |
| }); |
| }); |
| return Promise.all([stepsPromise, ...setPromises]); |
| }); |
| </script> |