helper_cancel_active_task.html (3196B)
1 <!DOCTYPE html> 2 <html> 3 <meta name="viewport" content="width=device-width; initial-scale=1.0"> 4 <title> 5 Tests that scheduled :hover task is surely destroyed when the target 6 document is destroyed 7 </title> 8 <script src="/tests/SimpleTest/SimpleTest.js"></script> 9 <script src="/tests/SimpleTest/paint_listener.js"></script> 10 <script src="apz_test_utils.js"></script> 11 <script src="apz_test_native_event_utils.js"></script> 12 <style> 13 iframe { 14 width: 100vw; 15 height: 100vh; 16 border: none; 17 } 18 </style> 19 <iframe></iframe> 20 <script> 21 async function test() { 22 const iframe = document.querySelector("iframe"); 23 await setupCrossOriginIFrame(iframe, "helper_fission_plain.html"); 24 const remoteType = await SpecialPowers.spawn(iframe, [], async () => { 25 return await SpecialPowers.spawnChrome([], () => { 26 return windowGlobalParent.domProcess.remoteType; 27 }); 28 }); 29 if (remoteType === "web") { 30 is(SpecialPowers.effectiveIsolationStrategy(), SpecialPowers.ISOLATION_STRATEGY.IsolateHighValue); 31 ok(true, "Skipping this test since the document on example.com got loaded in the same content process"); 32 return; 33 } 34 35 // Setup a touchstart and a touchend event listener in the iframe 36 // document. 37 const touchstartPromise = SpecialPowers.spawn(iframe, [], () => { 38 return new Promise(resolve => { 39 content.window.addEventListener("touchstart", () => { resolve(); }); 40 }); 41 }); 42 const touchendPromise = SpecialPowers.spawn(iframe, [], () => { 43 return new Promise(resolve => { 44 content.window.addEventListener("touchend", () => { resolve(); }); 45 }); 46 }); 47 await SpecialPowers.spawn(iframe, [], async () => { 48 await new Promise(resolve => resolve()); 49 }); 50 51 // Touch on the iframe. 52 // This will trigger a scheduled task to set :hover state. 53 const utils = SpecialPowers.DOMWindowUtils; 54 utils.sendTouchEvent("touchstart", 55 [0], [100], [100], [1], [1], [1], [1], [0], [0], [0], 0); 56 await touchstartPromise; 57 58 // In JS there's no way to ensure `APZStateChange::eStartTouch` notification 59 // has been processed. So we wait a couple of frames. 60 await new Promise(resolve => requestAnimationFrame(resolve)); 61 await new Promise(resolve => requestAnimationFrame(resolve)); 62 await new Promise(resolve => requestAnimationFrame(resolve)); 63 64 // And destroy the iframe while the scheduled task is still 65 // pending. 66 iframe.style.display = "none"; 67 // Flush the above change. 68 getComputedStyle(iframe).display; 69 70 // Wait a couple of frames just in case. 71 await new Promise(resolve => requestAnimationFrame(resolve)); 72 await new Promise(resolve => requestAnimationFrame(resolve)); 73 74 // Finish the touch block explicitely, otherwise in subsequent tests 75 // new touch events won't be dispatched as expected. 76 utils.sendTouchEvent("touchend", 77 [0], [100], [100], [1], [1], [1], [1], [0], [0], [0], 0); 78 await touchendPromise; 79 80 ok(true, "There's no need to check, it's okay if there's no leak"); 81 } 82 83 if (!SpecialPowers.Services.appinfo.fissionAutostart) { 84 ok(true, "This test doesn't need to run with disabling Fission"); 85 subtestDone(); 86 } else { 87 waitUntilApzStable() 88 .then(test) 89 .then(subtestDone, subtestFailed); 90 } 91 </script> 92 </html>