зеркало из https://github.com/mozilla/gecko-dev.git
Bug 766238 - Introduce Utils module in jsat. r=davidb
This commit is contained in:
Родитель
543be73801
Коммит
62e7becc7a
|
@ -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.
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
};
|
|
@ -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(
|
||||
|
|
Загрузка…
Ссылка в новой задаче