Skip to content

Commit 2b26333

Browse files
committed
AX: Elements with display: contents and content in a shadowroot do not have their content read when referenced by aria-labelledby
https://bugs.webkit.org/show_bug.cgi?id=275222 rdar://129361833 Reviewed by Joshua Hoffman. When computing accessible names for elements referenced by aria-labelledby, textUnderElement() relies on the render tree to find children. For display:contents shadow hosts, there is no renderer, so shadow root content was never included. The fix adds special handling in accessibleNameForNode() to explicitly traverse shadow root content for display:contents elements. * LayoutTests/accessibility/aria-labelledby-display-contents-shadow-root-expected.txt: Added. * LayoutTests/accessibility/aria-labelledby-display-contents-shadow-root.html: Added. * Source/WebCore/accessibility/AccessibilityNodeObject.cpp: (WebCore::accessibleNameForNode): Canonical link: https://commits.webkit.org/305918@main
1 parent 842e79a commit 2b26333

File tree

3 files changed

+63
-0
lines changed

3 files changed

+63
-0
lines changed
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
This test ensures aria-labelledby correctly references display:contents elements with shadow roots.
2+
3+
PASS: testButton.role.toLowerCase().includes('button') === true
4+
PASS: platformValueForW3CName(testButton) === 'Shadow Label Text'
5+
PASS: platformValueForW3CName(testButton).includes('should NOT appear') === false
6+
7+
PASS successfullyParsed is true
8+
9+
TEST COMPLETE
10+
Button Content
11+
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<script src="../resources/accessibility-helper.js"></script>
5+
<script src="../resources/js-test.js"></script>
6+
</head>
7+
<body>
8+
9+
<div id="label-element" style="display: contents;">
10+
<template shadowrootmode="open">
11+
<div>Shadow Label Text</div>
12+
</template>
13+
</div>
14+
15+
<button id="test-button" aria-labelledby="label-element">Button Content</button>
16+
17+
<div id="unrelated-shadow-host">
18+
<template shadowrootmode="open">
19+
<div>This should NOT appear in button name</div>
20+
</template>
21+
</div>
22+
23+
<script>
24+
var output = "This test ensures aria-labelledby correctly references display:contents elements with shadow roots.\n\n";
25+
26+
if (window.accessibilityController) {
27+
var testButton = accessibilityController.accessibleElementById("test-button");
28+
output += expect("testButton.role.toLowerCase().includes('button')", "true");
29+
output += expect("platformValueForW3CName(testButton)", "'Shadow Label Text'");
30+
output += expect("platformValueForW3CName(testButton).includes('should NOT appear')", "false");
31+
32+
debug(output);
33+
}
34+
</script>
35+
</body>
36+
</html>

Source/WebCore/accessibility/AccessibilityNodeObject.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4279,6 +4279,22 @@ static String accessibleNameForNode(Node& node, Node* labelledbyNode)
42794279
if (!title.isEmpty())
42804280
return title;
42814281

4282+
if (element && element->hasDisplayContents()) {
4283+
// For display:contents elements with shadow roots, the element doesn't have a renderer,
4284+
// so textUnderElement() won't find any children via the render tree. We need to explicitly
4285+
// traverse the shadow root content to compute the accessible name.
4286+
// https://bugs.webkit.org/show_bug.cgi?id=275222
4287+
if (RefPtr shadowRoot = shadowRootIgnoringUserAgentShadow(node)) {
4288+
StringBuilder builder;
4289+
for (RefPtr child = shadowRoot->firstChild(); child; child = child->nextSibling())
4290+
appendNameToStringBuilder(builder, accessibleNameForNode(*child));
4291+
4292+
String shadowText = builder.toString();
4293+
if (!shadowText.isEmpty())
4294+
return shadowText;
4295+
}
4296+
}
4297+
42824298
return { };
42834299
}
42844300

0 commit comments

Comments
 (0)