pointerevent_after_target_appended_interleaved.tentative.html (6407B)
1 <!DOCTYPE HTML> 2 <!-- 3 Tentative due to: 4 https://github.com/w3c/pointerevents/issues/492 5 --> 6 <title> 7 Enter/leave events fired to parent after child is added 8 right before compat mouse-event 9 </title> 10 <meta name="variant" content="?mouse"> 11 <meta name="variant" content="?touch"> 12 <meta name="variant" content="?pen"> 13 <script src="/resources/testharness.js"></script> 14 <script src="/resources/testharnessreport.js"></script> 15 <script src="/resources/testdriver.js"></script> 16 <script src="/resources/testdriver-actions.js"></script> 17 <script src="/resources/testdriver-vendor.js"></script> 18 <script src="pointerevent_support.js"></script> 19 20 <style> 21 div.target { 22 width: 100px; 23 height: 100px; 24 } 25 </style> 26 <div class="target" id="parent"> 27 <div class="target" id="child">child</div> 28 </div> 29 <div id="done">done</div> 30 31 <script> 32 'use strict'; 33 const pointer_type = location.search.substring(1); 34 35 const parent = document.getElementById("parent"); 36 const child = document.getElementById("child"); 37 const done = document.getElementById("done"); 38 39 let event_log = []; 40 let logged_event_prefix = ""; 41 let received_compat_mouse_events = false; 42 43 function logEvent(e) { 44 if (e.type.startsWith(logged_event_prefix) && e.eventPhase == e.AT_TARGET) { 45 event_log.push(e.type + "@" + e.target.id); 46 } 47 if (e.type.startsWith("mouse")) { 48 received_compat_mouse_events = true; 49 } 50 } 51 52 function attachChild(e) { 53 if (e.eventPhase == e.AT_TARGET) { 54 parent.appendChild(child); 55 event_log.push("(child-attached)"); 56 } 57 } 58 59 let child_moved = false; 60 61 function moveChild(e) { 62 if (!child_moved) { 63 child_moved = true; 64 parent.appendChild(child); 65 event_log.push("(child-moved)"); 66 } 67 } 68 69 function setup() { 70 const logged_event_suffixes = 71 ["over", "out", "enter", "leave", "down", "up"]; 72 let targets = document.getElementsByClassName("target"); 73 for (let i = 0; i < targets.length; i++) { 74 logged_event_suffixes.forEach(suffix => { 75 targets[i].addEventListener("pointer" + suffix, logEvent); 76 targets[i].addEventListener("mouse" + suffix, logEvent); 77 }); 78 targets[i].addEventListener("click", logEvent); 79 } 80 } 81 82 function addPromiseTestForNewChild(attaching_event, 83 tested_event_prefix, expected_events) { 84 const test_name = `${tested_event_prefix} events from ${pointer_type} `+ 85 `received before/after child attached at ${attaching_event}`; 86 87 promise_test(async test => { 88 event_log = []; 89 logged_event_prefix = tested_event_prefix; 90 91 // We started with child attached to ease event listener setup above. 92 parent.removeChild(child); 93 94 parent.addEventListener(attaching_event, attachChild); 95 test.add_cleanup(() => { 96 parent.removeEventListener(attaching_event, attachChild); 97 }); 98 99 let done_click_promise = getEvent("click", done); 100 101 let actions = new test_driver.Actions() 102 .addPointer("TestPointer", pointer_type) 103 .pointerMove(-30, -30, {origin: parent}) 104 .pointerDown() 105 .pointerUp() 106 .pointerMove(30, 30, {origin: parent}) 107 .pointerDown() 108 .pointerUp() 109 .pointerMove(0, 0, {origin: done}) 110 .pointerDown() 111 .pointerUp(); 112 113 await actions.send(); 114 await done_click_promise; 115 116 if (tested_event_prefix == "mouse" && !received_compat_mouse_events) { 117 expected_events = []; 118 } 119 120 assert_equals(event_log.toString(), expected_events.toString(), 121 "events received"); 122 }, test_name); 123 } 124 125 function addPromiseTestForMovedChild(mover_event, 126 tested_event_prefix, expected_events) { 127 const test_name = `${tested_event_prefix} events from ${pointer_type} `+ 128 `received before/after child moved at ${mover_event}`; 129 130 promise_test(async test => { 131 event_log = []; 132 logged_event_prefix = tested_event_prefix; 133 child_moved = false; 134 135 child.addEventListener(mover_event, moveChild); 136 test.add_cleanup(() => { 137 child.removeEventListener(mover_event, moveChild); 138 }); 139 140 let done_click_promise = getEvent("click", done); 141 142 let actions = new test_driver.Actions() 143 .addPointer("TestPointer", pointer_type) 144 .pointerMove(-30, -30, {origin: parent}) 145 .pointerDown() 146 .pointerUp() 147 .pointerMove(30, 30, {origin: parent}) 148 .pointerDown() 149 .pointerUp() 150 .pointerMove(0, 0, {origin: done}) 151 .pointerDown() 152 .pointerUp(); 153 154 await actions.send(); 155 await done_click_promise; 156 157 if (tested_event_prefix == "mouse" && !received_compat_mouse_events) { 158 expected_events = []; 159 } 160 161 assert_equals(event_log.toString(), expected_events.toString(), 162 "events received"); 163 }, test_name); 164 } 165 166 setup(); 167 168 // Tests for dispatched compatibility mouse events 169 // after DOM modification through pointer events. 170 addPromiseTestForNewChild("pointerdown", "mouse", [ 171 "mouseover@parent", "mouseenter@parent", 172 "mousedown@parent", "(child-attached)", 173 "mouseover@child", "mouseenter@child", 174 "mouseup@child", "click@parent", 175 "mousedown@child", "mouseup@child", "click@child", 176 "mouseout@child", "mouseleave@child", "mouseleave@parent" 177 ]); 178 addPromiseTestForNewChild("pointerup", "mouse", [ 179 "mouseover@parent", "mouseenter@parent", 180 "mousedown@parent", "mouseup@parent", "(child-attached)", "click@parent", 181 "mouseover@child", "mouseenter@child", 182 "mousedown@child", "mouseup@child", "click@child", 183 "mouseout@child", "mouseleave@child", "mouseleave@parent" 184 ]); 185 addPromiseTestForMovedChild("pointerdown", "mouse", [ 186 "mouseover@child", "mouseenter@parent", "mouseenter@child", 187 "mousedown@child", "(child-moved)", 188 "mouseover@child", "mouseenter@child", 189 "mouseup@child", "click@child", 190 "mousedown@child", "mouseup@child", "click@child", 191 "mouseout@child", "mouseleave@child", "mouseleave@parent" 192 ]); 193 addPromiseTestForMovedChild("pointerup", "mouse", [ 194 "mouseover@child", "mouseenter@parent", "mouseenter@child", 195 "mousedown@child", "mouseup@child", "(child-moved)", "click@child", 196 "mouseover@child", "mouseenter@child", 197 "mousedown@child", "mouseup@child", "click@child", 198 "mouseout@child", "mouseleave@child", "mouseleave@parent" 199 ]); 200 </script>