AXIsolatedObject support for table cells.
authorandresg_22@apple.com <andresg_22@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 27 Feb 2020 02:31:35 +0000 (02:31 +0000)
committerandresg_22@apple.com <andresg_22@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 27 Feb 2020 02:31:35 +0000 (02:31 +0000)
https://bugs.webkit.org/show_bug.cgi?id=208263

Reviewed by Chris Fleizach.

Covered by existing tests.

- Exposed the AccessibilityTableCell interface through AXCoreObject.
- This way there is no need to downcast in client code and the same
platform wrapper code works for AccessibilityObjects and
AXIsolatedObjects.
- Completed caching of table cell properties in AXIsolatedObject.

* accessibility/AccessibilityARIAGridCell.cpp:
(WebCore::AccessibilityARIAGridCell::rowIndexRange const):
(WebCore::AccessibilityARIAGridCell::axRowSpanWithRowIndex const):
(WebCore::AccessibilityARIAGridCell::columnIndexRange const):
* accessibility/AccessibilityARIAGridCell.h:
* accessibility/AccessibilityObject.h:
* accessibility/AccessibilityObjectInterface.h:
* accessibility/AccessibilityTable.cpp:
(WebCore::AccessibilityTable::cellForColumnAndRow):
* accessibility/AccessibilityTableCell.cpp:
(WebCore::AccessibilityTableCell::isColumnHeaderCell const):
(WebCore::AccessibilityTableCell::isRowHeaderCell const):
(WebCore::AccessibilityTableCell::isTableCellInSameColGroup):
(WebCore::AccessibilityTableCell::columnHeaders):
(WebCore::AccessibilityTableCell::rowHeaders):
(WebCore::AccessibilityTableCell::rowIndexRange const):
(WebCore::AccessibilityTableCell::columnIndexRange const):
* accessibility/AccessibilityTableCell.h:
* accessibility/AccessibilityTableRow.h:
* accessibility/atk/WebKitAccessibleInterfaceTableCell.cpp:
(webkitAccessibleTableCellGetColumnSpan):
(webkitAccessibleTableCellGetRowSpan):
(webkitAccessibleTableCellGetPosition):
* accessibility/ios/WebAccessibilityObjectWrapperIOS.mm:
(-[WebAccessibilityObjectWrapper accessibilityHeaderElements]):
(-[WebAccessibilityObjectWrapper accessibilityRowRange]):
(-[WebAccessibilityObjectWrapper accessibilityColumnRange]):
* accessibility/isolatedtree/AXIsolatedObject.cpp:
(WebCore::AXIsolatedObject::initializeAttributeData):
(WebCore::AXIsolatedObject::pairAttributeValue const):
* accessibility/isolatedtree/AXIsolatedObject.h:
* accessibility/mac/WebAccessibilityObjectWrapperMac.mm:
(-[WebAccessibilityObjectWrapper accessibilityAttributeValue:]):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@257548 268f45cc-cd09-0410-ab3c-d52691b4dbfc

15 files changed:
Source/WebCore/ChangeLog
Source/WebCore/accessibility/AccessibilityARIAGridCell.cpp
Source/WebCore/accessibility/AccessibilityARIAGridCell.h
Source/WebCore/accessibility/AccessibilityObject.h
Source/WebCore/accessibility/AccessibilityObjectInterface.h
Source/WebCore/accessibility/AccessibilityTable.cpp
Source/WebCore/accessibility/AccessibilityTableCell.cpp
Source/WebCore/accessibility/AccessibilityTableCell.h
Source/WebCore/accessibility/AccessibilityTableRow.h
Source/WebCore/accessibility/atk/WebKitAccessibleInterfaceTable.cpp
Source/WebCore/accessibility/atk/WebKitAccessibleInterfaceTableCell.cpp
Source/WebCore/accessibility/ios/WebAccessibilityObjectWrapperIOS.mm
Source/WebCore/accessibility/isolatedtree/AXIsolatedObject.cpp
Source/WebCore/accessibility/isolatedtree/AXIsolatedObject.h
Source/WebCore/accessibility/mac/WebAccessibilityObjectWrapperMac.mm

