mirror of
https://github.com/classilla/tenfourfox.git
synced 2024-10-22 02:25:05 +00:00
218 lines
7.0 KiB
JavaScript
218 lines
7.0 KiB
JavaScript
'use strict';
|
|
|
|
/* global getMainChromeWindow, AccessFuTest, GestureSettings, GestureTracker,
|
|
SimpleTest, getBoundsForDOMElm, Point, Utils */
|
|
/* exported loadJSON, eventMap */
|
|
|
|
var Ci = Components.interfaces;
|
|
var Cu = Components.utils;
|
|
|
|
Cu.import('resource://gre/modules/accessibility/Utils.jsm');
|
|
Cu.import('resource://gre/modules/Geometry.jsm');
|
|
Cu.import("resource://gre/modules/accessibility/Gestures.jsm");
|
|
|
|
var win = getMainChromeWindow(window);
|
|
|
|
/**
|
|
* Convert inch based point coordinates into pixels.
|
|
* @param {Array} aPoints Array of coordinates in inches.
|
|
* @return {Array} Array of coordinates in pixels.
|
|
*/
|
|
function convertPointCoordinates(aPoints) {
|
|
var dpi = Utils.dpi;
|
|
return aPoints.map(function convert(aPoint) {
|
|
return {
|
|
x: aPoint.x * dpi,
|
|
y: aPoint.y * dpi,
|
|
identifier: aPoint.identifier
|
|
};
|
|
});
|
|
}
|
|
|
|
/**
|
|
* For a given list of points calculate their coordinates in relation to the
|
|
* document body.
|
|
* @param {Array} aTouchPoints An array of objects of the following format: {
|
|
* base: {String}, // Id of an element to server as a base for the touch.
|
|
* x: {Number}, // An optional x offset from the base element's geometric
|
|
* // centre.
|
|
* y: {Number} // An optional y offset from the base element's geometric
|
|
* // centre.
|
|
* }
|
|
* @return {JSON} An array of {x, y} coordinations.
|
|
*/
|
|
function calculateTouchListCoordinates(aTouchPoints) {
|
|
var coords = [];
|
|
for (var i = 0, target = aTouchPoints[i]; i < aTouchPoints.length; ++i) {
|
|
var bounds = getBoundsForDOMElm(target.base);
|
|
var parentBounds = getBoundsForDOMElm('root');
|
|
var point = new Point(target.x || 0, target.y || 0);
|
|
point.scale(Utils.dpi);
|
|
point.add(bounds[0], bounds[1]);
|
|
point.add(bounds[2] / 2, bounds[3] / 2);
|
|
point.subtract(parentBounds[0], parentBounds[0]);
|
|
coords.push({
|
|
x: point.x,
|
|
y: point.y
|
|
});
|
|
}
|
|
return coords;
|
|
}
|
|
|
|
/**
|
|
* Send a touch event with specified touchPoints.
|
|
* @param {Array} aTouchPoints An array of points to be associated with
|
|
* touches.
|
|
* @param {String} aName A name of the touch event.
|
|
*/
|
|
function sendTouchEvent(aTouchPoints, aName) {
|
|
var touchList = sendTouchEvent.touchList;
|
|
if (aName === 'touchend') {
|
|
sendTouchEvent.touchList = null;
|
|
} else {
|
|
var coords = calculateTouchListCoordinates(aTouchPoints);
|
|
var touches = [];
|
|
for (var i = 0; i < coords.length; ++i) {
|
|
var {x, y} = coords[i];
|
|
var node = document.elementFromPoint(x, y);
|
|
var touch = document.createTouch(window, node, aName === 'touchstart' ?
|
|
1 : touchList.item(i).identifier, x, y, x, y);
|
|
touches.push(touch);
|
|
}
|
|
touchList = document.createTouchList(touches);
|
|
sendTouchEvent.touchList = touchList;
|
|
}
|
|
var evt = document.createEvent('TouchEvent');
|
|
evt.initTouchEvent(aName, true, true, window, 0, false, false, false, false,
|
|
touchList, touchList, touchList);
|
|
document.dispatchEvent(evt);
|
|
}
|
|
|
|
sendTouchEvent.touchList = null;
|
|
|
|
/**
|
|
* A map of event names to the functions that actually send them.
|
|
* @type {Object}
|
|
*/
|
|
var eventMap = {
|
|
touchstart: sendTouchEvent,
|
|
touchend: sendTouchEvent,
|
|
touchmove: sendTouchEvent
|
|
};
|
|
|
|
var originalDwellThreshold = GestureSettings.dwellThreshold;
|
|
var originalSwipeMaxDuration = GestureSettings.swipeMaxDuration;
|
|
var originalConsecutiveGestureDelay =
|
|
GestureSettings.maxConsecutiveGestureDelay;
|
|
|
|
/**
|
|
* Attach a listener for the mozAccessFuGesture event that tests its
|
|
* type.
|
|
* @param {Array} aExpectedGestures A stack of expected event types.
|
|
* @param {String} aTitle Title of this sequence, if any.
|
|
* Note: the listener is removed once the stack reaches 0.
|
|
*/
|
|
function testMozAccessFuGesture(aExpectedGestures, aTitle) {
|
|
var types = aExpectedGestures;
|
|
function handleGesture(aEvent) {
|
|
if (aEvent.detail.type !== types[0].type) {
|
|
info('Got ' + aEvent.detail.type + ' waiting for ' + types[0].type);
|
|
// The is not the event of interest.
|
|
return;
|
|
}
|
|
is(!!aEvent.detail.edge, !!types[0].edge);
|
|
is(aEvent.detail.touches.length, types[0].fingers || 1,
|
|
'failed to count fingers: ' + types[0].type);
|
|
ok(true, 'Received correct mozAccessFuGesture: ' +
|
|
JSON.stringify(types.shift()) + '. (' + aTitle + ')');
|
|
if (types.length === 0) {
|
|
win.removeEventListener('mozAccessFuGesture', handleGesture);
|
|
if (AccessFuTest.sequenceCleanup) {
|
|
AccessFuTest.sequenceCleanup();
|
|
}
|
|
AccessFuTest.nextTest();
|
|
}
|
|
}
|
|
win.addEventListener('mozAccessFuGesture', handleGesture);
|
|
}
|
|
|
|
/**
|
|
* Reset the thresholds and max delays that affect gesture rejection.
|
|
* @param {Number} aTimeStamp Gesture time stamp.
|
|
* @param {Boolean} aRemoveDwellThreshold An optional flag to reset dwell
|
|
* threshold.
|
|
* @param {Boolean} aRemoveSwipeMaxDuration An optional flag to reset swipe max
|
|
* duration.
|
|
*/
|
|
function setTimers(aTimeStamp, aRemoveDwellThreshold, aRemoveSwipeMaxDuration) {
|
|
if (!aRemoveDwellThreshold && !aRemoveSwipeMaxDuration) {
|
|
return;
|
|
}
|
|
if (aRemoveDwellThreshold) {
|
|
GestureSettings.dwellThreshold = 0;
|
|
}
|
|
if (aRemoveSwipeMaxDuration) {
|
|
GestureSettings.swipeMaxDuration = 0;
|
|
}
|
|
GestureTracker.current.clearTimer();
|
|
GestureTracker.current.startTimer(aTimeStamp);
|
|
}
|
|
|
|
function resetTimers() {
|
|
GestureSettings.dwellThreshold = originalDwellThreshold;
|
|
GestureSettings.swipeMaxDuration = originalSwipeMaxDuration;
|
|
}
|
|
|
|
/**
|
|
* An extention to AccessFuTest that adds an ability to test a sequence of
|
|
* pointer events and their expected mozAccessFuGesture events.
|
|
* @param {Object} aSequence An object that has a list of pointer events to be
|
|
* generated and the expected mozAccessFuGesture events.
|
|
*/
|
|
AccessFuTest.addSequence = function AccessFuTest_addSequence(aSequence) {
|
|
AccessFuTest.addFunc(function testSequence() {
|
|
testMozAccessFuGesture(aSequence.expectedGestures, aSequence.title);
|
|
var events = aSequence.events;
|
|
function fireEvent(aEvent) {
|
|
var event = {
|
|
points: convertPointCoordinates(aEvent.points),
|
|
type: aEvent.type
|
|
};
|
|
var timeStamp = Date.now();
|
|
resetTimers();
|
|
GestureSettings.maxConsecutiveGestureDelay =
|
|
aEvent.removeConsecutiveGestureDelay ?
|
|
0 : originalConsecutiveGestureDelay;
|
|
GestureTracker.handle(event, timeStamp);
|
|
setTimers(timeStamp, aEvent.removeDwellThreshold,
|
|
aEvent.removeSwipeMaxDuration);
|
|
processEvents();
|
|
}
|
|
function processEvents() {
|
|
if (events.length === 0) {
|
|
return;
|
|
}
|
|
var event = events.shift();
|
|
SimpleTest.executeSoon(function() {
|
|
fireEvent(event);
|
|
});
|
|
}
|
|
processEvents();
|
|
});
|
|
};
|
|
|
|
/**
|
|
* A helper function that loads JSON files.
|
|
* @param {String} aPath A path to a JSON file.
|
|
* @param {Function} aCallback A callback to be called on success.
|
|
*/
|
|
function loadJSON(aPath, aCallback) {
|
|
var request = new XMLHttpRequest();
|
|
request.open('GET', aPath, true);
|
|
request.responseType = 'json';
|
|
request.onload = function onload() {
|
|
aCallback(request.response);
|
|
};
|
|
request.send();
|
|
}
|