beforematch-element-removal-002.html (2684B)
1 <!DOCTYPE html> 2 <link rel="author" title="Tim Nguyen" href="https://github.com/nt1m"> 3 <link rel="help" href="https://html.spec.whatwg.org/#ancestor-revealing-algorithm"> 4 <script src="/resources/testharness.js"></script> 5 <script src="/resources/testharnessreport.js"></script> 6 7 <details id="a4"> 8 <details id="a3"> 9 <div id="a2" hidden="until-found"> 10 <details id="a1" hidden="until-found"> 11 <div id="a1child">Hidden</div> 12 </details> 13 </div> 14 </details> 15 </details> 16 17 <script> 18 function test_state({ a1open, a1hidden, a2hidden, a3open }) { 19 assert_equals(a1.open, a1open, `a1 should ${a1open ? "" : "not "}be open`); 20 assert_equals(a1.hidden, a1hidden ? "until-found" : false, `a1 should ${a1hidden ? "" : "not "}be hidden`); 21 assert_equals(a2.hidden, a2hidden ? "until-found" : false, `a2 should ${a2hidden ? "" : "not "}be hidden`); 22 assert_equals(a3.open, a3open, `a3 should ${a3open ? "" : "not "}be open`); 23 } 24 t = async_test("hidden=until-found and details revealing algorithm should abort if attribute states are mutated on beforematch events."); 25 test_state({ 26 a1open: false, 27 a1hidden: true, 28 a2hidden: true, 29 a3open: false 30 }); 31 a1.addEventListener("beforematch", t.step_func(() => { 32 test_state({ 33 a1open: true, // We find the <details> element before finding hidden=until-found as a consequence of tree-traversal order. 34 a1hidden: true, // hidden=until-found removal happens after beforematch event. 35 a2hidden: true, 36 a3open: false 37 }); 38 a2.addEventListener("beforematch", t.step_func((e) => { 39 assert_equals(e.target, a1, "a1 beforematch event bubbles up"); 40 // No change in state, since it's part of the same event dispatch as above. 41 test_state({ 42 a1open: true, 43 a1hidden: true, 44 a2hidden: true, 45 a3open: false 46 }); 47 a1.hidden = false; 48 a2.addEventListener("beforematch", t.step_func((e) => { 49 assert_equals(e.target, a2, "beforematch event for a2"); 50 test_state({ 51 a1open: true, 52 a1hidden: false, // a1 was revealed after its beforematch event. 53 a2hidden: true, 54 a3open: false 55 }); 56 a3.addEventListener("toggle", t.unreached_func("Algorithm should have aborted due to element removal.")); 57 a3.remove(); 58 a4.addEventListener("toggle", t.unreached_func("Algorithm should have aborted due to element removal.")); 59 t.done(); 60 }), { once: true }); 61 }), { once: true }); 62 }), { once: true }); 63 64 location.hash = "#a1child"; 65 </script>