WebKit Bugzilla
New
Browse
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
RESOLVED FIXED
231993
AX: Using aria-activedescendant to set the active cell within a grid does not convey focus movement
https://bugs.webkit.org/show_bug.cgi?id=231993
Summary
AX: Using aria-activedescendant to set the active cell within a grid does not...
Joyce Zhu
Reported
2021-10-19 16:52:52 PDT
When navigating within a grid via non-VoiceOver keys (i.e. those provided by the web page), the change in active cell is not announced by VoiceOver if the element with `role="grid"` uses `aria-activedescendant` instead of explicit `element.focus()` calls on individual cell DOM nodes. Steps to Reproduce: 1. Open the sample page at
https://jscholes.github.io/basic-grid-activedescendant.html
with Safari. Focus will be automatically placed on a link before the grid. 2. Activate VoiceOver. 3. Disable VoiceOver Quick Nav if necessary by pressing Left and Right Arrow together until VO announces: "Quick Nav off". 4. Move to the grid, by pressing either Tab or VO+Right Arrow. VO will announce the grid name, role and size, as well as the value of the first cell: "Hello". 5. Move to the second cell on the first and only row, by pressing the Right Arrow key without modifiers. Expected Behavior: Since `aria-activedescendant` can be used to manage focus (
https://www.w3.org/TR/wai-aria-1.2/#aria-activedescendant
), VoiceOver should announce the change in active cell, specifically by conveying the text of the new active cell ("World") and the coordinates of the new active cell ("Column 2 of 2"). Actual Behavior: VoiceOver doesn't speak or otherwise indicate the change. ------------------------------------------------------------ Other notes which may be helpful: * Following the same repro steps in Google Chrome 94.0.4606.81, with the same version of macOS (11.6) results in the output listed in the "Expected Behavior" section. That is, users will hear: "World. Column 2 of 2". * While users can navigate the grid using VoiceOver-specific keys (e.g. VO+Right Arrow to move to the next column), this is not adequate for web applications which rely on users operating the grid with key handlers provided by the webpage, e.g. to load data on demand in large grids. * While navigating the grid using VoiceOver-specific keys in Safari or Chrome, the VoiceOver hint text consistently indicates that the user is "currently on a text element inside a cell". However, when the grid initially receives focus, or when navigating via page-provided keys in Google Chrome rather than VoiceOver-specific ones, the hint text indicates the role of the current element as a "cell" directly. This may or may not have something to do with the bug being reported.
Attachments
Patch
(18.17 KB, patch)
2023-04-11 17:33 PDT
,
chris fleizach
no flags
Details
Formatted Diff
Diff
Patch
(25.33 KB, patch)
2023-04-11 23:13 PDT
,
chris fleizach
no flags
Details
Formatted Diff
Diff
Patch
(26.39 KB, patch)
2023-04-11 23:49 PDT
,
chris fleizach
no flags
Details
Formatted Diff
Diff
Patch
(26.31 KB, patch)
2023-04-11 23:52 PDT
,
chris fleizach
no flags
Details
Formatted Diff
Diff
Patch
(29.03 KB, patch)
2023-04-13 17:02 PDT
,
chris fleizach
ews-feeder
: commit-queue-
Details
Formatted Diff
Diff
Patch
(28.79 KB, patch)
2023-04-13 17:12 PDT
,
chris fleizach
no flags
Details
Formatted Diff
Diff
Patch
(29.56 KB, patch)
2023-04-14 10:24 PDT
,
chris fleizach
no flags
Details
Formatted Diff
Diff
Patch
(29.34 KB, patch)
2023-04-14 12:29 PDT
,
chris fleizach
no flags
Details
Formatted Diff
Diff
Patch
(29.49 KB, patch)
2023-04-19 13:39 PDT
,
chris fleizach
no flags
Details
Formatted Diff
Diff
Patch
(31.17 KB, patch)
2023-04-19 13:56 PDT
,
chris fleizach
no flags
Details
Formatted Diff
Diff
Patch
(31.17 KB, patch)
2023-04-19 15:19 PDT
,
chris fleizach
no flags
Details
Formatted Diff
Diff
Patch
(31.19 KB, patch)
2023-04-20 11:13 PDT
,
chris fleizach
ews-feeder
: commit-queue-
Details
Formatted Diff
Diff
Show Obsolete
(11)
View All
Add attachment
proposed patch, testcase, etc.
Radar WebKit Bug Importer
Comment 1
2021-10-19 16:53:08 PDT
<
rdar://problem/84439987
>
Sommer Panage
Comment 2
2022-11-16 12:44:25 PST
Still seeing this on 13.1 Beta (22C5044e).
chris fleizach
Comment 3
2023-04-10 00:40:10 PDT
(In reply to Sommer Panage from
comment #2
)
> Still seeing this on 13.1 Beta (22C5044e).
In short, we don't support selected cells and selected cells changed for grids. Need to add that
chris fleizach
Comment 4
2023-04-11 17:33:20 PDT
Created
attachment 465853
[details]
Patch
Tyler Wilcock
Comment 5
2023-04-11 18:15:12 PDT
Comment on
attachment 465853
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=465853&action=review
> Source/WebCore/accessibility/AccessibilityObject.cpp:2843 > + for (auto cell : cells()) {
The type of cell is RefPtr<AXCoreObject>, and the codestyle we've been following recently uses RefPtr (no <>) over auto.
> Source/WebCore/accessibility/AccessibilityObject.cpp:2848 > + if (auto activeDesc = activeDescendant()) {
`activeDescendant` returns a pointer, so this should be auto*. Also, I think WebKit coding style prefers no abbreviations, so this line could maybe be: if (auto* activeDescendant = this->activeDescendant()) {
> LayoutTests/accessibility/mac/grid-selected-cells.html:12 > + <tr ca="tr" role="row" aria-level="1" id="row1">
Is this `ca` attribute necessary? Same question for the other uses in this file.
> LayoutTests/accessibility/mac/grid-selected-cells.html:41 > + output += "Received notification: " + notification + "\n";
You can use JS template literals here: output += `Received notification: ${notification}\n`;
chris fleizach
Comment 6
2023-04-11 23:13:05 PDT
Created
attachment 465858
[details]
Patch
chris fleizach
Comment 7
2023-04-11 23:49:04 PDT
Created
attachment 465859
[details]
Patch
chris fleizach
Comment 8
2023-04-11 23:52:22 PDT
Created
attachment 465860
[details]
Patch
chris fleizach
Comment 9
2023-04-11 23:55:47 PDT
(In reply to Tyler Wilcock from
comment #5
)
> Comment on
attachment 465853
[details]
> Patch >
Thanks - addressed feedback
Andres Gonzalez
Comment 10
2023-04-12 06:34:59 PDT
I'm concerned with the premise of this request and change. ActiveDescendant should not be equated to a selected item. The goal of ActiveDescendant is to signal that a descendant has gain a "pseudo focus", i.e., it is the point of attention, while the ancestor retains focus. The ActiveDescendant element can then be operated on from the input device (e.g., Keyboard), can be edited, selected or deselected, deleted, etc. So ActiveDescendant should not be used to automatically extend the selected items in any container. There are other means to signal that an element has been selected or deselected, and the propagation of the update in the AX tree should start from there. There are some parts of this change that are still valid, adding an exposing the selectedCells() method for tables. (In reply to chris fleizach from
comment #8
)
> Created
attachment 465860
[details]
> Patch
--- a/Source/WebCore/accessibility/AXObjectCache.cpp +++ b/Source/WebCore/accessibility/AXObjectCache.cpp @@ -1974,6 +1972,14 @@ void AXObjectCache::handleActiveDescendantChanged(Element& element) #endif postPlatformNotification(target, AXNotification::AXActiveDescendantChanged); + + // Table cell active descendant changes should trigger selected cell changes. + if (target->isTable() && activeDescendant->isTableCell()) { +#if ENABLE(ACCESSIBILITY_ISOLATED_TREE) + updateIsolatedTree(*object, AXNotification::AXSelectedCellsChanged); object or target? +#endif + postPlatformNotification(object, AXSelectedCellsChanged); Same as above. // HTML tables don't support these attributes. - if ([attributeName isEqualToString:NSAccessibilitySelectedColumnsAttribute] - || [attributeName isEqualToString:NSAccessibilitySelectedCellsAttribute]) + if ([attributeName isEqualToString:NSAccessibilitySelectedColumnsAttribute]) return nil; In the comment, these attributes -> this attribute. --- a/Tools/DumpRenderTree/AccessibilityUIElement.h +++ b/Tools/DumpRenderTree/AccessibilityUIElement.h + void selectedCells(Vector<AccessibilityUIElement>& elements) const; This should return a Vector instead of taking an out param. --- a/Tools/WebKitTestRunner/InjectedBundle/mac/AccessibilityUIElementMac.mm +++ b/Tools/WebKitTestRunner/InjectedBundle/mac/AccessibilityUIElementMac.mm +JSValueRef AccessibilityUIElement::selectedCells() const +{ + BEGIN_AX_OBJC_EXCEPTIONS + Vector<RefPtr<AccessibilityUIElement>> elements; + auto value = attributeValue(NSAccessibilitySelectedCellsAttribute); + if ([value isKindOfClass:[NSArray class]]) + elements = makeVector<RefPtr<AccessibilityUIElement>>(value.get()); + return makeJSArray(elements); + END_AX_OBJC_EXCEPTIONS +} Don't need the temp elements, can be written as: +JSValueRef AccessibilityUIElement::selectedCells() const +{ + BEGIN_AX_OBJC_EXCEPTIONS + auto value = attributeValue(NSAccessibilitySelectedCellsAttribute); + if ([value isKindOfClass:[NSArray class]]) + retrun makeJSArray(makeVector<RefPtr<AccessibilityUIElement>>(value.get())); + END_AX_OBJC_EXCEPTIONS + return nullptr; +}
chris fleizach
Comment 11
2023-04-13 17:02:04 PDT
Created
attachment 465900
[details]
Patch
chris fleizach
Comment 12
2023-04-13 17:12:06 PDT
Created
attachment 465901
[details]
Patch
chris fleizach
Comment 13
2023-04-14 10:24:47 PDT
Created
attachment 465918
[details]
Patch
chris fleizach
Comment 14
2023-04-14 12:29:09 PDT
Created
attachment 465920
[details]
Patch
Andres Gonzalez
Comment 15
2023-04-18 08:28:44 PDT
(In reply to chris fleizach from
comment #14
)
> Created
attachment 465920
[details]
> Patch
--- a/Source/WebCore/accessibility/AXObjectCache.cpp +++ b/Source/WebCore/accessibility/AXObjectCache.cpp + // Table cell active descendant changes should trigger selected cell changes. We should qualify this comment by saying that we only support the case where active descendant changes result in selection changes. In general, that assumption is not true, e.g., the case of a table or list that supports non-contiguous selection. + if (target->isTable() && activeDescendant->isTableCell()) { +#if ENABLE(ACCESSIBILITY_ISOLATED_TREE) + updateIsolatedTree(*object, AXNotification::AXSelectedCellsChanged); +#endif + postPlatformNotification(object, AXSelectedCellsChanged); + } Should pass target instead of object to updateIsolatedTree and postPlatformNotification ? --- a/Source/WebCore/accessibility/AccessibilityObject.cpp +++ b/Source/WebCore/accessibility/AccessibilityObject.cpp +AXCoreObject::AccessibilityChildrenVector AccessibilityObject::selectedCells() +{ ... + for (RefPtr cell : cells()) { I think it should be auto or auto& instead of RefPtr because RefPtr would create a new RefPtr to hold a pointer that is already held in a RefPtr, each item in the Vector cells() is already a RefPtr. + if (auto* activeDescendant = this->activeDescendant()) { + if (!selectedCells.contains(activeDescendant)) + selectedCells.append(activeDescendant); + } Should we add the active descendant to the selection without checking that is actually selected and a cell? And if it is a cell and selected, then we don't need this, it would be added by the for loop above. --- a/Source/WebCore/accessibility/mac/WebAccessibilityObjectWrapperMac.mm +++ b/Source/WebCore/accessibility/mac/WebAccessibilityObjectWrapperMac.mm // HTML tables don't support these attributes. - if ([attributeName isEqualToString:NSAccessibilitySelectedColumnsAttribute] - || [attributeName isEqualToString:NSAccessibilitySelectedCellsAttribute]) + if ([attributeName isEqualToString:NSAccessibilitySelectedColumnsAttribute]) return nil; in the comment, change "these attributes" to singular. --- a/Tools/DumpRenderTree/AccessibilityUIElement.h +++ b/Tools/DumpRenderTree/AccessibilityUIElement.h + void selectedCells(Vector<AccessibilityUIElement>& elements) const; Can we make it to return the Vector instead of taking an out parameter? -- a/Tools/WebKitTestRunner/InjectedBundle/mac/AccessibilityUIElementMac.mm +++ b/Tools/WebKitTestRunner/InjectedBundle/mac/AccessibilityUIElementMac.mm +JSValueRef AccessibilityUIElement::selectedCells() const +{ + BEGIN_AX_OBJC_EXCEPTIONS + Vector<RefPtr<AccessibilityUIElement>> elements; + auto value = attributeValue(NSAccessibilitySelectedCellsAttribute); + if ([value isKindOfClass:[NSArray class]]) + elements = makeVector<RefPtr<AccessibilityUIElement>>(value.get()); + return makeJSArray(elements); + END_AX_OBJC_EXCEPTIONS +} Instead of using the temp elements, can be written as: JSValueRef AccessibilityUIElement::selectedCells() const { BEGIN_AX_OBJC_EXCEPTIONS auto value = attributeValue(NSAccessibilitySelectedCellsAttribute); if ([value isKindOfClass:[NSArray class]]) return makeJSArray(makeVector<RefPtr<AccessibilityUIElement>>(value.get())); END_AX_OBJC_EXCEPTIONS return nullptr; } --- /dev/null +++ b/LayoutTests/accessibility/mac/grid-selected-cells.html +<body id="body"> Doesn't need the id.
chris fleizach
Comment 16
2023-04-19 13:39:17 PDT
Created
attachment 465987
[details]
Patch
chris fleizach
Comment 17
2023-04-19 13:56:09 PDT
Created
attachment 465989
[details]
Patch
chris fleizach
Comment 18
2023-04-19 15:19:17 PDT
Created
attachment 465991
[details]
Patch
chris fleizach
Comment 19
2023-04-20 11:13:31 PDT
Created
attachment 466018
[details]
Patch
EWS
Comment 20
2023-04-20 12:47:13 PDT
Committed
263189@main
(0290a8bc9c69): <
https://commits.webkit.org/263189@main
> All reviewed patches have been landed. Closing bug and clearing flags on
attachment 466018
[details]
.
Todd Kloots
Comment 21
2023-11-30 16:32:41 PST
Verified fixed. Tested using Mac OS 14.1.1 in both Chrome (Version 119.0.6045.199) and Safari (Version 17.1 (19616.2.9.11.7).
Note
You need to
log in
before you can comment on or make changes to this bug.
Top of Page
Format For Printing
XML
Clone This Bug