1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/layout/base/tests/bug970964_inner.html Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,342 @@ 1.4 +<!DOCTYPE HTML> 1.5 +<html> 1.6 +<!-- 1.7 +https://bugzilla.mozilla.org/show_bug.cgi?id=970964 1.8 +--> 1.9 +<head> 1.10 + <title>Test for Bug 970964</title> 1.11 + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> 1.12 + <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script> 1.13 + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> 1.14 +</head> 1.15 +<body> 1.16 +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=970964">Mozilla Bug 970964</a> 1.17 +<p id="display"></p> 1.18 +<div id="content" style="display: none"> 1.19 + 1.20 +</div> 1.21 +<pre id="test"> 1.22 +<script type="application/javascript"> 1.23 + 1.24 +/** Test for Bug 970964 **/ 1.25 + 1.26 +function ok(condition, msg) { 1.27 + parent.ok(condition, msg); 1.28 +} 1.29 + 1.30 +function is(a, b, msg) { 1.31 + parent.is(a, b, msg); 1.32 +} 1.33 + 1.34 +function testtouch(aOptions) { 1.35 + if (!aOptions) 1.36 + aOptions = {}; 1.37 + this.identifier = aOptions.identifier || 0; 1.38 + this.target = aOptions.target || 0; 1.39 + this.page = aOptions.page || {x: 0, y: 0}; 1.40 + this.radius = aOptions.radius || {x: 0, y: 0}; 1.41 + this.rotationAngle = aOptions.rotationAngle || 0; 1.42 + this.force = aOptions.force || 1; 1.43 +} 1.44 + 1.45 +function touchEvent(aOptions) { 1.46 + if (!aOptions) { 1.47 + aOptions = {}; 1.48 + } 1.49 + this.ctrlKey = aOptions.ctrlKey || false; 1.50 + this.altKey = aOptions.altKey || false; 1.51 + this.shiftKey = aOptions.shiftKey || false; 1.52 + this.metaKey = aOptions.metaKey || false; 1.53 + this.touches = aOptions.touches || []; 1.54 + this.targetTouches = aOptions.targetTouches || []; 1.55 + this.changedTouches = aOptions.changedTouches || []; 1.56 +} 1.57 + 1.58 +function sendTouchEvent(windowUtils, aType, aEvent, aModifiers) { 1.59 + var ids = [], xs=[], ys=[], rxs = [], rys = [], 1.60 + rotations = [], forces = []; 1.61 + 1.62 + for (var touchType of ["touches", "changedTouches", "targetTouches"]) { 1.63 + for (var i = 0; i < aEvent[touchType].length; i++) { 1.64 + if (ids.indexOf(aEvent[touchType][i].identifier) == -1) { 1.65 + ids.push(aEvent[touchType][i].identifier); 1.66 + xs.push(aEvent[touchType][i].page.x); 1.67 + ys.push(aEvent[touchType][i].page.y); 1.68 + rxs.push(aEvent[touchType][i].radius.x); 1.69 + rys.push(aEvent[touchType][i].radius.y); 1.70 + rotations.push(aEvent[touchType][i].rotationAngle); 1.71 + forces.push(aEvent[touchType][i].force); 1.72 + } 1.73 + } 1.74 + } 1.75 + return windowUtils.sendTouchEvent(aType, 1.76 + ids, xs, ys, rxs, rys, 1.77 + rotations, forces, 1.78 + ids.length, aModifiers, 0); 1.79 +} 1.80 + 1.81 +function getDefaultArgEvent(eventname) { 1.82 + return new PointerEvent(eventname, { 1.83 + bubbles: true, cancelable: true, view: window, 1.84 + detail: 0, screenX: 0, screenY: 0, clientX: 0, clientY: 0, 1.85 + ctrlKey: false, altKey: false, shiftKey: false, metaKey: false, 1.86 + button: 0, relatedTarget: null, pointerId: 0 1.87 + }); 1.88 +} 1.89 + 1.90 +function getTouchEventForTarget(target, cwu, id) { 1.91 + var bcr = target.getBoundingClientRect(); 1.92 + var touch = new testtouch({ 1.93 + page: {x: Math.round(bcr.left + bcr.width/2), 1.94 + y: Math.round(bcr.top + bcr.height/2)}, 1.95 + target: target, 1.96 + identifier: id, 1.97 + }); 1.98 + var event = new touchEvent({ 1.99 + touches: [touch], 1.100 + targetTouches: [touch], 1.101 + changedTouches: [touch] 1.102 + }); 1.103 + return event; 1.104 +} 1.105 + 1.106 +function runTests() { 1.107 + var d0 = document.getElementById("d0"); 1.108 + var d1 = document.getElementById("d1"); 1.109 + var d2 = document.getElementById("d2"); 1.110 + var d3 = document.getElementById("d3"); 1.111 + 1.112 + // Test Pointer firing before any mouse/touch original source 1.113 + 1.114 + var mouseDownTriggered = 0; 1.115 + var pointerDownTriggered = 0; 1.116 + var touchDownTriggered = 0; 1.117 + var touchCancelTriggered = 0; 1.118 + var pointerCancelTriggered = 0; 1.119 + 1.120 + d0.onmousedown = function(e) { 1.121 + mouseDownTriggered = 1; 1.122 + is(pointerDownTriggered , 1, "Mouse event must be triggered after pointer event!"); 1.123 + }; 1.124 + d0.ontouchstart = function(e) { 1.125 + touchDownTriggered = 1; 1.126 + is(touchDownTriggered , 1, "Touch event must be triggered after pointer event!"); 1.127 + } 1.128 + d0.ontouchcancel = function(e) { 1.129 + touchCancelTriggered = 1; 1.130 + is(pointerCancelTriggered, 1, "Touch cancel event must be triggered after pointer event!"); 1.131 + } 1.132 + d0.onpointerdown = function(e) { 1.133 + pointerDownTriggered = 1; 1.134 + is(mouseDownTriggered, 0, "Pointer event must be triggered before mouse event!"); 1.135 + is(touchDownTriggered, 0, "Pointer event must be triggered before touch event!"); 1.136 + }; 1.137 + d0.addEventListener("pointercancel", function(ev) { 1.138 + d0.removeEventListener("pointercancel", arguments.callee, false); 1.139 + is(ev.pointerId, 0, "Correct default pointerId"); 1.140 + is(ev.bubbles, true, "bubbles should be true"); 1.141 + is(ev.cancelable, false, "pointercancel cancelable should be false "); 1.142 + pointerCancelTriggered = 1; 1.143 + is(touchCancelTriggered, 0, "Pointer event must be triggered before touch event!"); 1.144 + }, false); 1.145 + 1.146 + // Test pointer event generated from mouse event 1.147 + synthesizeMouse(d1, 3, 3, { type: "mousemove"}); 1.148 + synthesizeMouse(d1, 3, 3, { type: "mousedown"}); 1.149 + synthesizeMouse(d1, 3, 3, { type: "mouseup"}); 1.150 + 1.151 + // Test pointer event generated from touch event 1.152 + pointerDownTriggered = 0; 1.153 + mouseDownTriggered = 0; 1.154 + 1.155 + var cwu = SpecialPowers.getDOMWindowUtils(window); 1.156 + var event1 = getTouchEventForTarget(d1, cwu, 0); 1.157 + sendTouchEvent(cwu, "touchmove", event1, 0); 1.158 + sendTouchEvent(cwu, "touchstart", event1, 0); 1.159 + // Test Touch to Pointer Cancel 1.160 + sendTouchEvent(cwu, "touchcancel", event1, 0); 1.161 + 1.162 + // Check Pointer enter/leave from mouse generated event 1.163 + var mouseEnterTriggered = 0; 1.164 + var pointerEnterTriggered = 0; 1.165 + d2.onpointerenter = function(e) { 1.166 + pointerEnterTriggered = 1; 1.167 + is(e.bubbles, false, "bubbles should be false"); 1.168 + is(e.cancelable, false, "cancelable should be false"); 1.169 + is(mouseEnterTriggered, 0, "Pointer event must be triggered before mouse event!"); 1.170 + }; 1.171 + d2.onmouseenter = function(e) { 1.172 + mouseEnterTriggered = 1; 1.173 + is(pointerEnterTriggered , 1, "Mouse event must be triggered after pointer event!"); 1.174 + }; 1.175 + synthesizeMouse(d2, 3, 3, { type: "mousemove"}); 1.176 + d2.onmouseenter = function(e) {} 1.177 + 1.178 + // Test Multi Pointer enter/leave for pointers generated from Mouse and Touch at the same time 1.179 + // Enter mouse and touch generated pointers to different elements 1.180 + var d1enterCount = 0; 1.181 + var d2enterCount = 0; 1.182 + var d3enterCount = 0; 1.183 + var d1leaveCount = 0; 1.184 + var d2leaveCount = 0; 1.185 + var d3leaveCount = 0; 1.186 + var mousePointerEnterLeaveCount = 0; 1.187 + var touchPointerEnterLeaveCount = 0; 1.188 + 1.189 + var checkPointerType = function(pointerType) { 1.190 + if (pointerType == "mouse") { 1.191 + ++mousePointerEnterLeaveCount; 1.192 + } else if (pointerType == "touch") { 1.193 + ++touchPointerEnterLeaveCount; 1.194 + } 1.195 + }; 1.196 + 1.197 + d1.onpointerenter = function(e) { 1.198 + ++d1enterCount; 1.199 + is(e.bubbles, false, "bubbles should be false"); 1.200 + is(e.cancelable, false, "cancelable should be false"); 1.201 + checkPointerType(e.pointerType); 1.202 + }; 1.203 + d2.onpointerenter = function(e) { 1.204 + ++d2enterCount; 1.205 + is(e.bubbles, false, "bubbles should be false"); 1.206 + is(e.cancelable, false, "cancelable should be false"); 1.207 + checkPointerType(e.pointerType); 1.208 + }; 1.209 + d3.onpointerenter = function(e) { 1.210 + ++d3enterCount; 1.211 + is(e.bubbles, false, "bubbles should be false"); 1.212 + is(e.cancelable, false, "cancelable should be false"); 1.213 + checkPointerType(e.pointerType); 1.214 + }; 1.215 + d1.onpointerleave = function(e) { 1.216 + ++d1leaveCount; 1.217 + is(e.bubbles, false, "bubbles should be false"); 1.218 + is(e.cancelable, false, "cancelable should be false"); 1.219 + checkPointerType(e.pointerType); 1.220 + }; 1.221 + d2.onpointerleave = function(e) { 1.222 + ++d2leaveCount; 1.223 + is(e.bubbles, false, "bubbles should be false"); 1.224 + is(e.cancelable, false, "cancelable should be false"); 1.225 + checkPointerType(e.pointerType); 1.226 + }; 1.227 + d3.onpointerleave = function(e) { 1.228 + ++d3leaveCount; 1.229 + is(e.bubbles, false, "bubbles should be false"); 1.230 + is(e.cancelable, false, "cancelable should be false"); 1.231 + checkPointerType(e.pointerType); 1.232 + }; 1.233 + 1.234 + synthesizeMouse(d1, 3, 3, { type: "mousemove"}); 1.235 + sendTouchEvent(cwu, "touchmove", getTouchEventForTarget(d3, cwu, 3), 0); 1.236 + is(touchPointerEnterLeaveCount, 1, "Wrong touch enterLeave count for!"); 1.237 + is(mousePointerEnterLeaveCount, 2, "Wrong mouse enterLeave count for!"); 1.238 + 1.239 + is(d1enterCount, 1, "Wrong enter count for! d1"); 1.240 + is(d2leaveCount, 1, "Wrong leave count for! d2"); 1.241 + is(d3enterCount, 1, "Wrong enter count for! d3"); 1.242 + 1.243 + sendTouchEvent(cwu, "touchmove", getTouchEventForTarget(d1, cwu, 3), 0); 1.244 + synthesizeMouse(d3, 3, 3, { type: "mousemove"}); 1.245 + is(touchPointerEnterLeaveCount, 3, "Wrong touch enterLeave count for!"); 1.246 + is(mousePointerEnterLeaveCount, 4, "Wrong mouse enterLeave count for!"); 1.247 + 1.248 + is(d3leaveCount, 1, "Wrong leave count for! d3"); 1.249 + is(d1leaveCount, 1, "Wrong leave count for! d1"); 1.250 + is(d1enterCount, 2, "Wrong enter count for! d1"); 1.251 + is(d3enterCount, 2, "Wrong enter count for! d3"); 1.252 + 1.253 + sendTouchEvent(cwu, "touchmove", getTouchEventForTarget(d2, cwu, 3), 0); 1.254 + synthesizeMouse(d2, 3, 3, { type: "mousemove"}); 1.255 + is(touchPointerEnterLeaveCount, 5, "Wrong touch enterLeave count for!"); 1.256 + is(mousePointerEnterLeaveCount, 6, "Wrong mouse enterLeave count for!"); 1.257 + 1.258 + is(d1leaveCount, 2, "Wrong leave count for! d1"); 1.259 + is(d2enterCount, 2, "Wrong enter count for! d2"); 1.260 + is(d3leaveCount, 2, "Wrong leave count for! d3"); 1.261 + 1.262 + sendTouchEvent(cwu, "touchmove", getTouchEventForTarget(d1, cwu, 3), 0); 1.263 + synthesizeMouse(d1, 3, 3, { type: "mousemove"}); 1.264 + is(touchPointerEnterLeaveCount, 7, "Wrong touch enterLeave count for!"); 1.265 + is(mousePointerEnterLeaveCount, 8, "Wrong mouse enterLeave count for!"); 1.266 + 1.267 + is(d2leaveCount, 3, "Wrong leave count for! d2"); 1.268 + is(d1enterCount, 4, "Wrong enter count for! d1"); 1.269 + 1.270 + // Test for pointer buttons when it generated from mousemove event 1.271 + d1.onpointermove = function(e) { 1.272 + is(e.buttons, 0, "Buttons must be 0 on pointer generated from mousemove"); 1.273 + is(e.button, -1, "Button must be -1 on pointer generated from mousemove when no buttons pressed"); 1.274 + is(e.pointerType, "mouse", "Pointer type must be mouse"); 1.275 + }; 1.276 + cwu.sendMouseEvent("mousemove", 4, 4, 0, 0, 0, false, 0, 0); 1.277 + 1.278 + d1.onpointermove = function(e) { 1.279 + is(e.buttons, 1, "Buttons must be 1 on pointer generated from touch event"); 1.280 + is(e.button, 0, "Button must be 0 on pointer generated from touch eventd"); 1.281 + is(e.pointerType, "touch", "Pointer type must be touch"); 1.282 + }; 1.283 + sendTouchEvent(cwu, "touchmove", getTouchEventForTarget(d1, cwu, 2), 0); 1.284 + 1.285 + // Test for cancel trigger pointerOut (Touch Pointer must be at d1 now) 1.286 + pointerCancelTriggered = 0; 1.287 + var pointerOutTriggeredForCancelEvent = 0; 1.288 + var pointerLeaveTriggeredForCancelEvent = 0; 1.289 + d1.onpointerout = function(e) { 1.290 + if (pointerOutTriggeredForCancelEvent == 0) { 1.291 + is(e.pointerId, 3, "Wrong Pointer type, should be id from Touch event"); 1.292 + is(e.pointerType, "touch", "Wrong Pointer type, should be touch type"); 1.293 + } else { 1.294 + is(e.pointerId, 0, "Wrong Pointer type, should be id from mouse event"); 1.295 + is(e.pointerType, "mouse", "Wrong Pointer type, should be mouse type"); 1.296 + } 1.297 + pointerOutTriggeredForCancelEvent = 1; 1.298 + }; 1.299 + d1.onpointerleave = function(e) { 1.300 + is(pointerOutTriggeredForCancelEvent, 1, "Pointer Out must be dispatched bedore Pointer leave"); 1.301 + if (pointerLeaveTriggeredForCancelEvent == 0) { 1.302 + is(e.pointerId, 3, "Wrong Pointer type, should be id from Touch event"); 1.303 + is(e.pointerType, "touch", "Wrong Pointer type, should be touch type"); 1.304 + } else { 1.305 + is(e.pointerId, 0, "Wrong Pointer type, should be id from mouse event"); 1.306 + is(e.pointerType, "mouse", "Wrong Pointer type, should be mouse type"); 1.307 + } 1.308 + pointerLeaveTriggeredForCancelEvent = 1; 1.309 + } 1.310 + 1.311 + sendTouchEvent(cwu, "touchcancel", getTouchEventForTarget(d1, cwu, 3), 0); 1.312 + is(pointerOutTriggeredForCancelEvent, 1, "Pointer Out not dispatched on PointerCancel"); 1.313 + is(pointerLeaveTriggeredForCancelEvent, 1, "Pointer Leave not dispatched on PointerCancel"); 1.314 + 1.315 + finishTest(); 1.316 +} 1.317 + 1.318 +function finishTest() { 1.319 + // Let window.onerror have a chance to fire 1.320 + setTimeout(function() { 1.321 + setTimeout(function() { 1.322 + window.parent.postMessage("SimpleTest.finish();", "*"); 1.323 + }, 0); 1.324 + }, 0); 1.325 +} 1.326 + 1.327 +window.onload = function () { 1.328 + SpecialPowers.pushPrefEnv({ 1.329 + "set": [ 1.330 + ["dom.w3c_pointer_events.enabled", true], 1.331 + ] 1.332 + }, runTests); 1.333 +} 1.334 + 1.335 +SimpleTest.waitForExplicitFinish(); 1.336 + 1.337 +</script> 1.338 +</pre> 1.339 +<div id="d0"> 1.340 +Test divs -- 1.341 +<div id="d1">t</div><div id="d2">t</div><div id="d3">t</div> 1.342 +-- 1.343 +</div> 1.344 +</body> 1.345 +</html>