move-node-local-root.html (2777B)
1 <!DOCTYPE html> 2 <title>Node moves to another document</title> 3 <link rel="author" title="Dominic Farolino" href="mailto:dom@chromium.org"> 4 <link rel="help" href="https://crbug.com/40277823"> 5 <script src="/resources/testharness.js"></script> 6 <script src="/resources/testharnessreport.js"></script> 7 <script src="/common/get-host-info.sub.js"></script> 8 9 <body> 10 <button id=button></button> 11 <script> 12 // This is a regression test for a Chromium crash: https://crbug.com/40277823. 13 // The test is reproducible by: 14 // 1. Creating a node with an event listener for an event type that the 15 // compositor cares about; `touchmove` in this case. 16 // 2. Adopting that node into a tree with a *different* local root (i.e., a 17 // tree where the root is a local frame, different from this document, with 18 // a remote parent). 19 // 3. Maintaining a reference to the node that now exists in a different local 20 // frame root. 21 // 4. Add a same-type event listener to the document that used to host the 22 // now-adopted node. This fails an assertion in the event handler 23 // registry's consistency checker, which is mistakenly holding a reference 24 // to the node that is now hosted in a different local frame root, which 25 // the checker does not expect. 26 promise_test(async t => { 27 const crossOriginChild = document.createElement('iframe'); 28 const crossOriginChildURL = new URL('resources/cross-origin-middle-frame.html', get_host_info().HTTP_REMOTE_ORIGIN + location.pathname); 29 crossOriginChild.src = crossOriginChildURL; 30 31 const grandchildLoadPromise = new Promise(resolve => { 32 window.onmessage = e => { 33 if (e.data === 'grandchild loaded') { 34 resolve(); 35 } 36 } 37 }); 38 document.body.append(crossOriginChild); 39 await grandchildLoadPromise; 40 41 const sameOriginGrandchild = window.frames[0][0]; 42 assert_not_equals(sameOriginGrandchild.document, null, 43 "same-origin grandchild frame exists"); 44 45 button.addEventListener('touchmove', e => {}); 46 47 // This is important because before https://crbug.com/40277823 was fixed, it 48 // would prevent the garbage collector from removing `button` from this 49 // document's event handler registry. As long as it's still (incorrectly) in 50 // the registry when we add the `touchmove` event handler is added to this 51 // document later (post-adoption), the registry's consistency checker would 52 // crash, asserting that the still-tracked event target is rooted at its *old* 53 // local frame root. 54 window.buttonHolder = button; 55 56 sameOriginGrandchild.document.adoptNode(button); 57 // This below would previously cause the Chromium crash. 58 document.body.addEventListener('touchmove', e => {}); 59 }, "Event handler-bearing node moved across local roots in the same tab/page"); 60 </script> 61 </body>