Commit b0dc887e authored by Akihiro Ota's avatar Akihiro Ota Committed by Commit Bot

Naive functionality for AXNode PosInSet and SetSize

Added functionality for AXNode::PosInSet(), which determines a node's
position within an ordered container, and AXNode::SetSize, which
determines the total number of elements within the node's container.

Change-Id: Idd1849891db8cb96c30edda4d4b85b9a206220f2
Reviewed-on: https://chromium-review.googlesource.com/c/1336327
Commit-Queue: Akihiro Ota <akihiroota@chromium.org>
Reviewed-by: default avatarDominic Mazzoni <dmazzoni@chromium.org>
Cr-Commit-Position: refs/heads/master@{#608241}
parent 82a86217
...@@ -473,4 +473,68 @@ void AXNode::IdVectorToNodeVector(std::vector<int32_t>& ids, ...@@ -473,4 +473,68 @@ void AXNode::IdVectorToNodeVector(std::vector<int32_t>& ids,
} }
} }
bool AXNode::IsPosInSetUsedInRole() const {
switch (data().role) {
case ax::mojom::Role::kArticle:
case ax::mojom::Role::kListItem:
case ax::mojom::Role::kMenuItem:
case ax::mojom::Role::kMenuItemRadio:
case ax::mojom::Role::kTab:
case ax::mojom::Role::kMenuItemCheckBox:
case ax::mojom::Role::kTreeItem:
case ax::mojom::Role::kListBoxOption:
case ax::mojom::Role::kRadioButton:
return true;
default:
return false;
}
}
// Finds the position of this node within a list.
// Only takes into account elements that have same role as node.
int32_t AXNode::PosInSet() const {
AXNode* parent = GetUnignoredParent();
// Error checks
if (!parent)
return 0;
if (parent->data().role != ax::mojom::Role::kList)
return 0;
if (!IsPosInSetUsedInRole())
return 0;
int position = 0;
for (int i = 0; i < parent->GetUnignoredChildCount(); ++i) {
AXNode* candidate = parent->GetUnignoredChildAtIndex(i);
if (candidate->data().role == data().role)
++position;
if (candidate == this)
return position;
}
return 0;
}
// Finds the total number of elements of the list this node is contained within.
// Only counts the elements that have the same role as node.
int32_t AXNode::SetSize() const {
AXNode* parent = GetUnignoredParent();
// Error checks
if (!parent)
return 0;
if (parent->data().role != ax::mojom::Role::kList)
return 0;
if (!IsPosInSetUsedInRole())
return 0;
int count = 0;
for (int i = 0; i < parent->GetUnignoredChildCount(); ++i) {
AXNode* child = parent->GetUnignoredChildAtIndex(i);
if (child->data().role == data().role)
++count;
}
return count;
}
} // namespace ui } // namespace ui
...@@ -181,6 +181,15 @@ class AX_EXPORT AXNode final { ...@@ -181,6 +181,15 @@ class AX_EXPORT AXNode final {
return data().GetHtmlAttribute(attribute, value); return data().GetHtmlAttribute(attribute, value);
} }
// Returns the position of node within a list. Returns 1-based index if
// contained within a list, and 0 if not.
int32_t PosInSet() const;
// Returns the total number of nodes in the same list as node. Returns 0
// if the node is not contained wihtin a list.
int32_t SetSize() const;
// Returns true if the aria-posinset attribute is used in node's role
bool IsPosInSetUsedInRole() const;
const std::string& GetInheritedStringAttribute( const std::string& GetInheritedStringAttribute(
ax::mojom::StringAttribute attribute) const; ax::mojom::StringAttribute attribute) const;
base::string16 GetInheritedString16Attribute( base::string16 GetInheritedString16Attribute(
......
...@@ -1472,4 +1472,83 @@ TEST(AXTreeTest, ChildTreeIds) { ...@@ -1472,4 +1472,83 @@ TEST(AXTreeTest, ChildTreeIds) {
EXPECT_EQ(0U, child_tree_93_nodes.size()); EXPECT_EQ(0U, child_tree_93_nodes.size());
} }
// Simple test for PosInSet and SetSize.
TEST(AXTreeTest, GetPosInSetSetSize) {
AXTreeUpdate tree_update;
tree_update.root_id = 1;
tree_update.nodes.resize(4);
tree_update.nodes[0].id = 1;
tree_update.nodes[0].role = ax::mojom::Role::kList;
tree_update.nodes[0].child_ids = {2, 3, 4};
tree_update.nodes[1].id = 2;
tree_update.nodes[1].role = ax::mojom::Role::kListItem;
tree_update.nodes[2].id = 3;
tree_update.nodes[2].role = ax::mojom::Role::kListItem;
tree_update.nodes[3].id = 4;
tree_update.nodes[3].role = ax::mojom::Role::kListItem;
AXTree tree(tree_update);
AXNode* item1 = tree.GetFromId(2);
EXPECT_EQ(item1->PosInSet(), 1);
EXPECT_EQ(item1->SetSize(), 3);
AXNode* item2 = tree.GetFromId(3);
EXPECT_EQ(item2->PosInSet(), 2);
EXPECT_EQ(item2->SetSize(), 3);
AXNode* item3 = tree.GetFromId(4);
EXPECT_EQ(item3->PosInSet(), 3);
EXPECT_EQ(item3->SetSize(), 3);
}
// A test for PosInSet and SetSize on a list containing various roles.
TEST(AXTreeTest, GetPosInSetSetSizeDiverseList) {
AXTreeUpdate tree_update;
tree_update.root_id = 1;
tree_update.nodes.resize(9);
tree_update.nodes[0].id = 1;
tree_update.nodes[0].role = ax::mojom::Role::kList;
tree_update.nodes[0].child_ids = {2, 3, 4, 5, 6, 7, 8, 9};
tree_update.nodes[1].id = 2;
tree_update.nodes[1].role = ax::mojom::Role::kListItem;
tree_update.nodes[2].id = 3;
tree_update.nodes[2].role = ax::mojom::Role::kListItem;
tree_update.nodes[3].id = 4;
tree_update.nodes[3].role = ax::mojom::Role::kMenuItem;
tree_update.nodes[4].id = 5;
tree_update.nodes[4].role = ax::mojom::Role::kMenuItem;
tree_update.nodes[5].id = 6;
tree_update.nodes[5].role = ax::mojom::Role::kArticle;
tree_update.nodes[6].id = 7;
tree_update.nodes[6].role = ax::mojom::Role::kArticle;
tree_update.nodes[7].id = 8;
tree_update.nodes[7].role = ax::mojom::Role::kListItem;
tree_update.nodes[8].id = 9;
tree_update.nodes[8].role = ax::mojom::Role::kImage;
AXTree tree(tree_update);
AXNode* listitem1 = tree.GetFromId(2);
EXPECT_EQ(listitem1->PosInSet(), 1);
EXPECT_EQ(listitem1->SetSize(), 3);
AXNode* listitem2 = tree.GetFromId(3);
EXPECT_EQ(listitem2->PosInSet(), 2);
EXPECT_EQ(listitem2->SetSize(), 3);
AXNode* menuitem1 = tree.GetFromId(4);
EXPECT_EQ(menuitem1->PosInSet(), 1);
EXPECT_EQ(menuitem1->SetSize(), 2);
AXNode* menuitem2 = tree.GetFromId(5);
EXPECT_EQ(menuitem2->PosInSet(), 2);
EXPECT_EQ(menuitem2->SetSize(), 2);
AXNode* article1 = tree.GetFromId(6);
EXPECT_EQ(article1->PosInSet(), 1);
EXPECT_EQ(article1->SetSize(), 2);
AXNode* article2 = tree.GetFromId(7);
EXPECT_EQ(article2->PosInSet(), 2);
EXPECT_EQ(article2->SetSize(), 2);
AXNode* listitem3 = tree.GetFromId(8);
EXPECT_EQ(listitem3->PosInSet(), 3);
EXPECT_EQ(listitem3->SetSize(), 3);
AXNode* image1 = tree.GetFromId(9);
EXPECT_EQ(image1->PosInSet(), 0);
EXPECT_EQ(image1->SetSize(), 0);
}
} // namespace ui } // namespace ui
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