1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/browser/base/content/test/general/browser_gestureSupport.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,671 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 + 1.8 +// Simple gestures tests 1.9 +// 1.10 +// These tests require the ability to disable the fact that the 1.11 +// Firefox chrome intentionally prevents "simple gesture" events from 1.12 +// reaching web content. 1.13 + 1.14 +let test_utils; 1.15 +let test_commandset; 1.16 +let test_prefBranch = "browser.gesture."; 1.17 + 1.18 +function test() 1.19 +{ 1.20 + waitForExplicitFinish(); 1.21 + 1.22 + // Disable the default gestures support during the test 1.23 + gGestureSupport.init(false); 1.24 + 1.25 + test_utils = window.QueryInterface(Components.interfaces.nsIInterfaceRequestor). 1.26 + getInterface(Components.interfaces.nsIDOMWindowUtils); 1.27 + 1.28 + // Run the tests of "simple gesture" events generally 1.29 + test_EnsureConstantsAreDisjoint(); 1.30 + test_TestEventListeners(); 1.31 + test_TestEventCreation(); 1.32 + 1.33 + // Reenable the default gestures support. The remaining tests target 1.34 + // the Firefox gesture functionality. 1.35 + gGestureSupport.init(true); 1.36 + 1.37 + // Test Firefox's gestures support. 1.38 + test_commandset = document.getElementById("mainCommandSet"); 1.39 + test_swipeGestures(); 1.40 + test_latchedGesture("pinch", "out", "in", "MozMagnifyGesture"); 1.41 + test_thresholdGesture("pinch", "out", "in", "MozMagnifyGesture"); 1.42 + test_rotateGestures(); 1.43 +} 1.44 + 1.45 +let test_eventCount = 0; 1.46 +let test_expectedType; 1.47 +let test_expectedDirection; 1.48 +let test_expectedDelta; 1.49 +let test_expectedModifiers; 1.50 +let test_expectedClickCount; 1.51 +let test_imageTab; 1.52 + 1.53 +function test_gestureListener(evt) 1.54 +{ 1.55 + is(evt.type, test_expectedType, 1.56 + "evt.type (" + evt.type + ") does not match expected value"); 1.57 + is(evt.target, test_utils.elementFromPoint(20, 20, false, false), 1.58 + "evt.target (" + evt.target + ") does not match expected value"); 1.59 + is(evt.clientX, 20, 1.60 + "evt.clientX (" + evt.clientX + ") does not match expected value"); 1.61 + is(evt.clientY, 20, 1.62 + "evt.clientY (" + evt.clientY + ") does not match expected value"); 1.63 + isnot(evt.screenX, 0, 1.64 + "evt.screenX (" + evt.screenX + ") does not match expected value"); 1.65 + isnot(evt.screenY, 0, 1.66 + "evt.screenY (" + evt.screenY + ") does not match expected value"); 1.67 + 1.68 + is(evt.direction, test_expectedDirection, 1.69 + "evt.direction (" + evt.direction + ") does not match expected value"); 1.70 + is(evt.delta, test_expectedDelta, 1.71 + "evt.delta (" + evt.delta + ") does not match expected value"); 1.72 + 1.73 + is(evt.shiftKey, (test_expectedModifiers & Components.interfaces.nsIDOMEvent.SHIFT_MASK) != 0, 1.74 + "evt.shiftKey did not match expected value"); 1.75 + is(evt.ctrlKey, (test_expectedModifiers & Components.interfaces.nsIDOMEvent.CONTROL_MASK) != 0, 1.76 + "evt.ctrlKey did not match expected value"); 1.77 + is(evt.altKey, (test_expectedModifiers & Components.interfaces.nsIDOMEvent.ALT_MASK) != 0, 1.78 + "evt.altKey did not match expected value"); 1.79 + is(evt.metaKey, (test_expectedModifiers & Components.interfaces.nsIDOMEvent.META_MASK) != 0, 1.80 + "evt.metaKey did not match expected value"); 1.81 + 1.82 + if (evt.type == "MozTapGesture") { 1.83 + is(evt.clickCount, test_expectedClickCount, "evt.clickCount does not match"); 1.84 + } 1.85 + 1.86 + test_eventCount++; 1.87 +} 1.88 + 1.89 +function test_helper1(type, direction, delta, modifiers) 1.90 +{ 1.91 + // Setup the expected values 1.92 + test_expectedType = type; 1.93 + test_expectedDirection = direction; 1.94 + test_expectedDelta = delta; 1.95 + test_expectedModifiers = modifiers; 1.96 + 1.97 + let expectedEventCount = test_eventCount + 1; 1.98 + 1.99 + document.addEventListener(type, test_gestureListener, true); 1.100 + test_utils.sendSimpleGestureEvent(type, 20, 20, direction, delta, modifiers); 1.101 + document.removeEventListener(type, test_gestureListener, true); 1.102 + 1.103 + is(expectedEventCount, test_eventCount, "Event (" + type + ") was never received by event listener"); 1.104 +} 1.105 + 1.106 +function test_clicks(type, clicks) 1.107 +{ 1.108 + // Setup the expected values 1.109 + test_expectedType = type; 1.110 + test_expectedDirection = 0; 1.111 + test_expectedDelta = 0; 1.112 + test_expectedModifiers = 0; 1.113 + test_expectedClickCount = clicks; 1.114 + 1.115 + let expectedEventCount = test_eventCount + 1; 1.116 + 1.117 + document.addEventListener(type, test_gestureListener, true); 1.118 + test_utils.sendSimpleGestureEvent(type, 20, 20, 0, 0, 0, clicks); 1.119 + document.removeEventListener(type, test_gestureListener, true); 1.120 + 1.121 + is(expectedEventCount, test_eventCount, "Event (" + type + ") was never received by event listener"); 1.122 +} 1.123 + 1.124 +function test_TestEventListeners() 1.125 +{ 1.126 + let e = test_helper1; // easier to type this name 1.127 + 1.128 + // Swipe gesture animation events 1.129 + e("MozSwipeGestureStart", 0, -0.7, 0); 1.130 + e("MozSwipeGestureUpdate", 0, -0.4, 0); 1.131 + e("MozSwipeGestureEnd", 0, 0, 0); 1.132 + e("MozSwipeGestureStart", 0, 0.6, 0); 1.133 + e("MozSwipeGestureUpdate", 0, 0.3, 0); 1.134 + e("MozSwipeGestureEnd", 0, 1, 0); 1.135 + 1.136 + // Swipe gesture event 1.137 + e("MozSwipeGesture", SimpleGestureEvent.DIRECTION_LEFT, 0.0, 0); 1.138 + e("MozSwipeGesture", SimpleGestureEvent.DIRECTION_RIGHT, 0.0, 0); 1.139 + e("MozSwipeGesture", SimpleGestureEvent.DIRECTION_UP, 0.0, 0); 1.140 + e("MozSwipeGesture", SimpleGestureEvent.DIRECTION_DOWN, 0.0, 0); 1.141 + e("MozSwipeGesture", 1.142 + SimpleGestureEvent.DIRECTION_UP | SimpleGestureEvent.DIRECTION_LEFT, 0.0, 0); 1.143 + e("MozSwipeGesture", 1.144 + SimpleGestureEvent.DIRECTION_DOWN | SimpleGestureEvent.DIRECTION_RIGHT, 0.0, 0); 1.145 + e("MozSwipeGesture", 1.146 + SimpleGestureEvent.DIRECTION_UP | SimpleGestureEvent.DIRECTION_RIGHT, 0.0, 0); 1.147 + e("MozSwipeGesture", 1.148 + SimpleGestureEvent.DIRECTION_DOWN | SimpleGestureEvent.DIRECTION_LEFT, 0.0, 0); 1.149 + 1.150 + // magnify gesture events 1.151 + e("MozMagnifyGestureStart", 0, 50.0, 0); 1.152 + e("MozMagnifyGestureUpdate", 0, -25.0, 0); 1.153 + e("MozMagnifyGestureUpdate", 0, 5.0, 0); 1.154 + e("MozMagnifyGesture", 0, 30.0, 0); 1.155 + 1.156 + // rotate gesture events 1.157 + e("MozRotateGestureStart", SimpleGestureEvent.ROTATION_CLOCKWISE, 33.0, 0); 1.158 + e("MozRotateGestureUpdate", SimpleGestureEvent.ROTATION_COUNTERCLOCKWISE, -13.0, 0); 1.159 + e("MozRotateGestureUpdate", SimpleGestureEvent.ROTATION_CLOCKWISE, 13.0, 0); 1.160 + e("MozRotateGesture", SimpleGestureEvent.ROTATION_CLOCKWISE, 33.0, 0); 1.161 + 1.162 + // Tap and presstap gesture events 1.163 + test_clicks("MozTapGesture", 1); 1.164 + test_clicks("MozTapGesture", 2); 1.165 + test_clicks("MozTapGesture", 3); 1.166 + test_clicks("MozPressTapGesture", 1); 1.167 + 1.168 + // simple delivery test for edgeui gestures 1.169 + e("MozEdgeUIStarted", 0, 0, 0); 1.170 + e("MozEdgeUICanceled", 0, 0, 0); 1.171 + e("MozEdgeUICompleted", 0, 0, 0); 1.172 + 1.173 + // event.shiftKey 1.174 + let modifier = Components.interfaces.nsIDOMEvent.SHIFT_MASK; 1.175 + e("MozSwipeGesture", SimpleGestureEvent.DIRECTION_RIGHT, 0, modifier); 1.176 + 1.177 + // event.metaKey 1.178 + modifier = Components.interfaces.nsIDOMEvent.META_MASK; 1.179 + e("MozSwipeGesture", SimpleGestureEvent.DIRECTION_RIGHT, 0, modifier); 1.180 + 1.181 + // event.altKey 1.182 + modifier = Components.interfaces.nsIDOMEvent.ALT_MASK; 1.183 + e("MozSwipeGesture", SimpleGestureEvent.DIRECTION_RIGHT, 0, modifier); 1.184 + 1.185 + // event.ctrlKey 1.186 + modifier = Components.interfaces.nsIDOMEvent.CONTROL_MASK; 1.187 + e("MozSwipeGesture", SimpleGestureEvent.DIRECTION_RIGHT, 0, modifier); 1.188 +} 1.189 + 1.190 +function test_eventDispatchListener(evt) 1.191 +{ 1.192 + test_eventCount++; 1.193 + evt.stopPropagation(); 1.194 +} 1.195 + 1.196 +function test_helper2(type, direction, delta, altKey, ctrlKey, shiftKey, metaKey) 1.197 +{ 1.198 + let event = null; 1.199 + let successful; 1.200 + 1.201 + try { 1.202 + event = document.createEvent("SimpleGestureEvent"); 1.203 + successful = true; 1.204 + } 1.205 + catch (ex) { 1.206 + successful = false; 1.207 + } 1.208 + ok(successful, "Unable to create SimpleGestureEvent"); 1.209 + 1.210 + try { 1.211 + event.initSimpleGestureEvent(type, true, true, window, 1, 1.212 + 10, 10, 10, 10, 1.213 + ctrlKey, altKey, shiftKey, metaKey, 1.214 + 1, window, 1.215 + 0, direction, delta, 0); 1.216 + successful = true; 1.217 + } 1.218 + catch (ex) { 1.219 + successful = false; 1.220 + } 1.221 + ok(successful, "event.initSimpleGestureEvent should not fail"); 1.222 + 1.223 + // Make sure the event fields match the expected values 1.224 + is(event.type, type, "Mismatch on evt.type"); 1.225 + is(event.direction, direction, "Mismatch on evt.direction"); 1.226 + is(event.delta, delta, "Mismatch on evt.delta"); 1.227 + is(event.altKey, altKey, "Mismatch on evt.altKey"); 1.228 + is(event.ctrlKey, ctrlKey, "Mismatch on evt.ctrlKey"); 1.229 + is(event.shiftKey, shiftKey, "Mismatch on evt.shiftKey"); 1.230 + is(event.metaKey, metaKey, "Mismatch on evt.metaKey"); 1.231 + is(event.view, window, "Mismatch on evt.view"); 1.232 + is(event.detail, 1, "Mismatch on evt.detail"); 1.233 + is(event.clientX, 10, "Mismatch on evt.clientX"); 1.234 + is(event.clientY, 10, "Mismatch on evt.clientY"); 1.235 + is(event.screenX, 10, "Mismatch on evt.screenX"); 1.236 + is(event.screenY, 10, "Mismatch on evt.screenY"); 1.237 + is(event.button, 1, "Mismatch on evt.button"); 1.238 + is(event.relatedTarget, window, "Mismatch on evt.relatedTarget"); 1.239 + 1.240 + // Test event dispatch 1.241 + let expectedEventCount = test_eventCount + 1; 1.242 + document.addEventListener(type, test_eventDispatchListener, true); 1.243 + document.dispatchEvent(event); 1.244 + document.removeEventListener(type, test_eventDispatchListener, true); 1.245 + is(expectedEventCount, test_eventCount, "Dispatched event was never received by listener"); 1.246 +} 1.247 + 1.248 +function test_TestEventCreation() 1.249 +{ 1.250 + // Event creation 1.251 + test_helper2("MozMagnifyGesture", SimpleGestureEvent.DIRECTION_RIGHT, 20.0, 1.252 + true, false, true, false); 1.253 + test_helper2("MozMagnifyGesture", SimpleGestureEvent.DIRECTION_LEFT, -20.0, 1.254 + false, true, false, true); 1.255 +} 1.256 + 1.257 +function test_EnsureConstantsAreDisjoint() 1.258 +{ 1.259 + let up = SimpleGestureEvent.DIRECTION_UP; 1.260 + let down = SimpleGestureEvent.DIRECTION_DOWN; 1.261 + let left = SimpleGestureEvent.DIRECTION_LEFT; 1.262 + let right = SimpleGestureEvent.DIRECTION_RIGHT; 1.263 + 1.264 + let clockwise = SimpleGestureEvent.ROTATION_CLOCKWISE; 1.265 + let cclockwise = SimpleGestureEvent.ROTATION_COUNTERCLOCKWISE; 1.266 + 1.267 + ok(up ^ down, "DIRECTION_UP and DIRECTION_DOWN are not bitwise disjoint"); 1.268 + ok(up ^ left, "DIRECTION_UP and DIRECTION_LEFT are not bitwise disjoint"); 1.269 + ok(up ^ right, "DIRECTION_UP and DIRECTION_RIGHT are not bitwise disjoint"); 1.270 + ok(down ^ left, "DIRECTION_DOWN and DIRECTION_LEFT are not bitwise disjoint"); 1.271 + ok(down ^ right, "DIRECTION_DOWN and DIRECTION_RIGHT are not bitwise disjoint"); 1.272 + ok(left ^ right, "DIRECTION_LEFT and DIRECTION_RIGHT are not bitwise disjoint"); 1.273 + ok(clockwise ^ cclockwise, "ROTATION_CLOCKWISE and ROTATION_COUNTERCLOCKWISE are not bitwise disjoint"); 1.274 +} 1.275 + 1.276 +// Helper for test of latched event processing. Emits the actual 1.277 +// gesture events to test whether the commands associated with the 1.278 +// gesture will only trigger once for each direction of movement. 1.279 +function test_emitLatchedEvents(eventPrefix, initialDelta, cmd) 1.280 +{ 1.281 + let cumulativeDelta = 0; 1.282 + let isIncreasing = initialDelta > 0; 1.283 + 1.284 + let expect = {}; 1.285 + // Reset the call counters and initialize expected values 1.286 + for (let dir in cmd) 1.287 + cmd[dir].callCount = expect[dir] = 0; 1.288 + 1.289 + let check = function(aDir, aMsg) ok(cmd[aDir].callCount == expect[aDir], aMsg); 1.290 + let checkBoth = function(aNum, aInc, aDec) { 1.291 + let prefix = "Step " + aNum + ": "; 1.292 + check("inc", prefix + aInc); 1.293 + check("dec", prefix + aDec); 1.294 + }; 1.295 + 1.296 + // Send the "Start" event. 1.297 + test_utils.sendSimpleGestureEvent(eventPrefix + "Start", 0, 0, 0, initialDelta, 0); 1.298 + cumulativeDelta += initialDelta; 1.299 + if (isIncreasing) { 1.300 + expect.inc++; 1.301 + checkBoth(1, "Increasing command was not triggered", "Decreasing command was triggered"); 1.302 + } else { 1.303 + expect.dec++; 1.304 + checkBoth(1, "Increasing command was triggered", "Decreasing command was not triggered"); 1.305 + } 1.306 + 1.307 + // Send random values in the same direction and ensure neither 1.308 + // command triggers. 1.309 + for (let i = 0; i < 5; i++) { 1.310 + let delta = Math.random() * (isIncreasing ? 100 : -100); 1.311 + test_utils.sendSimpleGestureEvent(eventPrefix + "Update", 0, 0, 0, delta, 0); 1.312 + cumulativeDelta += delta; 1.313 + checkBoth(2, "Increasing command was triggered", "Decreasing command was triggered"); 1.314 + } 1.315 + 1.316 + // Now go back in the opposite direction. 1.317 + test_utils.sendSimpleGestureEvent(eventPrefix + "Update", 0, 0, 0, 1.318 + - initialDelta, 0); 1.319 + cumulativeDelta += - initialDelta; 1.320 + if (isIncreasing) { 1.321 + expect.dec++; 1.322 + checkBoth(3, "Increasing command was triggered", "Decreasing command was not triggered"); 1.323 + } else { 1.324 + expect.inc++; 1.325 + checkBoth(3, "Increasing command was not triggered", "Decreasing command was triggered"); 1.326 + } 1.327 + 1.328 + // Send random values in the opposite direction and ensure neither 1.329 + // command triggers. 1.330 + for (let i = 0; i < 5; i++) { 1.331 + let delta = Math.random() * (isIncreasing ? -100 : 100); 1.332 + test_utils.sendSimpleGestureEvent(eventPrefix + "Update", 0, 0, 0, delta, 0); 1.333 + cumulativeDelta += delta; 1.334 + checkBoth(4, "Increasing command was triggered", "Decreasing command was triggered"); 1.335 + } 1.336 + 1.337 + // Go back to the original direction. The original command should trigger. 1.338 + test_utils.sendSimpleGestureEvent(eventPrefix + "Update", 0, 0, 0, 1.339 + initialDelta, 0); 1.340 + cumulativeDelta += initialDelta; 1.341 + if (isIncreasing) { 1.342 + expect.inc++; 1.343 + checkBoth(5, "Increasing command was not triggered", "Decreasing command was triggered"); 1.344 + } else { 1.345 + expect.dec++; 1.346 + checkBoth(5, "Increasing command was triggered", "Decreasing command was not triggered"); 1.347 + } 1.348 + 1.349 + // Send the wrap-up event. No commands should be triggered. 1.350 + test_utils.sendSimpleGestureEvent(eventPrefix, 0, 0, 0, cumulativeDelta, 0); 1.351 + checkBoth(6, "Increasing command was triggered", "Decreasing command was triggered"); 1.352 +} 1.353 + 1.354 +function test_addCommand(prefName, id) 1.355 +{ 1.356 + let cmd = test_commandset.appendChild(document.createElement("command")); 1.357 + cmd.setAttribute("id", id); 1.358 + cmd.setAttribute("oncommand", "this.callCount++;"); 1.359 + 1.360 + cmd.origPrefName = prefName; 1.361 + cmd.origPrefValue = gPrefService.getCharPref(prefName); 1.362 + gPrefService.setCharPref(prefName, id); 1.363 + 1.364 + return cmd; 1.365 +} 1.366 + 1.367 +function test_removeCommand(cmd) 1.368 +{ 1.369 + gPrefService.setCharPref(cmd.origPrefName, cmd.origPrefValue); 1.370 + test_commandset.removeChild(cmd); 1.371 +} 1.372 + 1.373 +// Test whether latched events are only called once per direction of motion. 1.374 +function test_latchedGesture(gesture, inc, dec, eventPrefix) 1.375 +{ 1.376 + let branch = test_prefBranch + gesture + "."; 1.377 + 1.378 + // Put the gesture into latched mode. 1.379 + let oldLatchedValue = gPrefService.getBoolPref(branch + "latched"); 1.380 + gPrefService.setBoolPref(branch + "latched", true); 1.381 + 1.382 + // Install the test commands for increasing and decreasing motion. 1.383 + let cmd = { 1.384 + inc: test_addCommand(branch + inc, "test:incMotion"), 1.385 + dec: test_addCommand(branch + dec, "test:decMotion"), 1.386 + }; 1.387 + 1.388 + // Test the gestures in each direction. 1.389 + test_emitLatchedEvents(eventPrefix, 500, cmd); 1.390 + test_emitLatchedEvents(eventPrefix, -500, cmd); 1.391 + 1.392 + // Restore the gesture to its original configuration. 1.393 + gPrefService.setBoolPref(branch + "latched", oldLatchedValue); 1.394 + for (let dir in cmd) 1.395 + test_removeCommand(cmd[dir]); 1.396 +} 1.397 + 1.398 +// Test whether non-latched events are triggered upon sufficient motion. 1.399 +function test_thresholdGesture(gesture, inc, dec, eventPrefix) 1.400 +{ 1.401 + let branch = test_prefBranch + gesture + "."; 1.402 + 1.403 + // Disable latched mode for this gesture. 1.404 + let oldLatchedValue = gPrefService.getBoolPref(branch + "latched"); 1.405 + gPrefService.setBoolPref(branch + "latched", false); 1.406 + 1.407 + // Set the triggering threshold value to 50. 1.408 + let oldThresholdValue = gPrefService.getIntPref(branch + "threshold"); 1.409 + gPrefService.setIntPref(branch + "threshold", 50); 1.410 + 1.411 + // Install the test commands for increasing and decreasing motion. 1.412 + let cmdInc = test_addCommand(branch + inc, "test:incMotion"); 1.413 + let cmdDec = test_addCommand(branch + dec, "test:decMotion"); 1.414 + 1.415 + // Send the start event but stop short of triggering threshold. 1.416 + cmdInc.callCount = cmdDec.callCount = 0; 1.417 + test_utils.sendSimpleGestureEvent(eventPrefix + "Start", 0, 0, 0, 49.5, 0); 1.418 + ok(cmdInc.callCount == 0, "Increasing command was triggered"); 1.419 + ok(cmdDec.callCount == 0, "Decreasing command was triggered"); 1.420 + 1.421 + // Now trigger the threshold. 1.422 + cmdInc.callCount = cmdDec.callCount = 0; 1.423 + test_utils.sendSimpleGestureEvent(eventPrefix + "Update", 0, 0, 0, 1, 0); 1.424 + ok(cmdInc.callCount == 1, "Increasing command was not triggered"); 1.425 + ok(cmdDec.callCount == 0, "Decreasing command was triggered"); 1.426 + 1.427 + // The tracking counter should go to zero. Go back the other way and 1.428 + // stop short of triggering the threshold. 1.429 + cmdInc.callCount = cmdDec.callCount = 0; 1.430 + test_utils.sendSimpleGestureEvent(eventPrefix + "Update", 0, 0, 0, -49.5, 0); 1.431 + ok(cmdInc.callCount == 0, "Increasing command was triggered"); 1.432 + ok(cmdDec.callCount == 0, "Decreasing command was triggered"); 1.433 + 1.434 + // Now cross the threshold and trigger the decreasing command. 1.435 + cmdInc.callCount = cmdDec.callCount = 0; 1.436 + test_utils.sendSimpleGestureEvent(eventPrefix + "Update", 0, 0, 0, -1.5, 0); 1.437 + ok(cmdInc.callCount == 0, "Increasing command was triggered"); 1.438 + ok(cmdDec.callCount == 1, "Decreasing command was not triggered"); 1.439 + 1.440 + // Send the wrap-up event. No commands should trigger. 1.441 + cmdInc.callCount = cmdDec.callCount = 0; 1.442 + test_utils.sendSimpleGestureEvent(eventPrefix, 0, 0, 0, -0.5, 0); 1.443 + ok(cmdInc.callCount == 0, "Increasing command was triggered"); 1.444 + ok(cmdDec.callCount == 0, "Decreasing command was triggered"); 1.445 + 1.446 + // Restore the gesture to its original configuration. 1.447 + gPrefService.setBoolPref(branch + "latched", oldLatchedValue); 1.448 + gPrefService.setIntPref(branch + "threshold", oldThresholdValue); 1.449 + test_removeCommand(cmdInc); 1.450 + test_removeCommand(cmdDec); 1.451 +} 1.452 + 1.453 +function test_swipeGestures() 1.454 +{ 1.455 + // easier to type names for the direction constants 1.456 + let up = SimpleGestureEvent.DIRECTION_UP; 1.457 + let down = SimpleGestureEvent.DIRECTION_DOWN; 1.458 + let left = SimpleGestureEvent.DIRECTION_LEFT; 1.459 + let right = SimpleGestureEvent.DIRECTION_RIGHT; 1.460 + 1.461 + let branch = test_prefBranch + "swipe."; 1.462 + 1.463 + // Install the test commands for the swipe gestures. 1.464 + let cmdUp = test_addCommand(branch + "up", "test:swipeUp"); 1.465 + let cmdDown = test_addCommand(branch + "down", "test:swipeDown"); 1.466 + let cmdLeft = test_addCommand(branch + "left", "test:swipeLeft"); 1.467 + let cmdRight = test_addCommand(branch + "right", "test:swipeRight"); 1.468 + 1.469 + function resetCounts() { 1.470 + cmdUp.callCount = 0; 1.471 + cmdDown.callCount = 0; 1.472 + cmdLeft.callCount = 0; 1.473 + cmdRight.callCount = 0; 1.474 + } 1.475 + 1.476 + // UP 1.477 + resetCounts(); 1.478 + test_utils.sendSimpleGestureEvent("MozSwipeGesture", 0, 0, up, 0, 0); 1.479 + ok(cmdUp.callCount == 1, "Step 1: Up command was not triggered"); 1.480 + ok(cmdDown.callCount == 0, "Step 1: Down command was triggered"); 1.481 + ok(cmdLeft.callCount == 0, "Step 1: Left command was triggered"); 1.482 + ok(cmdRight.callCount == 0, "Step 1: Right command was triggered"); 1.483 + 1.484 + // DOWN 1.485 + resetCounts(); 1.486 + test_utils.sendSimpleGestureEvent("MozSwipeGesture", 0, 0, down, 0, 0); 1.487 + ok(cmdUp.callCount == 0, "Step 2: Up command was triggered"); 1.488 + ok(cmdDown.callCount == 1, "Step 2: Down command was not triggered"); 1.489 + ok(cmdLeft.callCount == 0, "Step 2: Left command was triggered"); 1.490 + ok(cmdRight.callCount == 0, "Step 2: Right command was triggered"); 1.491 + 1.492 + // LEFT 1.493 + resetCounts(); 1.494 + test_utils.sendSimpleGestureEvent("MozSwipeGesture", 0, 0, left, 0, 0); 1.495 + ok(cmdUp.callCount == 0, "Step 3: Up command was triggered"); 1.496 + ok(cmdDown.callCount == 0, "Step 3: Down command was triggered"); 1.497 + ok(cmdLeft.callCount == 1, "Step 3: Left command was not triggered"); 1.498 + ok(cmdRight.callCount == 0, "Step 3: Right command was triggered"); 1.499 + 1.500 + // RIGHT 1.501 + resetCounts(); 1.502 + test_utils.sendSimpleGestureEvent("MozSwipeGesture", 0, 0, right, 0, 0); 1.503 + ok(cmdUp.callCount == 0, "Step 4: Up command was triggered"); 1.504 + ok(cmdDown.callCount == 0, "Step 4: Down command was triggered"); 1.505 + ok(cmdLeft.callCount == 0, "Step 4: Left command was triggered"); 1.506 + ok(cmdRight.callCount == 1, "Step 4: Right command was not triggered"); 1.507 + 1.508 + // Make sure combinations do not trigger events. 1.509 + let combos = [ up | left, up | right, down | left, down | right]; 1.510 + for (let i = 0; i < combos.length; i++) { 1.511 + resetCounts(); 1.512 + test_utils.sendSimpleGestureEvent("MozSwipeGesture", 0, 0, combos[i], 0, 0); 1.513 + ok(cmdUp.callCount == 0, "Step 5-"+i+": Up command was triggered"); 1.514 + ok(cmdDown.callCount == 0, "Step 5-"+i+": Down command was triggered"); 1.515 + ok(cmdLeft.callCount == 0, "Step 5-"+i+": Left command was triggered"); 1.516 + ok(cmdRight.callCount == 0, "Step 5-"+i+": Right command was triggered"); 1.517 + } 1.518 + 1.519 + // Remove the test commands. 1.520 + test_removeCommand(cmdUp); 1.521 + test_removeCommand(cmdDown); 1.522 + test_removeCommand(cmdLeft); 1.523 + test_removeCommand(cmdRight); 1.524 +} 1.525 + 1.526 + 1.527 +function test_rotateHelperGetImageRotation(aImageElement) 1.528 +{ 1.529 + // Get the true image rotation from the transform matrix, bounded 1.530 + // to 0 <= result < 360 1.531 + let transformValue = content.window.getComputedStyle(aImageElement, null) 1.532 + .transform; 1.533 + if (transformValue == "none") 1.534 + return 0; 1.535 + 1.536 + transformValue = transformValue.split("(")[1] 1.537 + .split(")")[0] 1.538 + .split(","); 1.539 + var rotation = Math.round(Math.atan2(transformValue[1], transformValue[0]) * 1.540 + (180 / Math.PI)); 1.541 + return (rotation < 0 ? rotation + 360 : rotation); 1.542 +} 1.543 + 1.544 +function test_rotateHelperOneGesture(aImageElement, aCurrentRotation, 1.545 + aDirection, aAmount, aStop) 1.546 +{ 1.547 + if (aAmount <= 0 || aAmount > 90) // Bound to 0 < aAmount <= 90 1.548 + return; 1.549 + 1.550 + // easier to type names for the direction constants 1.551 + let clockwise = SimpleGestureEvent.ROTATION_CLOCKWISE; 1.552 + let cclockwise = SimpleGestureEvent.ROTATION_COUNTERCLOCKWISE; 1.553 + 1.554 + let delta = aAmount * (aDirection == clockwise ? 1 : -1); 1.555 + 1.556 + // Kill transition time on image so test isn't wrong and doesn't take 10 seconds 1.557 + aImageElement.style.transitionDuration = "0s"; 1.558 + 1.559 + // Start the gesture, perform an update, and force flush 1.560 + test_utils.sendSimpleGestureEvent("MozRotateGestureStart", 0, 0, aDirection, .001, 0); 1.561 + test_utils.sendSimpleGestureEvent("MozRotateGestureUpdate", 0, 0, aDirection, delta, 0); 1.562 + aImageElement.clientTop; 1.563 + 1.564 + // If stop, check intermediate 1.565 + if (aStop) { 1.566 + // Send near-zero-delta to stop, and force flush 1.567 + test_utils.sendSimpleGestureEvent("MozRotateGestureUpdate", 0, 0, aDirection, .001, 0); 1.568 + aImageElement.clientTop; 1.569 + 1.570 + let stopExpectedRotation = (aCurrentRotation + delta) % 360; 1.571 + if (stopExpectedRotation < 0) 1.572 + stopExpectedRotation += 360; 1.573 + 1.574 + is(stopExpectedRotation, test_rotateHelperGetImageRotation(aImageElement), 1.575 + "Image rotation at gesture stop/hold: expected=" + stopExpectedRotation + 1.576 + ", observed=" + test_rotateHelperGetImageRotation(aImageElement) + 1.577 + ", init=" + aCurrentRotation + 1.578 + ", amt=" + aAmount + 1.579 + ", dir=" + (aDirection == clockwise ? "cl" : "ccl")); 1.580 + } 1.581 + // End it and force flush 1.582 + test_utils.sendSimpleGestureEvent("MozRotateGesture", 0, 0, aDirection, 0, 0); 1.583 + aImageElement.clientTop; 1.584 + 1.585 + let finalExpectedRotation; 1.586 + 1.587 + if (aAmount < 45 && aStop) { 1.588 + // Rotate a bit, then stop. Expect no change at end of gesture. 1.589 + finalExpectedRotation = aCurrentRotation; 1.590 + } 1.591 + else { 1.592 + // Either not stopping (expect 90 degree change in aDirection), OR 1.593 + // stopping but after 45, (expect 90 degree change in aDirection) 1.594 + finalExpectedRotation = (aCurrentRotation + 1.595 + (aDirection == clockwise ? 1 : -1) * 90) % 360; 1.596 + if (finalExpectedRotation < 0) 1.597 + finalExpectedRotation += 360; 1.598 + } 1.599 + 1.600 + is(finalExpectedRotation, test_rotateHelperGetImageRotation(aImageElement), 1.601 + "Image rotation gesture end: expected=" + finalExpectedRotation + 1.602 + ", observed=" + test_rotateHelperGetImageRotation(aImageElement) + 1.603 + ", init=" + aCurrentRotation + 1.604 + ", amt=" + aAmount + 1.605 + ", dir=" + (aDirection == clockwise ? "cl" : "ccl")); 1.606 +} 1.607 + 1.608 +function test_rotateGesturesOnTab() 1.609 +{ 1.610 + gBrowser.selectedBrowser.removeEventListener("load", test_rotateGesturesOnTab, true); 1.611 + 1.612 + if (!(content.document instanceof ImageDocument)) { 1.613 + ok(false, "Image document failed to open for rotation testing"); 1.614 + gBrowser.removeTab(test_imageTab); 1.615 + finish(); 1.616 + return; 1.617 + } 1.618 + 1.619 + // easier to type names for the direction constants 1.620 + let cl = SimpleGestureEvent.ROTATION_CLOCKWISE; 1.621 + let ccl = SimpleGestureEvent.ROTATION_COUNTERCLOCKWISE; 1.622 + 1.623 + let imgElem = content.document.body && 1.624 + content.document.body.firstElementChild; 1.625 + 1.626 + if (!imgElem) { 1.627 + ok(false, "Could not get image element on ImageDocument for rotation!"); 1.628 + gBrowser.removeTab(test_imageTab); 1.629 + finish(); 1.630 + return; 1.631 + } 1.632 + 1.633 + // Quick function to normalize rotation to 0 <= r < 360 1.634 + var normRot = function(rotation) { 1.635 + rotation = rotation % 360; 1.636 + if (rotation < 0) 1.637 + rotation += 360; 1.638 + return rotation; 1.639 + } 1.640 + 1.641 + for (var initRot = 0; initRot < 360; initRot += 90) { 1.642 + // Test each case: at each 90 degree snap; cl/ccl; 1.643 + // amount more or less than 45; stop and hold or don't (32 total tests) 1.644 + // The amount added to the initRot is where it is expected to be 1.645 + test_rotateHelperOneGesture(imgElem, normRot(initRot + 0), cl, 35, true ); 1.646 + test_rotateHelperOneGesture(imgElem, normRot(initRot + 0), cl, 35, false); 1.647 + test_rotateHelperOneGesture(imgElem, normRot(initRot + 90), cl, 55, true ); 1.648 + test_rotateHelperOneGesture(imgElem, normRot(initRot + 180), cl, 55, false); 1.649 + test_rotateHelperOneGesture(imgElem, normRot(initRot + 270), ccl, 35, true ); 1.650 + test_rotateHelperOneGesture(imgElem, normRot(initRot + 270), ccl, 35, false); 1.651 + test_rotateHelperOneGesture(imgElem, normRot(initRot + 180), ccl, 55, true ); 1.652 + test_rotateHelperOneGesture(imgElem, normRot(initRot + 90), ccl, 55, false); 1.653 + 1.654 + // Manually rotate it 90 degrees clockwise to prepare for next iteration, 1.655 + // and force flush 1.656 + test_utils.sendSimpleGestureEvent("MozRotateGestureStart", 0, 0, cl, .001, 0); 1.657 + test_utils.sendSimpleGestureEvent("MozRotateGestureUpdate", 0, 0, cl, 90, 0); 1.658 + test_utils.sendSimpleGestureEvent("MozRotateGestureUpdate", 0, 0, cl, .001, 0); 1.659 + test_utils.sendSimpleGestureEvent("MozRotateGesture", 0, 0, cl, 0, 0); 1.660 + imgElem.clientTop; 1.661 + } 1.662 + 1.663 + gBrowser.removeTab(test_imageTab); 1.664 + test_imageTab = null; 1.665 + finish(); 1.666 +} 1.667 + 1.668 +function test_rotateGestures() 1.669 +{ 1.670 + test_imageTab = gBrowser.addTab("chrome://branding/content/about-logo.png"); 1.671 + gBrowser.selectedTab = test_imageTab; 1.672 + 1.673 + gBrowser.selectedBrowser.addEventListener("load", test_rotateGesturesOnTab, true); 1.674 +}