Bug 766238 - Introduce Utils module in jsat. r=davidb

This commit is contained in:
Eitan Isaacson 2012-06-20 14:07:51 -07:00
parent c5ed151532
commit 7e79ad818f
4 changed files with 157 additions and 38 deletions

View File

@ -13,6 +13,7 @@ var EXPORTED_SYMBOLS = ['AccessFu'];
Cu.import('resource://gre/modules/Services.jsm');
Cu.import('resource://gre/modules/accessibility/Utils.jsm');
Cu.import('resource://gre/modules/accessibility/Presenters.jsm');
Cu.import('resource://gre/modules/accessibility/VirtualCursorController.jsm');
@ -34,7 +35,7 @@ var AccessFu = {
// XXX: only supports attaching to one window now.
throw new Error('Only one window could be attached to AccessFu');
dump('[AccessFu] attach\n');
Logger.info('attach');
this.chromeWin = aWindow;
this.presenters = [];
@ -43,7 +44,7 @@ var AccessFu = {
this.prefsBranch.addObserver('activate', this, false);
this.prefsBranch.addObserver('explorebytouch', this, false);
if (Services.appinfo.OS == 'Android')
if (Utils.OS == 'Android')
Services.obs.addObserver(this, 'Accessibility:Settings', false);
this._processPreferences();
@ -58,11 +59,11 @@ var AccessFu = {
return;
this._enabled = true;
dump('[AccessFu] enable\n');
Logger.info('enable');
this.addPresenter(new VisualPresenter());
// Implicitly add the Android presenter on Android.
if (Services.appinfo.OS == 'Android')
if (Utils.OS == 'Android')
this.addPresenter(new AndroidPresenter());
VirtualCursorController.attach(this.chromeWin);
@ -83,7 +84,7 @@ var AccessFu = {
return;
this._enabled = false;
dump('[AccessFu] disable\n');
Logger.info('disable');
this.presenters.forEach(function(p) { p.detach(); });
this.presenters = [];
@ -113,7 +114,7 @@ var AccessFu = {
} catch (x) {
}
if (Services.appinfo.OS == 'Android') {
if (Utils.OS == 'Android') {
if (accessPref == ACCESSFU_AUTO) {
Cc['@mozilla.org/android/bridge;1'].
getService(Ci.nsIAndroidBridge).handleGeckoMessage(
@ -128,8 +129,7 @@ var AccessFu = {
this._disable();
VirtualCursorController.exploreByTouch = ebtPref == ACCESSFU_ENABLE;
dump('[AccessFu] Explore by touch: ' +
VirtualCursorController.exploreByTouch + '\n');
Logger.info('Explore by touch:', VirtualCursorController.exploreByTouch);
},
addPresenter: function addPresenter(presenter) {
@ -160,7 +160,11 @@ var AccessFu = {
// If it has, than we will need to send a 'loading' message along with
// the usual 'newdoc' to presenters.
this._pendingDocuments[browser] = true;
this.presenters.forEach(function(p) { p.tabStateChanged(null, 'newtab'); });
this.presenters.forEach(
function(p) {
p.tabStateChanged(null, 'newtab');
}
);
break;
}
case 'DOMActivate':
@ -205,13 +209,17 @@ var AccessFu = {
event = aSubject.QueryInterface(Ci.nsIAccessibleEvent);
this._handleAccEvent(event);
} catch (ex) {
dump('[AccessFu] ' + ex + '\n');
Logger.error(ex);
return;
}
}
},
_handleAccEvent: function _handleAccEvent(aEvent) {
if (Logger.logLevel <= Logger.DEBUG)
Logger.debug(Logger.eventToString(aEvent),
Logger.accessibleToString(aEvent.accessible));
switch (aEvent.eventType) {
case Ci.nsIAccessibleEvent.EVENT_VIRTUALCURSOR_CHANGED:
{
@ -267,8 +275,8 @@ var AccessFu = {
// in a BUSY state (i.e. loading), and inform presenters.
// We need to do this because a state change event will not be
// fired when an object is created with the BUSY state.
// If this is not a new tab, don't bother because we sent 'loading'
// when the previous doc changed its state to BUSY.
// If this is not a new tab, don't bother because we sent
// 'loading' when the previous doc changed its state to BUSY.
let state = {};
docAcc.getState(state, {});
if (state.value & Ci.nsIAccessibleStates.STATE_BUSY &&
@ -322,22 +330,23 @@ var AccessFu = {
// XXX support live regions as well.
let event = aEvent.QueryInterface(Ci.nsIAccessibleTextChangeEvent);
let isInserted = event.isInserted();
let textIface = aEvent.accessible.QueryInterface(Ci.nsIAccessibleText);
let txtIface = aEvent.accessible.QueryInterface(Ci.nsIAccessibleText);
let text = '';
try {
text = textIface.
text = txtIface.
getText(0, Ci.nsIAccessibleText.TEXT_OFFSET_END_OF_TEXT);
} catch (x) {
// XXX we might have gotten an exception with of a
// zero-length text. If we did, ignore it (bug #749810).
if (textIface.characterCount)
if (txtIface.characterCount)
throw x;
}
this.presenters.forEach(
function(p) {
p.textChanged(isInserted, event.start, event.length, text, event.modifiedText);
p.textChanged(isInserted, event.start, event.length,
text, event.modifiedText);
}
);
}
@ -391,7 +400,7 @@ var AccessFu = {
if (!location)
return false;
return location.protocol != "about:";
return location.protocol != 'about:';
},
// A hash of documents that don't yet have an accessible tree.

View File

@ -9,8 +9,8 @@ const Ci = Components.interfaces;
const Cu = Components.utils;
const Cr = Components.results;
Cu.import('resource://gre/modules/accessibility/Utils.jsm');
Cu.import('resource://gre/modules/accessibility/UtteranceGenerator.jsm');
Cu.import('resource://gre/modules/Services.jsm');
var EXPORTED_SYMBOLS = ['VisualPresenter',
'AndroidPresenter',
@ -153,7 +153,7 @@ VisualPresenter.prototype = {
Ci.nsIAccessibleScrollType.SCROLL_TYPE_ANYWHERE);
this._highlight(aContext.accessible);
} catch (e) {
dump('Error getting bounds: ' + e);
Logger.error('Failed to get bounds: ' + e);
return;
}
},
@ -175,10 +175,7 @@ VisualPresenter.prototype = {
},
_highlight: function _highlight(aObject) {
let vp = (Services.appinfo.OS == 'Android') ?
this.chromeWin.BrowserApp.selectedTab.getViewport() :
{ zoom: 1.0, offsetY: 0 };
let vp = Utils.getViewport(this.chromeWin) || { zoom: 1.0, offsetY: 0 };
let bounds = this._getBounds(aObject, vp.zoom);
// First hide it to avoid flickering when changing the style.
@ -239,7 +236,7 @@ AndroidPresenter.prototype = {
let output = [];
aContext.newAncestry.forEach(
function (acc) {
function(acc) {
output.push.apply(output, UtteranceGenerator.genForObject(acc));
}
);
@ -248,7 +245,7 @@ AndroidPresenter.prototype = {
UtteranceGenerator.genForObject(aContext.accessible));
aContext.subtreePreorder.forEach(
function (acc) {
function(acc) {
output.push.apply(output, UtteranceGenerator.genForObject(acc));
}
);
@ -339,7 +336,7 @@ DummyAndroidPresenter.prototype = {
__proto__: AndroidPresenter.prototype,
sendMessageToJava: function DummyAndroidPresenter_sendMessageToJava(aMsg) {
dump(JSON.stringify(aMsg, null, 2) + '\n');
Logger.debug('Android event:\n' + JSON.stringify(aMsg, null, 2));
}
};

View File

@ -0,0 +1,121 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* 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/. */
'use strict';
const Cu = Components.utils;
const Cc = Components.classes;
const Ci = Components.interfaces;
Cu.import('resource://gre/modules/Services.jsm');
var EXPORTED_SYMBOLS = ['Utils', 'Logger'];
var gAccRetrieval = Cc['@mozilla.org/accessibleRetrieval;1'].
getService(Ci.nsIAccessibleRetrieval);
var Utils = {
get OS() {
if (!this._OS)
this._OS = Services.appinfo.OS;
return this._OS;
},
get AndroidSdkVersion() {
if (!this._AndroidSdkVersion) {
let shellVersion = Services.sysinfo.get('shellVersion') || '';
let matches = shellVersion.match(/\((\d+)\)$/);
if (matches)
this._AndroidSdkVersion = parseInt(matches[1]);
else
this._AndroidSdkVersion = 15; // Most useful in desktop debugging.
}
return this._AndroidSdkVersion;
},
set AndroidSdkVersion(value) {
// When we want to mimic another version.
this._AndroidSdkVersion = value;
},
getBrowserApp: function getBrowserApp(aWindow) {
switch (this.OS) {
case 'Android':
return aWindow.BrowserApp;
default:
return aWindow.gBrowser;
}
},
getViewport: function getViewport(aWindow) {
switch (this.OS) {
case 'Android':
return aWindow.BrowserApp.selectedTab.getViewport();
default:
return null;
}
}
};
var Logger = {
DEBUG: 0,
INFO: 1,
WARNING: 2,
ERROR: 3,
_LEVEL_NAMES: ['DEBUG', 'INFO', 'WARNING', 'ERROR'],
logLevel: 1, // INFO;
log: function log(aLogLevel) {
if (aLogLevel < this.logLevel)
return;
let message = Array.prototype.slice.call(arguments, 1).join(' ');
dump('[AccessFu] ' + this._LEVEL_NAMES[aLogLevel] + ' ' + message + '\n');
},
info: function info() {
this.log.apply(
this, [this.INFO].concat(Array.prototype.slice.call(arguments)));
},
debug: function debug() {
this.log.apply(
this, [this.DEBUG].concat(Array.prototype.slice.call(arguments)));
},
warning: function warning() {
this.log.apply(
this, [this.WARNING].concat(Array.prototype.slice.call(arguments)));
},
error: function error() {
this.log.apply(
this, [this.ERROR].concat(Array.prototype.slice.call(arguments)));
},
accessibleToString: function accessibleToString(aAccessible) {
let str = '[ defunct ]';
try {
str = '[ ' + gAccRetrieval.getStringRole(aAccessible.role) +
' | ' + aAccessible.name + ' ]';
} catch (x) {
}
return str;
},
eventToString: function eventToString(aEvent) {
let str = gAccRetrieval.getStringEventType(aEvent.eventType);
if (aEvent.eventType == Ci.nsIAccessibleEvent.EVENT_STATE_CHANGE) {
let event = aEvent.QueryInterface(Ci.nsIAccessibleStateChangeEvent);
let stateStrings = (event.isExtraState()) ?
gAccRetrieval.getStringStates(0, event.state) :
gAccRetrieval.getStringStates(event.state, 0);
str += ' (' + stateStrings.item(0) + ')';
}
return str;
}
};

View File

@ -11,8 +11,8 @@ const Cr = Components.results;
var EXPORTED_SYMBOLS = ['VirtualCursorController'];
Cu.import('resource://gre/modules/accessibility/Utils.jsm');
Cu.import('resource://gre/modules/XPCOMUtils.jsm');
Cu.import('resource://gre/modules/Services.jsm');
var gAccRetrieval = Cc['@mozilla.org/accessibleRetrieval;1'].
getService(Ci.nsIAccessibleRetrieval);
@ -419,17 +419,9 @@ var VirtualCursorController = {
this.chromeWin.document.removeEventListener('keypress', this, true);
},
_getBrowserApp: function _getBrowserApp() {
switch (Services.appinfo.OS) {
case 'Android':
return this.chromeWin.BrowserApp;
default:
return this.chromeWin.gBrowser;
}
},
handleEvent: function handleEvent(aEvent) {
let document = this._getBrowserApp().selectedBrowser.contentDocument;
let document = Utils.getBrowserApp(this.chromeWin).
selectedBrowser.contentDocument;
let target = aEvent.target;
switch (aEvent.keyCode) {
@ -487,7 +479,7 @@ var VirtualCursorController = {
target.blur();
}
if (Services.appinfo.OS == 'Android')
if (Utils.OS == 'Android')
// Return focus to native Android browser chrome.
Cc['@mozilla.org/android/bridge;1'].
getService(Ci.nsIAndroidBridge).handleGeckoMessage(