Bug 752127 - Provide names to all functions that are not in-line. Remove some dumps, wrap some lines. r=davidb

This commit is contained in:
Eitan Isaacson 2012-05-14 14:21:59 -07:00
parent 664f889a6d
commit 6f9926f602
4 changed files with 243 additions and 229 deletions

View File

@ -48,14 +48,14 @@ var AccessFu = {
} catch (x) {
}
this.processPreferences(accessPref);
this._processPreferences(accessPref);
},
/**
* Start AccessFu mode, this primarily means controlling the virtual cursor
* with arrow keys.
*/
enable: function enable() {
_enable: function _enable() {
if (this._enabled)
return;
this._enabled = true;
@ -79,7 +79,7 @@ var AccessFu = {
/**
* Disable AccessFu and return to default interaction mode.
*/
disable: function disable() {
_disable: function _disable() {
if (!this._enabled)
return;
this._enabled = false;
@ -98,7 +98,7 @@ var AccessFu = {
this.chromeWin.removeEventListener('TabOpen', this, true);
},
processPreferences: function processPreferences(aPref) {
_processPreferences: function _processPreferences(aPref) {
if (Services.appinfo.OS == 'Android') {
if (aPref == ACCESSFU_AUTO) {
if (!this._observingSystemSettings) {
@ -118,9 +118,9 @@ var AccessFu = {
}
if (aPref == ACCESSFU_ENABLE)
this.enable();
this._enable();
else
this.disable();
this._disable();
},
addPresenter: function addPresenter(presenter) {
@ -171,19 +171,19 @@ var AccessFu = {
switch (aTopic) {
case 'Accessibility:Settings':
if (JSON.parse(aData).enabled)
this.enable();
this._enable();
else
this.disable();
this._disable();
break;
case 'nsPref:changed':
if (aData == 'accessfu')
this.processPreferences(this.prefsBranch.getIntPref('accessfu'));
this._processPreferences(this.prefsBranch.getIntPref('accessfu'));
break;
case 'accessible-event':
let event;
try {
event = aSubject.QueryInterface(Ci.nsIAccessibleEvent);
this.handleAccEvent(event);
this._handleAccEvent(event);
} catch (ex) {
dump(ex);
return;
@ -191,7 +191,7 @@ var AccessFu = {
}
},
handleAccEvent: function handleAccEvent(aEvent) {
_handleAccEvent: function _handleAccEvent(aEvent) {
switch (aEvent.eventType) {
case Ci.nsIAccessibleEvent.EVENT_VIRTUALCURSOR_CHANGED:
{
@ -251,13 +251,13 @@ var AccessFu = {
let state = {};
docAcc.getState(state, {});
if (state.value & Ci.nsIAccessibleStates.STATE_BUSY &&
this.isNotChromeDoc(docAcc))
this._isNotChromeDoc(docAcc))
this.presenters.forEach(
function(p) { p.tabStateChanged(docAcc, 'loading'); }
);
delete this._pendingDocuments[aEvent.DOMNode];
}
if (this.isBrowserDoc(docAcc))
if (this._isBrowserDoc(docAcc))
// A new top-level content document has been attached
this.presenters.forEach(
function(p) { p.tabStateChanged(docAcc, 'newdoc'); }
@ -267,7 +267,7 @@ var AccessFu = {
}
case Ci.nsIAccessibleEvent.EVENT_DOCUMENT_LOAD_COMPLETE:
{
if (this.isNotChromeDoc(aEvent.accessible)) {
if (this._isNotChromeDoc(aEvent.accessible)) {
this.presenters.forEach(
function(p) {
p.tabStateChanged(aEvent.accessible, 'loaded');
@ -296,7 +296,7 @@ var AccessFu = {
}
case Ci.nsIAccessibleEvent.EVENT_FOCUS:
{
if (this.isBrowserDoc(aEvent.accessible)) {
if (this._isBrowserDoc(aEvent.accessible)) {
// The document recieved focus, call tabSelected to present current tab.
this.presenters.forEach(
function(p) { p.tabSelected(aEvent.accessible); });
@ -342,7 +342,7 @@ var AccessFu = {
* @param {nsIAccessible} aDocAcc the accessible to check.
* @return {boolean} true if this is a top-level content document.
*/
isBrowserDoc: function isBrowserDoc(aDocAcc) {
_isBrowserDoc: function _isBrowserDoc(aDocAcc) {
let parent = aDocAcc.parent;
if (!parent)
return false;
@ -360,7 +360,7 @@ var AccessFu = {
* @param {nsIDOMDocument} aDocument the document to check.
* @return {boolean} true if this is not a chrome document.
*/
isNotChromeDoc: function isNotChromeDoc(aDocument) {
_isNotChromeDoc: function _isNotChromeDoc(aDocument) {
let location = aDocument.DOMNode.location;
if (!location)
return false;

View File

@ -52,7 +52,9 @@ Presenter.prototype = {
/**
* Text has changed, either by the user or by the system. TODO.
*/
textChanged: function textChanged(aIsInserted, aStartOffset, aLength, aText, aModifiedText) {},
textChanged: function textChanged(aIsInserted, aStartOffset,
aLength, aText,
aModifiedText) {},
/**
* Text selection has changed. TODO.
@ -95,228 +97,236 @@ Presenter.prototype = {
function VisualPresenter() {}
VisualPresenter.prototype = new Presenter();
VisualPresenter.prototype = {
__proto__: Presenter.prototype,
/**
* The padding in pixels between the object and the highlight border.
*/
VisualPresenter.prototype.BORDER_PADDING = 2;
/**
* The padding in pixels between the object and the highlight border.
*/
BORDER_PADDING: 2,
VisualPresenter.prototype.attach = function(aWindow) {
this.chromeWin = aWindow;
attach: function VisualPresenter_attach(aWindow) {
this.chromeWin = aWindow;
// Add stylesheet
let stylesheetURL = 'chrome://global/content/accessibility/AccessFu.css';
this.stylesheet = aWindow.document.createProcessingInstruction(
'xml-stylesheet', 'href="' + stylesheetURL + '" type="text/css"');
aWindow.document.insertBefore(this.stylesheet, aWindow.document.firstChild);
// Add stylesheet
let stylesheetURL = 'chrome://global/content/accessibility/AccessFu.css';
this.stylesheet = aWindow.document.createProcessingInstruction(
'xml-stylesheet', 'href="' + stylesheetURL + '" type="text/css"');
aWindow.document.insertBefore(this.stylesheet, aWindow.document.firstChild);
// Add highlight box
this.highlightBox = this.chromeWin.document.
createElementNS('http://www.w3.org/1999/xhtml', 'div');
this.chromeWin.document.documentElement.appendChild(this.highlightBox);
this.highlightBox.id = 'virtual-cursor-box';
// Add highlight box
this.highlightBox = this.chromeWin.document.
createElementNS('http://www.w3.org/1999/xhtml', 'div');
this.chromeWin.document.documentElement.appendChild(this.highlightBox);
this.highlightBox.id = 'virtual-cursor-box';
// Add highlight inset for inner shadow
let inset = this.chromeWin.document.
createElementNS('http://www.w3.org/1999/xhtml', 'div');
inset.id = 'virtual-cursor-inset';
// Add highlight inset for inner shadow
let inset = this.chromeWin.document.
createElementNS('http://www.w3.org/1999/xhtml', 'div');
inset.id = 'virtual-cursor-inset';
this.highlightBox.appendChild(inset);
};
this.highlightBox.appendChild(inset);
},
VisualPresenter.prototype.detach = function() {
this.chromeWin.document.removeChild(this.stylesheet);
this.highlightBox.parentNode.removeChild(this.highlightBox);
this.highlightBox = this.stylesheet = null;
};
detach: function VisualPresenter_detach() {
this.chromeWin.document.removeChild(this.stylesheet);
this.highlightBox.parentNode.removeChild(this.highlightBox);
this.highlightBox = this.stylesheet = null;
},
VisualPresenter.prototype.viewportChanged = function() {
if (this._currentObject)
this.highlight(this._currentObject);
};
viewportChanged: function VisualPresenter_viewportChanged() {
if (this._currentObject)
this._highlight(this._currentObject);
},
VisualPresenter.prototype.pivotChanged = function(aObject, aNewContext) {
this._currentObject = aObject;
pivotChanged: function VisualPresenter_pivotChanged(aObject, aNewContext) {
this._currentObject = aObject;
if (!aObject) {
this.hide();
return;
if (!aObject) {
this._hide();
return;
}
try {
aObject.scrollTo(Ci.nsIAccessibleScrollType.SCROLL_TYPE_ANYWHERE);
this._highlight(aObject);
} catch (e) {
dump('Error getting bounds: ' + e);
return;
}
},
tabSelected: function VisualPresenter_tabSelected(aDocObj) {
let vcPos = aDocObj ? aDocObj.QueryInterface(Ci.nsIAccessibleCursorable).
virtualCursor.position : null;
this.pivotChanged(vcPos);
},
tabStateChanged: function VisualPresenter_tabStateChanged(aDocObj,
aPageState) {
if (aPageState == 'newdoc')
this.pivotChanged(null);
},
// Internals
_hide: function _hide() {
this.highlightBox.style.display = 'none';
},
_highlight: function _highlight(aObject) {
let vp = (Services.appinfo.OS == 'Android') ?
this.chromeWin.BrowserApp.selectedTab.getViewport() :
{ zoom: 1.0, offsetY: 0 };
let bounds = this._getBounds(aObject, vp.zoom);
// First hide it to avoid flickering when changing the style.
this.highlightBox.style.display = 'none';
this.highlightBox.style.top = bounds.top + 'px';
this.highlightBox.style.left = bounds.left + 'px';
this.highlightBox.style.width = bounds.width + 'px';
this.highlightBox.style.height = bounds.height + 'px';
this.highlightBox.style.display = 'block';
},
_getBounds: function _getBounds(aObject, aZoom, aStart, aEnd) {
let objX = {}, objY = {}, objW = {}, objH = {};
if (aEnd >= 0 && aStart >= 0 && aEnd != aStart) {
// TODO: Get bounds for text ranges. Leaving this blank until we have
// proper text navigation in the virtual cursor.
}
aObject.getBounds(objX, objY, objW, objH);
// Can't specify relative coords in nsIAccessible.getBounds, so we do it.
let docX = {}, docY = {};
let docRoot = aObject.rootDocument.QueryInterface(Ci.nsIAccessible);
docRoot.getBounds(docX, docY, {}, {});
let rv = {
left: Math.round((objX.value - docX.value - this.BORDER_PADDING) * aZoom),
top: Math.round((objY.value - docY.value - this.BORDER_PADDING) * aZoom),
width: Math.round((objW.value + (this.BORDER_PADDING * 2)) * aZoom),
height: Math.round((objH.value + (this.BORDER_PADDING * 2)) * aZoom)
};
return rv;
}
try {
aObject.scrollTo(Ci.nsIAccessibleScrollType.SCROLL_TYPE_ANYWHERE);
this.highlight(aObject);
} catch (e) {
dump('Error getting bounds: ' + e);
return;
}
};
VisualPresenter.prototype.tabSelected = function(aDocObj) {
let vcPos = aDocObj ?
aDocObj.QueryInterface(Ci.nsIAccessibleCursorable).virtualCursor.position :
null;
this.pivotChanged(vcPos);
};
VisualPresenter.prototype.tabStateChanged = function(aDocObj, aPageState) {
if (aPageState == "newdoc")
this.pivotChanged(null);
};
// Internals
VisualPresenter.prototype.hide = function hide() {
this.highlightBox.style.display = 'none';
};
VisualPresenter.prototype.highlight = function(aObject) {
let vp = (Services.appinfo.OS == 'Android') ?
this.chromeWin.BrowserApp.selectedTab.getViewport() :
{ zoom: 1.0, offsetY: 0 };
let bounds = this.getBounds(aObject, vp.zoom);
// First hide it to avoid flickering when changing the style.
this.highlightBox.style.display = 'none';
this.highlightBox.style.top = bounds.top + 'px';
this.highlightBox.style.left = bounds.left + 'px';
this.highlightBox.style.width = bounds.width + 'px';
this.highlightBox.style.height = bounds.height + 'px';
this.highlightBox.style.display = 'block';
};
VisualPresenter.prototype.getBounds = function(aObject, aZoom, aStart, aEnd) {
let objX = {}, objY = {}, objW = {}, objH = {};
if (aEnd >= 0 && aStart >= 0 && aEnd != aStart) {
// TODO: Get bounds for text ranges. Leaving this blank until we have
// proper text navigation in the virtual cursor.
}
aObject.getBounds(objX, objY, objW, objH);
// Can't specify relative coords in nsIAccessible.getBounds, so we do it.
let docX = {}, docY = {};
let docRoot = aObject.rootDocument.QueryInterface(Ci.nsIAccessible);
docRoot.getBounds(docX, docY, {}, {});
let rv = {
left: Math.round((objX.value - docX.value - this.BORDER_PADDING) * aZoom),
top: Math.round((objY.value - docY.value - this.BORDER_PADDING) * aZoom),
width: Math.round((objW.value + (this.BORDER_PADDING * 2)) * aZoom),
height: Math.round((objH.value + (this.BORDER_PADDING * 2)) * aZoom)
};
return rv;
};
/**
* Android presenter. Fires Android a11y events.
*/
const ANDROID_TYPE_VIEW_CLICKED = 0x01;
const ANDROID_TYPE_VIEW_LONG_CLICKED = 0x02;
const ANDROID_TYPE_VIEW_SELECTED = 0x04;
const ANDROID_TYPE_VIEW_FOCUSED = 0x08;
const ANDROID_TYPE_VIEW_TEXT_CHANGED = 0x10;
const ANDROID_TYPE_WINDOW_STATE_CHANGED = 0x20;
function AndroidPresenter() {}
AndroidPresenter.prototype = new Presenter();
AndroidPresenter.prototype = {
__proto__: Presenter.prototype,
// Android AccessibilityEvent type constants.
ANDROID_VIEW_CLICKED: 0x01,
ANDROID_VIEW_LONG_CLICKED: 0x02,
ANDROID_VIEW_SELECTED: 0x04,
ANDROID_VIEW_FOCUSED: 0x08,
ANDROID_VIEW_TEXT_CHANGED: 0x10,
ANDROID_WINDOW_STATE_CHANGED: 0x20,
pivotChanged: function AndroidPresenter_pivotChanged(aObject, aNewContext) {
let output = [];
for (let i in aNewContext)
output.push.apply(output,
UtteranceGenerator.genForObject(aNewContext[i]));
AndroidPresenter.prototype.pivotChanged = function(aObject, aNewContext) {
let output = [];
for (let i in aNewContext)
output.push.apply(output,
UtteranceGenerator.genForObject(aNewContext[i]));
UtteranceGenerator.genForObject(aObject, true));
output.push.apply(output,
UtteranceGenerator.genForObject(aObject, true));
this.sendMessageToJava({
gecko: {
type: 'Accessibility:Event',
eventType: this.ANDROID_VIEW_FOCUSED,
text: output
}
});
},
this.sendMessageToJava({
gecko: {
type: 'Accessibility:Event',
eventType: ANDROID_TYPE_VIEW_FOCUSED,
text: output
actionInvoked: function AndroidPresenter_actionInvoked(aObject, aActionName) {
this.sendMessageToJava({
gecko: {
type: 'Accessibility:Event',
eventType: this.ANDROID_VIEW_CLICKED,
text: UtteranceGenerator.genForAction(aObject, aActionName)
}
});
},
tabSelected: function AndroidPresenter_tabSelected(aDocObj) {
// Send a pivot change message with the full context utterance for this doc.
let vcDoc = aDocObj.QueryInterface(Ci.nsIAccessibleCursorable);
let context = [];
let parent = vcDoc.virtualCursor.position || aDocObj;
while ((parent = parent.parent)) {
context.push(parent);
if (parent == aDocObj)
break;
}
});
};
AndroidPresenter.prototype.actionInvoked = function(aObject, aActionName) {
this.sendMessageToJava({
gecko: {
context.reverse();
this.pivotChanged(vcDoc.virtualCursor.position || aDocObj, context);
},
tabStateChanged: function AndroidPresenter_tabStateChanged(aDocObj,
aPageState) {
let stateUtterance = UtteranceGenerator.
genForTabStateChange(aDocObj, aPageState);
if (!stateUtterance.length)
return;
this.sendMessageToJava({
gecko: {
type: 'Accessibility:Event',
eventType: this.ANDROID_VIEW_TEXT_CHANGED,
text: stateUtterance,
addedCount: stateUtterance.join(' ').length,
removedCount: 0,
fromIndex: 0
}
});
},
textChanged: function AndroidPresenter_textChanged(aIsInserted, aStart,
aLength, aText,
aModifiedText) {
let androidEvent = {
type: 'Accessibility:Event',
eventType: ANDROID_TYPE_VIEW_CLICKED,
text: UtteranceGenerator.genForAction(aObject, aActionName)
eventType: this.ANDROID_VIEW_TEXT_CHANGED,
text: [aText],
fromIndex: aStart
};
if (aIsInserted) {
androidEvent.addedCount = aLength;
androidEvent.beforeText =
aText.substring(0, aStart) + aText.substring(aStart + aLength);
} else {
androidEvent.removedCount = aLength;
androidEvent.beforeText =
aText.substring(0, aStart) + aModifiedText + aText.substring(aStart);
}
});
};
AndroidPresenter.prototype.tabSelected = function(aDocObj) {
// Send a pivot change message with the full context utterance for this doc.
let vcDoc = aDocObj.QueryInterface(Ci.nsIAccessibleCursorable);
let context = [];
this.sendMessageToJava({gecko: androidEvent});
},
let parent = vcDoc.virtualCursor.position || aDocObj;
while ((parent = parent.parent)) {
context.push(parent);
if (parent == aDocObj)
break;
sendMessageToJava: function AndroidPresenter_sendMessageTojava(aMessage) {
return Cc['@mozilla.org/android/bridge;1'].
getService(Ci.nsIAndroidBridge).
handleGeckoMessage(JSON.stringify(aMessage));
}
context.reverse();
this.pivotChanged(vcDoc.virtualCursor.position || aDocObj, context);
};
AndroidPresenter.prototype.tabStateChanged = function(aDocObj, aPageState) {
let stateUtterance = UtteranceGenerator.
genForTabStateChange(aDocObj, aPageState);
if (!stateUtterance.length)
return;
this.sendMessageToJava({
gecko: {
type: 'Accessibility:Event',
eventType: ANDROID_TYPE_VIEW_TEXT_CHANGED,
text: stateUtterance,
addedCount: stateUtterance.join(' ').length,
removedCount: 0,
fromIndex: 0
}
});
};
AndroidPresenter.prototype.textChanged = function(aIsInserted, aStart, aLength, aText, aModifiedText) {
let androidEvent = {
type: 'Accessibility:Event',
eventType: ANDROID_TYPE_VIEW_TEXT_CHANGED,
text: [aText],
fromIndex: aStart
};
if (aIsInserted) {
androidEvent.addedCount = aLength;
androidEvent.beforeText =
aText.substring(0, aStart) + aText.substring(aStart + aLength);
} else {
androidEvent.removedCount = aLength;
androidEvent.beforeText =
aText.substring(0, aStart) + aModifiedText + aText.substring(aStart);
}
this.sendMessageToJava({gecko: androidEvent});
};
AndroidPresenter.prototype.sendMessageToJava = function(aMessage) {
return Cc['@mozilla.org/android/bridge;1'].
getService(Ci.nsIAndroidBridge).
handleGeckoMessage(JSON.stringify(aMessage));
};
/**
@ -325,8 +335,10 @@ AndroidPresenter.prototype.sendMessageToJava = function(aMessage) {
function DummyAndroidPresenter() {}
DummyAndroidPresenter.prototype = new AndroidPresenter();
DummyAndroidPresenter.prototype = {
__proto__: AndroidPresenter.prototype,
DummyAndroidPresenter.prototype.sendMessageToJava = function(aMessage) {
dump(JSON.stringify(aMessage, null, 2) + '\n');
sendMessageToJava: function DummyAndroidPresenter_sendMessageToJava(aMsg) {
dump(JSON.stringify(aMsg, null, 2) + '\n');
}
};

View File

@ -65,10 +65,10 @@ var UtteranceGenerator = {
* @return {Array} Two string array. The first string describes the object
* and its states. The second string is the object's name. Some object
* types may have the description or name omitted, instead an empty string
* is returned as a placeholder. Whether the object's description or it's role
* is included is determined by {@link verbosityRoleMap}.
* is returned as a placeholder. Whether the object's description or it's
* role is included is determined by {@link verbosityRoleMap}.
*/
genForObject: function(aAccessible, aForceName) {
genForObject: function genForObject(aAccessible, aForceName) {
let roleString = gAccRetrieval.getStringRole(aAccessible.role);
let func = this.objectUtteranceFunctions[roleString] ||
@ -91,7 +91,7 @@ var UtteranceGenerator = {
* {@link gActionMap}.
* @return {Array} A one string array with the action.
*/
genForAction: function(aObject, aActionName) {
genForAction: function genForAction(aObject, aActionName) {
return [gStringBundle.GetStringFromName(this.gActionMap[aActionName])];
},
@ -103,7 +103,7 @@ var UtteranceGenerator = {
* {@link Presenter.tabStateChanged}.
* @return {Array} The tab state utterace.
*/
genForTabStateChange: function (aObject, aTabState) {
genForTabStateChange: function genForTabStateChange(aObject, aTabState) {
switch (aTabState) {
case 'newtab':
return [gStringBundle.GetStringFromName('tabNew')];
@ -177,7 +177,8 @@ var UtteranceGenerator = {
objectUtteranceFunctions: {
defaultFunc: function defaultFunc(aAccessible, aRoleStr, aFlags) {
let name = (aFlags & INCLUDE_NAME) ? (aAccessible.name || '') : '';
let desc = (aFlags & INCLUDE_ROLE) ? this._getLocalizedRole(aRoleStr) : '';
let desc = (aFlags & INCLUDE_ROLE) ?
this._getLocalizedRole(aRoleStr) : '';
let utterance = [];
@ -207,7 +208,7 @@ var UtteranceGenerator = {
return utterance;
},
heading: function(aAccessible, aRoleStr, aFlags) {
heading: function heading(aAccessible, aRoleStr, aFlags) {
let name = (aFlags & INCLUDE_NAME) ? (aAccessible.name || '') : '';
let level = {};
aAccessible.groupPosition(level, {}, {});
@ -220,7 +221,7 @@ var UtteranceGenerator = {
return utterance;
},
listitem: function(aAccessible, aRoleStr, aFlags) {
listitem: function listitem(aAccessible, aRoleStr, aFlags) {
let name = (aFlags & INCLUDE_NAME) ? (aAccessible.name || '') : '';
let localizedRole = this._getLocalizedRole(aRoleStr);
let itemno = {};

View File

@ -20,14 +20,15 @@ var gAccRetrieval = Cc['@mozilla.org/accessibleRetrieval;1'].
var VirtualCursorController = {
attach: function attach(aWindow) {
this.chromeWin = aWindow;
this.chromeWin.document.addEventListener('keypress', this.onkeypress, true);
this.chromeWin.document.addEventListener('keypress', this._onkeypress, true);
},
detach: function detach() {
this.chromeWin.document.removeEventListener('keypress', this.onkeypress, true);
this.chromeWin.document.removeEventListener('keypress', this._onkeypress,
true);
},
getBrowserApp: function getBrowserApp() {
_getBrowserApp: function _getBrowserApp() {
switch (Services.appinfo.OS) {
case 'Android':
return this.chromeWin.BrowserApp;
@ -36,8 +37,8 @@ var VirtualCursorController = {
}
},
onkeypress: function onkeypress(aEvent) {
let document = VirtualCursorController.getBrowserApp().
_onkeypress: function _onkeypress(aEvent) {
let document = VirtualCursorController._getBrowserApp().
selectedBrowser.contentDocument;
dump('keypress ' + aEvent.keyCode + '\n');
@ -57,7 +58,7 @@ var VirtualCursorController = {
break;
case aEvent.DOM_VK_UP:
if (Services.appinfo.OS == 'Android')
// Return focus to browser chrome, which in Android is a native widget.
// Return focus to native Android browser chrome.
Cc['@mozilla.org/android/bridge;1'].
getService(Ci.nsIAndroidBridge).handleGeckoMessage(
JSON.stringify({ gecko: { type: 'ToggleChrome:Focus' } }));
@ -110,7 +111,7 @@ var VirtualCursorController = {
},
SimpleTraversalRule: {
getMatchRoles: function(aRules) {
getMatchRoles: function SimpleTraversalRule_getmatchRoles(aRules) {
aRules.value = this._matchRoles;
return this._matchRoles.length;
},
@ -118,7 +119,7 @@ var VirtualCursorController = {
preFilter: Ci.nsIAccessibleTraversalRule.PREFILTER_DEFUNCT |
Ci.nsIAccessibleTraversalRule.PREFILTER_INVISIBLE,
match: function(aAccessible) {
match: function SimpleTraversalRule_match(aAccessible) {
switch (aAccessible.role) {
case Ci.nsIAccessibleRole.ROLE_COMBOBOX:
// We don't want to ignore the subtree because this is often