summaryrefslogtreecommitdiffstats
path: root/dom/events/test/test_bug603008.html
diff options
context:
space:
mode:
Diffstat (limited to 'dom/events/test/test_bug603008.html')
-rw-r--r--dom/events/test/test_bug603008.html559
1 files changed, 559 insertions, 0 deletions
diff --git a/dom/events/test/test_bug603008.html b/dom/events/test/test_bug603008.html
new file mode 100644
index 0000000000..ccba289a51
--- /dev/null
+++ b/dom/events/test/test_bug603008.html
@@ -0,0 +1,559 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=508906
+-->
+<head>
+ <title>Test for Bug 603008</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=508906">Mozilla Bug 603008</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script class="testbody" type="application/javascript">
+
+/** Test for Bug 306008 - Touch* Events **/
+
+let tests = [], testTarget, parent;
+
+let touch = {
+ id: 0,
+ point: {x: 0, y: 0},
+ radius: {x: 0, y: 0},
+ rotation: 0,
+ force: 0.5,
+ target: null
+}
+
+function nextTest() {
+ if (tests.length)
+ SimpleTest.executeSoon(tests.shift());
+}
+
+function random() {
+ return Math.floor(Math.random() * 100);
+}
+
+function checkEvent(aFakeEvent) {
+ return function(aEvent) {
+ is(aFakeEvent.ctrlKey, aEvent.ctrlKey, "Correct ctrlKey");
+ is(aFakeEvent.altKey, aEvent.altKey, "Correct altKey");
+ is(aFakeEvent.shiftKey, aEvent.shiftKey, "Correct shiftKey");
+ is(aFakeEvent.metaKey, aEvent.metaKey, "Correct metaKey");
+ checkTouches(aFakeEvent.touches, aEvent.touches);
+ checkTouches(aFakeEvent.targetTouches, aEvent.targetTouches);
+ checkTouches(aFakeEvent.changedTouches, aEvent.changedTouches);
+ }
+}
+
+function checkTouches(aTouches1, aTouches2) {
+ is(aTouches1.length, aTouches2.length, "Correct touches length");
+ for (var i = 0; i < aTouches1.length; i++) {
+ checkTouch(aTouches1[i], aTouches2[i]);
+ }
+}
+
+function checkTouch(aFakeTouch, aTouch) {
+ is(aFakeTouch.identifier, aTouch.identifier, "Touch has correct identifier");
+ is(aFakeTouch.target, aTouch.target, "Touch has correct target");
+ is(aFakeTouch.page.x, aTouch.pageX, "Touch has correct pageX");
+ is(aFakeTouch.page.y, aTouch.pageY, "Touch has correct pageY");
+ is(aFakeTouch.page.x + Math.round(window.mozInnerScreenX), aTouch.screenX, "Touch has correct screenX");
+ is(aFakeTouch.page.y + Math.round(window.mozInnerScreenY), aTouch.screenY, "Touch has correct screenY");
+ is(aFakeTouch.page.x, aTouch.clientX, "Touch has correct clientX");
+ is(aFakeTouch.page.y, aTouch.clientY, "Touch has correct clientY");
+ is(aFakeTouch.radius.x, aTouch.radiusX, "Touch has correct radiusX");
+ is(aFakeTouch.radius.y, aTouch.radiusY, "Touch has correct radiusY");
+ is(aFakeTouch.rotationAngle, aTouch.rotationAngle, "Touch has correct rotationAngle");
+ is(aFakeTouch.force, aTouch.force, "Touch has correct force");
+}
+
+function sendTouchEvent(windowUtils, aType, aEvent, aModifiers) {
+ var ids = [], xs=[], ys=[], rxs = [], rys = [],
+ rotations = [], forces = [], tiltXs = [], tiltYs = [], twists = [];
+
+ for (var touchType of ["touches", "changedTouches", "targetTouches"]) {
+ for (var i = 0; i < aEvent[touchType].length; i++) {
+ if (!ids.includes(aEvent[touchType][i].identifier)) {
+ ids.push(aEvent[touchType][i].identifier);
+ xs.push(aEvent[touchType][i].page.x);
+ ys.push(aEvent[touchType][i].page.y);
+ rxs.push(aEvent[touchType][i].radius.x);
+ rys.push(aEvent[touchType][i].radius.y);
+ rotations.push(aEvent[touchType][i].rotationAngle);
+ forces.push(aEvent[touchType][i].force);
+ tiltXs.push(0);
+ tiltYs.push(0);
+ twists.push(0);
+ }
+ }
+ }
+ return windowUtils.sendTouchEvent(aType,
+ ids, xs, ys, rxs, rys,
+ rotations, forces, tiltXs, tiltYs, twists,
+ aModifiers, 0);
+}
+
+function touchEvent(aOptions) {
+ if (!aOptions) {
+ aOptions = {};
+ }
+ this.ctrlKey = aOptions.ctrlKey || false;
+ this.altKey = aOptions.altKey || false;
+ this.shiftKey = aOptions.shiftKey || false;
+ this.metaKey = aOptions.metaKey || false;
+ this.touches = aOptions.touches || [];
+ this.targetTouches = aOptions.targetTouches || [];
+ this.changedTouches = aOptions.changedTouches || [];
+}
+
+function testtouch(aOptions) {
+ if (!aOptions)
+ aOptions = {};
+ this.identifier = aOptions.identifier || 0;
+ this.target = aOptions.target || 0;
+ this.page = aOptions.page || {x: 0, y: 0};
+ this.radius = aOptions.radius || {x: 0, y: 0};
+ this.rotationAngle = aOptions.rotationAngle || 0;
+ this.force = aOptions.force || 1;
+}
+
+function testSingleTouch(name) {
+ let cwu = SpecialPowers.getDOMWindowUtils(window);
+ let target = document.getElementById("testTarget");
+ let target2 = document.getElementById("testTarget2");
+ let bcr = target.getBoundingClientRect();
+ let bcr2 = target2.getBoundingClientRect();
+
+ let touch1 = new testtouch({
+ page: {x: Math.round(bcr.left + bcr.width/2),
+ y: Math.round(bcr.top + bcr.height/2)},
+ target
+ });
+ let event = new touchEvent({
+ touches: [touch1],
+ targetTouches: [touch1],
+ changedTouches: [touch1]
+ });
+
+ // test touchstart event fires correctly
+ var checkFunction = checkEvent(event);
+ window.addEventListener("touchstart", checkFunction);
+ sendTouchEvent(cwu, "touchstart", event, 0);
+ window.removeEventListener("touchstart", checkFunction);
+
+ // test touchmove event fires correctly
+ event.touches[0].page.x -= 1;
+ event.targetTouches[0].page.x -= 1;
+ event.changedTouches[0].page.x -= 1;
+ checkFunction = checkEvent(event);
+ window.addEventListener("touchmove", checkFunction);
+ sendTouchEvent(cwu, "touchmove", event, 0);
+ window.removeEventListener("touchmove", checkFunction);
+
+ // test touchend event fires correctly
+ event.touches = [];
+ event.targetTouches = [];
+ checkFunction = checkEvent(event);
+ window.addEventListener("touchend", checkFunction);
+ sendTouchEvent(cwu, "touchend", event, 0);
+ window.removeEventListener("touchend", checkFunction);
+
+ nextTest();
+}
+
+function testSingleTouch2(name) {
+ // firing a touchstart that includes only one touch will evict any touches in the queue with touchend messages
+ let cwu = SpecialPowers.getDOMWindowUtils(window);
+ let target = document.getElementById("testTarget");
+ let target2 = document.getElementById("testTarget2");
+ let bcr = target.getBoundingClientRect();
+ let bcr2 = target2.getBoundingClientRect();
+
+ let touch1 = new testtouch({
+ identifier: 0,
+ page: {x: Math.round(bcr.left + bcr.width/2),
+ y: Math.round(bcr.top + bcr.height/2)},
+ target
+ });
+ let event1 = new touchEvent({
+ touches: [touch1],
+ targetTouches: [touch1],
+ changedTouches: [touch1]
+ });
+ let touch2 = new testtouch({
+ identifier: 1,
+ page: {x: Math.round(bcr2.left + bcr2.width/2),
+ y: Math.round(bcr2.top + bcr2.height/2)},
+ target: target2
+ });
+ let event2 = new touchEvent({
+ touches: [touch2],
+ targetTouches: [touch2],
+ changedTouches: [touch2]
+ });
+
+ // test touchstart event fires correctly
+ var checkFunction1 = checkEvent(event1);
+ window.addEventListener("touchstart", checkFunction1);
+ sendTouchEvent(cwu, "touchstart", event1, 0);
+ window.removeEventListener("touchstart", checkFunction1);
+
+ event1.touches = [];
+ event1.targetTouches = [];
+ checkFunction1 = checkEvent(event1);
+ var checkFunction2 = checkEvent(event2);
+
+ window.addEventListener("touchend", checkFunction1);
+ window.addEventListener("touchstart", checkFunction2);
+ sendTouchEvent(cwu, "touchstart", event2, 0);
+ window.removeEventListener("touchend", checkFunction1);
+ window.removeEventListener("touchstart", checkFunction2);
+
+ sendTouchEvent(cwu, "touchstart", event1, 0);
+
+ nextTest();
+}
+
+
+function testMultiTouch(name) {
+ let cwu = SpecialPowers.getDOMWindowUtils(window);
+ let target1 = document.getElementById("testTarget");
+ let target2 = document.getElementById("testTarget2");
+ let bcr = target1.getBoundingClientRect();
+ let bcr2 = target2.getBoundingClientRect();
+
+ let touch1 = new testtouch({
+ identifier: 0,
+ page: {x: Math.round(bcr.left + bcr.width/2),
+ y: Math.round(bcr.top + bcr.height/2)},
+ target: target1
+ });
+ let touch2 = new testtouch({
+ identifier: 1,
+ page: {x: Math.round(bcr2.left + bcr2.width/2),
+ y: Math.round(bcr2.top + bcr2.height/2)},
+ target: target2
+ });
+ let event = new touchEvent({
+ touches: [touch1],
+ targetTouches: [touch1],
+ changedTouches: [touch1]
+ });
+
+ // test touchstart event fires correctly
+ var checkFunction = checkEvent(event);
+ window.addEventListener("touchstart", checkFunction);
+ sendTouchEvent(cwu, "touchstart", event, 0);
+ window.removeEventListener("touchstart", checkFunction);
+
+ event.touches.push(touch2);
+ event.targetTouches = [touch2];
+ event.changedTouches = [touch2];
+ window.addEventListener("touchstart", checkFunction);
+ sendTouchEvent(cwu, "touchstart", event, 0);
+ window.removeEventListener("touchstart", checkFunction);
+
+ // test moving one touch point
+ event.touches[0].page.x -= 1;
+ event.targetTouches = [event.touches[0]];
+ event.changedTouches = [event.touches[0]];
+ window.addEventListener("touchmove", checkFunction);
+ sendTouchEvent(cwu, "touchmove", event, 0);
+ window.removeEventListener("touchmove", checkFunction);
+
+ // test moving both touch points -- two touchmove events should fire, one on each target
+ event.touches[0].page.x -= 1;
+ event.touches[1].page.x -= 1;
+ event.targetTouches = event.touches;
+ event.changedTouches = event.touches;
+ var touchMoveEvents = 0;
+ var checkFunction2 = function(aEvent) {
+ is(event.ctrlKey, aEvent.ctrlKey, "Correct ctrlKey");
+ is(event.altKey, aEvent.altKey, "Correct altKey");
+ is(event.shiftKey, aEvent.shiftKey, "Correct shiftKey");
+ is(event.metaKey, aEvent.metaKey, "Correct metaKey");
+ checkTouches(event.touches, aEvent.touches);
+ checkTouches(event.changedTouches, aEvent.changedTouches);
+ if (aEvent.targetTouches[0].target == target1) {
+ checkTouches([event.touches[0]], aEvent.targetTouches);
+ } else if (aEvent.targetTouches[0].target == target2) {
+ checkTouches([event.touches[1]], aEvent.targetTouches);
+ } else
+ ok(false, "Event target is incorrect: " + event.targetTouches[0].target.nodeName + "#" + event.targetTouches[0].target.id);
+ touchMoveEvents++;
+ };
+ window.addEventListener("touchmove", checkFunction2);
+ sendTouchEvent(cwu, "touchmove", event, 0);
+ is(touchMoveEvents, 2, "Correct number of touchmove events fired");
+ window.removeEventListener("touchmove", checkFunction2);
+
+ // test removing just one finger
+ var expected = new touchEvent({
+ touches: [touch2],
+ targetTouches: [],
+ changedTouches: [touch1]
+ });
+ checkFunction = checkEvent(expected);
+
+ event.touches = [];
+ event.targetTouches = [];
+ event.changedTouches = [touch1];
+
+ // test removing the other finger
+ window.addEventListener("touchend", checkFunction);
+ sendTouchEvent(cwu, "touchend", event, 0);
+ window.removeEventListener("touchend", checkFunction);
+
+ event.touches = [];
+ event.targetTouches = [];
+ event.changedTouches = [touch2];
+ checkFunction = checkEvent(event);
+ window.addEventListener("touchend", checkFunction);
+ sendTouchEvent(cwu, "touchend", event, 0);
+ window.removeEventListener("touchend", checkFunction);
+
+ nextTest();
+}
+
+function testTouchChanged() {
+ let cwu = SpecialPowers.getDOMWindowUtils(window);
+ let target1 = document.getElementById("testTarget");
+ let bcr = target1.getBoundingClientRect();
+
+ let touch1 = new testtouch({
+ identifier: 0,
+ page: {x: Math.round(bcr.left + bcr.width/2),
+ y: Math.round(bcr.top + bcr.height/2)},
+ target: target1
+ });
+ let event = new touchEvent({
+ touches: [touch1],
+ targetTouches: [touch1],
+ changedTouches: [touch1]
+ });
+
+ var checkFunction = checkEvent(event);
+ sendTouchEvent(cwu, "touchstart", event, 0);
+
+ var moveEvents = 0;
+ function onMove(aEvent) {
+ moveEvents++;
+ }
+
+ window.addEventListener("touchmove", onMove);
+
+ // the first touchmove should always fire an event
+ sendTouchEvent(cwu, "touchmove", event, 0);
+
+ // changing nothing should not fire a touchmove event
+ sendTouchEvent(cwu, "touchmove", event, 0);
+
+ // test moving x
+ event.touches[0].page.x -= 1;
+ sendTouchEvent(cwu, "touchmove", event, 0);
+
+ // test moving y
+ event.touches[0].page.y -= 1;
+ sendTouchEvent(cwu, "touchmove", event, 0);
+
+ // test changing y radius
+ event.touches[0].radius.y += 1;
+ sendTouchEvent(cwu, "touchmove", event, 0);
+
+ // test changing x radius
+ event.touches[0].radius.x += 1;
+ sendTouchEvent(cwu, "touchmove", event, 0);
+
+ // test changing rotationAngle
+ event.touches[0].rotationAngle += 1;
+ sendTouchEvent(cwu, "touchmove", event, 0);
+
+ // test changing force
+ event.touches[0].force += 1;
+ sendTouchEvent(cwu, "touchmove", event, 0);
+
+ // changing nothing again
+ sendTouchEvent(cwu, "touchmove", event, 0);
+
+ is(moveEvents, 7, "Six move events fired");
+
+ window.removeEventListener("touchmove", onMove);
+ sendTouchEvent(cwu, "touchend", event, 0);
+ nextTest();
+}
+
+function testPreventDefault() {
+ let cwu = SpecialPowers.getDOMWindowUtils(window);
+ let target = document.getElementById("testTarget");
+ let target2 = document.getElementById("testTarget2");
+ let bcr = target.getBoundingClientRect();
+ let bcr2 = target2.getBoundingClientRect();
+
+ let touch1 = new testtouch({
+ page: {x: bcr.left + bcr.width/2,
+ y: bcr.top + bcr.height/2},
+ target
+ });
+ let event = new touchEvent({
+ touches: [touch1],
+ targetTouches: [touch1],
+ changedTouches: [touch1]
+ });
+
+ let preventFunction = function(aEvent) {
+ aEvent.preventDefault();
+ }
+
+ let subTests = [
+ [{ name: "touchstart", prevent: false },
+ { name: "touchmove", prevent: false },
+ { name: "touchmove", prevent: false },
+ { name: "touchend", prevent: false }],
+ [{ name: "touchstart", prevent: true, doPrevent: true },
+ { name: "touchmove", prevent: false },
+ { name: "touchmove", prevent: false },
+ { name: "touchend", prevent: false }],
+ [{ name: "touchstart", prevent: false },
+ { name: "touchmove", prevent: true, doPrevent: true },
+ { name: "touchmove", prevent: false },
+ { name: "touchend", prevent: false }],
+ [{ name: "touchstart", prevent: false },
+ { name: "touchmove", prevent: false },
+ { name: "touchmove", prevent: false, doPrevent: true },
+ { name: "touchend", prevent: false }],
+ [{ name: "touchstart", prevent: false },
+ { name: "touchmove", prevent: false },
+ { name: "touchmove", prevent: false },
+ { name: "touchend", prevent: true, doPrevent: true }]
+ ];
+
+ var dotest = function(aTest) {
+ if (aTest.doPrevent) {
+ target.addEventListener(aTest.name, preventFunction);
+ }
+
+ if (aTest.name == "touchmove") {
+ touch1.page.x++;
+ event.touches[0] = touch1;
+ }
+
+ is(sendTouchEvent(cwu, aTest.name, event, 0), aTest.prevent, "Got correct status");
+
+ if (aTest.doPrevent)
+ target.removeEventListener(aTest.name, preventFunction);
+ }
+
+ for (var i = 0; i < subTests.length; i++) {
+ for (var j = 0; j < subTests[i].length; j++) {
+ dotest(subTests[i][j]);
+ }
+ }
+
+ nextTest();
+}
+
+function testRemovingElement() {
+ let cwu = SpecialPowers.getDOMWindowUtils(window);
+ let target = document.getElementById("testTarget");
+ let bcr = document.getElementById("testTarget").getBoundingClientRect();
+
+ let touch1 = new testtouch({
+ page: {x: bcr.left + bcr.width/2,
+ y: bcr.top + bcr.height/2},
+ });
+ let e = new touchEvent({
+ touches: [touch1],
+ targetTouches: [touch1],
+ changedTouches: [touch1]
+ });
+
+ var touchEvents = 0;
+ var removeTarget = function(aEvent) {
+ aEvent.target.remove();
+ };
+
+ var checkTarget = function(aEvent) {
+ is(aEvent.target, target, "Event has correct target");
+ touchEvents++;
+ };
+
+ target.addEventListener("touchstart", removeTarget);
+ target.addEventListener("touchmove", checkTarget);
+ target.addEventListener("touchend", checkTarget);
+
+ sendTouchEvent(cwu, "touchstart", e, 0);
+
+ e.touches[0].page.x++;
+ sendTouchEvent(cwu, "touchmove", e, 0);
+ sendTouchEvent(cwu, "touchend", e, 0);
+
+ target.removeEventListener("touchstart", removeTarget);
+ target.removeEventListener("touchmove", checkTarget);
+ target.removeEventListener("touchend", checkTarget);
+
+ is(touchEvents, 2, "Check target was called twice");
+
+ nextTest();
+}
+
+function testNAC() {
+ let cwu = SpecialPowers.getDOMWindowUtils(window);
+ let target = document.getElementById("testTarget3");
+ let bcr = target.getBoundingClientRect();
+
+ let touch1 = new testtouch({
+ page: {x: Math.round(bcr.left + bcr.width/2),
+ y: Math.round(bcr.top + bcr.height/2)},
+ target
+ });
+ let event = new touchEvent({
+ touches: [touch1],
+ targetTouches: [touch1],
+ changedTouches: [touch1]
+ });
+
+ // test touchstart event fires correctly
+ var checkFunction = checkEvent(event);
+ window.addEventListener("touchstart", checkFunction);
+ sendTouchEvent(cwu, "touchstart", event, 0);
+ window.removeEventListener("touchstart", checkFunction);
+
+ sendTouchEvent(cwu, "touchend", event, 0);
+
+ nextTest();
+}
+
+function doTest() {
+ tests.push(testSingleTouch);
+ tests.push(testSingleTouch2);
+ tests.push(testMultiTouch);
+ tests.push(testPreventDefault);
+ tests.push(testTouchChanged);
+ tests.push(testRemovingElement);
+ tests.push(testNAC);
+
+ tests.push(function() {
+ SimpleTest.finish();
+ });
+
+ nextTest();
+}
+
+SimpleTest.waitForExplicitFinish();
+addLoadEvent(doTest);
+
+</script>
+</pre>
+<div id="parent">
+ <span id="testTarget" style="padding: 5px; border: 1px solid black;">testTarget</span>
+ <span id="testTarget2" style="padding: 5px; border: 1px solid blue;">testTarget</span>
+ <input type="text" id="testTarget3">
+</div>
+</body>
+</html>