mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-05-13 08:57:27 +00:00
Bug 978075 - Screen reader turn on and off announce. r=yzen
This patch does several other things: 1. When a PrefCache with no default setting available is created, or cleared, set value to null. 2. Removed weird margin change in announce box. 3. Add announce method to speech presenter. 4. Don't start and stop AccessFu implicitly in AccessFuTest. 5. Change tests to two start/stop pairs where in one pair we activate via pref, and the other one via settings (TODO).
This commit is contained in:
parent
dc243c34da
commit
e22a4c8a91
@ -38,7 +38,6 @@
|
||||
|
||||
#announce-box:not(.showing) {
|
||||
opacity: 0.0;
|
||||
margin: 0.1em;
|
||||
-moz-transition: opacity 0.4s linear;
|
||||
}
|
||||
|
||||
|
@ -134,6 +134,11 @@ this.AccessFu = {
|
||||
this.readyCallback();
|
||||
delete this.readyCallback;
|
||||
}
|
||||
|
||||
if (Utils.MozBuildApp !== 'mobile/android') {
|
||||
this.announce(
|
||||
Utils.stringBundle.GetStringFromName('screenReaderStarted'));
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
@ -149,6 +154,11 @@ this.AccessFu = {
|
||||
|
||||
Utils.win.document.removeChild(this.stylesheet.get());
|
||||
|
||||
if (Utils.MozBuildApp !== 'mobile/android') {
|
||||
this.announce(
|
||||
Utils.stringBundle.GetStringFromName('screenReaderStopped'));
|
||||
}
|
||||
|
||||
for each (let mm in Utils.AllMessageManagers) {
|
||||
mm.sendAsyncMessage('AccessFu:Stop');
|
||||
this._removeMessageListeners(mm);
|
||||
@ -368,8 +378,7 @@ this.AccessFu = {
|
||||
},
|
||||
|
||||
announce: function announce(aAnnouncement) {
|
||||
this._output(Presentation.announce(aAnnouncement),
|
||||
Utils.CurrentBrowser);
|
||||
this._output(Presentation.announce(aAnnouncement), Utils.CurrentBrowser);
|
||||
},
|
||||
|
||||
// So we don't enable/disable twice
|
||||
@ -515,7 +524,8 @@ var Output = {
|
||||
|
||||
init: function init() {
|
||||
let window = Utils.win;
|
||||
this.webspeechEnabled = !!window.speechSynthesis;
|
||||
this.webspeechEnabled = !!window.speechSynthesis &&
|
||||
!!window.SpeechSynthesisUtterance;
|
||||
|
||||
let settingsToGet = 2;
|
||||
let settingsCallback = (aName, aSetting) => {
|
||||
|
@ -33,10 +33,6 @@ XPCOMUtils.defineLazyModuleGetter(this, 'Roles',
|
||||
XPCOMUtils.defineLazyModuleGetter(this, 'States',
|
||||
'resource://gre/modules/accessibility/Constants.jsm');
|
||||
|
||||
var gStringBundle = Cc['@mozilla.org/intl/stringbundle;1'].
|
||||
getService(Ci.nsIStringBundleService).
|
||||
createBundle('chrome://global/locale/AccessFu.properties');
|
||||
|
||||
this.EXPORTED_SYMBOLS = ['UtteranceGenerator', 'BrailleGenerator'];
|
||||
|
||||
this.OutputGenerator = {
|
||||
@ -194,7 +190,7 @@ this.OutputGenerator = {
|
||||
return;
|
||||
}
|
||||
|
||||
let landmark = gStringBundle.GetStringFromName(landmarkName);
|
||||
let landmark = Utils.stringBundle.GetStringFromName(landmarkName);
|
||||
if (!landmark) {
|
||||
return;
|
||||
}
|
||||
@ -221,7 +217,7 @@ this.OutputGenerator = {
|
||||
}
|
||||
typeName = 'textInputType_' + typeName;
|
||||
try {
|
||||
aDesc.push(gStringBundle.GetStringFromName(typeName));
|
||||
aDesc.push(Utils.stringBundle.GetStringFromName(typeName));
|
||||
} catch (x) {
|
||||
Logger.warning('Failed to get a string from a bundle for', typeName);
|
||||
}
|
||||
@ -244,7 +240,7 @@ this.OutputGenerator = {
|
||||
_getLocalizedState: function _getLocalizedState(aState) {},
|
||||
|
||||
_getPluralFormString: function _getPluralFormString(aString, aCount) {
|
||||
let str = gStringBundle.GetStringFromName(this._getOutputName(aString));
|
||||
let str = Utils.stringBundle.GetStringFromName(this._getOutputName(aString));
|
||||
str = PluralForm.get(aCount, str);
|
||||
return str.replace('#1', aCount);
|
||||
},
|
||||
@ -378,7 +374,7 @@ this.OutputGenerator = {
|
||||
let output = [];
|
||||
let desc = this._getLocalizedState(aState);
|
||||
desc.push(
|
||||
gStringBundle.formatStringFromName(
|
||||
Utils.stringBundle.formatStringFromName(
|
||||
'objItemOf', [localizedRole, itemno.value, itemof.value], 3));
|
||||
output.push(desc.join(' '));
|
||||
|
||||
@ -406,7 +402,7 @@ this.OutputGenerator = {
|
||||
table.columnCount);
|
||||
let tableRowInfo = this._getPluralFormString('tableRowInfo',
|
||||
table.rowCount);
|
||||
output.push(gStringBundle.formatStringFromName(
|
||||
output.push(Utils.stringBundle.formatStringFromName(
|
||||
this._getOutputName('tableInfo'), [this._getLocalizedRole(aRoleStr),
|
||||
tableColumnInfo, tableRowInfo], 3));
|
||||
this._addName(output, aAccessible, aFlags);
|
||||
@ -455,13 +451,13 @@ this.UtteranceGenerator = {
|
||||
|
||||
//TODO: May become more verbose in the future.
|
||||
genForAction: function genForAction(aObject, aActionName) {
|
||||
return [gStringBundle.GetStringFromName(this.gActionMap[aActionName])];
|
||||
return [Utils.stringBundle.GetStringFromName(this.gActionMap[aActionName])];
|
||||
},
|
||||
|
||||
genForLiveRegion: function genForLiveRegion(aContext, aIsHide, aModifiedText) {
|
||||
let utterance = [];
|
||||
if (aIsHide) {
|
||||
utterance.push(gStringBundle.GetStringFromName('hidden'));
|
||||
utterance.push(Utils.stringBundle.GetStringFromName('hidden'));
|
||||
}
|
||||
return utterance.concat(
|
||||
aModifiedText || this.genForContext(aContext).output);
|
||||
@ -469,7 +465,7 @@ this.UtteranceGenerator = {
|
||||
|
||||
genForAnnouncement: function genForAnnouncement(aAnnouncement) {
|
||||
try {
|
||||
return [gStringBundle.GetStringFromName(aAnnouncement)];
|
||||
return [Utils.stringBundle.GetStringFromName(aAnnouncement)];
|
||||
} catch (x) {
|
||||
return [aAnnouncement];
|
||||
}
|
||||
@ -478,24 +474,24 @@ this.UtteranceGenerator = {
|
||||
genForTabStateChange: function genForTabStateChange(aObject, aTabState) {
|
||||
switch (aTabState) {
|
||||
case 'newtab':
|
||||
return [gStringBundle.GetStringFromName('tabNew')];
|
||||
return [Utils.stringBundle.GetStringFromName('tabNew')];
|
||||
case 'loading':
|
||||
return [gStringBundle.GetStringFromName('tabLoading')];
|
||||
return [Utils.stringBundle.GetStringFromName('tabLoading')];
|
||||
case 'loaded':
|
||||
return [aObject.name || '',
|
||||
gStringBundle.GetStringFromName('tabLoaded')];
|
||||
Utils.stringBundle.GetStringFromName('tabLoaded')];
|
||||
case 'loadstopped':
|
||||
return [gStringBundle.GetStringFromName('tabLoadStopped')];
|
||||
return [Utils.stringBundle.GetStringFromName('tabLoadStopped')];
|
||||
case 'reload':
|
||||
return [gStringBundle.GetStringFromName('tabReload')];
|
||||
return [Utils.stringBundle.GetStringFromName('tabReload')];
|
||||
default:
|
||||
return [];
|
||||
}
|
||||
},
|
||||
|
||||
genForEditingMode: function genForEditingMode(aIsEditing) {
|
||||
return [gStringBundle.GetStringFromName(
|
||||
aIsEditing ? 'editingMode' : 'navigationMode')];
|
||||
return [Utils.stringBundle.GetStringFromName(
|
||||
aIsEditing ? 'editingMode' : 'navigationMode')];
|
||||
},
|
||||
|
||||
objectOutputFunctions: {
|
||||
@ -510,7 +506,8 @@ this.UtteranceGenerator = {
|
||||
let level = {};
|
||||
aAccessible.groupPosition(level, {}, {});
|
||||
let utterance =
|
||||
[gStringBundle.formatStringFromName('headingLevel', [level.value], 1)];
|
||||
[Utils.stringBundle.formatStringFromName(
|
||||
'headingLevel', [level.value], 1)];
|
||||
|
||||
this._addName(utterance, aAccessible, aFlags);
|
||||
this._addLandmark(utterance, aAccessible);
|
||||
@ -524,9 +521,9 @@ this.UtteranceGenerator = {
|
||||
aAccessible.groupPosition({}, itemof, itemno);
|
||||
let utterance = [];
|
||||
if (itemno.value == 1) // Start of list
|
||||
utterance.push(gStringBundle.GetStringFromName('listStart'));
|
||||
utterance.push(Utils.stringBundle.GetStringFromName('listStart'));
|
||||
else if (itemno.value == itemof.value) // last item
|
||||
utterance.push(gStringBundle.GetStringFromName('listEnd'));
|
||||
utterance.push(Utils.stringBundle.GetStringFromName('listEnd'));
|
||||
|
||||
this._addName(utterance, aAccessible, aFlags);
|
||||
this._addLandmark(utterance, aAccessible);
|
||||
@ -560,13 +557,13 @@ this.UtteranceGenerator = {
|
||||
let desc = [];
|
||||
let addCellChanged = function addCellChanged(aDesc, aChanged, aString, aIndex) {
|
||||
if (aChanged) {
|
||||
aDesc.push(gStringBundle.formatStringFromName(aString,
|
||||
aDesc.push(Utils.stringBundle.formatStringFromName(aString,
|
||||
[aIndex + 1], 1));
|
||||
}
|
||||
};
|
||||
let addExtent = function addExtent(aDesc, aExtent, aString) {
|
||||
if (aExtent > 1) {
|
||||
aDesc.push(gStringBundle.formatStringFromName(aString,
|
||||
aDesc.push(Utils.stringBundle.formatStringFromName(aString,
|
||||
[aExtent], 1));
|
||||
}
|
||||
};
|
||||
@ -609,7 +606,8 @@ this.UtteranceGenerator = {
|
||||
|
||||
_getLocalizedRole: function _getLocalizedRole(aRoleStr) {
|
||||
try {
|
||||
return gStringBundle.GetStringFromName(this._getOutputName(aRoleStr));
|
||||
return Utils.stringBundle.GetStringFromName(
|
||||
this._getOutputName(aRoleStr));
|
||||
} catch (x) {
|
||||
return '';
|
||||
}
|
||||
@ -619,7 +617,8 @@ this.UtteranceGenerator = {
|
||||
let stateUtterances = [];
|
||||
|
||||
if (aState.contains(States.UNAVAILABLE)) {
|
||||
stateUtterances.push(gStringBundle.GetStringFromName('stateUnavailable'));
|
||||
stateUtterances.push(
|
||||
Utils.stringBundle.GetStringFromName('stateUnavailable'));
|
||||
}
|
||||
|
||||
// Don't utter this in Jelly Bean, we let TalkBack do it for us there.
|
||||
@ -629,29 +628,33 @@ this.UtteranceGenerator = {
|
||||
if (Utils.AndroidSdkVersion < 16 && aState.contains(States.CHECKABLE)) {
|
||||
let statetr = aState.contains(States.CHECKED) ?
|
||||
'stateChecked' : 'stateNotChecked';
|
||||
stateUtterances.push(gStringBundle.GetStringFromName(statetr));
|
||||
stateUtterances.push(Utils.stringBundle.GetStringFromName(statetr));
|
||||
}
|
||||
|
||||
if (aState.contains(States.EXPANDABLE)) {
|
||||
let statetr = aState.contains(States.EXPANDED) ?
|
||||
'stateExpanded' : 'stateCollapsed';
|
||||
stateUtterances.push(gStringBundle.GetStringFromName(statetr));
|
||||
stateUtterances.push(Utils.stringBundle.GetStringFromName(statetr));
|
||||
}
|
||||
|
||||
if (aState.contains(States.REQUIRED)) {
|
||||
stateUtterances.push(gStringBundle.GetStringFromName('stateRequired'));
|
||||
stateUtterances.push(
|
||||
Utils.stringBundle.GetStringFromName('stateRequired'));
|
||||
}
|
||||
|
||||
if (aState.contains(States.TRAVERSED)) {
|
||||
stateUtterances.push(gStringBundle.GetStringFromName('stateTraversed'));
|
||||
stateUtterances.push(
|
||||
Utils.stringBundle.GetStringFromName('stateTraversed'));
|
||||
}
|
||||
|
||||
if (aState.contains(States.HASPOPUP)) {
|
||||
stateUtterances.push(gStringBundle.GetStringFromName('stateHasPopup'));
|
||||
stateUtterances.push(
|
||||
Utils.stringBundle.GetStringFromName('stateHasPopup'));
|
||||
}
|
||||
|
||||
if (aState.contains(States.SELECTED)) {
|
||||
stateUtterances.push(gStringBundle.GetStringFromName('stateSelected'));
|
||||
stateUtterances.push(
|
||||
Utils.stringBundle.GetStringFromName('stateSelected'));
|
||||
}
|
||||
|
||||
return stateUtterances;
|
||||
@ -744,7 +747,7 @@ this.BrailleGenerator = {
|
||||
}
|
||||
};
|
||||
|
||||
desc.push(gStringBundle.formatStringFromName(
|
||||
desc.push(Utils.stringBundle.formatStringFromName(
|
||||
this._getOutputName('cellInfo'), [cell.columnIndex + 1,
|
||||
cell.rowIndex + 1], 2));
|
||||
|
||||
@ -815,10 +818,11 @@ this.BrailleGenerator = {
|
||||
|
||||
_getLocalizedRole: function _getLocalizedRole(aRoleStr) {
|
||||
try {
|
||||
return gStringBundle.GetStringFromName(this._getOutputName(aRoleStr));
|
||||
return Utils.stringBundle.GetStringFromName(
|
||||
this._getOutputName(aRoleStr));
|
||||
} catch (x) {
|
||||
try {
|
||||
return gStringBundle.GetStringFromName(
|
||||
return Utils.stringBundle.GetStringFromName(
|
||||
OutputGenerator._getOutputName(aRoleStr));
|
||||
} catch (y) {
|
||||
return '';
|
||||
|
@ -499,6 +499,17 @@ SpeechPresenter.prototype = {
|
||||
}]
|
||||
}
|
||||
};
|
||||
},
|
||||
|
||||
announce: function SpeechPresenter_announce(aAnnouncement) {
|
||||
return {
|
||||
type: this.type,
|
||||
details: {
|
||||
actions: [{
|
||||
method: 'speak', data: aAnnouncement, options: { enqueue: false }
|
||||
}]
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -169,6 +169,13 @@ this.Utils = {
|
||||
return this.isContentProcess;
|
||||
},
|
||||
|
||||
get stringBundle() {
|
||||
delete this.stringBundle;
|
||||
this.stringBundle = Services.strings.createBundle(
|
||||
'chrome://global/locale/AccessFu.properties');
|
||||
return this.stringBundle;
|
||||
},
|
||||
|
||||
getMessageManager: function getMessageManager(aBrowser) {
|
||||
try {
|
||||
return aBrowser.QueryInterface(Ci.nsIFrameLoaderOwner).
|
||||
@ -775,18 +782,23 @@ this.PrefCache = function PrefCache(aName, aCallback, aRunCallbackNow) {
|
||||
|
||||
PrefCache.prototype = {
|
||||
_getValue: function _getValue(aBranch) {
|
||||
if (!this.type) {
|
||||
this.type = aBranch.getPrefType(this.name);
|
||||
}
|
||||
switch (this.type) {
|
||||
case Ci.nsIPrefBranch.PREF_STRING:
|
||||
return aBranch.getCharPref(this.name);
|
||||
case Ci.nsIPrefBranch.PREF_INT:
|
||||
return aBranch.getIntPref(this.name);
|
||||
case Ci.nsIPrefBranch.PREF_BOOL:
|
||||
return aBranch.getBoolPref(this.name);
|
||||
default:
|
||||
return null;
|
||||
try {
|
||||
if (!this.type) {
|
||||
this.type = aBranch.getPrefType(this.name);
|
||||
}
|
||||
switch (this.type) {
|
||||
case Ci.nsIPrefBranch.PREF_STRING:
|
||||
return aBranch.getCharPref(this.name);
|
||||
case Ci.nsIPrefBranch.PREF_INT:
|
||||
return aBranch.getIntPref(this.name);
|
||||
case Ci.nsIPrefBranch.PREF_BOOL:
|
||||
return aBranch.getBoolPref(this.name);
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
} catch (x) {
|
||||
// Pref does not exist.
|
||||
return null;
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -93,16 +93,11 @@ var AccessFuTest = {
|
||||
// Disable the console service logging.
|
||||
Logger.test = false;
|
||||
Logger.logLevel = Logger.INFO;
|
||||
AccessFu.doneCallback = function doneCallback() {
|
||||
// This is being called once AccessFu has been shut down.
|
||||
// Detach AccessFu from everything it attached itself to.
|
||||
// Finish through idle callback to let AccessFu._disable complete.
|
||||
SimpleTest.executeSoon(function () {
|
||||
AccessFu.detach();
|
||||
// and finish the test run.
|
||||
SimpleTest.finish();
|
||||
};
|
||||
// Tear down accessibility and make AccessFu stop.
|
||||
SpecialPowers.setIntPref("accessibility.accessfu.notify_output", 0);
|
||||
SpecialPowers.setIntPref("accessibility.accessfu.activate", 0);
|
||||
});
|
||||
},
|
||||
|
||||
nextTest: function AccessFuTest_nextTest() {
|
||||
@ -138,8 +133,12 @@ var AccessFuTest = {
|
||||
// Enable logging to the console service.
|
||||
Logger.test = true;
|
||||
Logger.logLevel = Logger.DEBUG;
|
||||
// This is being called once accessibility has been turned on.
|
||||
};
|
||||
|
||||
SpecialPowers.pushPrefEnv({
|
||||
'set': [['accessibility.accessfu.notify_output', 1],
|
||||
['dom.mozSettings.enabled', true]]
|
||||
}, function () {
|
||||
if (AccessFuTest._waitForExplicitFinish) {
|
||||
// Run all test functions asynchronously.
|
||||
AccessFuTest.nextTest();
|
||||
@ -148,11 +147,7 @@ var AccessFuTest = {
|
||||
[testFunc() for (testFunc of gTestFuncs)];
|
||||
AccessFuTest.finish();
|
||||
}
|
||||
};
|
||||
|
||||
// Invoke the whole thing.
|
||||
SpecialPowers.setIntPref("accessibility.accessfu.activate", 1);
|
||||
SpecialPowers.setIntPref("accessibility.accessfu.notify_output", 1);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -13,43 +13,57 @@
|
||||
src="./jsatcommon.js"></script>
|
||||
<script type="application/javascript">
|
||||
|
||||
function confirmAccessFuStart() {
|
||||
ok(AccessFu._enabled, "AccessFu was started and enabled.");
|
||||
AccessFuTest.nextTest();
|
||||
function prefStart() {
|
||||
// Start AccessFu via pref.
|
||||
SpecialPowers.setIntPref("accessibility.accessfu.activate", 1);
|
||||
AccessFuTest.once_log("EventManager.start", AccessFuTest.nextTest);
|
||||
}
|
||||
|
||||
// Listen for 'EventManager.stop' and enable AccessFu again.
|
||||
function onStop() {
|
||||
function settingsStart() {
|
||||
ok(true, "EventManager was stopped.");
|
||||
isnot(AccessFu._enabled, true, "AccessFu was disabled.");
|
||||
AccessFuTest.once_log("EventManager.start", AccessFuTest.nextTest);
|
||||
AccessFu._enable();
|
||||
AccessFuTest.once([{
|
||||
"method": "speak",
|
||||
"data": "Screen reader started",
|
||||
"options": {
|
||||
"enqueue": false
|
||||
}
|
||||
}], AccessFuTest.nextTest);
|
||||
// XXX: Bug 978076 - test start with SettingsManager.
|
||||
//navigator.mozSettings.createLock().set(
|
||||
// {'accessibility.screenreader': false});
|
||||
AccessFu._enable()
|
||||
}
|
||||
|
||||
// Make sure EventManager is started again.
|
||||
function onFinalStart() {
|
||||
ok(true, "EventManager was started again.");
|
||||
function settingsStop() {
|
||||
ok(AccessFu._enabled, "AccessFu was enabled again.");
|
||||
AccessFuTest.finish();
|
||||
}
|
||||
|
||||
// Listen for initial 'EventManager.start' and disable AccessFu.
|
||||
function onInitialStart() {
|
||||
ok(true, "EventManager was started.");
|
||||
AccessFuTest.once_log("EventManager.stop", AccessFuTest.nextTest);
|
||||
AccessFuTest.once([{
|
||||
"method": "speak",
|
||||
"data": "Screen reader stopped",
|
||||
"options": {
|
||||
"enqueue": false
|
||||
}
|
||||
}], AccessFuTest.finish);
|
||||
// XXX: Bug 978076 - test stop with SettingsManager.
|
||||
//navigator.mozSettings.createLock().set(
|
||||
// {'accessibility.screenreader': false});
|
||||
AccessFu._disable();
|
||||
}
|
||||
|
||||
function init() {
|
||||
AccessFuTest.once_log("EventManager.start", AccessFuTest.nextTest);
|
||||
// Listen for initial 'EventManager.start' and disable AccessFu.
|
||||
function prefStop() {
|
||||
ok(AccessFu._enabled, "AccessFu was started via preference.");
|
||||
AccessFuTest.once_log("EventManager.stop", AccessFuTest.nextTest);
|
||||
SpecialPowers.setIntPref("accessibility.accessfu.activate", 0);
|
||||
}
|
||||
|
||||
function doTest() {
|
||||
AccessFuTest.addFunc(confirmAccessFuStart);
|
||||
AccessFuTest.addFunc(init);
|
||||
AccessFuTest.addFunc(onInitialStart);
|
||||
AccessFuTest.addFunc(onStop);
|
||||
AccessFuTest.addFunc(onFinalStart);
|
||||
AccessFuTest.addFunc(prefStart);
|
||||
AccessFuTest.addFunc(prefStop);
|
||||
AccessFuTest.addFunc(settingsStart);
|
||||
AccessFuTest.addFunc(settingsStop);
|
||||
AccessFuTest.waitForExplicitFinish();
|
||||
AccessFuTest.runTests(); // Will call SimpleTest.finish();
|
||||
}
|
||||
|
@ -13,10 +13,16 @@
|
||||
src="./jsatcommon.js"></script>
|
||||
<script type="application/javascript">
|
||||
|
||||
function EventManagerStarted() {
|
||||
function startAccessFu() {
|
||||
SpecialPowers.setIntPref("accessibility.accessfu.activate", 1);
|
||||
AccessFuTest.once_log("EventManager.start", AccessFuTest.nextTest);
|
||||
}
|
||||
|
||||
function stopAccessFu() {
|
||||
SpecialPowers.setIntPref("accessibility.accessfu.activate", 0);
|
||||
AccessFuTest.once_log("EventManager.stop", AccessFuTest.finish);
|
||||
}
|
||||
|
||||
function hide(id) {
|
||||
var element = document.getElementById(id);
|
||||
element.style.display = "none";
|
||||
@ -245,14 +251,14 @@
|
||||
}];
|
||||
|
||||
function doTest() {
|
||||
AccessFuTest.addFunc(EventManagerStarted);
|
||||
AccessFuTest.addFunc(startAccessFu);
|
||||
tests.forEach(function addTest(test) {
|
||||
AccessFuTest.addFunc(function () {
|
||||
AccessFuTest.once(test.expected, AccessFuTest.nextTest);
|
||||
test.action();
|
||||
});
|
||||
});
|
||||
AccessFuTest.addFunc(AccessFuTest.finish);
|
||||
AccessFuTest.addFunc(stopAccessFu);
|
||||
AccessFuTest.waitForExplicitFinish();
|
||||
AccessFuTest.runTests();
|
||||
}
|
||||
|
@ -2,6 +2,11 @@
|
||||
# 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/.
|
||||
|
||||
# Screen reader started/stopped
|
||||
screenReaderStarted = Screen reader started
|
||||
screenReaderStopped = Screen reader stopped
|
||||
|
||||
# Roles
|
||||
menubar = menu bar
|
||||
scrollbar = scroll bar
|
||||
grip = grip
|
||||
|
Loading…
x
Reference in New Issue
Block a user