index b7f42ba..860174d 100644 (file)
@@ -1,3 +1,52 @@
+2020-02-26  Andres Gonzalez  <andresg_22@apple.com>
+
+        AXIsolatedObject support for table cells.
+        https://bugs.webkit.org/show_bug.cgi?id=208263
+
+        Reviewed by Chris Fleizach.
+
+        Covered by existing tests.
+
+        - Exposed the AccessibilityTableCell interface through AXCoreObject.
+        - This way there is no need to downcast in client code and the same
+        platform wrapper code works for AccessibilityObjects and
+        AXIsolatedObjects.
+        - Completed caching of table cell properties in AXIsolatedObject.
+
+        * accessibility/AccessibilityARIAGridCell.cpp:
+        (WebCore::AccessibilityARIAGridCell::rowIndexRange const):
+        (WebCore::AccessibilityARIAGridCell::axRowSpanWithRowIndex const):
+        (WebCore::AccessibilityARIAGridCell::columnIndexRange const):
+        * accessibility/AccessibilityARIAGridCell.h:
+        * accessibility/AccessibilityObject.h:
+        * accessibility/AccessibilityObjectInterface.h:
+        * accessibility/AccessibilityTable.cpp:
+        (WebCore::AccessibilityTable::cellForColumnAndRow):
+        * accessibility/AccessibilityTableCell.cpp:
+        (WebCore::AccessibilityTableCell::isColumnHeaderCell const):
+        (WebCore::AccessibilityTableCell::isRowHeaderCell const):
+        (WebCore::AccessibilityTableCell::isTableCellInSameColGroup):
+        (WebCore::AccessibilityTableCell::columnHeaders):
+        (WebCore::AccessibilityTableCell::rowHeaders):
+        (WebCore::AccessibilityTableCell::rowIndexRange const):
+        (WebCore::AccessibilityTableCell::columnIndexRange const):
+        * accessibility/AccessibilityTableCell.h:
+        * accessibility/AccessibilityTableRow.h:
+        * accessibility/atk/WebKitAccessibleInterfaceTableCell.cpp:
+        (webkitAccessibleTableCellGetColumnSpan):
+        (webkitAccessibleTableCellGetRowSpan):
+        (webkitAccessibleTableCellGetPosition):
+        * accessibility/ios/WebAccessibilityObjectWrapperIOS.mm:
+        (-[WebAccessibilityObjectWrapper accessibilityHeaderElements]):
+        (-[WebAccessibilityObjectWrapper accessibilityRowRange]):
+        (-[WebAccessibilityObjectWrapper accessibilityColumnRange]):
+        * accessibility/isolatedtree/AXIsolatedObject.cpp:
+        (WebCore::AXIsolatedObject::initializeAttributeData):
+        (WebCore::AXIsolatedObject::pairAttributeValue const):
+        * accessibility/isolatedtree/AXIsolatedObject.h:
+        * accessibility/mac/WebAccessibilityObjectWrapperMac.mm:
+        (-[WebAccessibilityObjectWrapper accessibilityAttributeValue:]):
+
 2020-02-26  Said Abou-Hallawa  <sabouhallawa@apple.com>
 
         Implement the remote RenderingBackend
index 6c4af15..639c460 100644 (file)
@@ -63,11 +63,12 @@ AccessibilityTable* AccessibilityARIAGridCell::parentTable() const
     return nullptr;
 }
     
