pointerevent_to_slotted_target.html (3115B)
1 <!DOCTYPE HTML> 2 <link rel="help" href="https://w3c.github.io/pointerevents/#firing-events-using-the-pointerevent-interface"> 3 <title>Enter/leave events fired to parent after child is removed from slot</title> 4 <meta name="variant" content="?mouse"> 5 <meta name="variant" content="?touch"> 6 <meta name="variant" content="?pen"> 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-actions.js"></script> 11 <script src="/resources/testdriver-vendor.js"></script> 12 <script src="pointerevent_support.js"></script> 13 14 <template id="template"> 15 <style> 16 div { 17 width: 100px; 18 height: 100px; 19 } 20 </style> 21 <div id="parent"> 22 <slot id="slot">slot</slot> 23 </div> 24 </template> 25 26 <style> 27 div, my-elem { 28 width: 100px; 29 height: 100px; 30 display: block; 31 } 32 </style> 33 34 <my-elem id="host"> 35 <div id="child">child</div> 36 </my-elem> 37 <div id="done">done</div> 38 39 <script> 40 "use strict"; 41 42 customElements.define( 43 "my-elem", 44 class extends HTMLElement { 45 constructor() { 46 super(); 47 let content = document.getElementById("template").content; 48 const shadowRoot = this.attachShadow({ mode: "open" }); 49 shadowRoot.appendChild(content.cloneNode(true)); 50 } 51 }, 52 ); 53 54 const pointer_type = location.search.substring(1); 55 56 const shadow_host = document.getElementById("host"); 57 const parent = shadow_host.shadowRoot.getElementById("parent"); 58 const slot = parent.firstElementChild; 59 const slotted_child = document.getElementById("child"); 60 const done = document.getElementById("done"); 61 62 let event_log = []; 63 64 function logEvent(e) { 65 if (e.eventPhase == e.AT_TARGET) { 66 event_log.push(e.type + "@" + e.target.id); 67 } 68 } 69 70 function setup() { 71 const events = ["pointerover", "pointerout", 72 "pointerenter", "pointerleave", "pointerdown", "pointerup"]; 73 let targets = [shadow_host, parent, slot, slotted_child]; 74 for (let i = 0; i < targets.length; i++) { 75 events.forEach(event => targets[i].addEventListener(event, logEvent)); 76 } 77 } 78 79 setup(); 80 81 promise_test(async test => { 82 event_log = []; 83 84 let done_click_promise = getEvent("click", done); 85 86 let actions = new test_driver.Actions() 87 .addPointer("TestPointer", pointer_type) 88 .pointerMove(0, 0, {origin: shadow_host}) 89 .pointerDown() 90 .pointerUp() 91 .pointerMove(0, 0, {origin: done}) 92 .pointerDown() 93 .pointerUp(); 94 95 await actions.send(); 96 await done_click_promise; 97 98 const expected_events = [ 99 "pointerover@child", 100 "pointerenter@host", "pointerenter@parent", "pointerenter@slot", "pointerenter@child", 101 "pointerdown@child", "pointerup@child", 102 "pointerout@child", 103 "pointerleave@child", "pointerleave@slot", "pointerleave@parent", "pointerleave@host" 104 ]; 105 assert_equals(event_log.toString(), expected_events.toString(), 106 "events received"); 107 }, `Pointer events from ${pointer_type} to slotted element and shadow-host`); 108 </script>