repeatn-remove-add-animation.html (3507B)
1 <!doctype html> 2 <meta charset="utf-8"> 3 <title>Remove and add an animation element while the animation is repeating</title> 4 <script src="/resources/testharness.js"></script> 5 <script src="/resources/testharnessreport.js"></script> 6 <svg> 7 <animate id="anim" attributeName="visibility" to="visible" begin="0s" dur="2s" repeatCount="4"/> 8 <rect x="0" y="0" width="50" height="50" fill="lime"> 9 <set attributeName="fill" to="red" begin="anim.repeat(0)"/> 10 </rect> 11 <rect x="50" y="0" width="50" height="50" fill="red"> 12 <set attributeName="fill" to="lime" begin="anim.repeat(1)"/> 13 </rect> 14 <rect x="0" y="50" width="50" height="50" fill="red"> 15 <set attributeName="fill" to="lime" begin="anim.repeat(2)"/> 16 </rect> 17 <rect x="50" y="50" width="50" height="50" fill="red"> 18 <set attributeName="fill" to="lime" begin="anim.repeat(3)"/> 19 </rect> 20 </svg> 21 <script> 22 function recreate(anim) { 23 anim.parentNode.removeChild(anim); 24 return document.querySelector('svg').appendChild(anim.cloneNode()); 25 } 26 27 function waitFrame() { 28 return new Promise(resolve => { 29 window.requestAnimationFrame(resolve); 30 }); 31 } 32 33 function checkSetElements(setElements, expected) { 34 let fillValues = Array.from(setElements).map(set => { 35 return getComputedStyle(set.targetElement, '').fill; 36 }); 37 let remappedExpected = expected.map(color => { 38 const colorMap = {'red': 'rgb(255, 0, 0)', 'lime': 'rgb(0, 255, 0)'}; 39 return colorMap[color]; 40 }) 41 assert_array_equals(fillValues, remappedExpected); 42 } 43 44 promise_test(t => { 45 let svg = document.querySelector('svg'); 46 let anim = document.getElementById('anim'); 47 let animWatcher = new EventWatcher(t, anim, ['beginEvent', 'repeatEvent']); 48 // Wait for #anims 'beginEvent' and then step through the 49 // 'repeatEvents' one at a time. 50 let stepsPromise = animWatcher.wait_for('beginEvent').then(() => { 51 checkSetElements(setElements, ['lime', 'red', 'red', 'red']); 52 svg.setCurrentTime(1.999); 53 return animWatcher.wait_for('repeatEvent'); 54 }).then(() => { 55 return waitFrame(); 56 }).then(() => { 57 checkSetElements(setElements, ['lime', 'lime', 'red', 'red']); 58 svg.setCurrentTime(2.999); 59 return waitFrame(); 60 }).then(() => { 61 checkSetElements(setElements, ['lime', 'lime', 'red', 'red']); 62 svg.setCurrentTime(3.999); 63 return animWatcher.wait_for('repeatEvent'); 64 }).then(() => { 65 return waitFrame(); 66 }).then(() => { 67 checkSetElements(setElements, ['lime', 'lime', 'lime', 'red']); 68 let newAnim = recreate(anim); 69 let animWatcher = new EventWatcher(t, newAnim, ['repeatEvent']); 70 svg.setCurrentTime(5.999); 71 return animWatcher.wait_for('repeatEvent'); 72 }).then(() => { 73 return waitFrame(); 74 }).then(() => { 75 checkSetElements(setElements, ['lime', 'lime', 'lime', 'lime']); 76 }); 77 let setElements = document.getElementsByTagName('set'); 78 let setBeginWatchers = Array.from(setElements).map(element => { 79 return new EventWatcher(t, element, 'beginEvent'); 80 }); 81 // Expect 'beginEvent' to be dispatched once for all but the first 'set' element. 82 let setPromises = setBeginWatchers.slice(1).map(watcher => { 83 return watcher.wait_for('beginEvent').then(evt => { 84 let target = evt.target.targetElement; 85 assert_equals(getComputedStyle(target, '').fill, 'rgb(0, 255, 0)'); 86 }); 87 }); 88 return Promise.all([stepsPromise, ...setPromises]); 89 }); 90 </script>