-void AccessibilityARIAGridCell::rowIndexRange(std::pair<unsigned, unsigned>& rowRange) const
+std::pair<unsigned, unsigned> AccessibilityARIAGridCell::rowIndexRange() const
 {
+    std::pair<unsigned, unsigned> rowRange { 0, 1 };
     AXCoreObject* parent = parentObjectUnignored();
     if (!parent)
-        return;
+        return rowRange;
 
     if (is<AccessibilityTableRow>(*parent)) {
         // We already got a table row, use its API.
@@ -77,7 +78,7 @@ void AccessibilityARIAGridCell::rowIndexRange(std::pair<unsigned, unsigned>& row
         // children to determine the row index for the cell in it.
         unsigned columnCount = downcast<AccessibilityTable>(*parent).columnCount();
         if (!columnCount)
-            return;
+            return rowRange;
 
         const auto& siblings = parent->children();
         unsigned childrenSize = siblings.size();
@@ -92,15 +93,16 @@ void AccessibilityARIAGridCell::rowIndexRange(std::pair<unsigned, unsigned>& row
     // ARIA 1.1, aria-rowspan attribute is intended for cells and gridcells which are not contained in a native table.
     // So we should check for that attribute here.
     rowRange.second = axRowSpanWithRowIndex(rowRange.first);
+
+    return rowRange;
 }
 
 unsigned AccessibilityARIAGridCell::axRowSpanWithRowIndex(unsigned rowIndex) const
 {
     int rowSpan = AccessibilityTableCell::axRowSpan();
     if (rowSpan == -1) {
-        std::pair<unsigned, unsigned> range;
-        AccessibilityTableCell::rowIndexRange(range);
-        return std::max(static_cast<int>(range.second), 1);
+        auto range = AccessibilityTableCell::rowIndexRange();
+        return std::max(range.second, static_cast<unsigned>(1));
     }
 
     AXCoreObject* parent = parentObjectUnignored();
@@ -132,21 +134,22 @@ unsigned AccessibilityARIAGridCell::axRowSpanWithRowIndex(unsigned rowIndex) con
     return rowSpan;
 }
 
-void AccessibilityARIAGridCell::columnIndexRange(std::pair<unsigned, unsigned>& columnRange) const
+std::pair<unsigned, unsigned> AccessibilityARIAGridCell::columnIndexRange() const
 {
+    std::pair<unsigned, unsigned> columnRange { 0, 1 };
     AXCoreObject* parent = parentObjectUnignored();
     if (!parent)
-        return;
+        return columnRange;
 
     if (!is<AccessibilityTableRow>(*parent)
         && !(is<AccessibilityTable>(*parent) && downcast<AccessibilityTable>(*parent).isExposable()))
-        return;
+        return columnRange;
 
     const AccessibilityChildrenVector& siblings = parent->children();
     unsigned childrenSize = siblings.size();
     unsigned indexWithSpan = 0;
     for (unsigned k = 0; k < childrenSize; ++k) {
-        auto child = siblings[k].get();
+        auto* child = siblings[k].get();
         if (child == this) {
             columnRange.first = indexWithSpan;
             break;
@@ -158,12 +161,13 @@ void AccessibilityARIAGridCell::columnIndexRange(std::pair<unsigned, unsigned>&
     // So we should check for that attribute here.
     int columnSpan = AccessibilityTableCell::axColumnSpan();
     if (columnSpan == -1) {
-        std::pair<unsigned, unsigned> range;
-        AccessibilityTableCell::columnIndexRange(range);
+        auto range = AccessibilityTableCell::columnIndexRange();
         columnSpan = range.second;
     }
 
     columnRange.second = std::max(columnSpan, 1);
+
+    return columnRange;
 }
 
 AccessibilityObject* AccessibilityARIAGridCell::parentRowGroup() const
index e41a270..e7fae92 100644 (file)
@@ -36,12 +36,13 @@ class AccessibilityARIAGridCell final : public AccessibilityTableCell {
 public:
     static Ref<AccessibilityARIAGridCell> create(RenderObject*);
     virtual ~AccessibilityARIAGridCell();
-    
-    // fills in the start location and row span of cell
-    void rowIndexRange(std::pair<unsigned, unsigned>& rowRange) const override;
-    // fills in the start location and column span of cell
-    void columnIndexRange(std::pair<unsigned, unsigned>& columnRange) const override;
-    
+
+protected:
+    // Returns the start location and row span of the cell.
+    std::pair<unsigned, unsigned> rowIndexRange() const override;
+    // Returns the start location and column span of the cell.
+    std::pair<unsigned, unsigned> columnIndexRange() const override;
+
 private:
     explicit AccessibilityARIAGridCell(RenderObject*);
 
index bd49d3f..6b15de2 100644 (file)
@@ -171,13 +171,21 @@ public:
     int axColumnCount() const override { return 0; }
     int axRowCount() const override { return 0; }
 
+    // Table cell support.
+    bool isTableCell() const override { return false; }
+    // Returns the start location and row span of the cell.
+    std::pair<unsigned, unsigned> rowIndexRange() const override { return { 0, 1 }; }
+    // Returns the start location and column span of the cell.
+    std::pair<unsigned, unsigned> columnIndexRange() const override { return { 0, 1 }; }
+    int axColumnIndex() const override { return -1; }
+    int axRowIndex() const override { return -1; }
+
     bool isTableRow() const override { return false; }
 
     bool isTableColumn() const override { return false; }
     unsigned columnIndex() const override { return 0; }
     AXCoreObject* columnHeader() override { return nullptr; }
 
-    bool isTableCell() const override { return false; }
     bool isFieldset() const override { return false; }
     bool isGroup() const override { return false; }
     bool isARIATreeGridRow() const override { return false; }
index 1709fcf..204c98a 100644 (file)
@@ -552,6 +552,15 @@ public:
     virtual int axColumnCount() const = 0;
     virtual int axRowCount() const = 0;
 
+    // Table cell support.
+    virtual bool isTableCell() const = 0;
+    // Returns the start location and row span of the cell.
+    virtual std::pair<unsigned, unsigned> rowIndexRange() const = 0;
+    // Returns the start location and column span of the cell.
+    virtual std::pair<unsigned, unsigned> columnIndexRange() const = 0;
+    virtual int axColumnIndex() const = 0;
+    virtual int axRowIndex() const = 0;
+
     virtual bool isTableRow() const = 0;
 
     // Table column support.
@@ -559,8 +568,6 @@ public:
     virtual unsigned columnIndex() const = 0;
     virtual AXCoreObject* columnHeader() = 0;
 
-    virtual bool isTableCell() const = 0;
-
     virtual bool isFieldset() const = 0;
     virtual bool isGroup() const = 0;
     virtual bool isARIATreeGridRow() const = 0;
index 1bce886..d33384f 100644 (file)
@@ -637,19 +637,16 @@ AccessibilityTableCell* AccessibilityTable::cellForColumnAndRow(unsigned column,
             ASSERT(is<AccessibilityTableCell>(*child));
             if (!is<AccessibilityTableCell>(*child))
                 continue;
-            
-            std::pair<unsigned, unsigned> columnRange;
-            std::pair<unsigned, unsigned> rowRange;
-            auto& tableCellChild = downcast<AccessibilityTableCell>(*child);
-            tableCellChild.columnIndexRange(columnRange);
-            tableCellChild.rowIndexRange(rowRange);
-            
+
+            auto columnRange = child->columnIndexRange();
+            auto rowRange = child->rowIndexRange();
+
             if ((column >= columnRange.first && column < (columnRange.first + columnRange.second))
                 && (row >= rowRange.first && row < (rowRange.first + rowRange.second)))
-                return &tableCellChild;
+                return downcast<AccessibilityTableCell>(child);
         }
     }
-    
+
     return nullptr;
 }
 
index 01327d2..cb6f2de 100644 (file)
@@ -165,8 +165,7 @@ bool AccessibilityTableCell::isColumnHeaderCell() const
         if (parentNode->hasTagName(tfootTag))
             return false;
         if (parentNode->hasTagName(tableTag) || parentNode->hasTagName(tbodyTag)) {
-            std::pair<unsigned, unsigned> rowRange;
-            rowIndexRange(rowRange);
+            auto rowRange = rowIndexRange();
             if (!rowRange.first)
                 return true;
             return false;
@@ -190,8 +189,7 @@ bool AccessibilityTableCell::isRowHeaderCell() const
     // Checking tableTag allows to check the case of direct row placement in the table and lets stop the loop at the table level.
     for (Node* parentNode = node(); parentNode; parentNode = parentNode->parentNode()) {
         if (parentNode->hasTagName(tfootTag) || parentNode->hasTagName(tbodyTag) || parentNode->hasTagName(tableTag)) {
-            std::pair<unsigned, unsigned> colRange;
-            columnIndexRange(colRange);
+            auto colRange = columnIndexRange();
             if (!colRange.first)
                 return true;
             return false;
@@ -222,12 +220,9 @@ bool AccessibilityTableCell::isTableCellInSameRowGroup(AccessibilityTableCell* o
 
 bool AccessibilityTableCell::isTableCellInSameColGroup(AccessibilityTableCell* tableCell)
 {
-    std::pair<unsigned, unsigned> colRange;
-    columnIndexRange(colRange);
-    
-    std::pair<unsigned, unsigned> otherColRange;
-    tableCell->columnIndexRange(otherColRange);
-    
+    auto colRange = columnIndexRange();
+    auto otherColRange = tableCell->columnIndexRange();
+
     if (colRange.first <= (otherColRange.first + otherColRange.second))
         return true;
     return false;
@@ -255,21 +250,15 @@ AXCoreObject::AccessibilityChildrenVector AccessibilityTableCell::columnHeaders(
     // If the headers attribute returned valid values, then do not further search for column headers.
     if (!headers.isEmpty())
         return headers;
-    
-    std::pair<unsigned, unsigned> rowRange;
-    rowIndexRange(rowRange);
-    
-    std::pair<unsigned, unsigned> colRange;
-    columnIndexRange(colRange);
-    
+
+    auto rowRange = rowIndexRange();
+    auto colRange = columnIndexRange();
+
     for (unsigned row = 0; row < rowRange.first; row++) {
         AccessibilityTableCell* tableCell = parent->cellForColumnAndRow(colRange.first, row);
         if (!tableCell || tableCell == this || headers.contains(tableCell))
             continue;
 
-        std::pair<unsigned, unsigned> childRowRange;
-        tableCell->rowIndexRange(childRowRange);
-            
         const AtomString& scope = tableCell->getAttribute(scopeAttr);
         if (scope == "colgroup" && isTableCellInSameColGroup(tableCell))
             headers.append(tableCell);
@@ -287,11 +276,8 @@ AXCoreObject::AccessibilityChildrenVector AccessibilityTableCell::rowHeaders()
     if (!parent)
         return headers;
 
-    std::pair<unsigned, unsigned> rowRange;
-    rowIndexRange(rowRange);
-
-    std::pair<unsigned, unsigned> colRange;
-    columnIndexRange(colRange);
+    auto rowRange = rowIndexRange();
+    auto colRange = columnIndexRange();
 
     for (unsigned column = 0; column < colRange.first; column++) {
         AccessibilityTableCell* tableCell = parent->cellForColumnAndRow(column, rowRange.first);
@@ -316,11 +302,12 @@ AccessibilityTableRow* AccessibilityTableCell::parentRow() const
     return downcast<AccessibilityTableRow>(parent);
 }
 
-void AccessibilityTableCell::rowIndexRange(std::pair<unsigned, unsigned>& rowRange) const
+std::pair<unsigned, unsigned> AccessibilityTableCell::rowIndexRange() const
 {
+    std::pair<unsigned, unsigned> rowRange { 0, 1 };
     if (!is<RenderTableCell>(renderer()))
-        return;
-    
+        return rowRange;
+
     RenderTableCell& renderCell = downcast<RenderTableCell>(*m_renderer);
 
     // ARIA 1.1's aria-rowspan attribute is intended for cells and gridcells which are not contained
@@ -332,13 +319,16 @@ void AccessibilityTableCell::rowIndexRange(std::pair<unsigned, unsigned>& rowRan
     
     if (AccessibilityTableRow* parentRow = this->parentRow())
         rowRange.first = parentRow->rowIndex();
+
+    return rowRange;
 }
     
-void AccessibilityTableCell::columnIndexRange(std::pair<unsigned, unsigned>& columnRange) const
+std::pair<unsigned, unsigned> AccessibilityTableCell::columnIndexRange() const
 {
+    std::pair<unsigned, unsigned> columnRange { 0, 1 };
     if (!is<RenderTableCell>(renderer()))
-        return;
-    
+        return columnRange;
+
     const RenderTableCell& cell = downcast<RenderTableCell>(*m_renderer);
     columnRange.first = cell.table()->colToEffCol(cell.col());
 
@@ -347,9 +337,11 @@ void AccessibilityTableCell::columnIndexRange(std::pair<unsigned, unsigned>& col
     // native host language value for the colspan, expose the ARIA value.
     columnRange.second = axColumnSpan();
     if (static_cast<int>(columnRange.second) != -1)
-        return;
+        return columnRange;
 
     columnRange.second = cell.table()->colToEffCol(cell.col() + cell.colSpan()) - columnRange.first;
+
+    return columnRange;
 }
     
 AccessibilityObject* AccessibilityTableCell::titleUIElement() const
index fa361c6..7675bb7 100644 (file)
@@ -39,22 +39,22 @@ class AccessibilityTableCell : public AccessibilityRenderObject {
 public:
     static Ref<AccessibilityTableCell> create(RenderObject*);
     virtual ~AccessibilityTableCell();
-    
+
     bool isTableCell() const final;
     bool isTableHeaderCell() const;
     bool isColumnHeaderCell() const;
     bool isRowHeaderCell() const;
-    
-    // fills in the start location and row span of cell
-    virtual void rowIndexRange(std::pair<unsigned, unsigned>& rowRange) const;
-    // fills in the start location and column span of cell
-    virtual void columnIndexRange(std::pair<unsigned, unsigned>& columnRange) const;
+
+    // Returns the start location and row span of the cell.
+    std::pair<unsigned, unsigned> rowIndexRange() const override;
+    // Returns the start location and column span of the cell.
+    std::pair<unsigned, unsigned> columnIndexRange() const override;
 
     AccessibilityChildrenVector columnHeaders() override;
     AccessibilityChildrenVector rowHeaders() override;
 
-    int axColumnIndex() const;
-    int axRowIndex() const;
+    int axColumnIndex() const override;
+    int axRowIndex() const override;
     int axColumnSpan() const;
     int axRowSpan() const;
     void setAXColIndexFromRow(int index) { m_axColIndexFromRow = index; }
index 79bf05f..cf42578 100644 (file)
@@ -51,10 +51,10 @@ public:
     void appendChild(AccessibilityObject*);
     
     void addChildren() override;
-    
-    int axColumnIndex() const;
-    int axRowIndex() const;
-    
+
+    int axColumnIndex() const override;
+    int axRowIndex() const override;
+
 protected:
     explicit AccessibilityTableRow(RenderObject*);
 
index d78bf4c..6c79311 100644 (file)
@@ -120,8 +120,7 @@ static gint webkitAccessibleTableGetColumnAtIndex(AtkTable* table, gint index)
 
     AccessibilityTableCell* axCell = cellAtIndex(table, index);
     if (axCell) {
-        std::pair<unsigned, unsigned> columnRange;
-        axCell->columnIndexRange(columnRange);
+        auto columnRange = axCell->columnIndexRange();
         return columnRange.first;
     }
     return -1;
@@ -134,8 +133,7 @@ static gint webkitAccessibleTableGetRowAtIndex(AtkTable* table, gint index)
 
     AccessibilityTableCell* axCell = cellAtIndex(table, index);
     if (axCell) {
-        std::pair<unsigned, unsigned> rowRange;
-        axCell->rowIndexRange(rowRange);
+        auto rowRange = axCell->rowIndexRange();
         return rowRange.first;
     }
     return -1;
@@ -178,8 +176,7 @@ static gint webkitAccessibleTableGetColumnExtentAt(AtkTable* table, gint row, gi
 
     AccessibilityTableCell* axCell = cell(table, row, column);
     if (axCell) {
-        std::pair<unsigned, unsigned> columnRange;
-        axCell->columnIndexRange(columnRange);
+        auto columnRange = axCell->columnIndexRange();
         return columnRange.second;
     }
     return 0;
@@ -192,8 +189,7 @@ static gint webkitAccessibleTableGetRowExtentAt(AtkTable* table, gint row, gint
 
     AccessibilityTableCell* axCell = cell(table, row, column);
     if (axCell) {
-        std::pair<unsigned, unsigned> rowRange;
-        axCell->rowIndexRange(rowRange);
+        auto rowRange = axCell->rowIndexRange();
         return rowRange.second;
     }
     return 0;
@@ -209,8 +205,7 @@ static AtkObject* webkitAccessibleTableGetColumnHeader(AtkTable* table, gint col
         auto columnHeaders = downcast<AccessibilityTable>(*accTable).columnHeaders();
 
         for (const auto& columnHeader : columnHeaders) {
-            std::pair<unsigned, unsigned> columnRange;
-            downcast<AccessibilityTableCell>(*columnHeader).columnIndexRange(columnRange);
+            auto columnRange = columnHeader->columnIndexRange();
             if (columnRange.first <= static_cast<unsigned>(column) && static_cast<unsigned>(column) < columnRange.first + columnRange.second)
                 return ATK_OBJECT(columnHeader->wrapper());
         }
@@ -228,8 +223,7 @@ static AtkObject* webkitAccessibleTableGetRowHeader(AtkTable* table, gint row)
         auto rowHeaders = downcast<AccessibilityTable>(*accTable).rowHeaders();
 
         for (const auto& rowHeader : rowHeaders) {
-            std::pair<unsigned, unsigned> rowRange;
-            downcast<AccessibilityTableCell>(*rowHeader).rowIndexRange(rowRange);
+            auto rowRange = rowHeader->rowIndexRange();
             if (rowRange.first <= static_cast<unsigned>(row) && static_cast<unsigned>(row) < rowRange.first + rowRange.second)
                 return ATK_OBJECT(rowHeader->wrapper());
         }
index ed1925b..289d3a7 100644 (file)
@@ -85,10 +85,7 @@ gint webkitAccessibleTableCellGetColumnSpan(AtkTableCell* cell)
     if (!is<AccessibilityTableCell>(axObject))
         return 0;
 
-    std::pair<unsigned, unsigned> columnRange;
-    downcast<AccessibilityTableCell>(*axObject).columnIndexRange(columnRange);
-
-    return columnRange.second;
+    return axObject->columnIndexRange().second;
 }
 
 gint webkitAccessibleTableCellGetRowSpan(AtkTableCell* cell)
@@ -100,10 +97,7 @@ gint webkitAccessibleTableCellGetRowSpan(AtkTableCell* cell)
     if (!is<AccessibilityTableCell>(axObject))
         return 0;
 
-    std::pair<unsigned, unsigned> rowRange;
-    downcast<AccessibilityTableCell>(*axObject).rowIndexRange(rowRange);
-
-    return rowRange.second;
+    return axObject->rowIndexRange().second;
 }
 
 gboolean webkitAccessibleTableCellGetPosition(AtkTableCell* cell, gint* row, gint* column)
@@ -115,23 +109,18 @@ gboolean webkitAccessibleTableCellGetPosition(AtkTableCell* cell, gint* row, gin
     if (!is<AccessibilityTableCell>(axObject))
         return false;
 
-    std::pair<unsigned, unsigned> columnRowRange;
     if (row) {
         // aria-rowindex is 1-based.
-        int rowIndex = downcast<AccessibilityTableCell>(*axObject).axRowIndex() - 1;
-        if (rowIndex <= -1) {
-            downcast<AccessibilityTableCell>(*axObject).rowIndexRange(columnRowRange);
-            rowIndex = columnRowRange.first;
-        }
+        int rowIndex = axObject->axRowIndex() - 1;
+        if (rowIndex <= -1)
+            rowIndex = axObject->rowIndexRange().first;
         *row = rowIndex;
     }
     if (column) {
         // aria-colindex is 1-based.
-        int columnIndex = downcast<AccessibilityTableCell>(*axObject).axColumnIndex() - 1;
-        if (columnIndex <= -1) {
-            downcast<AccessibilityTableCell>(*axObject).columnIndexRange(columnRowRange);
-            columnIndex = columnRowRange.first;
-        }
+        int columnIndex = axObject->axColumnIndex() - 1;
+        if (columnIndex <= -1)
+            columnIndex = axObject->columnIndexRange().first;
         *column = columnIndex;
     }
 
index 0b3b267..80636c7 100644 (file)
@@ -1226,10 +1226,8 @@ static void appendStringToResult(NSMutableString *result, NSString *string)
         return nil;
     
     // Get the row and column range, so we can use them to find the headers.
-    std::pair<unsigned, unsigned> rowRange;
-    std::pair<unsigned, unsigned> columnRange;
-    tableCell->rowIndexRange(rowRange);
-    tableCell->columnIndexRange(columnRange);
+    auto rowRange = tableCell->rowIndexRange();
+    auto columnRange = tableCell->columnIndexRange();
 
     auto rowHeaders = table->rowHeaders();
     auto columnHeaders = table->columnHeaders();
@@ -1250,8 +1248,7 @@ static void appendStringToResult(NSMutableString *result, NSString *string)
     for (const auto& rowHeader : rowHeaders) {
         if (!is<AccessibilityTableCell>(*rowHeader))
             break;
-        std::pair<unsigned, unsigned> rowHeaderRange;
-        downcast<AccessibilityTableCell>(*rowHeader).rowIndexRange(rowHeaderRange);
+        auto rowHeaderRange = rowHeader->rowIndexRange();
         if (rowRangeIndex >= rowHeaderRange.first && rowRangeIndex < rowHeaderRange.first + rowHeaderRange.second) {
             if (AccessibilityObjectWrapper* wrapper = rowHeader->wrapper())
                 [headers addObject:wrapper];
@@ -1364,9 +1361,8 @@ static void appendStringToResult(NSMutableString *result, NSString *string)
     AccessibilityTableCell* tableCell = [self tableCellParent];
     if (!tableCell)
         return NSMakeRange(NSNotFound, 0);
-    
-    std::pair<unsigned, unsigned> rowRange;
-    tableCell->rowIndexRange(rowRange);
+
+    auto rowRange = tableCell->rowIndexRange();
     return NSMakeRange(rowRange.first, rowRange.second);
 }
 
@@ -1378,9 +1374,8 @@ static void appendStringToResult(NSMutableString *result, NSString *string)
     AccessibilityTableCell* tableCell = [self tableCellParent];
     if (!tableCell)
         return NSMakeRange(NSNotFound, 0);
-    
-    std::pair<unsigned, unsigned> columnRange;
-    tableCell->columnIndexRange(columnRange);
+
+    auto columnRange = tableCell->columnIndexRange();
     return NSMakeRange(columnRange.first, columnRange.second);
 }
 
index a6b010a..d4946d5 100644 (file)
@@ -114,7 +114,6 @@ void AXIsolatedObject::initializeAttributeData(AXCoreObject& object, bool isRoot
     setProperty(AXPropertyName::IsSelectedOptionActive, object.isSelectedOptionActive());
     setProperty(AXPropertyName::IsSlider, object.isSlider());
     setProperty(AXPropertyName::IsStyleFormatGroup, object.isStyleFormatGroup());
-    setProperty(AXPropertyName::IsTableCell, object.isTableCell());
     setProperty(AXPropertyName::IsTableRow, object.isTableRow());
     setProperty(AXPropertyName::IsTextControl, object.isTextControl());
     setProperty(AXPropertyName::IsTree, object.isTree());
@@ -236,6 +235,16 @@ void AXIsolatedObject::initializeAttributeData(AXCoreObject& object, bool isRoot
         setProperty(AXPropertyName::AXRowCount, object.axRowCount());
     }
 
+    if (object.isTableCell()) {
+        setProperty(AXPropertyName::IsTableCell, object.isTableCell());
+        setProperty(AXPropertyName::ColumnIndexRange, object.columnIndexRange());
+        setProperty(AXPropertyName::RowIndexRange, object.rowIndexRange());
+        setObjectVectorProperty(AXPropertyName::ColumnHeaders, object.columnHeaders());
+        setObjectVectorProperty(AXPropertyName::RowHeaders, object.rowHeaders());
+        setProperty(AXPropertyName::AXColumnIndex, object.axColumnIndex());
+        setProperty(AXPropertyName::AXRowIndex, object.axRowIndex());
+    }
+
     if (object.isTableColumn()) {
         setProperty(AXPropertyName::IsTableColumn, object.isTableColumn());
         setProperty(AXPropertyName::ColumnIndex, object.columnIndex());
@@ -742,6 +751,16 @@ OptionSet<T> AXIsolatedObject::optionSetAttributeValue(AXPropertyName propertyNa
     );
 }
 
+template<typename T>
+std::pair<T, T> AXIsolatedObject::pairAttributeValue(AXPropertyName propertyName) const
+{
+    auto value = m_attributeMap.get(propertyName);
+    return WTF::switchOn(value,
+        [] (std::pair<T, T>& typedValue) { return typedValue; },
+        [] (auto&) { return std::pair<T, T>(0, 1); }
+    );
+}
+
 uint64_t AXIsolatedObject::uint64AttributeValue(AXPropertyName propertyName) const
 {
     auto value = m_attributeMap.get(propertyName);
index e7f2a5e..5a03fd0 100644 (file)
@@ -99,7 +99,9 @@ private:
         ARIARoleAttribute,
         ARIAOwnsElements,
         AXColumnCount,
+        AXColumnIndex,
         AXRowCount,
+        AXRowIndex,
         BlockquoteLevel,
         BoundingBoxRect,
         CanHaveSelectedChildren,
@@ -123,6 +125,7 @@ private:
         ColumnHeader,
         ColumnHeaders,
         ColumnIndex,
+        ColumnIndexRange,
         ComputedLabel,
         ComputedRoleString,
         CurrentState,
@@ -284,6 +287,7 @@ private:
         Rows,
         RowCount,
         RowHeaders,
+        RowIndexRange,
         SelectedChildren,
         SelectedRadioButton,
         SelectedTabItem,
@@ -330,8 +334,8 @@ private:
         AccessibilityTextSource textSource;
         Vector<AXID> textElements;
     };
-    
-    using AttributeValueVariant = Variant<std::nullptr_t, String, bool, int, unsigned, double, float, uint64_t, Color, URL, LayoutRect, FloatRect, AXID, IntPoint, OptionSet<SpeakAs>, Vector<AccessibilityIsolatedTreeText>, Vector<AXID>, Vector<AccessibilityIsolatedTreeMathMultiscriptPair>, Vector<String>>;
+
+    using AttributeValueVariant = Variant<std::nullptr_t, String, bool, int, unsigned, double, float, uint64_t, Color, URL, LayoutRect, FloatRect, AXID, IntPoint, OptionSet<SpeakAs>, std::pair<unsigned, unsigned>, Vector<AccessibilityIsolatedTreeText>, Vector<AXID>, Vector<AccessibilityIsolatedTreeMathMultiscriptPair>, Vector<String>>;
     void setProperty(AXPropertyName, AttributeValueVariant&&, bool shouldRemove = false);
     void setObjectProperty(AXPropertyName, AXCoreObject*);
     void setObjectVectorProperty(AXPropertyName, const AccessibilityChildrenVector&);
@@ -350,6 +354,7 @@ private:
     template<typename T> T rectAttributeValue(AXPropertyName) const;
     template<typename T> Vector<T> vectorAttributeValue(AXPropertyName) const;
     template<typename T> OptionSet<T> optionSetAttributeValue(AXPropertyName) const;
+    template<typename T> std::pair<T, T> pairAttributeValue(AXPropertyName) const;
 
     void fillChildrenVectorForProperty(AXPropertyName, AccessibilityChildrenVector&) const;
     void setMathscripts(AXPropertyName, AXCoreObject&);
@@ -400,6 +405,15 @@ private:
     int axColumnCount() const override { return intAttributeValue(AXPropertyName::AXColumnCount); }
     int axRowCount() const override { return intAttributeValue(AXPropertyName::AXRowCount); }
 
+    // Table cell support.
+    bool isTableCell() const override { return boolAttributeValue(AXPropertyName::IsTableCell); }
+    // Returns the start location and row span of the cell.
+    std::pair<unsigned, unsigned> rowIndexRange() const override { return pairAttributeValue<unsigned>(AXPropertyName::RowIndexRange); }
+    // Returns the start location and column span of the cell.
+    std::pair<unsigned, unsigned> columnIndexRange() const override { return pairAttributeValue<unsigned>(AXPropertyName::ColumnIndexRange); }
+    int axColumnIndex() const override { return intAttributeValue(AXPropertyName::AXColumnIndex); }
+    int axRowIndex() const override { return intAttributeValue(AXPropertyName::AXRowIndex); }
+
     bool isTableRow() const override { return boolAttributeValue(AXPropertyName::IsTableRow); }
 
     // Table column support.
@@ -407,7 +421,6 @@ private:
     unsigned columnIndex() const override { return unsignedAttributeValue(AXPropertyName::ColumnIndex); }
     AXCoreObject* columnHeader() override { return objectAttributeValue(AXPropertyName::ColumnHeader); }
 
-    bool isTableCell() const override { return boolAttributeValue(AXPropertyName::IsTableCell); }
     bool isFieldset() const override { return boolAttributeValue(AXPropertyName::IsFieldset); }
     bool isGroup() const override { return boolAttributeValue(AXPropertyName::IsGroup); }
     bool isARIATreeGridRow() const override { return boolAttributeValue(AXPropertyName::IsARIATreeGridRow); }
index 3849949..657e3f7 100644 (file)
@@ -2758,29 +2758,28 @@ ALLOW_DEPRECATED_IMPLEMENTATIONS_END
         }
     }
 
-    if (is<AccessibilityTableCell>(*backingObject)) {
-        auto& cell = downcast<AccessibilityTableCell>(*backingObject);
+    if (backingObject->isTableCell()) {
         if ([attributeName isEqualToString:NSAccessibilityRowIndexRangeAttribute]) {
-            std::pair<unsigned, unsigned> rowRange;
-            cell.rowIndexRange(rowRange);
+            auto rowRange = backingObject->rowIndexRange();
             return [NSValue valueWithRange:NSMakeRange(rowRange.first, rowRange.second)];
         }
+
         if ([attributeName isEqualToString:NSAccessibilityColumnIndexRangeAttribute]) {
-            std::pair<unsigned, unsigned> columnRange;
-            cell.columnIndexRange(columnRange);
+            auto columnRange = backingObject->columnIndexRange();
             return [NSValue valueWithRange:NSMakeRange(columnRange.first, columnRange.second)];
         }
+
         if ([attributeName isEqualToString:NSAccessibilityColumnHeaderUIElementsAttribute])
-            return convertToNSArray(cell.columnHeaders());
+            return convertToNSArray(backingObject->columnHeaders());
 
         if ([attributeName isEqualToString:NSAccessibilityRowHeaderUIElementsAttribute])
-            return convertToNSArray(cell.rowHeaders());
+            return convertToNSArray(backingObject->rowHeaders());
 
         if ([attributeName isEqualToString:NSAccessibilityARIAColumnIndexAttribute])
-            return @(cell.axColumnIndex());
+            return @(backingObject->axColumnIndex());
 
         if ([attributeName isEqualToString:NSAccessibilityARIARowIndexAttribute])
-            return @(cell.axRowIndex());
+            return @(backingObject->axRowIndex());
     }
 
     if (backingObject->isTree()) {