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.

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

mercurial