From 40fd5efe05bc2f0cf3abaf6b47b44408d39d0d38 Mon Sep 17 00:00:00 2001 From: abaevbog Date: Wed, 17 Jul 2024 00:34:16 -0700 Subject: [PATCH] vpat 48: announce selection for default virtualized table (#4391) * vpat 48: announce selection for default virt table For simpler virtualized tables (e.g. style manager in Zotero_Preferences.Cite), the table does not get re-rendered when selection changes, so aria-activedescendant does not get updated in render(). - a single function to update aria-activedescendant of the table - call it in _updateTree of the tree selection because _onSelection is not called the very first time a table is rendered. In that case, after restart, collectionTree would have a selected row but no aria-activedescendant - remove this.forceUpdate() from selection handlers of itemTree and collectionTree because judging by the coment it's main purpose was to set aria-activedescendant through render() - set aria-activedescendant in _onSelection handler of virtualized table. - construct and set aria-label for rows build via makeRowRenderer of VirtualizedTable so that is is announced when the row is selected. --- chrome/content/zotero/collectionTree.jsx | 2 -- .../zotero/components/virtualized-table.jsx | 23 ++++++++++++++----- chrome/content/zotero/itemTree.jsx | 2 -- 3 files changed, 17 insertions(+), 10 deletions(-) diff --git a/chrome/content/zotero/collectionTree.jsx b/chrome/content/zotero/collectionTree.jsx index 113196a74e..6cfcb6345d 100644 --- a/chrome/content/zotero/collectionTree.jsx +++ b/chrome/content/zotero/collectionTree.jsx @@ -220,8 +220,6 @@ var CollectionTree = class CollectionTree extends LibraryTree { } } } - // Update aria-activedescendant on the tree - this.forceUpdate(); if (shouldDebounce) { this._onSelectionChangeDebounced(); } diff --git a/chrome/content/zotero/components/virtualized-table.jsx b/chrome/content/zotero/components/virtualized-table.jsx index c7d7476ae6..ac5f3cecd4 100644 --- a/chrome/content/zotero/components/virtualized-table.jsx +++ b/chrome/content/zotero/components/virtualized-table.jsx @@ -256,6 +256,7 @@ class TreeSelection { _updateTree(shouldDebounce) { if (!this.selectEventsSuppressed && this._tree.props.onSelectionChange) { this._tree.props.onSelectionChange(this, shouldDebounce); + this._tree._setAriaAciveDescendant(); } } @@ -1281,12 +1282,6 @@ class VirtualizedTable extends React.Component { if (this.props.role == 'treegrid') { props['aria-readonly'] = true; } - if (this.selection.count > 0) { - const elem = this._jsWindow && this._jsWindow.getElementByIndex(this.selection.focused); - if (elem) { - props['aria-activedescendant'] = elem.id; - } - } let jsWindowProps = { id: this._jsWindowID, className: "virtualized-table-body", @@ -1434,6 +1429,15 @@ class VirtualizedTable extends React.Component { this._columns = new Columns(this); await new Promise((resolve) => {this.forceUpdate(resolve)}); } + + // Set aria-activedescendant on table container + _setAriaAciveDescendant() { + if (!this.selection.focused) return; + let selected = this._jsWindow?.getElementByIndex(this.selection.focused); + if (selected) { + selected.closest(".virtualized-table").setAttribute("aria-activedescendant", selected.id); + } + } } /** @@ -1771,6 +1775,7 @@ function makeRowRenderer(getRowData) { div.classList.toggle('selected', selection.isSelected(index)); div.classList.toggle('focused', selection.focused == index); const rowData = getRowData(index); + let ariaLabel = ""; if (columns.length) { for (let column of columns) { @@ -1782,12 +1787,18 @@ function makeRowRenderer(getRowData) { else { div.appendChild(renderCell(index, rowData[column.dataKey], column)); } + let columnName = column.label; + if (column.label in Zotero.Intl.strings) { + columnName = Zotero.getString(column.label); + } + ariaLabel += `${columnName}: ${rowData[column.dataKey]} `; } } else { div.appendChild(renderCell(index, rowData)); } + div.setAttribute("aria-label", ariaLabel); return div; }; } diff --git a/chrome/content/zotero/itemTree.jsx b/chrome/content/zotero/itemTree.jsx index 2d616699e3..5aef911d2b 100644 --- a/chrome/content/zotero/itemTree.jsx +++ b/chrome/content/zotero/itemTree.jsx @@ -3121,8 +3121,6 @@ var ItemTree = class ItemTree extends LibraryTree { this.tree.invalidateRow(this._rowMap[id]); } } - // Update aria-activedescendant on the tree - this.forceUpdate(); this.duplicateMouseSelection = false; if (shouldDebounce) { this._onSelectionChangeDebounced();