From 65ddfb65c2c984afc961335ebb938b7b1122e8b4 Mon Sep 17 00:00:00 2001 From: Sascha Cowley <16543535+SaschaCowley@users.noreply.github.com> Date: Wed, 7 Feb 2024 12:53:00 +1100 Subject: [PATCH] Contenteditable table headers (#15977) Fixes #14113 Summary of the issue: When navigating tables in contenteditable HTML elements in focus mode, table row and column headers are not reported. Description of user facing changes Table row and column headers are now reported when navigating tables in contenteditable HTML elements in focus mode. Description of development approach Added appropriate fields to the `TextInfos.ControlField` returned by `CompoundTextInfo._getControlFieldForObject`. Also added special case handling for Chromium, which erroneously reports heder cells as being their own headers. --- source/NVDAObjects/IAccessible/__init__.py | 19 +++++++++++++++++-- source/compoundDocuments.py | 5 ++++- user_docs/en/changes.t2t | 1 + 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/source/NVDAObjects/IAccessible/__init__.py b/source/NVDAObjects/IAccessible/__init__.py index 7bfb7891ebf..08b524fc343 100644 --- a/source/NVDAObjects/IAccessible/__init__.py +++ b/source/NVDAObjects/IAccessible/__init__.py @@ -1,5 +1,5 @@ # A part of NonVisual Desktop Access (NVDA) -# Copyright (C) 2006-2023 NV Access Limited, Babbage B.V., Cyrille Bougot +# Copyright (C) 2006-2024 NV Access Limited, Babbage B.V., Cyrille Bougot # This file is covered by the GNU General Public License. # See the file COPYING for more details. @@ -1348,8 +1348,23 @@ def _tableHeaderTextHelper(self, axis): # Each header must be fetched from the headers array once and only once, # as it gets released when it gets garbage collected. for i in range(nHeaders): + header = headers[i] try: - text = headers[i].QueryInterface(IA2.IAccessible2).accName(0) + headerIA2Ptr = header.QueryInterface(IA2.IAccessible2) + except COMError: + log.debugWarning("could not get IAccessible2 pointer for table header", exc_info=True) + continue + # Chromium exposes cells as their own headers, so exclude cells with the same `Iaccessible2::uniqueID`. + if self.IA2UniqueID is not None: # No point checking if we don't have this cell's UID + try: + headerUniqueID = headerIA2Ptr.uniqueID + except COMError: + log.debugWarning("could not get IAccessible2::uniqueID to use as headerUniqueID", exc_info=True) + headerUniqueID = None + if self.IA2UniqueID == headerUniqueID: + continue + try: + text = headerIA2Ptr.accName(0) except COMError: continue if not text: diff --git a/source/compoundDocuments.py b/source/compoundDocuments.py index fa21e3b2ed6..a7f1916e93e 100644 --- a/source/compoundDocuments.py +++ b/source/compoundDocuments.py @@ -1,7 +1,8 @@ # A part of NonVisual Desktop Access (NVDA) # This file is covered by the GNU General Public License. # See the file COPYING for more details. -# Copyright (C) 2010-2022 NV Access Limited, Bram Duvigneau +# Copyright (C) 2010-2024 NV Access Limited, Bram Duvigneau + from typing import ( Optional, Dict, @@ -172,6 +173,8 @@ def _getControlFieldForObject(self, obj: NVDAObject, ignoreEditableText=True): field["table-id"] = 1 # FIXME field["table-rownumber"] = obj.rowNumber field["table-columnnumber"] = obj.columnNumber + field["table-rowheadertext"] = obj.rowHeaderText + field["table-columnheadertext"] = obj.columnHeaderText # Row/column span is not supported by all implementations (e.g. LibreOffice) try: field['table-rowsspanned']=obj.rowSpan diff --git a/user_docs/en/changes.t2t b/user_docs/en/changes.t2t index b18ddffce66..4d1e7bfa95d 100644 --- a/user_docs/en/changes.t2t +++ b/user_docs/en/changes.t2t @@ -6,6 +6,7 @@ What's New in NVDA = 2024.2 = == New Features == +- Reporting row and column headers is now supported in contenteditable HTML elements. (#14113) - In Windows 11, NVDA will announce alerts from voice typing and suggested actions including the top suggestion when copying data such as phone numbers to the clipboard (Windows 11 2022 Update and later). (#16009, @josephsl) - Added support for the BrailleEdgeS2 braille device. (#16033) -