diff options
Diffstat (limited to 'dom/events/test/test_bug603008.html')
-rw-r--r-- | dom/events/test/test_bug603008.html | 559 |
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> |