Bug 865449 - Make AccessFu more desktop-browser friendly. r=yzen

- Use Speech presenter on everything but mobile/android
- Filter out accessibility events that are chrome related.
- Don't capture key presses on desktop
- Rework TouchAdapter to take mouse events on desktop.
    Generating touch events does not work on desktop since that interface is preffed out by default.
    We lost the ability to do multiple finger gestures with modifier keys, but that was not really used anyway.
This commit is contained in:
Eitan Isaacson 2013-04-25 12:39:16 -07:00
parent b02f33de95
commit 7336ca6c65
4 changed files with 54 additions and 92 deletions

View File

@ -475,12 +475,18 @@ var Input = {
editState: {},
start: function start() {
Utils.win.document.addEventListener('keypress', this, true);
// XXX: This is too disruptive on desktop for now.
// Might need to add special modifiers.
if (Utils.MozBuildApp != 'browser') {
Utils.win.document.addEventListener('keypress', this, true);
}
Utils.win.addEventListener('mozAccessFuGesture', this, true);
},
stop: function stop() {
Utils.win.document.removeEventListener('keypress', this, true);
if (Utils.MozBuildApp != 'browser') {
Utils.win.document.removeEventListener('keypress', this, true);
}
Utils.win.removeEventListener('mozAccessFuGesture', this, true);
},

View File

@ -105,6 +105,13 @@ this.EventManager = {
Logger.debug('A11yEvent', Logger.eventToString(aEvent),
Logger.accessibleToString(aEvent.accessible));
// Don't bother with non-content events in firefox.
if (Utils.MozBuildApp == 'browser' &&
aEvent.eventType != Ci.nsIAccessibleEvent.EVENT_VIRTUALCURSOR_CHANGED &&
aEvent.accessibleDocument != Utils.CurrentContentDoc) {
return;
}
switch (aEvent.eventType) {
case Ci.nsIAccessibleEvent.EVENT_VIRTUALCURSOR_CHANGED:
{

View File

@ -361,11 +361,11 @@ this.Presentation = {
delete this.presenters;
this.presenters = [new VisualPresenter()];
if (Utils.MozBuildApp == 'b2g') {
if (Utils.MozBuildApp == 'mobile/android') {
this.presenters.push(new AndroidPresenter());
} else {
this.presenters.push(new SpeechPresenter());
this.presenters.push(new HapticPresenter());
} else if (Utils.MozBuildApp == 'mobile/android') {
this.presenters.push(new AndroidPresenter());
}
return this.presenters;

View File

@ -39,8 +39,8 @@ this.TouchAdapter = {
// maximum distance the mouse could move during a tap in inches
TAP_MAX_RADIUS: 0.2,
// The virtual touch ID generated by an Android hover event.
HOVER_ID: 'hover',
// The virtual touch ID generated by a mouse event.
MOUSE_ID: 'mouse',
start: function TouchAdapter_start() {
Logger.info('TouchAdapter.start');
@ -62,16 +62,10 @@ this.TouchAdapter = {
target = this.glass;
}
target.addEventListener('mousemove', this, true, true);
target.addEventListener('mouseenter', this, true, true);
target.addEventListener('mouseleave', this, true, true);
for each (let eventType in this.eventsOfInterest) {
target.addEventListener(eventType, this, true, true);
}
target.addEventListener('touchend', this, true, true);
target.addEventListener('touchmove', this, true, true);
target.addEventListener('touchstart', this, true, true);
if (Utils.OS != 'Android')
Mouse2Touch.start();
},
stop: function TouchAdapter_stop() {
@ -84,19 +78,34 @@ this.TouchAdapter = {
this.glass.parentNode.removeChild(this.glass);
}
target.removeEventListener('mousemove', this, true, true);
target.removeEventListener('mouseenter', this, true, true);
target.removeEventListener('mouseleave', this, true, true);
for each (let eventType in this.eventsOfInterest) {
target.removeEventListener(eventType, this, true, true);
}
},
target.removeEventListener('touchend', this, true, true);
target.removeEventListener('touchmove', this, true, true);
target.removeEventListener('touchstart', this, true, true);
get eventsOfInterest() {
delete this.eventsOfInterest;
if (Utils.OS != 'Android')
Mouse2Touch.stop();
if ('ontouchstart' in Utils.win) {
this.eventsOfInterest = ['touchstart', 'touchmove', 'touchend'];
if (Utils.MozBuildApp == 'mobile/android') {
this.eventsOfInterest.push.apply(
this.eventsOfInterest, ['mouseenter', 'mousemove', 'mouseleave']);
}
} else {
this.eventsOfInterest = ['mousedown', 'mousemove', 'mouseup'];
}
return this.eventsOfInterest;
},
handleEvent: function TouchAdapter_handleEvent(aEvent) {
// Don't bother with chrome mouse events.
if (Utils.MozBuildApp == 'browser' &&
aEvent.view.top instanceof Ci.nsIDOMChromeWindow) {
return;
}
if (this._delayedEvent) {
Utils.win.clearTimeout(this._delayedEvent);
delete this._delayedEvent;
@ -108,13 +117,14 @@ this.TouchAdapter = {
// instead of milliseconds.
let timeStamp = (Utils.OS == 'Android') ? aEvent.timeStamp : Date.now();
switch (aEvent.type) {
case 'mousedown':
case 'mouseenter':
case 'touchstart':
for (var i = 0; i < changedTouches.length; i++) {
let touch = changedTouches[i];
let touchPoint = new TouchPoint(touch, timeStamp, this._dpi);
let identifier = (touch.identifier == undefined) ?
this.HOVER_ID : touch.identifier;
this.MOUSE_ID : touch.identifier;
this._touchPoints[identifier] = touchPoint;
this._lastExploreTime = timeStamp + this.SWIPE_MAX_DURATION;
}
@ -128,7 +138,7 @@ this.TouchAdapter = {
for (var i = 0; i < changedTouches.length; i++) {
let touch = changedTouches[i];
let identifier = (touch.identifier == undefined) ?
this.HOVER_ID : touch.identifier;
this.MOUSE_ID : touch.identifier;
let touchPoint = this._touchPoints[identifier];
if (touchPoint)
touchPoint.update(touch, timeStamp);
@ -138,12 +148,13 @@ this.TouchAdapter = {
this._lastExploreTime = timeStamp;
}
break;
case 'mouseup':
case 'mouseleave':
case 'touchend':
for (var i = 0; i < changedTouches.length; i++) {
let touch = changedTouches[i];
let identifier = (touch.identifier == undefined) ?
this.HOVER_ID : touch.identifier;
this.MOUSE_ID : touch.identifier;
let touchPoint = this._touchPoints[identifier];
if (touchPoint) {
touchPoint.update(touch, timeStamp);
@ -155,6 +166,7 @@ this.TouchAdapter = {
}
aEvent.preventDefault();
aEvent.stopImmediatePropagation();
},
cleanupTouches: function cleanupTouches() {
@ -239,13 +251,13 @@ this.TouchAdapter = {
// to single taps.
if (Utils.MozBuildApp == 'mobile/android' &&
Utils.AndroidSdkVersion >= 14 &&
aDetails.touches[0] != this.HOVER_ID) {
aDetails.touches[0] != this.MOUSE_ID) {
if (aDetails.touches.length == 1) {
if (aDetails.type == 'tap') {
emitDelay = 50;
aDetails.type = 'doubletap';
} else {
aDetails.touches.push(this.HOVER_ID);
aDetails.touches.push(this.MOUSE_ID);
}
}
}
@ -370,66 +382,3 @@ TouchPoint.prototype = {
return this.getDistanceToCoord(this.startX, this.startY);
}
};
var Mouse2Touch = {
_MouseToTouchMap: {
mousedown: 'touchstart',
mouseup: 'touchend',
mousemove: 'touchmove'
},
start: function Mouse2Touch_start() {
Utils.win.addEventListener('mousedown', this, true, true);
Utils.win.addEventListener('mouseup', this, true, true);
Utils.win.addEventListener('mousemove', this, true, true);
},
stop: function Mouse2Touch_stop() {
Utils.win.removeEventListener('mousedown', this, true, true);
Utils.win.removeEventListener('mouseup', this, true, true);
Utils.win.removeEventListener('mousemove', this, true, true);
},
handleEvent: function Mouse2Touch_handleEvent(aEvent) {
if (aEvent.buttons == 0)
return;
let name = this._MouseToTouchMap[aEvent.type];
let evt = Utils.win.document.createEvent("touchevent");
let points = [Utils.win.document.createTouch(
Utils.win, aEvent.target, 0,
aEvent.pageX, aEvent.pageY, aEvent.screenX, aEvent.screenY,
aEvent.clientX, aEvent.clientY, 1, 1, 0, 0)];
// Simulate another touch point at a 5px offset when ctrl is pressed.
if (aEvent.ctrlKey)
points.push(Utils.win.document.createTouch(
Utils.win, aEvent.target, 1,
aEvent.pageX + 5, aEvent.pageY + 5,
aEvent.screenX + 5, aEvent.screenY + 5,
aEvent.clientX + 5, aEvent.clientY + 5,
1, 1, 0, 0));
// Simulate another touch point at a -5px offset when alt is pressed.
if (aEvent.altKey)
points.push(Utils.win.document.createTouch(
Utils.win, aEvent.target, 2,
aEvent.pageX - 5, aEvent.pageY - 5,
aEvent.screenX - 5, aEvent.screenY - 5,
aEvent.clientX - 5, aEvent.clientY - 5,
1, 1, 0, 0));
let touches = Utils.win.document.createTouchList(points);
if (name == "touchend") {
let empty = Utils.win.document.createTouchList();
evt.initTouchEvent(name, true, true, Utils.win, 0,
false, false, false, false, empty, empty, touches);
} else {
evt.initTouchEvent(name, true, true, Utils.win, 0,
false, false, false, false, touches, touches, touches);
}
aEvent.target.dispatchEvent(evt);
aEvent.preventDefault();
aEvent.stopImmediatePropagation();
}
};