Bug 1894436: Only expose an implicit selected state for focused option, tab and treeitem Accessibles. r=morgan

Previously, we did this for any focused, selectable item.
However, the ARIA spec says we should only do this for option, tab and treeitem.
In particular, we shouldn't do this for gridcell, as this can expose gridcells as selected when they aren't.

Differential Revision: https://phabricator.services.mozilla.com/D209132
This commit is contained in:
James Teh 2024-05-03 10:47:59 +00:00
Родитель 029daef871
Коммит 76cf2fa9f9
2 изменённых файлов: 21 добавлений и 5 удалений

Просмотреть файл

@ -608,12 +608,15 @@ void Accessible::ApplyImplicitState(uint64_t& aState) const {
}
}
// If this is an ARIA item of the selectable widget and if it's focused and
// not marked unselected explicitly (i.e. aria-selected="false") then expose
// it as selected to make ARIA widget authors life easier.
// If this is an option, tab or treeitem and if it's focused and not marked
// unselected explicitly (i.e. aria-selected="false") then expose it as
// selected to make ARIA widget authors life easier.
const nsRoleMapEntry* roleMapEntry = ARIARoleMap();
if (roleMapEntry && !(aState & states::SELECTED) &&
ARIASelected().valueOr(true)) {
if (roleMapEntry &&
(roleMapEntry->Is(nsGkAtoms::option) ||
roleMapEntry->Is(nsGkAtoms::tab) ||
roleMapEntry->Is(nsGkAtoms::treeitem)) &&
!(aState & states::SELECTED) && ARIASelected().valueOr(true)) {
// Special case for tabs: focused tab or focus inside related tab panel
// implies selected state.
if (roleMapEntry->role == roles::PAGETAB) {

Просмотреть файл

@ -424,6 +424,11 @@ addAccessibleTask(
</div>
<div role="listbox" aria-multiselectable="true">
<div id="multiNoSel" role="option" tabindex="0">multiNoSel</div>
</div>
<div role="grid">
<div role="row">
<div id="gridcell" role="gridcell" tabindex="0">gridcell</div>
</div>
</div>
`,
async function (browser, docAcc) {
@ -450,6 +455,14 @@ addAccessibleTask(
multiNoSel.takeFocus();
await focused;
testStates(multiNoSel, STATE_FOCUSED, 0, STATE_SELECTED, 0);
const gridcell = findAccessibleChildByID(docAcc, "gridcell");
testStates(gridcell, 0, 0, STATE_FOCUSED | STATE_SELECTED, 0);
info("Focusing gridcell");
focused = waitForEvent(EVENT_FOCUS, gridcell);
gridcell.takeFocus();
await focused;
testStates(gridcell, STATE_FOCUSED, 0, STATE_SELECTED, 0);
},
{ topLevel: true, iframe: true, remoteIframe: true, chrome: true }
);