test_event_handler_cc.html (2554B)
1 <!DOCTYPE HTML> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <title>Test for cycle collection of event handlers</title> 6 <script src="/tests/SimpleTest/SimpleTest.js"></script> 7 <link rel="stylesheet" href="/tests/SimpleTest/test.css"/> 8 <script> 9 SimpleTest.waitForExplicitFinish(); 10 11 function listener() {} 12 13 function make_weak_ref(obj) { 14 let m = new WeakMap; 15 m.set(obj, {}); 16 return m; 17 } 18 19 function weak_ref_dead(r) { 20 return !SpecialPowers.nondeterministicGetWeakMapKeys(r).length; 21 } 22 23 function setupTarget1() { 24 let ifr = document.getElementById("target1"); 25 let doc = ifr.contentDocument; 26 let b = doc.createElement("button"); 27 doc.body.appendChild(b); 28 b.onclick = listener; 29 ifr.remove(); 30 return make_weak_ref(b); 31 } 32 33 function setupTarget2() { 34 let ifr = document.getElementById("target2"); 35 let doc = ifr.contentDocument; 36 let b = doc.createElement("button"); 37 doc.body.appendChild(b); 38 let setFunc = new ifr.contentWindow.Function(` 39 var b = document.querySelector("button"); 40 var proto = parent.HTMLElement.prototype; 41 var setter = Object.getOwnPropertyDescriptor(proto, "onclick").set; 42 // Here the current global (and hence CallbackObject global) will be 43 // the parent, the callback will be a known-live thing from the 44 // parent, but the incumbent global will be the child. 45 setter.call(b, parent.listener); 46 `); 47 setFunc(); 48 ifr.remove(); 49 return make_weak_ref(b); 50 } 51 52 var ref1; 53 var ref2; 54 var maxCounter = 20; 55 56 function GCCCUntilCollected() { 57 SpecialPowers.exactGC(function () { 58 SpecialPowers.forceCC(); 59 SpecialPowers.forceGC(); 60 SpecialPowers.forceGC(); 61 62 if ((!weak_ref_dead(ref1) || !weak_ref_dead(ref2)) && --maxCounter > 0) { 63 requestIdleCallback(GCCCUntilCollected, {timeout: 250}); 64 return; 65 } 66 67 ok(weak_ref_dead(ref1), 68 "Should collect cycle through callback global"); 69 ok(weak_ref_dead(ref2), 70 "Should collect cycle through incumbent global"); 71 72 SimpleTest.finish(); 73 }); 74 } 75 76 addLoadEvent(function() { 77 ref1 = setupTarget1(); 78 ref2 = setupTarget2(); 79 GCCCUntilCollected(); 80 }); 81 </script> 82 </head> 83 <body> 84 <p id="display"></p> 85 <div id="content" style="display: none"></div> 86 <iframe id="target1"></iframe> 87 <iframe id="target2"></iframe> 88 <pre id="test"></pre> 89 </body> 90 </html>