Skip to content

Commit

Permalink
[Interop] Orphaned listitems should be exposed as generic role
Browse files Browse the repository at this point in the history
According to [1], if a listitem is not a child of ol, menu, or ul, or if
the containing list element is no longer exposed with a list role, then
the listitem element should be exposed with a generic role.

This CL adds ParentObjectUnignoredNonGeneric() which skips intervening
divs when looking for the parent of a listitem. See [2] for context.

These changes make the following web platform subtests pass:
el-li-orphaned in html-aam/roles-generic.html
orphan div with listitem role in wai-aria/role/list-roles.html

[1]https://w3c.github.io/html-aam/#el-li
[2]web-platform-tests/wpt#45715 (comment)

Bug: 325975937, 41490744, 337035247, 337037595
Change-Id: I9be6fa394f705c5fdbf8d0458c02f75026e3303e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5426593
Reviewed-by: Aaron Leventhal <[email protected]>
Commit-Queue: Jocelyn Tran <[email protected]>
Reviewed-by: Akihiro Ota <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1292557}
  • Loading branch information
tranjocelyn authored and Chromium LUCI CQ committed Apr 25, 2024
1 parent a1ad60c commit 1c920e6
Show file tree
Hide file tree
Showing 21 changed files with 57 additions and 38 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ AX_TEST_F('SwitchAccessPredicateTest', 'IsActionable', async function() {
<input type="text" aria-label="input1">input1</input>
<button>button3</button>
<input type="range" aria-label="slider" value=5 min=0 max=10>
<div id="clickable" role="listitem" onclick="2+2"></div>
<ol><div id="clickable" role="listitem" onclick="2+2"></div></ol>
<div id="div1"><p>p1</p></div>`;
const loadedPage = await this.runWithLoadedTree(treeString);
const cache = new SACache();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ rootWebArea
++++++genericContainer
++++++link expanded
++++++list
++++++++listItem
++++++listBox expanded
++++++listItem
++++++log
++++++main
++++++marquee
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,10 @@
<div role="label" aria-expanded="true"></div>
<div role="legend" aria-expanded="true"></div>
<div role="link" aria-expanded="true"></div>
<div role="list" aria-expanded="true"></div>
<div role="list" aria-expanded="true">
<div role="listitem" aria-expanded="true"></div>
</div>
<div role="listbox" aria-expanded="true"></div>
<div role="listitem" aria-expanded="true"></div>
<div role="log" aria-expanded="true"></div>
<div role="main" aria-expanded="true"></div>
<div role="marquee" aria-expanded="true"></div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,9 @@
++++[table row] level:2
++++++[table cell] name='Cell at level 2' (row=1, col=0, row_span=1, col_span=1, n_row_headers=0, n_col_headers=0)
++++++++[static] name='Cell at level 2'
++[list item] level:1
++[section]
++++[static] name='List item at level 1'
++[list item] level:3
++[section]
++++[static] name='List item at level 3'
++[list]
++++[list item] level:2
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,10 @@ rootWebArea
++++++++++++cell name='Cell at level 2'
++++++++++++++staticText name='Cell at level 2'
++++++++++++++++inlineTextBox
++++++listItem hierarchicalLevel=1
++++++genericContainer
++++++++staticText name='List item at level 1'
++++++++++inlineTextBox
++++++listItem hierarchicalLevel=3
++++++genericContainer
++++++++staticText name='List item at level 3'
++++++++++inlineTextBox
++++++list
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,10 @@ Document
++++TreeItem
++++++DataItem Name='Cell at level 2' GridItem.Column=0 GridItem.ColumnSpan=1 GridItem.Row=1 GridItem.RowSpan=1
++++++++Text Name='Cell at level 2' IsControlElement=false
++ListItem Name='List item at level 1'
++++Text Name='List item at level 1' IsControlElement=false
++ListItem Name='List item at level 3'
++++Text Name='List item at level 3' IsControlElement=false
++Group
++++Text Name='List item at level 1'
++Group
++++Text Name='List item at level 3'
++List
++++ListItem Name='List item at level 2'
++++++Text Name='List item at level 2' IsControlElement=false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,9 @@ ROLE_SYSTEM_DOCUMENT READONLY FOCUSABLE
++++ROLE_SYSTEM_OUTLINEITEM level:2
++++++ROLE_SYSTEM_CELL name='Cell at level 2'
++++++++ROLE_SYSTEM_STATICTEXT name='Cell at level 2'
++ROLE_SYSTEM_LISTITEM READONLY level:1
++IA2_ROLE_SECTION
++++ROLE_SYSTEM_STATICTEXT name='List item at level 1'
++ROLE_SYSTEM_LISTITEM READONLY level:3
++IA2_ROLE_SECTION
++++ROLE_SYSTEM_STATICTEXT name='List item at level 3'
++ROLE_SYSTEM_LIST READONLY
++++ROLE_SYSTEM_LISTITEM READONLY level:2
Expand Down
2 changes: 1 addition & 1 deletion content/test/data/accessibility/aria/aria-level.html
Original file line number Diff line number Diff line change
Expand Up @@ -70,4 +70,4 @@ <h5 role="heading">Level 5</h5>
</div>
</div>
</body>
</html>
</html>
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,13 @@ WebView textSize:16.0 style:0 htmlInfo:[{htmlTag="#document"}, {display=""}]
++ListView textSize:16.0 style:0 htmlInfo:[{htmlTag="ul"}, {display="block"}, {aria-owns="two four"}]
++++View textSize:16.0 style:0 htmlInfo:[{htmlTag="li"}, {display="list-item"}]
++++++View text:"• " textSize:16.0 style:0 htmlInfo:[{htmlTag="::marker"}, {display="inline-block"}]
++++++View textSize:16.0 style:0 htmlInfo:[{htmlTag="div"}, {display="block"}]
++++++++TextView text:"One" textSize:16.0 style:0 htmlInfo:[{htmlTag=""}, {display=""}]
++++++TextView text:"One" textSize:16.0 style:0 htmlInfo:[{htmlTag="div"}, {display="block"}]
++++View textSize:16.0 style:0 htmlInfo:[{htmlTag="li"}, {display="list-item"}, {id="two"}]
++++++View text:"•" textSize:16.0 style:0 htmlInfo:[{htmlTag="::marker"}, {display="inline"}]
++++++View textSize:16.0 style:0 htmlInfo:[{htmlTag="div"}, {display="block"}]
++++++++TextView text:"Two" textSize:16.0 style:0 htmlInfo:[{htmlTag=""}, {display=""}]
++++++TextView text:"Two" textSize:16.0 style:0 htmlInfo:[{htmlTag="div"}, {display="block"}]
++++View textSize:16.0 style:0 htmlInfo:[{htmlTag="li"}, {display="list-item"}, {id="four"}]
++++++View text:"• " textSize:16.0 style:0 htmlInfo:[{htmlTag="::marker"}, {display="inline"}]
++++++TextView text:"Four" textSize:16.0 style:0 htmlInfo:[{htmlTag=""}, {display=""}]
++View textSize:16.0 style:0 htmlInfo:[{htmlTag="li"}, {display="list-item"}, {id="three"}]
++++View text:"•" textSize:16.0 style:0 htmlInfo:[{htmlTag="::marker"}, {display="inline"}]
++++View textSize:16.0 style:0 htmlInfo:[{htmlTag="div"}, {display="block"}]
++++++TextView text:"Three" textSize:16.0 style:0 htmlInfo:[{htmlTag=""}, {display=""}]
++++TextView text:"Three" textSize:16.0 style:0 htmlInfo:[{htmlTag="div"}, {display="block"}]
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@ WebView focusable focused actions:[CLEAR_FOCUS, AX_FOCUS] bundle:[chromeRole="ro
++++View viewIdResName:"four" CollectionItemInfo:[rowIndex=2, colIndex=0] actions:[AX_FOCUS] bundle:[chromeRole="listItem"]
++++++View text:"• " actions:[AX_FOCUS, NEXT, PREVIOUS] bundle:[chromeRole="listMarker"]
++++++TextView text:"Four" actions:[AX_FOCUS, NEXT, PREVIOUS] bundle:[chromeRole="staticText"]
++View viewIdResName:"three" CollectionItemInfo:[rowIndex=0, colIndex=0] actions:[AX_FOCUS] bundle:[chromeRole="listItem"]
++View viewIdResName:"three" actions:[AX_FOCUS] bundle:[chromeRole="genericContainer"]
++++View text:"•" actions:[AX_FOCUS, NEXT, PREVIOUS] bundle:[chromeRole="listMarker"]
++++TextView text:"Three" actions:[AX_FOCUS, NEXT, PREVIOUS] bundle:[chromeRole="genericContainer"]
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
++++[list item]
++++++[static] name='%E2%80%A2 '
++++++[static] name='Four'
++[list item]
++[section]
++++[static] name='%E2%80%A2'
++++[section]
++++++[static] name='Three'
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ rootWebArea
++++++++++++inlineTextBox
++++++genericContainer ignored
++++++genericContainer ignored
++++++++listItem
++++++++genericContainer
++++++++++listMarker name='%E2%80%A2'
++++++++++++staticText ignored name='%E2%80%A2'
++++++++++genericContainer
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
rootWebArea
++genericContainer ignored
++++genericContainer ignored
++++++listItem
++++++genericContainer
++++++++listMarker name='%E2%80%A2 '
++++++++++staticText ignored name='%E2%80%A2 '
++++++++staticText name='CSS list item'
++++++++staticText name='CSS list item (without list parent)'
++++++++++inlineTextBox
++++++list
++++++++listItem
++++++++++listMarker name='%E2%80%A2 '
++++++++++++staticText ignored name='%E2%80%A2 '
++++++++++staticText name='CSS list item'
++++++++++++inlineTextBox
3 changes: 2 additions & 1 deletion content/test/data/accessibility/css/display-list-item.html
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
<div style="display:list-item">CSS list item</div>
<div style="display:list-item">CSS list item (without list parent)</div>
<div role="list"><div style="display:list-item">CSS list item</div></div>
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,9 @@ rootWebArea
++++++++listItem hierarchicalLevel=1
++++++++++staticText name='Level 1, Item 4'
++++++++++++inlineTextBox
++++++listItem hierarchicalLevel=1
++++++genericContainer
++++++++staticText name='Level 1, Not within list group, Item 1'
++++++++++inlineTextBox
++++++listItem hierarchicalLevel=1
++++++genericContainer
++++++++staticText name='Level 1, Not within list group, Item 2'
++++++++++inlineTextBox
2 changes: 1 addition & 1 deletion content/test/data/accessibility/html/list-item-level.html
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,4 @@
}
</style>
</body>
</html>
</html>
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
rootWebArea
++genericContainer ignored
++++genericContainer ignored
++++++listItem description='@NO_CHILDREN_DUMP' descriptionFrom=ariaDescription
++++++genericContainer description='@NO_CHILDREN_DUMP' descriptionFrom=ariaDescription
++++++genericContainer
++++++++staticText name='Done'
++++++++++inlineTextBox
14 changes: 13 additions & 1 deletion third_party/blink/renderer/modules/accessibility/ax_object.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2697,7 +2697,7 @@ ax::mojom::blink::Role AXObject::ComputeFinalRoleForSerialization() const {
// possible to create these internal roles / platform mappings with a listitem
// (native or ARIA) inside of a doc-bibliography or doc-endnotes section.
if (role_ == ax::mojom::blink::Role::kListItem) {
AXObject* ancestor = ParentObject();
AXObject* ancestor = ParentObjectUnignoredNonGeneric();
if (ancestor && ancestor->RoleValue() == ax::mojom::blink::Role::kList) {
// Go up to the root, or next list, checking to see if the list item is
// inside an endnote or bibliography section. If it is, remap the role.
Expand All @@ -2714,6 +2714,8 @@ ax::mojom::blink::Role AXObject::ComputeFinalRoleForSerialization() const {
if (ancestor_role == ax::mojom::blink::Role::kDocEndnotes)
return ax::mojom::blink::Role::kDocEndnote;
}
} else {
return ax::mojom::blink::Role::kGenericContainer;
}
}

Expand Down Expand Up @@ -5939,6 +5941,16 @@ AXObject* AXObject::ParentObjectUnignored() const {
return parent;
}

AXObject* AXObject::ParentObjectUnignoredNonGeneric() const {
AXObject* parent;
for (parent = ParentObject();
parent && parent->IsIgnored() && parent->RoleValue() == ax::mojom::blink::Role::kGenericContainer;
parent = parent->ParentObject()) {
}

return parent;
}

AXObject* AXObject::ParentObjectIncludedInTree() const {
AXObject* parent;
for (parent = ParentObject();
Expand Down
4 changes: 4 additions & 0 deletions third_party/blink/renderer/modules/accessibility/ax_object.h
Original file line number Diff line number Diff line change
Expand Up @@ -1282,6 +1282,10 @@ class MODULES_EXPORT AXObject : public GarbageCollected<AXObject> {
// Works for all nodes.
AXObject* ParentObjectUnignored() const;

// Get or create the first ancestor that's not accessibility ignored and also
// not a generic container. Works for all nodes.
AXObject* ParentObjectUnignoredNonGeneric() const;

// Get or create the first ancestor that's included in the accessibility tree.
// Works for all nodes, and may return nodes that are accessibility ignored.
AXObject* ParentObjectIncludedInTree() const;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
This is a testharness.js-based test.
[FAIL] el-li-orphaned
assert_false: Computed Role: "listitem" does not match any of the acceptable role strings in ["generic", "", "none"]: <li data-testname="el-li-orphaned" class="ex-generic">x</li> expected false got true
All subtests passed and are omitted for brevity.
See https://chromium.googlesource.com/chromium/src/+/HEAD/docs/testing/writing_web_tests.md#Text-Test-Baselines for details.
Harness: the test ran to completion.
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
This is a testharness.js-based test.
[FAIL] orphan p with listitem role
assert_equals: <p role="listitem" data-testname="orphan p with listitem role" data-expectedrole="paragraph" class="ex">x</p> expected "paragraph" but got "listitem"
[FAIL] orphan div with listitem role
assert_false: Computed Role: "listitem" does not match any of the acceptable role strings in ["generic", "", "none"]: <div role="listitem" data-testname="orphan div with listitem role" class="ex-generic">x</div> expected false got true
Harness: the test ran to completion.
assert_equals: <p role="listitem" data-testname="orphan p with listitem role" data-expectedrole="paragraph" class="ex">x</p> expected "paragraph" but got "generic"
Harness: the test ran to completion.

0 comments on commit 1c920e6

Please sign in to comment.