Bug 1003491 - Make traversal rule land on bigger items that have simple subtrees. r=yzen

This commit is contained in:
Eitan Isaacson 2014-04-30 21:33:37 -07:00
Родитель c6bb7eed92
Коммит 099314ab80
5 изменённых файлов: 75 добавлений и 29 удалений

Просмотреть файл

@ -597,6 +597,14 @@ this.UtteranceGenerator = {
rowheader: function rowheader() {
return this.objectOutputFunctions.cell.apply(this, arguments);
},
statictext: function statictext(aAccessible) {
if (Utils.isListItemDecorator(aAccessible, true)) {
return [];
}
return this.objectOutputFunctions.defaultFunc.apply(this, arguments);
}
},
@ -778,7 +786,7 @@ this.BrailleGenerator = {
statictext: function statictext(aAccessible, aRoleStr, aState, aFlags) {
// Since we customize the list bullet's output, we add the static
// text from the first node in each listitem, so skip it here.
if (aAccessible.parent.role == Roles.LISTITEM) {
if (Utils.isListItemDecorator(aAccessible)) {
return [];
}

Просмотреть файл

@ -2,6 +2,10 @@
* 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/. */
/* global PrefCache, Roles, Prefilters, States, Filters, Utils,
TraversalRules */
/* exported TraversalRules */
'use strict';
const Cc = Components.classes;
@ -9,17 +13,17 @@ const Ci = Components.interfaces;
const Cu = Components.utils;
const Cr = Components.results;
this.EXPORTED_SYMBOLS = ['TraversalRules'];
this.EXPORTED_SYMBOLS = ['TraversalRules']; // jshint ignore:line
Cu.import('resource://gre/modules/accessibility/Utils.jsm');
Cu.import('resource://gre/modules/XPCOMUtils.jsm');
XPCOMUtils.defineLazyModuleGetter(this, 'Roles',
XPCOMUtils.defineLazyModuleGetter(this, 'Roles', // jshint ignore:line
'resource://gre/modules/accessibility/Constants.jsm');
XPCOMUtils.defineLazyModuleGetter(this, 'Filters',
XPCOMUtils.defineLazyModuleGetter(this, 'Filters', // jshint ignore:line
'resource://gre/modules/accessibility/Constants.jsm');
XPCOMUtils.defineLazyModuleGetter(this, 'States',
XPCOMUtils.defineLazyModuleGetter(this, 'States', // jshint ignore:line
'resource://gre/modules/accessibility/Constants.jsm');
XPCOMUtils.defineLazyModuleGetter(this, 'Prefilters',
XPCOMUtils.defineLazyModuleGetter(this, 'Prefilters', // jshint ignore:line
'resource://gre/modules/accessibility/Constants.jsm');
let gSkipEmptyImages = new PrefCache('accessibility.accessfu.skip_empty_images');
@ -30,7 +34,7 @@ function BaseTraversalRule(aRoles, aMatchFunc, aPreFilter) {
if (aRoles.indexOf(Roles.LABEL) < 0) {
this._matchRoles.push(Roles.LABEL);
}
this._matchFunc = aMatchFunc || function (acc) { return Filters.MATCH; };
this._matchFunc = aMatchFunc || function() { return Filters.MATCH; };
this.preFilter = aPreFilter || gSimplePreFilter;
}
@ -91,17 +95,28 @@ var gSimpleTraversalRoles =
Roles.SLIDER,
Roles.SPINBUTTON,
Roles.OPTION,
Roles.LISTITEM,
// Used for traversing in to child OOP frames.
Roles.INTERNAL_FRAME];
var gSimpleMatchFunc = function gSimpleMatchFunc(aAccessible) {
function hasZeroOrSingleChildDescendants () {
for (let acc = aAccessible; acc.childCount > 0; acc = acc.firstChild) {
if (acc.childCount > 1) {
// An object is simple, if it either has a single child lineage,
// or has a flat subtree.
function isSingleLineage(acc) {
for (let child = acc; child; child = child.firstChild) {
if (child.childCount > 1) {
return false;
}
}
return true;
}
function isFlatSubtree(acc) {
for (let child = acc.firstChild; child; child = child.nextSibling) {
if (child.childCount > 0) {
return false;
}
}
return true;
}
@ -114,30 +129,28 @@ var gSimpleMatchFunc = function gSimpleMatchFunc(aAccessible) {
{
// Nameless text leaves are boring, skip them.
let name = aAccessible.name;
if (name && name.trim())
return Filters.MATCH;
else
return Filters.IGNORE;
return (name && name.trim()) ? Filters.MATCH : Filters.IGNORE;
}
case Roles.STATICTEXT:
{
let parent = aAccessible.parent;
// Ignore prefix static text in list items. They are typically bullets or numbers.
if (parent.childCount > 1 && aAccessible.indexInParent == 0 &&
parent.role == Roles.LISTITEM)
return Filters.IGNORE;
return Filters.MATCH;
}
// Ignore prefix static text in list items. They are typically bullets or numbers.
return Utils.isListItemDecorator(aAccessible) ?
Filters.IGNORE : Filters.MATCH;
case Roles.GRAPHIC:
return TraversalRules._shouldSkipImage(aAccessible);
case Roles.HEADER:
case Roles.HEADING:
if ((aAccessible.childCount > 0 || aAccessible.name) &&
hasZeroOrSingleChildDescendants()) {
(isSingleLineage(aAccessible) || isFlatSubtree(aAccessible))) {
return Filters.MATCH | Filters.IGNORE_SUBTREE;
} else {
return Filters.IGNORE;
}
return Filters.IGNORE;
case Roles.LISTITEM:
{
let item = aAccessible.childCount === 2 &&
aAccessible.firstChild.role === Roles.STATICTEXT ?
aAccessible.lastChild : aAccessible;
return isSingleLineage(item) || isFlatSubtree(item) ?
Filters.MATCH | Filters.IGNORE_SUBTREE : Filters.IGNORE;
}
default:
// Ignore the subtree, if there is one. So that we don't land on
@ -152,7 +165,7 @@ var gSimplePreFilter = Prefilters.DEFUNCT |
Prefilters.ARIA_HIDDEN |
Prefilters.TRANSPARENT;
this.TraversalRules = {
this.TraversalRules = { // jshint ignore:line
Simple: new BaseTraversalRule(gSimpleTraversalRoles, gSimpleMatchFunc),
SimpleOnScreen: new BaseTraversalRule(

Просмотреть файл

@ -343,6 +343,17 @@ this.Utils = {
}
return null;
},
isListItemDecorator: function isListItemDecorator(aStaticText,
aExcludeOrdered) {
let parent = aStaticText.parent;
if (aExcludeOrdered && parent.parent.DOMNode.nodeName === 'OL') {
return false;
}
return parent.role === Roles.LISTITEM && parent.childCount > 1 &&
aStaticText.indexInParent === 0;
}
};

Просмотреть файл

@ -92,6 +92,17 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=753984
["1.", "list one"],
["1.", "list one"]
]
},
{
accOrElmOrID: "li_two",
expectedUtterance: [
["list 1 item", "First item", "list two"],
["list two", "First item", "list 1 item"]
],
expectedBraille: [
["*", "list two"],
["*", "list two"]
]
}, {
accOrElmOrID: "cell",
expectedUtterance: [[
@ -407,6 +418,9 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=753984
<ol id="list">
<li id="li_one">list one</li>
</ol>
<ul id="unorderd_list">
<li id="li_two">list two</li>
</ul>
<dl id="dlist">
<dd id="dd_one">
dd one

Просмотреть файл

@ -111,8 +111,8 @@
'A esoteric weapon wielded by only the most ' +
'formidable warriors, for its unrelenting strict' +
' power is unfathomable.',
'Lists of Programming Languages', 'Lisp ',
'Scheme', 'Racket', 'Clojure', 'JavaScript', 'heading-5',
'Lists of Programming Languages', 'Lisp ',
'1. Scheme', '2. Racket', '3. Clojure', 'JavaScript', 'heading-5',
'image-2', 'image-3', 'Not actually an image',
'link-1', 'anchor-1', 'link-2', 'anchor-2', 'link-3',
'3', '1', '4', '1', 'Just an innocuous separator',