[orca] Improve structural navigation in HTML tables with conflicting ARIA semantics
- From: Joanmarie Diggs <joanied src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [orca] Improve structural navigation in HTML tables with conflicting ARIA semantics
- Date: Tue, 5 May 2020 15:48:34 +0000 (UTC)
commit b326744b7c4fdcd6d7f2cd0687a89f7f605b93f3
Author: Joanmarie Diggs <jdiggs igalia com>
Date: Tue May 5 11:42:25 2020 -0400
Improve structural navigation in HTML tables with conflicting ARIA semantics
* For navigation, ensure we're always using the physical table. This is
needed to deal with rows/colums which are omitted via aria-rowindex/
aria-colindex.
* For presentation, ensure we're always prefering object attributes.
This is needed to ensure we present what the other has specified,
rather than the physical (rendered) reality.
src/orca/script_utilities.py | 4 +--
src/orca/scripts/web/script_utilities.py | 16 ++++++----
src/orca/structural_navigation.py | 53 ++++++++++++++++----------------
3 files changed, 38 insertions(+), 35 deletions(-)
---
diff --git a/src/orca/script_utilities.py b/src/orca/script_utilities.py
index 97264ff2f..f7c77fdff 100644
--- a/src/orca/script_utilities.py
+++ b/src/orca/script_utilities.py
@@ -4219,7 +4219,7 @@ class Utilities:
rowIndex = table.getRowAtIndex(index)
return table.getRowHeader(rowIndex)
- def coordinatesForCell(self, obj):
+ def coordinatesForCell(self, obj, preferAttribute=True):
roles = [pyatspi.ROLE_TABLE_CELL,
pyatspi.ROLE_TABLE_COLUMN_HEADER,
pyatspi.ROLE_TABLE_ROW_HEADER,
@@ -4253,7 +4253,7 @@ class Utilities:
row, col = table.getRowAtIndex(index), table.getColumnAtIndex(index)
return table.getRowExtentAt(row, col), table.getColumnExtentAt(row, col)
- def rowAndColumnCount(self, obj):
+ def rowAndColumnCount(self, obj, preferAttribute=True):
try:
table = obj.queryTable()
except:
diff --git a/src/orca/scripts/web/script_utilities.py b/src/orca/scripts/web/script_utilities.py
index 970297c4b..63381fc94 100644
--- a/src/orca/scripts/web/script_utilities.py
+++ b/src/orca/scripts/web/script_utilities.py
@@ -2756,7 +2756,7 @@ class Utilities(script_utilities.Utilities):
return ''
- def coordinatesForCell(self, obj):
+ def coordinatesForCell(self, obj, preferAttribute=True):
roles = [pyatspi.ROLE_TABLE_CELL,
pyatspi.ROLE_TABLE_COLUMN_HEADER,
pyatspi.ROLE_TABLE_ROW_HEADER,
@@ -2765,14 +2765,18 @@ class Utilities(script_utilities.Utilities):
if not (obj and obj.getRole() in roles):
return -1, -1
- rowindex, colindex = self._rowAndColumnIndices(obj)
- if rowindex is not None and colindex is not None:
- return int(rowindex) - 1, int(colindex) - 1
+ if preferAttribute:
+ rowindex, colindex = self._rowAndColumnIndices(obj)
+ if rowindex is not None and colindex is not None:
+ return int(rowindex) - 1, int(colindex) - 1
- return super().coordinatesForCell(obj)
+ return super().coordinatesForCell(obj, preferAttribute)
- def rowAndColumnCount(self, obj):
+ def rowAndColumnCount(self, obj, preferAttribute=True):
rows, cols = super().rowAndColumnCount(obj)
+ if not preferAttribute:
+ return rows, cols
+
attrs = self.objectAttributes(obj)
rows = attrs.get('rowcount', rows)
cols = attrs.get('colcount', cols)
diff --git a/src/orca/structural_navigation.py b/src/orca/structural_navigation.py
index 0558cb4b4..b984c03da 100644
--- a/src/orca/structural_navigation.py
+++ b/src/orca/structural_navigation.py
@@ -477,8 +477,7 @@ class StructuralNavigationObject:
def goCell(script, inputEvent):
obj, offset = script.utilities.getCaretContext()
thisCell = self.structuralNavigation.getCellForObj(obj)
- currentCoordinates = \
- self.structuralNavigation.getCellCoordinates(thisCell)
+ currentCoordinates = self.structuralNavigation.getCellCoordinates(thisCell, False)
if direction == "Left":
desiredCoordinates = [currentCoordinates[0],
currentCoordinates[1] - 1]
@@ -497,9 +496,9 @@ class StructuralNavigationObject:
desiredCoordinates = [-1, -1]
table = self.structuralNavigation.getTableForCell(thisCell)
if table:
- iTable = table.queryTable()
- lastRow = iTable.nRows - 1
- lastCol = iTable.nColumns - 1
+ nRows, nColumns = script.utilities.rowAndColumnCount(table, False)
+ lastRow = nRows - 1
+ lastCol = nColumns - 1
desiredCoordinates = [lastRow, lastCol]
self.structuralNavigation.goCell(self,
thisCell,
@@ -810,17 +809,7 @@ class StructuralNavigation:
"""
table = self.getTableForCell(thisCell)
- try:
- iTable = table.queryTable()
- except NotImplementedError:
- msg = 'ERROR: Table %s does not implement table interface' % table
- debug.println(debug.LEVEL_INFO, msg)
- iTable = None
- except:
- msg = 'ERROR: Exception querying table interface of %s' % table
- debug.println(debug.LEVEL_INFO, msg)
- iTable = None
- if not iTable:
+ if not table:
self._script.presentMessage(messages.TABLE_NOT_IN_A)
return None
@@ -828,24 +817,24 @@ class StructuralNavigation:
desiredRow, desiredCol = desiredCoordinates
rowDiff = desiredRow - currentRow
colDiff = desiredCol - currentCol
- oldRowHeaders = self._script.utilities.rowHeadersForCell(thisCell)
- oldColHeaders = self._script.utilities.columnHeadersForCell(thisCell)
+
+ nRows, nColumns = self._script.utilities.rowAndColumnCount(table, False)
cell = thisCell
while cell:
- cell = iTable.getAccessibleAt(desiredRow, desiredCol)
+ cell = self._script.utilities.cellForCoordinates(table, desiredRow, desiredCol)
if not cell:
if desiredCol < 0:
self._script.presentMessage(messages.TABLE_ROW_BEGINNING)
desiredCol = 0
- elif desiredCol > iTable.nColumns - 1:
+ elif desiredCol > nColumns - 1:
self._script.presentMessage(messages.TABLE_ROW_END)
- desiredCol = iTable.nColumns - 1
+ desiredCol = nColumns - 1
if desiredRow < 0:
self._script.presentMessage(messages.TABLE_COLUMN_TOP)
desiredRow = 0
- elif desiredRow > iTable.nRows - 1:
+ elif desiredRow > nRows - 1:
self._script.presentMessage(messages.TABLE_COLUMN_BOTTOM)
- desiredRow = iTable.nRows - 1
+ desiredRow = nRows - 1
elif thisCell == cell or (settings.skipBlankCells and self._isBlankCell(cell)):
if colDiff < 0:
desiredCol -= 1
@@ -855,11 +844,15 @@ class StructuralNavigation:
desiredRow -= 1
elif rowDiff > 0:
desiredRow += 1
+ else:
+ break
else:
break
self.lastTableCell = [desiredRow, desiredCol]
if cell:
+ oldRowHeaders = self._script.utilities.rowHeadersForCell(thisCell)
+ oldColHeaders = self._script.utilities.columnHeadersForCell(thisCell)
arg = [rowDiff, colDiff, oldRowHeaders, oldColHeaders]
structuralNavigationObject.present(cell, arg)
@@ -1042,8 +1035,8 @@ class StructuralNavigation:
if nonUniform:
nonUniformString = messages.TABLE_NON_UNIFORM + " "
- table = obj.queryTable()
- sizeString = messages.tableSize(table.nRows, table.nColumns)
+ nRows, nColumns = self._script.utilities.rowAndColumnCount(obj, True)
+ sizeString = messages.tableSize(nRows, nColumns)
return (nonUniformString + sizeString)
def getCellForObj(self, obj):
@@ -1174,17 +1167,23 @@ class StructuralNavigation:
text = self._getCellText(header)
speech.speak(text)
- def getCellCoordinates(self, obj):
+ def getCellCoordinates(self, obj, preferAttribute=True):
"""Returns the [row, col] of a ROLE_TABLE_CELL or [-1, -1]
if the coordinates cannot be found.
Arguments:
- obj: the accessible table cell whose coordinates we want.
+ - preferAttribute: If True, prefer object attribute over table interface
"""
cell = self.getCellForObj(obj)
table = self.getTableForCell(cell)
- thisRow, thisCol = self._script.utilities.coordinatesForCell(cell)
+ thisRow, thisCol = self._script.utilities.coordinatesForCell(cell, preferAttribute)
+
+ # If preferAttribute is True, we are getting coordinates to be spoken,
+ # and not to deal with the logic below.
+ if preferAttribute:
+ return thisRow, thisCol
# If we're in a cell that spans multiple rows and/or columns,
# thisRow and thisCol will refer to the upper left cell in
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]