--- a/accessible/jsat/Gestures.jsm
+++ b/accessible/jsat/Gestures.jsm
@@ -2,25 +2,25 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
/* global Components, GestureSettings, XPCOMUtils, Utils, Promise, Logger */
/* exported GestureSettings, GestureTracker */
/******************************************************************************
All gestures have the following pathways when being resolved(v)/rejected(x):
- Tap -> DoubleTap (v)
+ Tap -> DoubleTap (x)
-> Dwell (x)
-> Swipe (x)
- AndroidTap -> TripleTap (v)
+ AndroidTap -> TripleTap (x)
-> TapHold (x)
-> Swipe (x)
- DoubleTap -> TripleTap (v)
+ DoubleTap -> TripleTap (x)
-> TapHold (x)
-> Explore (x)
TripleTap -> DoubleTapHold (x)
-> Explore (x)
Dwell -> DwellEnd (v)
@@ -355,29 +355,32 @@ Gesture.prototype = {
// reject this gesture promise.
return GestureSettings.maxConsecutiveGestureDelay;
},
/**
* Clear the existing timer.
*/
clearTimer: function Gesture_clearTimer() {
+ Logger.gesture('clearTimeout', this.type);
clearTimeout(this._timer);
delete this._timer;
},
/**
* Start the timer for gesture timeout.
* @param {Number} aTimeStamp An original pointer event's timeStamp that
* started the gesture resolution sequence.
*/
startTimer: function Gesture_startTimer(aTimeStamp) {
+ Logger.gesture('startTimer', this.type);
this.clearTimer();
let delay = this._getDelay(aTimeStamp);
let handler = () => {
+ Logger.gesture('timer handler');
delete this._timer;
if (!this._inProgress) {
this._deferred.reject();
} else if (this._rejectToOnWait) {
this._deferred.reject(this._rejectToOnWait);
}
};
if (delay <= 0) {
@@ -667,69 +670,95 @@ DoubleTapHoldEnd.prototype = Object.crea
DoubleTapHoldEnd.prototype.type = 'doubletapholdend';
/**
* A common tap gesture object.
* @param {Number} aTimeStamp An original pointer event's timeStamp that started
* the gesture resolution sequence.
* @param {Object} aPoints An existing set of points (from previous events).
* @param {?String} aLastEvent Last pointer event type.
- * @param {Function} aRejectTo A constructor for the next gesture to reject to
- * in case no pointermove or pointerup happens within the
+ * @param {Function} aRejectToOnWait A constructor for the next gesture to
+ * reject to in case no pointermove or pointerup happens within the
* GestureSettings.dwellThreshold.
+ * @param {Function} aRejectToOnPointerDown A constructor for the gesture to
+ * reject to if a finger comes down immediately after the tap.
* @param {Function} aTravelTo An optional constuctor for the next gesture to
* reject to in case the the TravelGesture test fails.
*/
-function TapGesture(aTimeStamp, aPoints, aLastEvent, aRejectTo, aTravelTo) {
- this._rejectToOnWait = aRejectTo;
+function TapGesture(aTimeStamp, aPoints, aLastEvent, aRejectToOnWait, aTravelTo, aRejectToOnPointerDown) {
+ this._rejectToOnWait = aRejectToOnWait;
+ this._rejectToOnPointerDown = aRejectToOnPointerDown;
// If the pointer travels, reject to aTravelTo.
TravelGesture.call(this, aTimeStamp, aPoints, aLastEvent, aTravelTo,
TAP_MAX_RADIUS);
}
TapGesture.prototype = Object.create(TravelGesture.prototype);
TapGesture.prototype._getDelay = function TapGesture__getDelay() {
// If, for TapGesture, no pointermove or pointerup happens within the
// GestureSettings.dwellThreshold, reject.
// Note: the original pointer event's timeStamp is irrelevant here.
return GestureSettings.dwellThreshold;
};
+TapGesture.prototype.pointerup = function TapGesture_pointerup(aPoints) {
+ if (this._rejectToOnPointerDown) {
+ let complete = this._update(aPoints, 'pointerup', false, true);
+ if (complete) {
+ this.clearTimer();
+ this._pointerUpTimer = setTimeout(() => {
+ delete this._pointerUpTimer;
+ this._deferred.resolve();
+ }, GestureSettings.maxConsecutiveGestureDelay);
+ }
+ } else {
+ TravelGesture.prototype.pointerup.call(this, aPoints);
+ }
+};
+
+TapGesture.prototype.pointerdown = function TapGesture_pointerdown(aPoints, aTimeStamp) {
+ TravelGesture.prototype.pointerdown.call(this, aPoints, aTimeStamp);
+ if (this._pointerUpTimer) {
+ clearTimeout(this._pointerUpTimer);
+ delete this._pointerUpTimer;
+ this._deferred.reject(this._rejectToOnPointerDown);
+ }
+};
+
+
/**
* Tap gesture.
* @param {Number} aTimeStamp An original pointer event's timeStamp that started
* the gesture resolution sequence.
* @param {Object} aPoints An existing set of points (from previous events).
* @param {?String} aLastEvent Last pointer event type.
*/
function Tap(aTimeStamp, aPoints, aLastEvent) {
// If the pointer travels, reject to Swipe.
- TapGesture.call(this, aTimeStamp, aPoints, aLastEvent, Dwell, Swipe);
+ TapGesture.call(this, aTimeStamp, aPoints, aLastEvent, Dwell, Swipe, DoubleTap);
}
Tap.prototype = Object.create(TapGesture.prototype);
Tap.prototype.type = 'tap';
-Tap.prototype.resolveTo = DoubleTap;
/**
* Tap (multi) gesture on Android.
* @param {Number} aTimeStamp An original pointer event's timeStamp that started
* the gesture resolution sequence.
* @param {Object} aPoints An existing set of points (from previous events).
* @param {?String} aLastEvent Last pointer event type.
*/
function AndroidTap(aTimeStamp, aPoints, aLastEvent) {
// If the pointer travels, reject to Swipe. On dwell threshold reject to
// TapHold.
- TapGesture.call(this, aTimeStamp, aPoints, aLastEvent, TapHold, Swipe);
+ TapGesture.call(this, aTimeStamp, aPoints, aLastEvent, TapHold, Swipe, TripleTap);
}
AndroidTap.prototype = Object.create(TapGesture.prototype);
// Android double taps are translated to single taps.
AndroidTap.prototype.type = 'doubletap';
-AndroidTap.prototype.resolveTo = TripleTap;
/**
* Clear the pointerup handler timer in case of the 3 pointer swipe.
*/
AndroidTap.prototype.clearThreeFingerSwipeTimer = function AndroidTap_clearThreeFingerSwipeTimer() {
clearTimeout(this._threeFingerSwipeTimer);
delete this._threeFingerSwipeTimer;
};
@@ -762,31 +791,32 @@ AndroidTap.prototype.pointerup = functio
/**
* Double Tap gesture.
* @param {Number} aTimeStamp An original pointer event's timeStamp that started
* the gesture resolution sequence.
* @param {Object} aPoints An existing set of points (from previous events).
* @param {?String} aLastEvent Last pointer event type.
*/
function DoubleTap(aTimeStamp, aPoints, aLastEvent) {
- TapGesture.call(this, aTimeStamp, aPoints, aLastEvent, TapHold);
+ this._inProgress = true;
+ TapGesture.call(this, aTimeStamp, aPoints, aLastEvent, TapHold, null, TripleTap);
}
DoubleTap.prototype = Object.create(TapGesture.prototype);
DoubleTap.prototype.type = 'doubletap';
-DoubleTap.prototype.resolveTo = TripleTap;
/**
* Triple Tap gesture.
* @param {Number} aTimeStamp An original pointer event's timeStamp that started
* the gesture resolution sequence.
* @param {Object} aPoints An existing set of points (from previous events).
* @param {?String} aLastEvent Last pointer event type.
*/
function TripleTap(aTimeStamp, aPoints, aLastEvent) {
+ this._inProgress = true;
TapGesture.call(this, aTimeStamp, aPoints, aLastEvent, DoubleTapHold);
}
TripleTap.prototype = Object.create(TapGesture.prototype);
TripleTap.prototype.type = 'tripletap';
/**
* Common base object for gestures that are created as resolved.
--- a/accessible/tests/mochitest/jsat/dom_helper.js
+++ b/accessible/tests/mochitest/jsat/dom_helper.js
@@ -112,17 +112,17 @@ var originalSwipeMaxDuration = GestureSe
function testMozAccessFuGesture(aExpectedGestures) {
var types = aExpectedGestures;
function handleGesture(aEvent) {
if (aEvent.detail.type !== types[0].type) {
// The is not the event of interest.
return;
}
is(!!aEvent.detail.edge, !!types[0].edge);
- ok(true, 'Received correct mozAccessFuGesture: ' + types.shift() + '.');
+ ok(true, 'Received correct mozAccessFuGesture: ' + JSON.stringify(types.shift()) + '.');
if (types.length === 0) {
win.removeEventListener('mozAccessFuGesture', handleGesture);
if (AccessFuTest.sequenceCleanup) {
AccessFuTest.sequenceCleanup();
}
AccessFuTest.nextTest();
}
}
--- a/accessible/tests/mochitest/jsat/gestures.json
+++ b/accessible/tests/mochitest/jsat/gestures.json
@@ -31,52 +31,51 @@
{"type": "pointerup",
"points": [{"x": 1.03, "y": 1.02, "identifier": 1}]},
{"type": "pointerdown", "points": [{"x": 1, "y": 1, "identifier": 1}]},
{"type": "pointermove",
"points": [{"x": 0.97, "y": 1.01, "identifier": 1}]},
{"type": "pointerup",
"points": [{"x": 0.97, "y": 1.01, "identifier": 1}]}
],
- "expectedGestures": [{ "type": "tap" }, { "type": "doubletap" }]
+ "expectedGestures": [{ "type": "doubletap" }]
},
{
"events": [
{"type": "pointerdown", "points": [{"x": 1, "y": 1, "identifier": 1}]},
{"type": "pointerup", "points": [{"x": 1, "y": 1, "identifier": 1}]},
{"type": "pointerdown", "points": [{"x": 1, "y": 1, "identifier": 1}]},
{"type": "pointerup", "points": [{"x": 1, "y": 1, "identifier": 1}]},
{"type": "pointerdown", "points": [{"x": 1, "y": 1, "identifier": 1}]},
{"type": "pointerup", "points": [{"x": 1, "y": 1, "identifier": 1}]}
],
- "expectedGestures": [{ "type": "tap" }, { "type": "doubletap" }, { "type": "tripletap" }]
+ "expectedGestures": [{ "type": "tripletap" }]
},
{
"events": [
{"type": "pointerdown", "points": [{"x": 1, "y": 1, "identifier": 1}]},
{"type": "pointerup", "points": [{"x": 1, "y": 1, "identifier": 1}]},
{"type": "pointerdown", "points": [{"x": 1, "y": 1, "identifier": 1}]},
{"type": "pointerup", "points": [{"x": 1, "y": 1, "identifier": 1}]},
{"type": "pointerdown", "points": [{"x": 1, "y": 1, "identifier": 1}],
"removeDwellThreshold": true},
{"type": "pointerup", "points": [{"x": 1, "y": 1, "identifier": 1}]}
],
- "expectedGestures": [{ "type": "tap" }, { "type": "doubletap" },
- { "type": "doubletaphold" }, { "type": "doubletapholdend" }]
+ "expectedGestures": [{ "type": "doubletaphold" },
+ { "type": "doubletapholdend" }]
},
{
"events": [
{"type": "pointerdown", "points": [{"x": 1, "y": 1, "identifier": 1}]},
{"type": "pointerup", "points": [{"x": 1, "y": 1, "identifier": 1}]},
{"type": "pointerdown", "points": [{"x": 1, "y": 1, "identifier": 1}],
"removeDwellThreshold": true},
{"type": "pointerup", "points": [{"x": 1, "y": 1, "identifier": 1}]}
],
- "expectedGestures": [{ "type": "tap" }, { "type": "taphold" },
- { "type": "tapholdend" }]
+ "expectedGestures": [{ "type": "taphold" }, { "type": "tapholdend" }]
},
{
"events": [
{"type": "pointerdown", "points": [{"x": 1, "y": 1, "identifier": 1}]},
{"type": "pointermove", "points": [{"x": 1.5, "y": 1, "identifier": 1}]},
{"type": "pointerup", "points": [{"x": 1.5, "y": 1, "identifier": 1}]}
],
"expectedGestures": [{ "type": "swiperight" }]