accessible/tests/mochitest/jsat/dom_helper.js

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

michael@0 1 'use strict';
michael@0 2
michael@0 3 /* global getMainChromeWindow, AccessFuTest, GestureSettings, GestureTracker,
michael@0 4 SimpleTest, getBoundsForDOMElm, Point, Utils */
michael@0 5 /* exported loadJSON, eventMap */
michael@0 6
michael@0 7 const Ci = Components.interfaces;
michael@0 8 const Cu = Components.utils;
michael@0 9
michael@0 10 Cu.import('resource://gre/modules/accessibility/Utils.jsm');
michael@0 11 Cu.import('resource://gre/modules/Geometry.jsm');
michael@0 12 Cu.import("resource://gre/modules/accessibility/Gestures.jsm");
michael@0 13
michael@0 14 var win = getMainChromeWindow(window);
michael@0 15
michael@0 16 /**
michael@0 17 * Convert inch based point coordinates into pixels.
michael@0 18 * @param {Array} aPoints Array of coordinates in inches.
michael@0 19 * @return {Array} Array of coordinates in pixels.
michael@0 20 */
michael@0 21 function convertPointCoordinates(aPoints) {
michael@0 22 var dpi = Utils.dpi;
michael@0 23 return aPoints.map(function convert(aPoint) {
michael@0 24 return {
michael@0 25 x: aPoint.x * dpi,
michael@0 26 y: aPoint.y * dpi,
michael@0 27 identifier: aPoint.identifier
michael@0 28 };
michael@0 29 });
michael@0 30 }
michael@0 31
michael@0 32 /**
michael@0 33 * For a given list of points calculate their coordinates in relation to the
michael@0 34 * document body.
michael@0 35 * @param {Array} aTouchPoints An array of objects of the following format: {
michael@0 36 * base: {String}, // Id of an element to server as a base for the touch.
michael@0 37 * x: {Number}, // An optional x offset from the base element's geometric
michael@0 38 * // centre.
michael@0 39 * y: {Number} // An optional y offset from the base element's geometric
michael@0 40 * // centre.
michael@0 41 * }
michael@0 42 * @return {JSON} An array of {x, y} coordinations.
michael@0 43 */
michael@0 44 function calculateTouchListCoordinates(aTouchPoints) {
michael@0 45 var coords = [];
michael@0 46 for (var i = 0, target = aTouchPoints[i]; i < aTouchPoints.length; ++i) {
michael@0 47 var bounds = getBoundsForDOMElm(target.base);
michael@0 48 var parentBounds = getBoundsForDOMElm('root');
michael@0 49 var point = new Point(target.x || 0, target.y || 0);
michael@0 50 point.scale(Utils.dpi);
michael@0 51 point.add(bounds[0], bounds[1]);
michael@0 52 point.add(bounds[2] / 2, bounds[3] / 2);
michael@0 53 point.subtract(parentBounds[0], parentBounds[0]);
michael@0 54 coords.push({
michael@0 55 x: point.x,
michael@0 56 y: point.y
michael@0 57 });
michael@0 58 }
michael@0 59 return coords;
michael@0 60 }
michael@0 61
michael@0 62 /**
michael@0 63 * Send a touch event with specified touchPoints.
michael@0 64 * @param {Array} aTouchPoints An array of points to be associated with
michael@0 65 * touches.
michael@0 66 * @param {String} aName A name of the touch event.
michael@0 67 */
michael@0 68 function sendTouchEvent(aTouchPoints, aName) {
michael@0 69 var touchList = sendTouchEvent.touchList;
michael@0 70 if (aName === 'touchend') {
michael@0 71 sendTouchEvent.touchList = null;
michael@0 72 } else {
michael@0 73 var coords = calculateTouchListCoordinates(aTouchPoints);
michael@0 74 var touches = [];
michael@0 75 for (var i = 0; i < coords.length; ++i) {
michael@0 76 var {x, y} = coords[i];
michael@0 77 var node = document.elementFromPoint(x, y);
michael@0 78 var touch = document.createTouch(window, node, aName === 'touchstart' ?
michael@0 79 1 : touchList.item(i).identifier, x, y, x, y);
michael@0 80 touches.push(touch);
michael@0 81 }
michael@0 82 touchList = document.createTouchList(touches);
michael@0 83 sendTouchEvent.touchList = touchList;
michael@0 84 }
michael@0 85 var evt = document.createEvent('TouchEvent');
michael@0 86 evt.initTouchEvent(aName, true, true, window, 0, false, false, false, false,
michael@0 87 touchList, touchList, touchList);
michael@0 88 document.dispatchEvent(evt);
michael@0 89 }
michael@0 90
michael@0 91 sendTouchEvent.touchList = null;
michael@0 92
michael@0 93 /**
michael@0 94 * A map of event names to the functions that actually send them.
michael@0 95 * @type {Object}
michael@0 96 */
michael@0 97 var eventMap = {
michael@0 98 touchstart: sendTouchEvent,
michael@0 99 touchend: sendTouchEvent,
michael@0 100 touchmove: sendTouchEvent
michael@0 101 };
michael@0 102
michael@0 103 var originalDwellThreshold = GestureSettings.dwellThreshold;
michael@0 104 var originalSwipeMaxDuration = GestureSettings.swipeMaxDuration;
michael@0 105
michael@0 106 /**
michael@0 107 * Attach a listener for the mozAccessFuGesture event that tests its
michael@0 108 * type.
michael@0 109 * @param {Array} aExpectedGestures A stack of expected event types.
michael@0 110 * Note: the listener is removed once the stack reaches 0.
michael@0 111 */
michael@0 112 function testMozAccessFuGesture(aExpectedGestures) {
michael@0 113 var types = typeof aExpectedGestures === "string" ?
michael@0 114 [aExpectedGestures] : aExpectedGestures;
michael@0 115 function handleGesture(aEvent) {
michael@0 116 if (aEvent.detail.type !== types[0]) {
michael@0 117 // The is not the event of interest.
michael@0 118 return;
michael@0 119 }
michael@0 120 ok(true, 'Received correct mozAccessFuGesture: ' + types.shift() + '.');
michael@0 121 if (types.length === 0) {
michael@0 122 win.removeEventListener('mozAccessFuGesture', handleGesture);
michael@0 123 if (AccessFuTest.sequenceCleanup) {
michael@0 124 AccessFuTest.sequenceCleanup();
michael@0 125 }
michael@0 126 AccessFuTest.nextTest();
michael@0 127 }
michael@0 128 }
michael@0 129 win.addEventListener('mozAccessFuGesture', handleGesture);
michael@0 130 }
michael@0 131
michael@0 132 /**
michael@0 133 * Reset the thresholds and max delays that affect gesture rejection.
michael@0 134 * @param {Number} aTimeStamp Gesture time stamp.
michael@0 135 * @param {Boolean} aRemoveDwellThreshold An optional flag to reset dwell
michael@0 136 * threshold.
michael@0 137 * @param {Boolean} aRemoveSwipeMaxDuration An optional flag to reset swipe max
michael@0 138 * duration.
michael@0 139 */
michael@0 140 function setTimers(aTimeStamp, aRemoveDwellThreshold, aRemoveSwipeMaxDuration) {
michael@0 141 if (!aRemoveDwellThreshold && !aRemoveSwipeMaxDuration) {
michael@0 142 return;
michael@0 143 }
michael@0 144 if (aRemoveDwellThreshold) {
michael@0 145 GestureSettings.dwellThreshold = 0;
michael@0 146 }
michael@0 147 if (aRemoveSwipeMaxDuration) {
michael@0 148 GestureSettings.swipeMaxDuration = 0;
michael@0 149 }
michael@0 150 GestureTracker.current.clearTimer();
michael@0 151 GestureTracker.current.startTimer(aTimeStamp);
michael@0 152 }
michael@0 153
michael@0 154 function resetTimers() {
michael@0 155 GestureSettings.dwellThreshold = originalDwellThreshold;
michael@0 156 GestureSettings.swipeMaxDuration = originalSwipeMaxDuration;
michael@0 157 }
michael@0 158
michael@0 159 /**
michael@0 160 * An extention to AccessFuTest that adds an ability to test a sequence of
michael@0 161 * pointer events and their expected mozAccessFuGesture events.
michael@0 162 * @param {Object} aSequence An object that has a list of pointer events to be
michael@0 163 * generated and the expected mozAccessFuGesture events.
michael@0 164 */
michael@0 165 AccessFuTest.addSequence = function AccessFuTest_addSequence(aSequence) {
michael@0 166 AccessFuTest.addFunc(function testSequence() {
michael@0 167 testMozAccessFuGesture(aSequence.expectedGestures);
michael@0 168 var events = aSequence.events;
michael@0 169 function fireEvent(aEvent) {
michael@0 170 var event = {
michael@0 171 points: convertPointCoordinates(aEvent.points),
michael@0 172 type: aEvent.type
michael@0 173 };
michael@0 174 var timeStamp = Date.now();
michael@0 175 resetTimers();
michael@0 176 GestureTracker.handle(event, timeStamp);
michael@0 177 setTimers(timeStamp, aEvent.removeDwellThreshold,
michael@0 178 aEvent.removeSwipeMaxDuration);
michael@0 179 processEvents();
michael@0 180 }
michael@0 181 function processEvents() {
michael@0 182 if (events.length === 0) {
michael@0 183 return;
michael@0 184 }
michael@0 185 var event = events.shift();
michael@0 186 SimpleTest.executeSoon(function() {
michael@0 187 fireEvent(event);
michael@0 188 });
michael@0 189 }
michael@0 190 processEvents();
michael@0 191 });
michael@0 192 };
michael@0 193
michael@0 194 /**
michael@0 195 * A helper function that loads JSON files.
michael@0 196 * @param {String} aPath A path to a JSON file.
michael@0 197 * @param {Function} aCallback A callback to be called on success.
michael@0 198 */
michael@0 199 function loadJSON(aPath, aCallback) {
michael@0 200 var request = new XMLHttpRequest();
michael@0 201 request.open('GET', aPath, true);
michael@0 202 request.responseType = 'json';
michael@0 203 request.onload = function onload() {
michael@0 204 aCallback(request.response);
michael@0 205 };
michael@0 206 request.send();
michael@0 207 }

mercurial