Bug 2066575: Use CachedTableAccessible for XUL elements with table roles r=Jamie

Differential Revision: https://phabricator.services.mozilla.com/D321409
This commit is contained in:
Morgan Rae Reschenberg
2026-09-10 01:00:11 +00:00
committed by mreschenberg@mozilla.com
parent b8fbec1c6f
commit c940b181a6
9 changed files with 79 additions and 12 deletions
+1
View File
@@ -60,6 +60,7 @@ MOZ_DEFINE_ENUM_WITH_BASE(AccType, uint8_t,
eProgressType,
eRootType,
eXULLabelType,
eXULListboxType,
eXULListItemType,
eXULTabpanelsType,
eXULTooltipType,
+6 -9
View File
@@ -69,7 +69,7 @@ static StaticAutoPtr<CachedTablesMap> sCachedTables;
/* static */
CachedTableAccessible* CachedTableAccessible::GetFrom(Accessible* aAcc) {
MOZ_ASSERT(aAcc->IsTable());
MOZ_ASSERT(aAcc->IsTable() && !aAcc->IsCustomTable());
if (!sCachedTables) {
sCachedTables = new CachedTablesMap();
if (NS_IsMainThread()) {
@@ -255,18 +255,15 @@ CachedTableCellAccessible* CachedTableCellAccessible::GetFrom(
if (parent->IsDoc()) {
break; // Never cross document boundaries.
}
if (parent->IsCustomTable()) {
// This table provides its own cells, so it doesn't use
// CachedTableAccessible.
break;
}
TableAccessible* table = parent->AsTable();
if (!table) {
continue;
}
if (LocalAccessible* local = parent->AsLocal()) {
nsIContent* content = local->GetContent();
if (content && content->IsXULElement()) {
// XUL tables don't use CachedTableAccessible.
break;
}
}
// Non-XUL tables only use CachedTableAccessible.
auto* cachedTable = static_cast<CachedTableAccessible*>(table);
if (auto cellIdx = cachedTable->mAccToCellIdx.Lookup(aAcc)) {
return &cachedTable->mCells[*cellIdx];
+1 -1
View File
@@ -130,7 +130,7 @@ static already_AddRefed<LocalAccessible> MaybeCreateSpecificARIAAccessible(
return nullptr;
}
}
if (parent->IsTable()) {
if (parent->IsTable() && !parent->IsCustomTable()) {
return MakeAndAddRef<ARIAGridCellAccessible>(aContent, aDocument);
}
}
+8
View File
@@ -605,6 +605,12 @@ class Accessible {
bool IsTable() const { return HasGenericType(eTable); }
/**
* Return true for XUL trees and listboxes, which create their own cells
* rather than using CachedTableAccessible.
*/
bool IsCustomTable() const { return IsXULTree() || IsXULListbox(); }
bool IsHyperText() const { return HasGenericType(eHyperText); }
bool IsSelect() const { return HasGenericType(eSelect); }
@@ -680,6 +686,8 @@ class Accessible {
bool IsXULLabel() const { return mType == eXULLabelType; }
bool IsXULListbox() const { return mType == eXULListboxType; }
bool IsXULListItem() const { return mType == eXULListItemType; }
bool IsXULTabpanels() const { return mType == eXULTabpanelsType; }
+2 -2
View File
@@ -4802,14 +4802,14 @@ void LocalAccessible::StaticAsserts() const {
}
TableAccessible* LocalAccessible::AsTable() {
if (IsTable() && !mContent->IsXULElement()) {
if (IsTable() && !IsCustomTable()) {
return CachedTableAccessible::GetFrom(this);
}
return nullptr;
}
TableCellAccessible* LocalAccessible::AsTableCell() {
if (IsTableCell() && !mContent->IsXULElement()) {
if (IsTableCell()) {
return CachedTableCellAccessible::GetFrom(this);
}
return nullptr;
@@ -3,6 +3,7 @@ subsuite = "a11y"
support-files = [
"head.js",
"doc_xul.xhtml",
"doc_xul_grid.xhtml",
"!/accessible/tests/browser/shared-head.js",
"!/accessible/tests/mochitest/*.js",
"!/accessible/tests/mochitest/moz.png",
@@ -60,3 +61,5 @@ skip-if = [
["browser_test_nsIAccessibleDocument_URL.js"]
["browser_view_transition.js"]
["browser_xul_aria_grid.js"]
@@ -0,0 +1,39 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
/* import-globals-from ../../mochitest/role.js */
loadScripts({ name: "role.js", dir: MOCHITESTS_DIR });
/**
* Verify a XUL acc with role=grid exposes table properties.
*/
addAccessibleTask(
"tree/doc_xul_grid.xhtml",
async function testXULGridProperties(browser, accDoc) {
const gridAcc = findAccessibleChildByID(accDoc, "grid");
is(gridAcc.role, ROLE_GRID, "XUL hbox with role=grid has grid role");
const table = gridAcc.QueryInterface(Ci.nsIAccessibleTable);
is(table.rowCount, 2, "Grid has two rows");
is(table.columnCount, 3, "Grid has three columns");
const cellAcc = table.getCellAt(1, 2);
is(
getAccessibleDOMNodeID(cellAcc),
"cell12",
"Correct cell at row 1, column 2"
);
is(cellAcc.role, ROLE_GRID_CELL, "Cell has grid cell role");
const cell = cellAcc.QueryInterface(Ci.nsIAccessibleTableCell);
is(cell.rowIndex, 1, "Cell has correct row index");
is(cell.columnIndex, 2, "Cell has correct column index");
is(cell.rowExtent, 1, "Cell spans one row");
is(cell.columnExtent, 1, "Cell spans one column");
is(cell.table, table, "Cell reports the grid as its table");
},
{ topLevel: false, chrome: true }
);
@@ -0,0 +1,18 @@
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<window
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<hbox id="grid" role="grid">
<hbox role="row">
<label id="cell00" role="gridcell" value="cell 0 0"/>
<label id="cell01" role="gridcell" value="cell 0 1"/>
<label id="cell02" role="gridcell" value="cell 0 2"/>
</hbox>
<hbox role="row">
<label id="cell10" role="gridcell" value="cell 1 0"/>
<label id="cell11" role="gridcell" value="cell 1 1"/>
<label id="cell12" role="gridcell" value="cell 1 2"/>
</hbox>
</hbox>
</window>
+1
View File
@@ -58,6 +58,7 @@ void XULColumnItemAccessible::ActionNameAt(uint8_t aIndex, nsAString& aName) {
XULListboxAccessible::XULListboxAccessible(nsIContent* aContent,
DocAccessible* aDoc)
: XULSelectControlAccessible(aContent, aDoc) {
mType = eXULListboxType;
dom::Element* parentEl = mContent->GetParentElement();
if (parentEl) {
nsCOMPtr<nsIAutoCompletePopup> autoCompletePopupElm =