Commit b6397cf5 authored by David Tseng's avatar David Tseng Committed by Commit Bot

Reland: Use AXNode::GetSetSize/AXNode::GetPosInSet unconditionally

Fixed issue by only using the AXTree::GetPosInSet/AXTree::GetSetSize heuristics if they provide a nonzero answer. Otherwise, fall back to raw attributes.
This also exposes pos in set/set size if they are set without doing a role check as some renderers like ARC++ have no such restrictions.

TBR=dmazzoni@chromium.org
Original change description:
This moves ChromeVox to use AXNode::GetSetSize and AXNode::GetPosInSet through their automation bindings.

One issue is fixed:

In AXTree:PopulateOrderedSetItems, an assumption is made that the first child node of the ordered set node, should determine the hierarchical level of the current layer of items.

Unfortunately, for trees like:
tree
  static text
  tree item
  ...

this hueristic fails. See output_test.extjs::NestedLists.

Test: browser_tests --gtest_filter=ChromeVoxOutput*.*
Change-Id: I54911673215e245808a88fab07275a83c2d7109d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1536470Reviewed-by: default avatarDavid Tseng <dtseng@chromium.org>
Reviewed-by: default avatarDominic Mazzoni <dmazzoni@chromium.org>
Reviewed-by: default avatarAkihiro Ota <akihiroota@chromium.org>
Commit-Queue: David Tseng <dtseng@chromium.org>
Cr-Original-Commit-Position: refs/heads/master@{#645669}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1560015
Cr-Commit-Position: refs/heads/master@{#649245}
parent 4aa85f1c
......@@ -464,13 +464,12 @@ Output.RULES = {
$if($inPageLinkTarget, @internal_link, $role) $description`,
},
list: {
enter: `$role @@list_with_items($countChildren(listItem))`,
enter: `$role @@list_with_items($setSize)`,
speak: `$nameFromNode $descendants $role
@@list_with_items($countChildren(listItem)) $description $state`
@@list_with_items($setSize) $description $state`
},
listBox: {
enter: `$nameFromNode
$role @@list_with_items($countChildren(listBoxOption))
enter: `$nameFromNode $role @@list_with_items($setSize)
$restriction $description`
},
listBoxOption: {
......@@ -485,29 +484,23 @@ Output.RULES = {
menu: {
enter: `$name $role `,
speak: `$name $node(activeDescendant)
$role @@list_with_items(
$countChildren(menuItem, menuItemCheckBox, menuItemRadio))
$description $state $restriction`
$role @@list_with_items($setSize) $description $state $restriction`
},
menuItem: {
speak: `$name $role $if($hasPopup, @has_submenu)
@describe_index($if($posInSet, $posInSet, $indexInParent(menuItem, menuItemCheckBox, menuItemRadio)),
$if($setSize, $setSize, $parentChildCount(menuItem, menuItemCheckBox, menuItemRadio)))
$description $state $restriction`
@describe_index($posInSet, $setSize) $description $state $restriction`
},
menuItemCheckBox: {
speak: `$if($checked, $earcon(CHECK_ON), $earcon(CHECK_OFF))
$name $role $checked $state $restriction $description
@describe_index($if($posInSet, $posInSet, $indexInParent(menuItem, menuItemCheckBox, menuItemRadio)),
$if($setSize, $setSize, $parentChildCount(menuItem, menuItemCheckBox, menuItemRadio))) `
@describe_index($posInSet, $setSize)`
},
menuItemRadio: {
speak: `$if($checked, $earcon(CHECK_ON), $earcon(CHECK_OFF))
$if($checked, @describe_radio_selected($name),
@describe_radio_unselected($name)) $state $roleDescription
$restriction $description
@describe_index($if($posInSet, $posInSet, $indexInParent(menuItem, menuItemCheckBox, menuItemRadio)),
$if($setSize, $setSize, $parentChildCount(menuItem, menuItemCheckBox, menuItemRadio))) `
@describe_index($posInSet, $setSize)`
},
menuListOption: {
speak: `$name $role @describe_index($posInSet, $setSize) $state
......@@ -578,10 +571,7 @@ Output.RULES = {
$name $role $pressed $description $state $restriction`
},
toolbar: {enter: `$name $role $description $restriction`},
tree: {
enter: `$name $role @@list_with_items($countChildren(treeItem))
$restriction`
},
tree: {enter: `$name $role @@list_with_items($setSize) $restriction`},
treeItem: {
enter: `$role $expanded $collapsed $restriction
@describe_index($posInSet, $setSize)
......@@ -1321,25 +1311,6 @@ Output.prototype = {
this.append_(buff, String(count));
ruleStr.writeTokenWithValue(token, String(count));
}
} else if (token == 'parentChildCount') {
if (node.parent) {
options.annotation.push(token);
var roles;
if (tree.firstChild) {
roles = this.createRoles_(tree);
} else {
roles = new Set();
roles.add(node.role);
}
var count = node.parent.children
.filter(function(child) {
return roles.has(child.role);
})
.length;
this.append_(buff, String(count));
ruleStr.writeTokenWithValue(token, String(count));
}
} else if (token == 'restriction') {
var msg = Output.RESTRICTION_STATE_MAP[node.restriction];
if (msg) {
......@@ -1590,13 +1561,9 @@ Output.prototype = {
this.format_(node, '$indexInParent', buff, ruleStr);
}
} else if (token == 'setSize') {
if (node.setSize !== undefined) {
this.append_(buff, String(node.setSize));
ruleStr.writeTokenWithValue(token, String(node.setSize));
} else {
ruleStr.writeToken(token);
this.format_(node, '$parentChildCount', buff, ruleStr);
}
var size = node.setSize ? node.setSize : 0;
this.append_(buff, String(size));
ruleStr.writeTokenWithValue(token, String(node.setSize));
} else if (tree.firstChild) {
// Custom functions.
if (token == 'if') {
......@@ -1630,16 +1597,6 @@ Output.prototype = {
tree.firstChild.value, node.location || undefined));
this.append_(buff, '', options);
ruleStr.writeTokenWithValue(token, tree.firstChild.value);
} else if (token == 'countChildren') {
var roles = this.createRoles_(tree);
var count = node.children
.filter(function(e) {
return roles.has(e.role);
})
.length;
this.append_(buff, String(count));
ruleStr.writeTokenWithValue(token, String(count));
}
}
} else if (prefix == '@') {
......
......@@ -818,14 +818,12 @@ void AutomationInternalCustomBindings::AddRoutes() {
ui::ParseIntAttribute(attribute_name.c_str());
int attr_value;
if (attribute == ax::mojom::IntAttribute::kPosInSet) {
if (attribute == ax::mojom::IntAttribute::kPosInSet &&
node->GetPosInSet()) {
attr_value = node->GetPosInSet();
if (attr_value == 0)
return;
} else if (attribute == ax::mojom::IntAttribute::kSetSize) {
} else if (attribute == ax::mojom::IntAttribute::kSetSize &&
node->GetSetSize()) {
attr_value = node->GetSetSize();
if (attr_value == 0)
return;
} else if (!node->data().GetIntAttribute(attribute, &attr_value)) {
return;
}
......
......@@ -946,13 +946,16 @@ void AXTree::PopulateOrderedSetItems(const AXNode* ordered_set,
int original_level = original_node.GetIntAttribute(
ax::mojom::IntAttribute::kHierarchicalLevel);
// If original node is ordered set, then set its hierarchical level equal to
// its first child to ensure the items vector gets populated.
// This is due to ordered sets having a hierarchical level of 0, while their
// nodes have non-zero hierarchical values.
if ((ordered_set == &original_node) &&
ordered_set->GetUnignoredChildAtIndex(0)) {
original_level = ordered_set->GetUnignoredChildAtIndex(0)->GetIntAttribute(
ax::mojom::IntAttribute::kHierarchicalLevel);
// its first child that sets a hierarchical level, if any.
if (ordered_set == &original_node) {
for (int32_t i = 0; i < original_node.GetUnignoredChildCount(); ++i) {
int32_t level =
original_node.GetUnignoredChildAtIndex(i)->GetIntAttribute(
ax::mojom::IntAttribute::kHierarchicalLevel);
if (level)
original_level =
original_level ? std::min(level, original_level) : level;
}
}
int original_node_index = original_node.GetUnignoredIndexInParent();
bool node_is_radio_button =
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment