Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
1 <!DOCTYPE HTML>
2 <html>
3 <!--
4 https://bugzilla.mozilla.org/show_bug.cgi?id=970964
5 -->
6 <head>
7 <title>Test for Bug 970964</title>
8 <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
9 <script type="application/javascript" 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=970964">Mozilla Bug 970964</a>
14 <p id="display"></p>
15 <div id="content" style="display: none">
17 </div>
18 <pre id="test">
19 <script type="application/javascript">
21 /** Test for Bug 970964 **/
23 function ok(condition, msg) {
24 parent.ok(condition, msg);
25 }
27 function is(a, b, msg) {
28 parent.is(a, b, msg);
29 }
31 function testtouch(aOptions) {
32 if (!aOptions)
33 aOptions = {};
34 this.identifier = aOptions.identifier || 0;
35 this.target = aOptions.target || 0;
36 this.page = aOptions.page || {x: 0, y: 0};
37 this.radius = aOptions.radius || {x: 0, y: 0};
38 this.rotationAngle = aOptions.rotationAngle || 0;
39 this.force = aOptions.force || 1;
40 }
42 function touchEvent(aOptions) {
43 if (!aOptions) {
44 aOptions = {};
45 }
46 this.ctrlKey = aOptions.ctrlKey || false;
47 this.altKey = aOptions.altKey || false;
48 this.shiftKey = aOptions.shiftKey || false;
49 this.metaKey = aOptions.metaKey || false;
50 this.touches = aOptions.touches || [];
51 this.targetTouches = aOptions.targetTouches || [];
52 this.changedTouches = aOptions.changedTouches || [];
53 }
55 function sendTouchEvent(windowUtils, aType, aEvent, aModifiers) {
56 var ids = [], xs=[], ys=[], rxs = [], rys = [],
57 rotations = [], forces = [];
59 for (var touchType of ["touches", "changedTouches", "targetTouches"]) {
60 for (var i = 0; i < aEvent[touchType].length; i++) {
61 if (ids.indexOf(aEvent[touchType][i].identifier) == -1) {
62 ids.push(aEvent[touchType][i].identifier);
63 xs.push(aEvent[touchType][i].page.x);
64 ys.push(aEvent[touchType][i].page.y);
65 rxs.push(aEvent[touchType][i].radius.x);
66 rys.push(aEvent[touchType][i].radius.y);
67 rotations.push(aEvent[touchType][i].rotationAngle);
68 forces.push(aEvent[touchType][i].force);
69 }
70 }
71 }
72 return windowUtils.sendTouchEvent(aType,
73 ids, xs, ys, rxs, rys,
74 rotations, forces,
75 ids.length, aModifiers, 0);
76 }
78 function getDefaultArgEvent(eventname) {
79 return new PointerEvent(eventname, {
80 bubbles: true, cancelable: true, view: window,
81 detail: 0, screenX: 0, screenY: 0, clientX: 0, clientY: 0,
82 ctrlKey: false, altKey: false, shiftKey: false, metaKey: false,
83 button: 0, relatedTarget: null, pointerId: 0
84 });
85 }
87 function getTouchEventForTarget(target, cwu, id) {
88 var bcr = target.getBoundingClientRect();
89 var touch = new testtouch({
90 page: {x: Math.round(bcr.left + bcr.width/2),
91 y: Math.round(bcr.top + bcr.height/2)},
92 target: target,
93 identifier: id,
94 });
95 var event = new touchEvent({
96 touches: [touch],
97 targetTouches: [touch],
98 changedTouches: [touch]
99 });
100 return event;
101 }
103 function runTests() {
104 var d0 = document.getElementById("d0");
105 var d1 = document.getElementById("d1");
106 var d2 = document.getElementById("d2");
107 var d3 = document.getElementById("d3");
109 // Test Pointer firing before any mouse/touch original source
111 var mouseDownTriggered = 0;
112 var pointerDownTriggered = 0;
113 var touchDownTriggered = 0;
114 var touchCancelTriggered = 0;
115 var pointerCancelTriggered = 0;
117 d0.onmousedown = function(e) {
118 mouseDownTriggered = 1;
119 is(pointerDownTriggered , 1, "Mouse event must be triggered after pointer event!");
120 };
121 d0.ontouchstart = function(e) {
122 touchDownTriggered = 1;
123 is(touchDownTriggered , 1, "Touch event must be triggered after pointer event!");
124 }
125 d0.ontouchcancel = function(e) {
126 touchCancelTriggered = 1;
127 is(pointerCancelTriggered, 1, "Touch cancel event must be triggered after pointer event!");
128 }
129 d0.onpointerdown = function(e) {
130 pointerDownTriggered = 1;
131 is(mouseDownTriggered, 0, "Pointer event must be triggered before mouse event!");
132 is(touchDownTriggered, 0, "Pointer event must be triggered before touch event!");
133 };
134 d0.addEventListener("pointercancel", function(ev) {
135 d0.removeEventListener("pointercancel", arguments.callee, false);
136 is(ev.pointerId, 0, "Correct default pointerId");
137 is(ev.bubbles, true, "bubbles should be true");
138 is(ev.cancelable, false, "pointercancel cancelable should be false ");
139 pointerCancelTriggered = 1;
140 is(touchCancelTriggered, 0, "Pointer event must be triggered before touch event!");
141 }, false);
143 // Test pointer event generated from mouse event
144 synthesizeMouse(d1, 3, 3, { type: "mousemove"});
145 synthesizeMouse(d1, 3, 3, { type: "mousedown"});
146 synthesizeMouse(d1, 3, 3, { type: "mouseup"});
148 // Test pointer event generated from touch event
149 pointerDownTriggered = 0;
150 mouseDownTriggered = 0;
152 var cwu = SpecialPowers.getDOMWindowUtils(window);
153 var event1 = getTouchEventForTarget(d1, cwu, 0);
154 sendTouchEvent(cwu, "touchmove", event1, 0);
155 sendTouchEvent(cwu, "touchstart", event1, 0);
156 // Test Touch to Pointer Cancel
157 sendTouchEvent(cwu, "touchcancel", event1, 0);
159 // Check Pointer enter/leave from mouse generated event
160 var mouseEnterTriggered = 0;
161 var pointerEnterTriggered = 0;
162 d2.onpointerenter = function(e) {
163 pointerEnterTriggered = 1;
164 is(e.bubbles, false, "bubbles should be false");
165 is(e.cancelable, false, "cancelable should be false");
166 is(mouseEnterTriggered, 0, "Pointer event must be triggered before mouse event!");
167 };
168 d2.onmouseenter = function(e) {
169 mouseEnterTriggered = 1;
170 is(pointerEnterTriggered , 1, "Mouse event must be triggered after pointer event!");
171 };
172 synthesizeMouse(d2, 3, 3, { type: "mousemove"});
173 d2.onmouseenter = function(e) {}
175 // Test Multi Pointer enter/leave for pointers generated from Mouse and Touch at the same time
176 // Enter mouse and touch generated pointers to different elements
177 var d1enterCount = 0;
178 var d2enterCount = 0;
179 var d3enterCount = 0;
180 var d1leaveCount = 0;
181 var d2leaveCount = 0;
182 var d3leaveCount = 0;
183 var mousePointerEnterLeaveCount = 0;
184 var touchPointerEnterLeaveCount = 0;
186 var checkPointerType = function(pointerType) {
187 if (pointerType == "mouse") {
188 ++mousePointerEnterLeaveCount;
189 } else if (pointerType == "touch") {
190 ++touchPointerEnterLeaveCount;
191 }
192 };
194 d1.onpointerenter = function(e) {
195 ++d1enterCount;
196 is(e.bubbles, false, "bubbles should be false");
197 is(e.cancelable, false, "cancelable should be false");
198 checkPointerType(e.pointerType);
199 };
200 d2.onpointerenter = function(e) {
201 ++d2enterCount;
202 is(e.bubbles, false, "bubbles should be false");
203 is(e.cancelable, false, "cancelable should be false");
204 checkPointerType(e.pointerType);
205 };
206 d3.onpointerenter = function(e) {
207 ++d3enterCount;
208 is(e.bubbles, false, "bubbles should be false");
209 is(e.cancelable, false, "cancelable should be false");
210 checkPointerType(e.pointerType);
211 };
212 d1.onpointerleave = function(e) {
213 ++d1leaveCount;
214 is(e.bubbles, false, "bubbles should be false");
215 is(e.cancelable, false, "cancelable should be false");
216 checkPointerType(e.pointerType);
217 };
218 d2.onpointerleave = function(e) {
219 ++d2leaveCount;
220 is(e.bubbles, false, "bubbles should be false");
221 is(e.cancelable, false, "cancelable should be false");
222 checkPointerType(e.pointerType);
223 };
224 d3.onpointerleave = function(e) {
225 ++d3leaveCount;
226 is(e.bubbles, false, "bubbles should be false");
227 is(e.cancelable, false, "cancelable should be false");
228 checkPointerType(e.pointerType);
229 };
231 synthesizeMouse(d1, 3, 3, { type: "mousemove"});
232 sendTouchEvent(cwu, "touchmove", getTouchEventForTarget(d3, cwu, 3), 0);
233 is(touchPointerEnterLeaveCount, 1, "Wrong touch enterLeave count for!");
234 is(mousePointerEnterLeaveCount, 2, "Wrong mouse enterLeave count for!");
236 is(d1enterCount, 1, "Wrong enter count for! d1");
237 is(d2leaveCount, 1, "Wrong leave count for! d2");
238 is(d3enterCount, 1, "Wrong enter count for! d3");
240 sendTouchEvent(cwu, "touchmove", getTouchEventForTarget(d1, cwu, 3), 0);
241 synthesizeMouse(d3, 3, 3, { type: "mousemove"});
242 is(touchPointerEnterLeaveCount, 3, "Wrong touch enterLeave count for!");
243 is(mousePointerEnterLeaveCount, 4, "Wrong mouse enterLeave count for!");
245 is(d3leaveCount, 1, "Wrong leave count for! d3");
246 is(d1leaveCount, 1, "Wrong leave count for! d1");
247 is(d1enterCount, 2, "Wrong enter count for! d1");
248 is(d3enterCount, 2, "Wrong enter count for! d3");
250 sendTouchEvent(cwu, "touchmove", getTouchEventForTarget(d2, cwu, 3), 0);
251 synthesizeMouse(d2, 3, 3, { type: "mousemove"});
252 is(touchPointerEnterLeaveCount, 5, "Wrong touch enterLeave count for!");
253 is(mousePointerEnterLeaveCount, 6, "Wrong mouse enterLeave count for!");
255 is(d1leaveCount, 2, "Wrong leave count for! d1");
256 is(d2enterCount, 2, "Wrong enter count for! d2");
257 is(d3leaveCount, 2, "Wrong leave count for! d3");
259 sendTouchEvent(cwu, "touchmove", getTouchEventForTarget(d1, cwu, 3), 0);
260 synthesizeMouse(d1, 3, 3, { type: "mousemove"});
261 is(touchPointerEnterLeaveCount, 7, "Wrong touch enterLeave count for!");
262 is(mousePointerEnterLeaveCount, 8, "Wrong mouse enterLeave count for!");
264 is(d2leaveCount, 3, "Wrong leave count for! d2");
265 is(d1enterCount, 4, "Wrong enter count for! d1");
267 // Test for pointer buttons when it generated from mousemove event
268 d1.onpointermove = function(e) {
269 is(e.buttons, 0, "Buttons must be 0 on pointer generated from mousemove");
270 is(e.button, -1, "Button must be -1 on pointer generated from mousemove when no buttons pressed");
271 is(e.pointerType, "mouse", "Pointer type must be mouse");
272 };
273 cwu.sendMouseEvent("mousemove", 4, 4, 0, 0, 0, false, 0, 0);
275 d1.onpointermove = function(e) {
276 is(e.buttons, 1, "Buttons must be 1 on pointer generated from touch event");
277 is(e.button, 0, "Button must be 0 on pointer generated from touch eventd");
278 is(e.pointerType, "touch", "Pointer type must be touch");
279 };
280 sendTouchEvent(cwu, "touchmove", getTouchEventForTarget(d1, cwu, 2), 0);
282 // Test for cancel trigger pointerOut (Touch Pointer must be at d1 now)
283 pointerCancelTriggered = 0;
284 var pointerOutTriggeredForCancelEvent = 0;
285 var pointerLeaveTriggeredForCancelEvent = 0;
286 d1.onpointerout = function(e) {
287 if (pointerOutTriggeredForCancelEvent == 0) {
288 is(e.pointerId, 3, "Wrong Pointer type, should be id from Touch event");
289 is(e.pointerType, "touch", "Wrong Pointer type, should be touch type");
290 } else {
291 is(e.pointerId, 0, "Wrong Pointer type, should be id from mouse event");
292 is(e.pointerType, "mouse", "Wrong Pointer type, should be mouse type");
293 }
294 pointerOutTriggeredForCancelEvent = 1;
295 };
296 d1.onpointerleave = function(e) {
297 is(pointerOutTriggeredForCancelEvent, 1, "Pointer Out must be dispatched bedore Pointer leave");
298 if (pointerLeaveTriggeredForCancelEvent == 0) {
299 is(e.pointerId, 3, "Wrong Pointer type, should be id from Touch event");
300 is(e.pointerType, "touch", "Wrong Pointer type, should be touch type");
301 } else {
302 is(e.pointerId, 0, "Wrong Pointer type, should be id from mouse event");
303 is(e.pointerType, "mouse", "Wrong Pointer type, should be mouse type");
304 }
305 pointerLeaveTriggeredForCancelEvent = 1;
306 }
308 sendTouchEvent(cwu, "touchcancel", getTouchEventForTarget(d1, cwu, 3), 0);
309 is(pointerOutTriggeredForCancelEvent, 1, "Pointer Out not dispatched on PointerCancel");
310 is(pointerLeaveTriggeredForCancelEvent, 1, "Pointer Leave not dispatched on PointerCancel");
312 finishTest();
313 }
315 function finishTest() {
316 // Let window.onerror have a chance to fire
317 setTimeout(function() {
318 setTimeout(function() {
319 window.parent.postMessage("SimpleTest.finish();", "*");
320 }, 0);
321 }, 0);
322 }
324 window.onload = function () {
325 SpecialPowers.pushPrefEnv({
326 "set": [
327 ["dom.w3c_pointer_events.enabled", true],
328 ]
329 }, runTests);
330 }
332 SimpleTest.waitForExplicitFinish();
334 </script>
335 </pre>
336 <div id="d0">
337 Test divs --
338 <div id="d1">t</div><div id="d2">t</div><div id="d3">t</div>
339 --
340 </div>
341 </body>
342 </html>