Source code

Revision control

Copy as Markdown

Other Tools

Test Info: Errors

<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Test for Multiple Touches</title>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<script src="/tests/SimpleTest/EventUtils.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<p id="display"></p>
<div id="target0" style="width: 100px; height: 100px; background: green"></div>
<div id="target1" style="width: 100px; height: 100px; background: red"></div>
<script type="text/javascript">
// TODO: We should probably make EventUtils.js to support multiple touch.
// Currently the use case is simple, so we just add support here.
// Once we have more use cases, we could come out a more generic way to
// support it.
var touches = {
ids: [],
lefts: [],
tops: [],
rxs: [],
rys: [],
angles: [],
forces: [],
tiltXs: [],
tiltYs: [],
twists: [],
};
function synthesizeTouchEvent(aType, aTouches) {
var utils = _getDOMWindowUtils(window);
if (!utils) {
ok(false, "unable to get nsIDOMWindowUtils");
return;
}
utils.sendTouchEvent(aType, aTouches.ids, aTouches.lefts, aTouches.tops,
aTouches.rxs, aTouches.rys, aTouches.angles,
aTouches.forces, aTouches.tiltXs, aTouches.tiltYs,
aTouches.twists, 0 /* modifiers */);
}
function synthesizeTouchStart(aTarget, aId, aOffsetX, aOffsetY) {
if (touches.ids.some((aElem) => { return aElem === aId; })) {
ok(false, `touch with id=${aTouch.id} is already registered`);
return;
}
let rect = aTarget.getBoundingClientRect();
touches.ids.push(aId);
touches.lefts.push(rect.left + aOffsetX);
touches.tops.push(rect.top + aOffsetY);
touches.rxs.push(1);
touches.rys.push(1);
touches.angles.push(0);
touches.forces.push(1);
touches.tiltXs.push(0);
touches.tiltYs.push(0);
touches.twists.push(0);
synthesizeTouchEvent("touchstart", touches);
}
function synthesizeTouchEnd(aTarget, aId, aOffsetX, aOffsetY) {
let index = touches.ids.indexOf(aId);
if (-1 === index) {
ok(false, `touch with id=${aTouch.id} isn't registered`);
return;
}
var removedTouches = {
ids: touches.ids.splice(index, 1),
lefts: touches.lefts.splice(index, 1),
tops: touches.tops.splice(index, 1),
rxs: touches.rxs.splice(index, 1),
rys: touches.rys.splice(index, 1),
angles: touches.angles.splice(index, 1),
forces: touches.forces.splice(index, 1),
tiltXs: touches.tiltXs.splice(index, 1),
tiltYs: touches.tiltYs.splice(index, 1),
twists: touches.twists.splice(index, 1),
};
synthesizeTouchEvent("touchend", removedTouches);
}
function synthesizeTouchMove(aTarget, aId, aOffsetX, aOffsetY) {
let index = touches.ids.indexOf(aId);
if (-1 === index) {
ok(false, `touch with id=${aTouch.id} isn't registered`);
return;
}
let rect = aTarget.getBoundingClientRect();
touches.lefts[index] = rect.left + aOffsetX;
touches.tops[index] = rect.top + aOffsetY;
synthesizeTouchEvent("touchmove", touches);
}
var target0 = document.getElementById("target0");
var target1 = document.getElementById("target1");
function WaitExpectedEvents(aListenEvents, aExpectedEvents, aEventGenerator) {
let promise = new Promise(function(aResolve) {
let index = 0;
let checkReceivedEvents = function(aEvent) {
if (aExpectedEvents.length === 0) {
ok(false, `receive unexpected ${aEvent.type} event from ${aEvent.target}`);
return;
}
index++;
let expectedResult = aExpectedEvents.shift();
isDeeply(expectedResult, [aEvent.target, aEvent.type], `${index}. expect receive ${expectedResult[1]} event from ${expectedResult[0]}`);
if (aExpectedEvents.length === 0) {
// Wait a bit to see if there is any additional unexpected event fired.
setTimeout(function() {
// Clean up
aListenEvents.forEach((aElem) => {
target0.removeEventListener(aElem, checkReceivedEvents);
target1.removeEventListener(aElem, checkReceivedEvents);
});
aResolve();
}, 0);
}
};
aListenEvents.forEach((aElem) => {
target0.addEventListener(aElem, checkReceivedEvents);
target1.addEventListener(aElem, checkReceivedEvents);
});
});
aEventGenerator();
return promise;
}
// eslint-disable-next-line mozilla/no-addtask-setup
add_task(async function setup() {
await SimpleTest.promiseFocus();
await SpecialPowers.pushPrefEnv({
set: [["dom.w3c_pointer_events.implicit_capture", false]]
});
});
// Test for bug 1521082
add_task(async function ShouldNotSendDuplicatedPointerDown() {
return WaitExpectedEvents(
["pointerup", "pointerdown"],
[ // [event target, event type]
[target0, "pointerdown"],
[target1, "pointerdown"],
[target1, "pointerup"],
[target0, "pointerup"],
],
function() {
var defaultId = SpecialPowers.Ci.nsIDOMWindowUtils.DEFAULT_TOUCH_POINTER_ID;
synthesizeTouchStart(target0, defaultId, 10, 10);
synthesizeTouchStart(target1, defaultId + 1, 10, 10);
synthesizeTouchEnd(target1, defaultId + 1, 10, 10);
synthesizeTouchEnd(target0, defaultId, 10, 10);
}
);
});
// Test for bug 1323400
add_task(async function ShouldNotSendDuplicatedPointerMove() {
return WaitExpectedEvents(
["pointerup", "pointerdown","pointermove"],
[ // [event target, event type]
[target0, "pointerdown"],
[target1, "pointerdown"],
[target1, "pointermove"],
// Should receive only one pointer event for target 1.
[target1, "pointermove"],
[target1, "pointerup"],
[target0, "pointerup"],
],
function() {
var defaultId = SpecialPowers.Ci.nsIDOMWindowUtils.DEFAULT_TOUCH_POINTER_ID;
synthesizeTouchStart(target0, defaultId, 10, 10);
synthesizeTouchStart(target1, defaultId + 1, 10, 10);
synthesizeTouchMove(target1, defaultId + 1, 11, 11);
synthesizeTouchMove(target1, defaultId + 1, 12, 12);
synthesizeTouchEnd(target1, defaultId + 1, 10, 10);
synthesizeTouchEnd(target0, defaultId, 10, 10);
}
);
});
</script>
</body>
</html>