Skip to content


Browse files Browse the repository at this point in the history
AX: nested role="presentation" elements break role="tree" behavior

Reviewed by Andres Gonzalez.

Trees can have arbitrary levels of nesting of role="presentational" elements.

* LayoutTests/accessibility/mac/nested-tree-presentation-roles-expected.txt: Added.
* LayoutTests/accessibility/mac/nested-tree-presentation-roles.html: Added.
* Source/WebCore/accessibility/AccessibilityTree.cpp:
(WebCore::AccessibilityTree::isTreeValid const):
(WebCore::AccessibilityTree::nodeHasTreeItemChild const): Deleted.
* Source/WebCore/accessibility/AccessibilityTree.h:

Canonical link:
  • Loading branch information
fleizach committed Jan 4, 2023
1 parent ac2f8a4 commit 3f6b035
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 18 deletions.
@@ -0,0 +1,10 @@
This test ensures that trees with multi-level deep presentation roles still are marked as trees.

PASS: accessibilityController.accessibleElementById('item1').boolAttributeValue('AXSelected') === true
PASS: accessibilityController.accessibleElementById('tree').role === 'AXRole: AXOutline'

PASS successfullyParsed is true

Leaf 1
Leaf 2
34 changes: 34 additions & 0 deletions LayoutTests/accessibility/mac/nested-tree-presentation-roles.html
@@ -0,0 +1,34 @@
<script src="../../resources/accessibility-helper.js"></script>
<script src="../../resources/js-test.js"></script>

<div role="tree" class="tree" id="tree">
<div role="presentation">
<div role="presentation">
<div role="presentation">
<div role="treeitem" aria-selected="true" id="item1">
Leaf 1
<div role="treeitem" aria-selected="false">
Leaf 2

var output = "This test ensures that trees with multi-level deep presentation roles still are marked as trees.\n\n";

if (window.accessibilityController) {
output += expect("accessibilityController.accessibleElementById('item1').boolAttributeValue('AXSelected')", "true");
output += expect("accessibilityController.accessibleElementById('tree').role", "'AXRole: AXOutline'");
19 changes: 2 additions & 17 deletions Source/WebCore/accessibility/AccessibilityTree.cpp
Expand Up @@ -65,20 +65,10 @@ AccessibilityRole AccessibilityTree::determineAccessibilityRole()
return isTreeValid() ? AccessibilityRole::Tree : AccessibilityRole::Group;

bool AccessibilityTree::nodeHasTreeItemChild(Node& node) const
for (auto* child = node.firstChild(); child; child = child->nextSibling()) {
if (nodeHasRole(child, "treeitem"_s))
return true;
return false;

bool AccessibilityTree::isTreeValid() const
// A valid tree can only have treeitem or group of treeitems as a child
// A valid tree can only have treeitem or group of treeitems as a child.

Node* node = this->node();
if (!node)
return false;
Expand All @@ -94,12 +84,7 @@ bool AccessibilityTree::isTreeValid() const
if (nodeHasRole(child, "treeitem"_s))
if (nodeHasRole(child, "presentation"_s)) {
if (!nodeHasTreeItemChild(*child))
return false;
if (!nodeHasRole(child, "group"_s))
if (!nodeHasRole(child, "group"_s) && !nodeHasRole(child, "presentation"_s))
return false;

for (auto* groupChild = child->firstChild(); groupChild; groupChild = groupChild->nextSibling())
Expand Down
1 change: 0 additions & 1 deletion Source/WebCore/accessibility/AccessibilityTree.h
Expand Up @@ -43,7 +43,6 @@ class AccessibilityTree final : public AccessibilityRenderObject {
bool computeAccessibilityIsIgnored() const override;
AccessibilityRole determineAccessibilityRole() override;
bool isTreeValid() const;
bool nodeHasTreeItemChild(Node&) const;

} // namespace WebCore
Expand Down

0 comments on commit 3f6b035

Please sign in to comment.