animation-event-destroy-renderer.html (2927B)
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <title>Destroy and Hide Element in Animation Event</title> 5 <!-- Note: this is effectively a crashtest, but as crashtests do not 6 support variants, authoring as a promise test --> 7 <meta name="variant" content="?animationstart"> 8 <meta name="variant" content="?animationiteration"> 9 <link rel="help" href="https://bugs.webkit.org/show_bug.cgi?id=22635"> 10 <style> 11 .box { 12 height: 100px; 13 width: 100px; 14 margin: 10px; 15 background-color: blue; 16 /* Use a long duration and delay for precise control over when animation 17 events are triggered. With short animations, the animation-iteration 18 event could be dropped if the animation finishes too son. An 19 animation-iteration event does not fire when completing the last 20 iteration. 21 */ 22 animation-name: move; 23 animation-duration: 10000s; 24 animation-delay: 5000s; 25 animation-iteration-count: 2; 26 } 27 28 @keyframes move { 29 from { transform: translate(0px, 0px); } 30 to { transform: translate(100px, 0px); } 31 } 32 </style> 33 <div id="container"> 34 <div id="box1" class="box"></div> 35 <div id="box2" class="box"></div> 36 </div> 37 <script src="/resources/testharness.js"></script> 38 <script src="/resources/testharnessreport.js"></script> 39 <script src="/common/gc.js"></script> 40 <script> 41 'use strict'; 42 43 function eventPromise(target, event, callback) { 44 return new Promise(resolve => { 45 const listener = () => { 46 callback(); 47 resolve(); 48 }; 49 target.addEventListener(event, listener, 50 { once: true }); 51 }); 52 } 53 54 function setAnimationTime(time) { 55 document.getAnimations().forEach(a => a.currentTime = time); 56 } 57 58 promise_test(async t => { 59 const eventType = location.search.substring(1); 60 var box1 = document.getElementById('box1'); 61 var box2 = document.getElementById('box2'); 62 63 const promises = []; 64 promises.push(eventPromise(box1, eventType, () => { 65 box1.parentNode.removeChild(box1); 66 })); 67 promises.push(eventPromise(box2, eventType, () => { 68 box2.style.display = 'none'; 69 })); 70 71 await Promise.all(document.getAnimations().map(a => a.ready)); 72 73 promises.push(new Promise(resolve => { 74 requestAnimationFrame(() => { 75 // trip animationstart. 76 setAnimationTime(6000000); 77 requestAnimationFrame(() => { 78 // trip animationiteration on any animations that are still running. 79 setAnimationTime(16000000); 80 resolve(); 81 }); 82 }); 83 })); 84 85 await Promise.all(promises); 86 87 // Garbage collection is best effort. 88 if (window.garbageCollect) { 89 await garbageCollect(); 90 } 91 92 assert_equals(document.getAnimations().length, 0); 93 }, 'Triggering the cancel of an animation during event handling does not ' + 94 'crash.'); 95 96 </script> 97 </head> 98 </html>