Implement the AtkTableCell interface
Bug: 934815
Change-Id: I6d3ab551580818142b7ad7c289b442f6aa841343
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1492111
Commit-Queue: Joanmarie Diggs <joanmarie.diggs@gmail.com>
Reviewed-by: Dominic Mazzoni <dmazzoni@chromium.org>
Cr-Commit-Position: refs/heads/master@{#640819}
diff --git a/content/browser/accessibility/accessibility_tree_formatter_auralinux.cc b/content/browser/accessibility/accessibility_tree_formatter_auralinux.cc
index fc09678c..5a662f8 100644
--- a/content/browser/accessibility/accessibility_tree_formatter_auralinux.cc
+++ b/content/browser/accessibility/accessibility_tree_formatter_auralinux.cc
@@ -337,6 +337,14 @@
WriteAttribute(true, table_property, &line);
}
+ const base::ListValue* cell_info;
+ node.GetList("cell", &cell_info);
+ for (auto it = cell_info->begin(); it != cell_info->end(); ++it) {
+ std::string cell_property;
+ if (it->GetAsString(&cell_property))
+ WriteAttribute(true, cell_property, &line);
+ }
+
return line;
}
diff --git a/content/test/data/accessibility/html/caption-expected-auralinux.txt b/content/test/data/accessibility/html/caption-expected-auralinux.txt
index 970e6c0..0ac5603 100644
--- a/content/test/data/accessibility/html/caption-expected-auralinux.txt
+++ b/content/test/data/accessibility/html/caption-expected-auralinux.txt
@@ -3,17 +3,17 @@
++++[caption]
++++++[text] name='Browser and Engine'
++++[table row]
-++++++[column header] name='Browser'
+++++++[column header] name='Browser' (row=0, col=0, row_span=1, col_span=1 n_row_headers=0, n_col_headers=0)
++++++++[text] name='Browser'
-++++++[column header] name='Engine'
+++++++[column header] name='Engine' (row=0, col=1, row_span=1, col_span=1 n_row_headers=0, n_col_headers=0)
++++++++[text] name='Engine'
++++[table row]
-++++++[table cell] name='Chrome'
+++++++[table cell] name='Chrome' (row=1, col=0, row_span=1, col_span=1 n_row_headers=0, n_col_headers=1)
++++++++[text] name='Chrome'
-++++++[table cell] name='Blink'
+++++++[table cell] name='Blink' (row=1, col=1, row_span=1, col_span=1 n_row_headers=0, n_col_headers=1)
++++++++[text] name='Blink'
++++[table row]
-++++++[table cell] name='Safari'
+++++++[table cell] name='Safari' (row=2, col=0, row_span=1, col_span=1 n_row_headers=0, n_col_headers=1)
++++++++[text] name='Safari'
-++++++[table cell] name='WebKit'
+++++++[table cell] name='WebKit' (row=2, col=1, row_span=1, col_span=1 n_row_headers=0, n_col_headers=1)
++++++++[text] name='WebKit'
diff --git a/content/test/data/accessibility/html/col-expected-auralinux.txt b/content/test/data/accessibility/html/col-expected-auralinux.txt
index 293ae464..6863cda8 100644
--- a/content/test/data/accessibility/html/col-expected-auralinux.txt
+++ b/content/test/data/accessibility/html/col-expected-auralinux.txt
@@ -1,12 +1,12 @@
[document web]
++[table] cols=2 headers=('Browser', 'Rendering Engine'); rows=2 headers=(NONE); caption=false; spans=(all: 1x1)
++++[table row]
-++++++[column header] name='Browser'
+++++++[column header] name='Browser' (row=0, col=0, row_span=1, col_span=1 n_row_headers=0, n_col_headers=0)
++++++++[text] name='Browser'
-++++++[column header] name='Rendering Engine'
+++++++[column header] name='Rendering Engine' (row=0, col=1, row_span=1, col_span=1 n_row_headers=0, n_col_headers=0)
++++++++[text] name='Rendering Engine'
++++[table row]
-++++++[table cell] name='Chrome'
+++++++[table cell] name='Chrome' (row=1, col=0, row_span=1, col_span=1 n_row_headers=0, n_col_headers=1)
++++++++[text] name='Chrome'
-++++++[table cell] name='Blink'
+++++++[table cell] name='Blink' (row=1, col=1, row_span=1, col_span=1 n_row_headers=0, n_col_headers=1)
++++++++[text] name='Blink'
diff --git a/content/test/data/accessibility/html/colgroup-expected-auralinux.txt b/content/test/data/accessibility/html/colgroup-expected-auralinux.txt
index a3b6397..93d4721 100644
--- a/content/test/data/accessibility/html/colgroup-expected-auralinux.txt
+++ b/content/test/data/accessibility/html/colgroup-expected-auralinux.txt
@@ -1,12 +1,12 @@
[document web]
++[table] cols=2 headers=('Single', 'Pair'); rows=2 headers=(NONE); caption=false; spans=(all: 1x1)
++++[table row]
-++++++[column header] name='Single'
+++++++[column header] name='Single' (row=0, col=0, row_span=1, col_span=1 n_row_headers=0, n_col_headers=0)
++++++++[text] name='Single'
-++++++[column header] name='Pair'
+++++++[column header] name='Pair' (row=0, col=1, row_span=1, col_span=1 n_row_headers=0, n_col_headers=0)
++++++++[text] name='Pair'
++++[table row]
-++++++[table cell] name='A'
+++++++[table cell] name='A' (row=1, col=0, row_span=1, col_span=1 n_row_headers=0, n_col_headers=1)
++++++++[text] name='A'
-++++++[table cell] name='AA'
+++++++[table cell] name='AA' (row=1, col=1, row_span=1, col_span=1 n_row_headers=0, n_col_headers=1)
++++++++[text] name='AA'
diff --git a/content/test/data/accessibility/html/contenteditable-descendants-expected-auralinux.txt b/content/test/data/accessibility/html/contenteditable-descendants-expected-auralinux.txt
index a5a5d7b..fb2efbe 100644
--- a/content/test/data/accessibility/html/contenteditable-descendants-expected-auralinux.txt
+++ b/content/test/data/accessibility/html/contenteditable-descendants-expected-auralinux.txt
@@ -11,7 +11,7 @@
++++++[text] name='.' editable
++++[table] editable cols=1 headers=(NONE); rows=1 headers=(NONE); caption=false; spans=(all: 1x1)
++++++[table row] editable
-++++++++[table cell] name='Always expose editable tables as tables.' editable
+++++++++[table cell] name='Always expose editable tables as tables.' editable (row=0, col=0, row_span=1, col_span=1 n_row_headers=0, n_col_headers=0)
++++++++++[text] name='Always expose editable tables as tables.' editable
++++[list] editable
++++++[list item] editable
diff --git a/content/test/data/accessibility/html/contenteditable-descendants-with-selection-expected-auralinux.txt b/content/test/data/accessibility/html/contenteditable-descendants-with-selection-expected-auralinux.txt
index 125348a..2fa7f7a 100644
--- a/content/test/data/accessibility/html/contenteditable-descendants-with-selection-expected-auralinux.txt
+++ b/content/test/data/accessibility/html/contenteditable-descendants-with-selection-expected-auralinux.txt
@@ -11,7 +11,7 @@
++++++[text] name='.' editable
++++[table] editable cols=1 headers=(NONE); rows=1 headers=(NONE); caption=false; spans=(all: 1x1)
++++++[table row] editable
-++++++++[table cell] name='Always expose editable tables as tables.' editable
+++++++++[table cell] name='Always expose editable tables as tables.' editable (row=0, col=0, row_span=1, col_span=1 n_row_headers=0, n_col_headers=0)
++++++++++[text] name='Always expose editable tables as tables.' editable
++++[list] editable
++++++[list item] editable
diff --git a/content/test/data/accessibility/html/table-focusable-sections-expected-auralinux.txt b/content/test/data/accessibility/html/table-focusable-sections-expected-auralinux.txt
index 97848ca..f776f1d 100644
--- a/content/test/data/accessibility/html/table-focusable-sections-expected-auralinux.txt
+++ b/content/test/data/accessibility/html/table-focusable-sections-expected-auralinux.txt
@@ -2,24 +2,24 @@
++[table] cols=2 headers=('Sum', 'Subtraction'); rows=4 headers=(NONE); caption=false; spans=(all: 1x1)
++++[panel]
++++++[table row]
-++++++++[column header] name='Sum'
+++++++++[column header] name='Sum' (row=0, col=0, row_span=1, col_span=1 n_row_headers=0, n_col_headers=0)
++++++++++[text] name='Sum'
-++++++++[column header] name='Subtraction'
+++++++++[column header] name='Subtraction' (row=0, col=1, row_span=1, col_span=1 n_row_headers=0, n_col_headers=0)
++++++++++[text] name='Subtraction'
++++[panel]
++++++[table row]
-++++++++[table cell] name='10'
+++++++++[table cell] name='10' (row=1, col=0, row_span=1, col_span=1 n_row_headers=0, n_col_headers=1)
++++++++++[text] name='10'
-++++++++[table cell] name='7'
+++++++++[table cell] name='7' (row=1, col=1, row_span=1, col_span=1 n_row_headers=0, n_col_headers=1)
++++++++++[text] name='7'
++++++[table row]
-++++++++[table cell] name='2'
+++++++++[table cell] name='2' (row=2, col=0, row_span=1, col_span=1 n_row_headers=0, n_col_headers=1)
++++++++++[text] name='2'
-++++++++[table cell] name='4'
+++++++++[table cell] name='4' (row=2, col=1, row_span=1, col_span=1 n_row_headers=0, n_col_headers=1)
++++++++++[text] name='4'
++++[panel]
++++++[table row]
-++++++++[table cell] name='12'
+++++++++[table cell] name='12' (row=3, col=0, row_span=1, col_span=1 n_row_headers=0, n_col_headers=1)
++++++++++[text] name='12'
-++++++++[table cell] name='3'
+++++++++[table cell] name='3' (row=3, col=1, row_span=1, col_span=1 n_row_headers=0, n_col_headers=1)
++++++++++[text] name='3'
diff --git a/content/test/data/accessibility/html/table-simple-expected-auralinux.txt b/content/test/data/accessibility/html/table-simple-expected-auralinux.txt
index 0687a97..6f2a7de 100644
--- a/content/test/data/accessibility/html/table-simple-expected-auralinux.txt
+++ b/content/test/data/accessibility/html/table-simple-expected-auralinux.txt
@@ -1,17 +1,17 @@
[document web] name='Table example'
++[table] cols=2 headers=('Pair', 'Single'); rows=3 headers=(NONE); caption=false; spans=(all: 1x1)
++++[table row]
-++++++[column header] name='Pair'
+++++++[column header] name='Pair' (row=0, col=0, row_span=1, col_span=1 n_row_headers=0, n_col_headers=0)
++++++++[text] name='Pair'
-++++++[column header] name='Single'
+++++++[column header] name='Single' (row=0, col=1, row_span=1, col_span=1 n_row_headers=0, n_col_headers=0)
++++++++[text] name='Single'
++++[table row]
-++++++[table cell] name='AB'
+++++++[table cell] name='AB' (row=1, col=0, row_span=1, col_span=1 n_row_headers=0, n_col_headers=1)
++++++++[text] name='AB'
-++++++[table cell] name='B'
+++++++[table cell] name='B' (row=1, col=1, row_span=1, col_span=1 n_row_headers=0, n_col_headers=1)
++++++++[text] name='B'
++++[table row]
-++++++[table cell] name='CD'
+++++++[table cell] name='CD' (row=2, col=0, row_span=1, col_span=1 n_row_headers=0, n_col_headers=1)
++++++++[text] name='CD'
-++++++[table cell] name='D'
+++++++[table cell] name='D' (row=2, col=1, row_span=1, col_span=1 n_row_headers=0, n_col_headers=1)
++++++++[text] name='D'
diff --git a/content/test/data/accessibility/html/table-spans-expected-auralinux.txt b/content/test/data/accessibility/html/table-spans-expected-auralinux.txt
index f0fa7c7..3380342 100644
--- a/content/test/data/accessibility/html/table-spans-expected-auralinux.txt
+++ b/content/test/data/accessibility/html/table-spans-expected-auralinux.txt
@@ -1,21 +1,21 @@
[document web] name='Table example with rowspan and colspan'
++[table] cols=2 headers=(NONE); rows=2 headers=(NONE); caption=false; spans=(cell at 0,0: 2x1, cell at 1,0: 2x1)
++++[table row]
-++++++[table cell] name='AD'
+++++++[table cell] name='AD' (row=0, col=0, row_span=2, col_span=1 n_row_headers=0, n_col_headers=0)
++++++++[text] name='AD'
-++++++[table cell] name='BC'
+++++++[table cell] name='BC' (row=0, col=1, row_span=1, col_span=1 n_row_headers=0, n_col_headers=0)
++++++++[text] name='BC'
++++[table row]
-++++++[table cell] name='EF'
+++++++[table cell] name='EF' (row=1, col=1, row_span=1, col_span=1 n_row_headers=0, n_col_headers=0)
++++++++[text] name='EF'
++[table] cols=3 headers=(NONE); rows=2 headers=(NONE); caption=false; spans=(cell at 0,0: 2x1, cell at 0,1: 1x2, cell at 0,2: 1x2, cell at 1,0: 2x1)
++++[table row]
-++++++[table cell] name='AD'
+++++++[table cell] name='AD' (row=0, col=0, row_span=2, col_span=1 n_row_headers=0, n_col_headers=0)
++++++++[text] name='AD'
-++++++[table cell] name='BC'
+++++++[table cell] name='BC' (row=0, col=1, row_span=1, col_span=2 n_row_headers=0, n_col_headers=0)
++++++++[text] name='BC'
++++[table row]
-++++++[table cell] name='EF'
+++++++[table cell] name='EF' (row=1, col=1, row_span=1, col_span=1 n_row_headers=0, n_col_headers=0)
++++++++[text] name='EF'
-++++++[table cell] name='GH'
+++++++[table cell] name='GH' (row=1, col=2, row_span=1, col_span=1 n_row_headers=0, n_col_headers=0)
++++++++[text] name='GH'
diff --git a/content/test/data/accessibility/html/table-th-colheader-expected-auralinux.txt b/content/test/data/accessibility/html/table-th-colheader-expected-auralinux.txt
index 10721b8..15a3f20 100644
--- a/content/test/data/accessibility/html/table-th-colheader-expected-auralinux.txt
+++ b/content/test/data/accessibility/html/table-th-colheader-expected-auralinux.txt
@@ -1,12 +1,12 @@
[document web]
++[table] cols=2 headers=('Firstname', 'Lastname'); rows=2 headers=(NONE); caption=false; spans=(all: 1x1)
++++[table row]
-++++++[column header] name='Firstname' table-cell-index:0
+++++++[column header] name='Firstname' table-cell-index:0 (row=0, col=0, row_span=1, col_span=1 n_row_headers=0, n_col_headers=0)
++++++++[text] name='Firstname'
-++++++[column header] name='Lastname' table-cell-index:1
+++++++[column header] name='Lastname' table-cell-index:1 (row=0, col=1, row_span=1, col_span=1 n_row_headers=0, n_col_headers=0)
++++++++[text] name='Lastname'
++++[table row]
-++++++[table cell] name='Jill' table-cell-index:2
+++++++[table cell] name='Jill' table-cell-index:2 (row=1, col=0, row_span=1, col_span=1 n_row_headers=0, n_col_headers=1)
++++++++[text] name='Jill'
-++++++[table cell] name='Smith' table-cell-index:3
+++++++[table cell] name='Smith' table-cell-index:3 (row=1, col=1, row_span=1, col_span=1 n_row_headers=0, n_col_headers=1)
++++++++[text] name='Smith'
diff --git a/content/test/data/accessibility/html/table-th-rowheader-expected-auralinux.txt b/content/test/data/accessibility/html/table-th-rowheader-expected-auralinux.txt
index db40158..ed81a2c 100644
--- a/content/test/data/accessibility/html/table-th-rowheader-expected-auralinux.txt
+++ b/content/test/data/accessibility/html/table-th-rowheader-expected-auralinux.txt
@@ -1,12 +1,12 @@
[document web] name='Table example - th rowheader'
++[table] cols=2 headers=(NONE); rows=2 headers=('Firstname', 'Lastname'); caption=false; spans=(all: 1x1)
++++[table row]
-++++++[row header] name='Firstname'
+++++++[row header] name='Firstname' (row=0, col=0, row_span=1, col_span=1 n_row_headers=0, n_col_headers=0)
++++++++[text] name='Firstname'
-++++++[table cell] name='Jill'
+++++++[table cell] name='Jill' (row=0, col=1, row_span=1, col_span=1 n_row_headers=1, n_col_headers=0)
++++++++[text] name='Jill'
++++[table row]
-++++++[row header] name='Lastname'
+++++++[row header] name='Lastname' (row=1, col=0, row_span=1, col_span=1 n_row_headers=0, n_col_headers=0)
++++++++[text] name='Lastname'
-++++++[table cell] name='Smith'
+++++++[table cell] name='Smith' (row=1, col=1, row_span=1, col_span=1 n_row_headers=1, n_col_headers=0)
++++++++[text] name='Smith'
diff --git a/content/test/data/accessibility/html/table-thead-tbody-tfoot-expected-auralinux.txt b/content/test/data/accessibility/html/table-thead-tbody-tfoot-expected-auralinux.txt
index 285701d..f71c4455 100644
--- a/content/test/data/accessibility/html/table-thead-tbody-tfoot-expected-auralinux.txt
+++ b/content/test/data/accessibility/html/table-thead-tbody-tfoot-expected-auralinux.txt
@@ -1,22 +1,22 @@
[document web] name='Table example - thead, tbody, tfoot'
++[table] cols=2 headers=('Sum', 'Subtraction'); rows=4 headers=(NONE); caption=false; spans=(all: 1x1)
++++[table row]
-++++++[column header] name='Sum'
+++++++[column header] name='Sum' (row=0, col=0, row_span=1, col_span=1 n_row_headers=0, n_col_headers=0)
++++++++[text] name='Sum'
-++++++[column header] name='Subtraction'
+++++++[column header] name='Subtraction' (row=0, col=1, row_span=1, col_span=1 n_row_headers=0, n_col_headers=0)
++++++++[text] name='Subtraction'
++++[table row]
-++++++[table cell] name='10'
+++++++[table cell] name='10' (row=1, col=0, row_span=1, col_span=1 n_row_headers=0, n_col_headers=1)
++++++++[text] name='10'
-++++++[table cell] name='7'
+++++++[table cell] name='7' (row=1, col=1, row_span=1, col_span=1 n_row_headers=0, n_col_headers=1)
++++++++[text] name='7'
++++[table row]
-++++++[table cell] name='2'
+++++++[table cell] name='2' (row=2, col=0, row_span=1, col_span=1 n_row_headers=0, n_col_headers=1)
++++++++[text] name='2'
-++++++[table cell] name='4'
+++++++[table cell] name='4' (row=2, col=1, row_span=1, col_span=1 n_row_headers=0, n_col_headers=1)
++++++++[text] name='4'
++++[table row]
-++++++[table cell] name='12'
+++++++[table cell] name='12' (row=3, col=0, row_span=1, col_span=1 n_row_headers=0, n_col_headers=1)
++++++++[text] name='12'
-++++++[table cell] name='3'
+++++++[table cell] name='3' (row=3, col=1, row_span=1, col_span=1 n_row_headers=0, n_col_headers=1)
++++++++[text] name='3'
diff --git a/ui/accessibility/platform/ax_platform_node_auralinux.cc b/ui/accessibility/platform/ax_platform_node_auralinux.cc
index 0963a99..2a95a27 100644
--- a/ui/accessibility/platform/ax_platform_node_auralinux.cc
+++ b/ui/accessibility/platform/ax_platform_node_auralinux.cc
@@ -4,6 +4,7 @@
#include "ui/accessibility/platform/ax_platform_node_auralinux.h"
+#include <dlfcn.h>
#include <stdint.h>
#include <algorithm>
@@ -56,6 +57,47 @@
// null if if the AtkObject is destroyed.
AtkObject* g_active_top_level_frame = nullptr;
+// AtkTableCell was introduced in ATK 2.12. Ubuntu Trusty has ATK 2.10.
+// Compile-time checks are in place for ATK versions that are older than 2.12.
+// However, we also need runtime checks in case the version we are building
+// against is newer than the runtime version. To prevent a runtime error, we
+// check that we have a version of ATK that supports AtkTableCell. If we do,
+// we dynamically load the symbol; if we don't, the interface is absent from
+// the accessible object and its methods will not be exposed or callable.
+// The definitions below ensure we have no missing symbols. Note that in
+// environments where we have ATK > 2.12, the definitions of AtkTableCell and
+// AtkTableCellIface below are overridden by the runtime version.
+// TODO(accessibility) Remove these definitions, along with the use of
+// LoadTableCellMethods() when 2.12 is the minimum supported version.
+typedef struct _AtkTableCell AtkTableCell;
+typedef struct _AtkTableCellIface AtkTableCellIface;
+typedef GType (*cell_get_type_func)();
+typedef GPtrArray* (*get_column_header_cells_func)(AtkTableCell* cell);
+typedef GPtrArray* (*get_row_header_cells_func)(AtkTableCell* cell);
+typedef bool (*get_row_column_span_func)(AtkTableCell* cell,
+ gint* row,
+ gint* column,
+ gint* row_span,
+ gint* col_span);
+
+cell_get_type_func cell_get_type = nullptr;
+get_column_header_cells_func get_column_header_cells = nullptr;
+get_row_header_cells_func get_row_header_cells = nullptr;
+get_row_column_span_func get_row_column_span = nullptr;
+
+static bool LoadTableCellMethods() {
+ cell_get_type = reinterpret_cast<cell_get_type_func>(
+ dlsym(RTLD_DEFAULT, "atk_table_cell_get_type"));
+ get_column_header_cells = reinterpret_cast<get_column_header_cells_func>(
+ dlsym(RTLD_DEFAULT, "atk_table_cell_get_column_header_cells"));
+ get_row_header_cells = reinterpret_cast<get_row_header_cells_func>(
+ dlsym(RTLD_DEFAULT, "atk_table_cell_get_row_header_cells"));
+ get_row_column_span = reinterpret_cast<get_row_column_span_func>(
+ dlsym(RTLD_DEFAULT, "atk_table_cell_get_row_column_span"));
+
+ return cell_get_type;
+}
+
static AtkObject* FindAtkObjectParentFrame(AtkObject* atk_object) {
while (atk_object) {
if (atk_object_get_role(atk_object) == ATK_ROLE_FRAME)
@@ -286,6 +328,10 @@
"footnote", // ATK_ROLE_FOOTNOTE = 122.
};
+#if defined(ATK_CHECK_VERSION) && ATK_CHECK_VERSION(2, 12, 0)
+#define ATK_212
+#endif
+
#if defined(ATK_CHECK_VERSION) && ATK_CHECK_VERSION(2, 16, 0)
#define ATK_216
#endif
@@ -1581,6 +1627,116 @@
nullptr};
//
+// AtkTableCell interface (Requires at least ATK 2.12)
+//
+static void IdsToGPtrArray(AXPlatformNodeDelegate* delegate,
+ std::vector<int32_t>& ids,
+ GPtrArray* array) {
+ for (const auto& node_id : ids) {
+ if (AXPlatformNode* header = delegate->GetFromNodeID(node_id)) {
+ if (AtkObject* atk_header = header->GetNativeViewAccessible()) {
+ g_object_ref(atk_header);
+ g_ptr_array_add(array, atk_header);
+ }
+ }
+ }
+}
+
+#if defined(ATK_212)
+gint AXPlatformNodeAuraLinuxGetColumnSpan(AtkTableCell* cell) {
+ if (auto* obj = AtkObjectToAXPlatformNodeAuraLinux(ATK_OBJECT(cell)))
+ return obj->GetTableColumnSpan();
+
+ return 0;
+}
+
+GPtrArray* AXPlatformNodeAuraLinuxGetColumnHeaderCells(AtkTableCell* cell) {
+ GPtrArray* array = g_ptr_array_new();
+
+ // AtkTableCell is implemented on cells, row headers, and column headers.
+ // Calling GetColHeaderNodeIds() on a column header cell will include that
+ // column header, along with any other column headers in the column which
+ // may or may not describe the header cell in question. Therefore, just return
+ // headers for non-header cells.
+ if (atk_object_get_role(ATK_OBJECT(cell)) != ATK_ROLE_TABLE_CELL)
+ return array;
+
+ if (auto* obj = AtkObjectToAXPlatformNodeAuraLinux(ATK_OBJECT(cell))) {
+ if (auto* table = obj->GetTable()) {
+ std::vector<int32_t> ids =
+ table->GetDelegate()->GetColHeaderNodeIds(obj->GetTableColumn());
+ IdsToGPtrArray(table->GetDelegate(), ids, array);
+ }
+ }
+
+ return array;
+}
+
+gboolean AXPlatformNodeAuraLinuxGetCellPosition(AtkTableCell* cell,
+ gint* row,
+ gint* column) {
+ if (auto* obj = AtkObjectToAXPlatformNodeAuraLinux(ATK_OBJECT(cell))) {
+ *row = obj->GetTableRow();
+ *column = obj->GetTableColumn();
+ return true;
+ }
+
+ return false;
+}
+
+gint AXPlatformNodeAuraLinuxGetRowSpan(AtkTableCell* cell) {
+ if (auto* obj = AtkObjectToAXPlatformNodeAuraLinux(ATK_OBJECT(cell)))
+ return obj->GetTableRowSpan();
+
+ return 0;
+}
+
+GPtrArray* AXPlatformNodeAuraLinuxGetRowHeaderCells(AtkTableCell* cell) {
+ GPtrArray* array = g_ptr_array_new();
+
+ // AtkTableCell is implemented on cells, row headers, and column headers.
+ // Calling GetRowHeaderNodeIds() on a row header cell will include that
+ // row header, along with any other row headers in the row which may or
+ // may not describe the header cell in question. Therefore, just return
+ // headers for non-header cells.
+ if (atk_object_get_role(ATK_OBJECT(cell)) != ATK_ROLE_TABLE_CELL)
+ return array;
+
+ if (auto* obj = AtkObjectToAXPlatformNodeAuraLinux(ATK_OBJECT(cell))) {
+ if (auto* table = obj->GetTable()) {
+ std::vector<int32_t> ids =
+ table->GetDelegate()->GetRowHeaderNodeIds(obj->GetTableRow());
+ IdsToGPtrArray(table->GetDelegate(), ids, array);
+ }
+ }
+
+ return array;
+}
+
+AtkObject* AXPlatformNodeAuraLinuxGetTable(AtkTableCell* cell) {
+ if (auto* obj = AtkObjectToAXPlatformNodeAuraLinux(ATK_OBJECT(cell))) {
+ if (auto* table = obj->GetTable())
+ return table->GetNativeViewAccessible();
+ }
+
+ return nullptr;
+}
+
+static void AXTableCellInterfaceBaseInit(AtkTableCellIface* iface) {
+ iface->get_column_span = AXPlatformNodeAuraLinuxGetColumnSpan;
+ iface->get_column_header_cells = AXPlatformNodeAuraLinuxGetColumnHeaderCells;
+ iface->get_position = AXPlatformNodeAuraLinuxGetCellPosition;
+ iface->get_row_span = AXPlatformNodeAuraLinuxGetRowSpan;
+ iface->get_row_header_cells = AXPlatformNodeAuraLinuxGetRowHeaderCells;
+ iface->get_table = AXPlatformNodeAuraLinuxGetTable;
+}
+
+static const GInterfaceInfo TableCellInfo = {
+ reinterpret_cast<GInterfaceInitFunc>(AXTableCellInterfaceBaseInit), nullptr,
+ nullptr};
+#endif
+
+//
// The rest of the AXPlatformNodeAtk code, not specific to one
// of the Atk* interfaces.
//
@@ -1708,6 +1864,15 @@
if (role == ATK_ROLE_TABLE)
interface_mask |= 1 << ATK_TABLE_INTERFACE;
+ // Because the TableCell Interface is only supported in ATK version 2.12 and
+ // later, GetAccessibilityGType has a runtime check to verify we have a recent
+ // enough version. If we don't, GetAccessibilityGType will exclude
+ // AtkTableCell from the supported interfaces and none of its methods or
+ // properties will be exposed to assistive technologies.
+ if (role == ATK_ROLE_TABLE_CELL || role == ATK_ROLE_COLUMN_HEADER ||
+ role == ATK_ROLE_ROW_HEADER)
+ interface_mask |= 1 << ATK_TABLE_CELL_INTERFACE;
+
return interface_mask;
}
@@ -1756,6 +1921,11 @@
if (interface_mask_ & (1 << ATK_TABLE_INTERFACE))
g_type_add_interface_static(type, ATK_TYPE_TABLE, &TableInfo);
+ // Run-time check to ensure AtkTableCell is supported (requires ATK 2.12).
+ if (LoadTableCellMethods() &&
+ interface_mask_ & (1 << ATK_TABLE_CELL_INTERFACE))
+ g_type_add_interface_static(type, cell_get_type(), &TableCellInfo);
+
return type;
}
@@ -2526,8 +2696,6 @@
base::StringPrintf("caption=%s;", caption ? "true" : "false"));
// Summarize information about the cells from the table's perspective here.
- // TODO(jdiggs): When AtkTableCell is implemented, we will use it to output
- // specifics on a per-cell basis.
std::vector<std::string> span_info;
for (int r = 0; r < n_rows; r++) {
for (int c = 0; c < n_cols; c++) {
@@ -2547,6 +2715,48 @@
}
dict->Set("table", std::move(table_properties));
+
+ // Properties obtained via AtkTableCell, if possible. If we do not have at
+ // least ATK 2.12, use the same logic in our AtkTableCell implementation so
+ // that tests can still be run.
+ auto cell_properties = std::make_unique<base::ListValue>();
+ if (role == ATK_ROLE_TABLE_CELL || role == ATK_ROLE_COLUMN_HEADER ||
+ role == ATK_ROLE_ROW_HEADER) {
+ int row, col, row_span, col_span;
+ GPtrArray* col_headers;
+ GPtrArray* row_headers;
+ if (cell_get_type) {
+ AtkTableCell* cell = G_TYPE_CHECK_INSTANCE_CAST(
+ (atk_object_), cell_get_type(), AtkTableCell);
+ col_headers = get_column_header_cells(cell);
+ row_headers = get_row_header_cells(cell);
+ get_row_column_span(cell, &row, &col, &row_span, &col_span);
+ } else {
+ auto* obj = AtkObjectToAXPlatformNodeAuraLinux(atk_object_);
+ row = obj->GetTableRow();
+ col = obj->GetTableColumn();
+ row_span = obj->GetTableRowSpan();
+ col_span = obj->GetTableColumnSpan();
+ col_headers = g_ptr_array_new();
+ row_headers = g_ptr_array_new();
+ if (role == ATK_ROLE_TABLE_CELL) {
+ auto* delegate = obj->GetTable()->GetDelegate();
+ std::vector<int32_t> col_header_ids =
+ delegate->GetColHeaderNodeIds(col);
+ std::vector<int32_t> row_header_ids =
+ delegate->GetRowHeaderNodeIds(row);
+ IdsToGPtrArray(delegate, col_header_ids, col_headers);
+ IdsToGPtrArray(delegate, row_header_ids, row_headers);
+ }
+ }
+ cell_properties->AppendString(
+ base::StringPrintf("(row=%i, col=%i, row_span=%i, col_span=%i", row,
+ col, row_span, col_span));
+ cell_properties->AppendString(
+ base::StringPrintf("n_row_headers=%i, n_col_headers=%i)",
+ row_headers->len, col_headers->len));
+ }
+ dict->Set("cell", std::move(cell_properties));
}
gfx::NativeViewAccessible AXPlatformNodeAuraLinux::GetNativeViewAccessible() {
diff --git a/ui/accessibility/platform/ax_platform_node_auralinux.h b/ui/accessibility/platform/ax_platform_node_auralinux.h
index ff805bb5..fb9125c 100644
--- a/ui/accessibility/platform/ax_platform_node_auralinux.h
+++ b/ui/accessibility/platform/ax_platform_node_auralinux.h
@@ -139,6 +139,7 @@
ATK_IMAGE_INTERFACE,
ATK_SELECTION_INTERFACE,
ATK_TABLE_INTERFACE,
+ ATK_TABLE_CELL_INTERFACE,
ATK_TEXT_INTERFACE,
ATK_VALUE_INTERFACE,
ATK_WINDOW_INTERFACE,