test_bug967796.html (11208B)
1 <!DOCTYPE HTML> 2 <html> 3 <!-- 4 https://bugzilla.mozilla.org/show_bug.cgi?id=967796 5 --> 6 <head> 7 <title>Test for Bug 967796</title> 8 <script src="/tests/SimpleTest/SimpleTest.js"></script> 9 <script src="/tests/SimpleTest/EventUtils.js"></script> 10 <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> 11 </head> 12 <body> 13 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=967796">Mozilla Bug 967796</a> 14 <p id="display"></p> 15 <div id="content" style="display: none"> 16 17 </div> 18 <pre id="test"> 19 <script type="application/javascript"> 20 21 /** Test for Bug 967796 */ 22 SimpleTest.waitForExplicitFinish(); 23 SimpleTest.waitForFocus(runTests); 24 var outer; 25 var middle; 26 var inner; 27 var outside; 28 var container; 29 var file; 30 var iframe; 31 var checkRelatedTarget = false; 32 var expectedRelatedEnter = null; 33 var expectedRelatedLeave = null; 34 var pointerentercount = 0; 35 var pointerleavecount = 0; 36 var pointerovercount = 0; 37 var pointeroutcount = 0; 38 39 function sendMouseEventToElement(t, elem) { 40 var r = elem.getBoundingClientRect(); 41 synthesizeMouse(elem, r.width / 2, r.height / 2, {type: t, id: 0}); 42 } 43 44 var expectedPointerEnterTargets = []; 45 var expectedPointerLeaveTargets = []; 46 47 function runTests() { 48 outer = document.getElementById("outertest"); 49 middle = document.getElementById("middletest"); 50 inner = document.getElementById("innertest"); 51 outside = document.getElementById("outside"); 52 container = document.getElementById("container"); 53 file = document.getElementById("file"); 54 iframe = document.getElementById("iframe"); 55 iframe.addEventListener("pointerenter", penter); 56 iframe.addEventListener("pointerleave", pleave); 57 iframe.addEventListener("pointerout", pout); 58 iframe.addEventListener("pointerover", pover); 59 60 // Make sure ESM thinks pointer is outside the test elements. 61 sendMouseEventToElement("mousemove", outside); 62 63 pointerentercount = 0; 64 pointerleavecount = 0; 65 pointerovercount = 0; 66 pointeroutcount = 0; 67 checkRelatedTarget = true; 68 expectedRelatedEnter = outside; 69 expectedRelatedLeave = inner; 70 expectedPointerEnterTargets = ["outertest", "middletest", "innertest"]; 71 info("Synthesizing mousemove on the inner..."); 72 sendMouseEventToElement("mousemove", inner); 73 is(pointerentercount, 3, "Unexpected pointerenter event count!"); 74 is(pointerovercount, 1, "Unexpected pointerover event count!"); 75 is(pointeroutcount, 0, "Unexpected pointerout event count!"); 76 is(pointerleavecount, 0, "Unexpected pointerleave event count!"); 77 expectedRelatedEnter = inner; 78 expectedRelatedLeave = outside; 79 expectedPointerLeaveTargets = ["innertest", "middletest", "outertest"]; 80 info("Synthesizing mousemove on the outside after the inner..."); 81 sendMouseEventToElement("mousemove", outside); 82 is(pointerentercount, 3, "Unexpected pointerenter event count!"); 83 is(pointerovercount, 1, "Unexpected pointerover event count!"); 84 is(pointeroutcount, 1, "Unexpected pointerout event count!"); 85 is(pointerleavecount, 3, "Unexpected pointerleave event count!"); 86 87 // Event handling over native anonymous content. 88 var r = file.getBoundingClientRect(); 89 expectedRelatedEnter = outside; 90 expectedRelatedLeave = file; 91 info("Synthesizing mousemove on the file control #1..."); 92 synthesizeMouse(file, r.width / 6, r.height / 2, {type: "mousemove"}); 93 is(pointerentercount, 4, "Unexpected pointerenter event count!"); 94 is(pointerovercount, 2, "Unexpected pointerover event count!"); 95 is(pointeroutcount, 1, "Unexpected pointerout event count!"); 96 is(pointerleavecount, 3, "Unexpected pointerleave event count!"); 97 98 // Moving pointer over type="file" shouldn't cause pointerover/out/enter/leave events 99 info("Synthesizing mousemove on the file control #2..."); 100 synthesizeMouse(file, r.width - (r.width / 6), r.height / 2, {type: "mousemove"}); 101 is(pointerentercount, 4, "Unexpected pointerenter event count!"); 102 is(pointerovercount, 2, "Unexpected pointerover event count!"); 103 is(pointeroutcount, 1, "Unexpected pointerout event count!"); 104 is(pointerleavecount, 3, "Unexpected pointerleave event count!"); 105 106 expectedRelatedEnter = file; 107 expectedRelatedLeave = outside; 108 info("Synthesizing mousemove on the outside after the file control..."); 109 sendMouseEventToElement("mousemove", outside); 110 is(pointerentercount, 4, "Unexpected pointerenter event count!"); 111 is(pointerovercount, 2, "Unexpected pointerover event count!"); 112 is(pointeroutcount, 2, "Unexpected pointerout event count!"); 113 is(pointerleavecount, 4, "Unexpected pointerleave event count!"); 114 115 // Initialize iframe 116 iframe.contentDocument.documentElement.style.overflow = "hidden"; 117 iframe.contentDocument.body.style.margin = "0px"; 118 iframe.contentDocument.body.style.width = "100%"; 119 iframe.contentDocument.body.style.height = "100%"; 120 iframe.contentDocument.body.innerHTML = 121 "<div style='width: 100%; height: 50%; border: 1px solid black;'></div>" + 122 "<div style='width: 100%; height: 50%; border: 1px solid black;'></div>"; 123 iframe.contentDocument.body.offsetLeft; // flush 124 125 iframe.contentDocument.body.firstChild.onpointerenter = penter; 126 iframe.contentDocument.body.firstChild.onpointerleave = pleave; 127 iframe.contentDocument.body.lastChild.onpointerenter = penter; 128 iframe.contentDocument.body.lastChild.onpointerleave = pleave; 129 r = iframe.getBoundingClientRect(); 130 expectedRelatedEnter = outside; 131 expectedRelatedLeave = iframe; 132 // Move pointer inside the iframe. 133 info("Synthesizing mousemove on the body in the iframe #1..."); 134 synthesizeMouse(iframe.contentDocument.body, r.width / 2, r.height / 4, {type: "mousemove"}, 135 iframe.contentWindow); 136 is(pointerentercount, 6, "Unexpected pointerenter event count!"); 137 is(pointerleavecount, 4, "Unexpected pointerleave event count!"); 138 info("Synthesizing mousemove on the body in the iframe #2..."); 139 synthesizeMouse(iframe.contentDocument.body, r.width / 2, r.height - (r.height / 4), {type: "mousemove"}, 140 iframe.contentWindow); 141 is(pointerentercount, 7, "Unexpected pointerenter event count!"); 142 is(pointerleavecount, 5, "Unexpected pointerleave event count!"); 143 expectedRelatedEnter = iframe; 144 expectedRelatedLeave = outside; 145 info("Synthesizing mousemove on the outside after the iframe..."); 146 sendMouseEventToElement("mousemove", outside); 147 is(pointerentercount, 7, "Unexpected pointerenter event count!"); 148 is(pointerleavecount, 7, "Unexpected pointerleave event count!"); 149 150 // pointerdown must produce pointerenter event 151 expectedRelatedEnter = outside; 152 expectedRelatedLeave = iframe; 153 // Move pointer inside the iframe. 154 info("Synthesizing mousemove on the body in the iframe #3..."); 155 synthesizeMouse(iframe.contentDocument.body, r.width / 2, r.height / 4, {type: "mousedown"}, 156 iframe.contentWindow); 157 info("Synthesizing mousemove on the body in the iframe #4..."); 158 synthesizeMouse(iframe.contentDocument.body, r.width / 2, r.height - (r.height / 4), {type: "mousedown"}, 159 iframe.contentWindow); 160 is(pointerentercount, 10, "Unexpected pointerenter event count!"); 161 162 // pointerdown + pointermove must produce single pointerenter event 163 expectedRelatedEnter = outside; 164 expectedRelatedLeave = iframe; 165 info("Synthesizing mousemove on the body in the iframe #5..."); 166 synthesizeMouse(iframe.contentDocument.body, r.width / 2, r.height / 4, {type: "mousedown"}, 167 iframe.contentWindow); 168 info("Synthesizing mousemove on the body in the iframe #6..."); 169 synthesizeMouse(iframe.contentDocument.body, r.width / 2 + 1, r.height / 4 + 1, {type: "mousemove"}, 170 iframe.contentWindow); 171 is(pointerentercount, 11, "Unexpected pointerenter event count!"); 172 173 Array.from(document.querySelectorAll('*')) 174 .concat([iframe.contentDocument.body.firstChild, iframe.contentDocument.body.lastChild]) 175 .forEach((elt) => { 176 elt.onpointerenter = null; 177 elt.onpointerleave = null; 178 elt.onpointerenter = null; 179 elt.onpointerleave = null; 180 }); 181 SimpleTest.finish(); 182 } 183 184 function penter(evt) { 185 if (evt.pointerId != 0) { 186 return; // Preceding test must have used the unexpected pointer. Ignore pointer boundary events for the pointer. 187 } 188 ++pointerentercount; 189 evt.stopPropagation(); 190 if (expectedPointerEnterTargets.length) { 191 var t = expectedPointerEnterTargets.shift(); 192 is(evt.target.id, t, "Wrong event target!"); 193 } 194 is(evt.bubbles, false, evt.type + " should not bubble!"); 195 is(evt.cancelable, false, evt.type + " is cancelable!"); 196 is(evt.target, evt.currentTarget, "Wrong event target!"); 197 ok(!evt.relatedTarget || evt.target.ownerDocument == evt.relatedTarget.ownerDocument, 198 "Leaking nodes to another document?"); 199 if (checkRelatedTarget && evt.target.ownerDocument == document) { 200 is(evt.relatedTarget, expectedRelatedEnter, "Wrong related target (pointerenter)"); 201 } 202 } 203 204 function pleave(evt) { 205 if (evt.pointerId != 0) { 206 return; // Preceding test must have used the unexpected pointer. Ignore pointer boundary events for the pointer. 207 } 208 ++pointerleavecount; 209 evt.stopPropagation(); 210 if (expectedPointerLeaveTargets.length) { 211 var t = expectedPointerLeaveTargets.shift(); 212 is(evt.target.id, t, "Wrong event target!"); 213 } 214 is(evt.bubbles, false, evt.type + " should not bubble!"); 215 is(evt.cancelable, false, evt.type + " is cancelable!"); 216 is(evt.target, evt.currentTarget, "Wrong event target!"); 217 ok(!evt.relatedTarget || evt.target.ownerDocument == evt.relatedTarget.ownerDocument, 218 "Leaking nodes to another document?"); 219 if (checkRelatedTarget && evt.target.ownerDocument == document) { 220 is(evt.relatedTarget, expectedRelatedLeave, "Wrong related target (pointerleave)"); 221 } 222 } 223 224 function pover(evt) { 225 if (evt.pointerId != 0) { 226 return; // Preceding test must have used the unexpected pointer. Ignore pointer boundary events for the pointer. 227 } 228 ++pointerovercount; 229 evt.stopPropagation(); 230 } 231 232 function pout(evt) { 233 if (evt.pointerId != 0) { 234 return; // Preceding test must have used the unexpected pointer. Ignore pointer boundary events for the pointer. 235 } 236 ++pointeroutcount; 237 evt.stopPropagation(); 238 } 239 240 </script> 241 </pre> 242 <div id="container" onpointerenter="penter(event)" onpointerleave="pleave(event)" 243 onpointerout="pout(event)" onpointerover="pover(event)"> 244 <div id="outside" onpointerout="event.stopPropagation()" onpointerover="event.stopPropagation()">foo</div> 245 <div id="outertest" onpointerenter="penter(event)" onpointerleave="pleave(event)" 246 onpointerout="pout(event)" onpointerover="pover(event)"> 247 <div id="middletest" onpointerenter="penter(event)" onpointerleave="pleave(event)" 248 onpointerout="pout(event)" onpointerover="pover(event)"> 249 <div id="innertest" onpointerenter="penter(event)" onpointerleave="pleave(event)" 250 onpointerout="pout(event)" onpointerover="pover(event)">foo</div> 251 </div> 252 </div> 253 <input type="file" id="file" 254 onpointerenter="penter(event)" onpointerleave="pleave(event)" 255 onpointerout="pout(event)" onpointerover="pover(event)"> 256 <br> 257 <iframe id="iframe" width="50" height="50"></iframe> 258 </div> 259 </body> 260 </html>