test_multiple_touches.html (6191B)
1 <!DOCTYPE HTML> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <title>Test for Multiple Touches</title> 6 <script src="/tests/SimpleTest/SimpleTest.js"></script> 7 <script src="/tests/SimpleTest/EventUtils.js"></script> 8 <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> 9 </head> 10 <body> 11 <p id="display"></p> 12 <div id="target0" style="width: 100px; height: 100px; background: green"></div> 13 <div id="target1" style="width: 100px; height: 100px; background: red"></div> 14 <script type="text/javascript"> 15 // TODO: We should probably make EventUtils.js to support multiple touch. 16 // Currently the use case is simple, so we just add support here. 17 // Once we have more use cases, we could come out a more generic way to 18 // support it. 19 var touches = { 20 ids: [], 21 lefts: [], 22 tops: [], 23 rxs: [], 24 rys: [], 25 angles: [], 26 forces: [], 27 tiltXs: [], 28 tiltYs: [], 29 twists: [], 30 }; 31 32 function synthesizeTouchEvent(aType, aTouches) { 33 var utils = _getDOMWindowUtils(window); 34 if (!utils) { 35 ok(false, "unable to get nsIDOMWindowUtils"); 36 return; 37 } 38 39 utils.sendTouchEvent(aType, aTouches.ids, aTouches.lefts, aTouches.tops, 40 aTouches.rxs, aTouches.rys, aTouches.angles, 41 aTouches.forces, aTouches.tiltXs, aTouches.tiltYs, 42 aTouches.twists, 0 /* modifiers */); 43 } 44 45 function synthesizeTouchStart(aTarget, aId, aOffsetX, aOffsetY) { 46 if (touches.ids.some((aElem) => { return aElem === aId; })) { 47 ok(false, `touch with id=${aTouch.id} is already registered`); 48 return; 49 } 50 51 let rect = aTarget.getBoundingClientRect(); 52 touches.ids.push(aId); 53 touches.lefts.push(rect.left + aOffsetX); 54 touches.tops.push(rect.top + aOffsetY); 55 touches.rxs.push(1); 56 touches.rys.push(1); 57 touches.angles.push(0); 58 touches.forces.push(1); 59 touches.tiltXs.push(0); 60 touches.tiltYs.push(0); 61 touches.twists.push(0); 62 63 synthesizeTouchEvent("touchstart", touches); 64 } 65 66 function synthesizeTouchEnd(aTarget, aId, aOffsetX, aOffsetY) { 67 let index = touches.ids.indexOf(aId); 68 if (-1 === index) { 69 ok(false, `touch with id=${aTouch.id} isn't registered`); 70 return; 71 } 72 73 var removedTouches = { 74 ids: touches.ids.splice(index, 1), 75 lefts: touches.lefts.splice(index, 1), 76 tops: touches.tops.splice(index, 1), 77 rxs: touches.rxs.splice(index, 1), 78 rys: touches.rys.splice(index, 1), 79 angles: touches.angles.splice(index, 1), 80 forces: touches.forces.splice(index, 1), 81 tiltXs: touches.tiltXs.splice(index, 1), 82 tiltYs: touches.tiltYs.splice(index, 1), 83 twists: touches.twists.splice(index, 1), 84 }; 85 86 synthesizeTouchEvent("touchend", removedTouches); 87 } 88 89 function synthesizeTouchMove(aTarget, aId, aOffsetX, aOffsetY) { 90 let index = touches.ids.indexOf(aId); 91 if (-1 === index) { 92 ok(false, `touch with id=${aTouch.id} isn't registered`); 93 return; 94 } 95 96 let rect = aTarget.getBoundingClientRect(); 97 touches.lefts[index] = rect.left + aOffsetX; 98 touches.tops[index] = rect.top + aOffsetY; 99 100 synthesizeTouchEvent("touchmove", touches); 101 } 102 103 var target0 = document.getElementById("target0"); 104 var target1 = document.getElementById("target1"); 105 106 function WaitExpectedEvents(aListenEvents, aExpectedEvents, aEventGenerator) { 107 let promise = new Promise(function(aResolve) { 108 let index = 0; 109 let checkReceivedEvents = function(aEvent) { 110 if (aExpectedEvents.length === 0) { 111 ok(false, `receive unexpected ${aEvent.type} event from ${aEvent.target}`); 112 return; 113 } 114 index++; 115 let expectedResult = aExpectedEvents.shift(); 116 isDeeply(expectedResult, [aEvent.target, aEvent.type], `${index}. expect receive ${expectedResult[1]} event from ${expectedResult[0]}`); 117 if (aExpectedEvents.length === 0) { 118 // Wait a bit to see if there is any additional unexpected event fired. 119 setTimeout(function() { 120 // Clean up 121 aListenEvents.forEach((aElem) => { 122 target0.removeEventListener(aElem, checkReceivedEvents); 123 target1.removeEventListener(aElem, checkReceivedEvents); 124 }); 125 aResolve(); 126 }, 0); 127 } 128 }; 129 130 aListenEvents.forEach((aElem) => { 131 target0.addEventListener(aElem, checkReceivedEvents); 132 target1.addEventListener(aElem, checkReceivedEvents); 133 }); 134 }); 135 136 aEventGenerator(); 137 138 return promise; 139 } 140 141 // eslint-disable-next-line mozilla/no-addtask-setup 142 add_task(async function setup() { 143 await SimpleTest.promiseFocus(); 144 await SpecialPowers.pushPrefEnv({ 145 set: [["dom.w3c_pointer_events.implicit_capture", false]] 146 }); 147 }); 148 149 // Test for bug 1521082 150 add_task(async function ShouldNotSendDuplicatedPointerDown() { 151 return WaitExpectedEvents( 152 ["pointerup", "pointerdown"], 153 [ // [event target, event type] 154 [target0, "pointerdown"], 155 [target1, "pointerdown"], 156 [target1, "pointerup"], 157 [target0, "pointerup"], 158 ], 159 function() { 160 var defaultId = SpecialPowers.Ci.nsIDOMWindowUtils.DEFAULT_TOUCH_POINTER_ID; 161 synthesizeTouchStart(target0, defaultId, 10, 10); 162 synthesizeTouchStart(target1, defaultId + 1, 10, 10); 163 synthesizeTouchEnd(target1, defaultId + 1, 10, 10); 164 synthesizeTouchEnd(target0, defaultId, 10, 10); 165 } 166 ); 167 }); 168 169 // Test for bug 1323400 170 add_task(async function ShouldNotSendDuplicatedPointerMove() { 171 return WaitExpectedEvents( 172 ["pointerup", "pointerdown","pointermove"], 173 [ // [event target, event type] 174 [target0, "pointerdown"], 175 [target1, "pointerdown"], 176 [target1, "pointermove"], 177 // Should receive only one pointer event for target 1. 178 [target1, "pointermove"], 179 [target1, "pointerup"], 180 [target0, "pointerup"], 181 ], 182 function() { 183 var defaultId = SpecialPowers.Ci.nsIDOMWindowUtils.DEFAULT_TOUCH_POINTER_ID; 184 synthesizeTouchStart(target0, defaultId, 10, 10); 185 synthesizeTouchStart(target1, defaultId + 1, 10, 10); 186 synthesizeTouchMove(target1, defaultId + 1, 11, 11); 187 synthesizeTouchMove(target1, defaultId + 1, 12, 12); 188 synthesizeTouchEnd(target1, defaultId + 1, 10, 10); 189 synthesizeTouchEnd(target0, defaultId, 10, 10); 190 } 191 ); 192 }); 193 194 </script> 195 </body> 196 </html>