inert-iframe-hittest.html (3660B)
1 <!DOCTYPE html> 2 <meta charset="utf-8"> 3 <title>Hit-testing with inert iframe</title> 4 <link rel="author" title="Oriol Brufau" href="mailto:obrufau@igalia.com"> 5 <link rel="help" href="https://html.spec.whatwg.org/multipage/interaction.html#inert"> 6 <meta assert="assert" content="Contents of an inert iframe can't be reached by hit-testing"> 7 <script src="/resources/testharness.js"></script> 8 <script src="/resources/testharnessreport.js"></script> 9 <script src="/resources/testdriver.js"></script> 10 <script src="/resources/testdriver-vendor.js"></script> 11 <script src="/resources/testdriver-actions.js"></script> 12 <style> 13 body { 14 padding: 5px; 15 } 16 </style> 17 <div id="wrapper" style="width: min-content"> 18 <iframe id="iframe" inert></iframe> 19 </div> 20 21 <script> 22 const events = [ 23 "mousedown", "mouseenter", "mousemove", "mouseover", 24 "pointerdown", "pointerenter", "pointermove", "pointerover", 25 ]; 26 const iframe = document.getElementById("iframe"); 27 let iframeDoc; 28 let target; 29 30 promise_setup(async () => { 31 await new Promise(resolve => { 32 iframe.addEventListener("load", resolve, {once: true}); 33 iframe.srcdoc = ` 34 <style>#target { position: fixed; inset: 0 }</style> 35 <a id="target" href="#">target</a> 36 `; 37 }); 38 iframeDoc = iframe.contentDocument; 39 target = iframeDoc.getElementById("target"); 40 target.addEventListener("click", e => { 41 e.preventDefault(); 42 }); 43 }); 44 45 async function mouseDownAndGetEvents(test) { 46 await new test_driver.Actions() 47 .pointerMove(1, 1, { origin: document.body }) 48 .send(); 49 50 const receivedEvents = { 51 target: [], 52 wrapper: [], 53 }; 54 for (let event of events) { 55 target.addEventListener(event, () => { 56 receivedEvents.target.push(event); 57 }, { once: true, capture: true }); 58 wrapper.addEventListener(event, () => { 59 receivedEvents.wrapper.push(event); 60 }, { once: true, capture: true }); 61 } 62 63 await new test_driver.Actions() 64 .pointerMove(0, 0, { origin: wrapper }) 65 .pointerDown() 66 .send(); 67 test.add_cleanup(() => test_driver.click(document.body)); 68 69 // Exact order of events is not interoperable. 70 receivedEvents.target.sort(); 71 receivedEvents.wrapper.sort(); 72 return receivedEvents; 73 } 74 75 promise_test(async function() { 76 const receivedEvents = await mouseDownAndGetEvents(this); 77 assert_array_equals(receivedEvents.target, [], "target got no event"); 78 assert_array_equals(receivedEvents.wrapper, events, "wrapper got all events"); 79 80 assert_false(target.matches(":focus"), "target is not focused"); 81 assert_false(target.matches(":active"), "target is not active"); 82 assert_false(target.matches(":hover"), "target is not hovered"); 83 assert_true(wrapper.matches(":hover"), "wrapper is hovered"); 84 }, "Hit-testing doesn't reach contents of an inert iframe"); 85 86 promise_test(async function() { 87 iframe.inert = false; 88 89 const receivedEvents = await mouseDownAndGetEvents(this); 90 assert_array_equals(receivedEvents.target, events, "target got all events"); 91 if (receivedEvents.wrapper.length === 2) { 92 // Firefox is unstable, sometimes missing the mouse events. 93 assert_array_equals( 94 receivedEvents.wrapper, 95 ["pointerenter", "pointerover"], 96 "wrapper got enter and over pointer events"); 97 } else { 98 assert_array_equals( 99 receivedEvents.wrapper, 100 ["mouseenter", "mouseover", "pointerenter", "pointerover"], 101 "wrapper got enter and over events"); 102 } 103 104 assert_true(target.matches(":active"), "target is active"); 105 assert_true(target.matches(":hover"), "target is hovered"); 106 assert_true(wrapper.matches(":hover"), "wrapper is hovered"); 107 }, "Hit-testing can reach contents of a no longer inert iframe"); 108 </script>