AXIsolatedObject support for tables.
authorandresg_22@apple.com <andresg_22@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 24 Feb 2020 00:54:42 +0000 (00:54 +0000)
committerandresg_22@apple.com <andresg_22@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 24 Feb 2020 00:54:42 +0000 (00:54 +0000)
https://bugs.webkit.org/show_bug.cgi?id=208074

Reviewed by Chris Fleizach.

Covered by existing tests.

AccessibilityObjectWrapper code and some utility functions in
AccessibilityObject.cpp assume that AX objects can be downcast to a
specialized subclass like AccessibilityTable. That is not true for
AXIsolatedObjects, and the reason why tables don’t work in IsolatedTree
mode.

To solve this problem, this patch exposes the AccessibilityTable
interface as part of the AXCoreObject. Thus it eliminates the need to
downcast an AX object to an AccessibilityTable. It also implements the
AccessibilityTable interface in the AXIsolatedObject class. The same
approach will be used in subsequent patches for other specialized
interfaces used by client code.

* accessibility/AccessibilityARIAGrid.cpp:
(WebCore::AccessibilityARIAGrid::addChildren):
* accessibility/AccessibilityARIAGrid.h:
* accessibility/AccessibilityARIAGridCell.cpp:
(WebCore::AccessibilityARIAGridCell::parentTable const):
(WebCore::AccessibilityARIAGridCell::rowIndexRange const):
(WebCore::AccessibilityARIAGridCell::columnIndexRange const):
* accessibility/AccessibilityARIAGridRow.cpp:
(WebCore::AccessibilityARIAGridRow::disclosedRows):
(WebCore::AccessibilityARIAGridRow::disclosedByRow const):
(WebCore::AccessibilityARIAGridRow::parentTable const):
* accessibility/AccessibilityNodeObject.cpp:
(WebCore::shouldUseAccessibilityObjectInnerText):
* accessibility/AccessibilityObject.cpp:
(WebCore::appendChildrenToArray): Use AXCoreObject interface instead of downcasting.
(WebCore::Accessibility::isAccessibilityObjectSearchMatchAtIndex): Use AXCoreObject interface instead of downcasting.
* accessibility/AccessibilityObject.h:
* accessibility/AccessibilityObjectInterface.h: AXCoreObject now exposes the table interface.
* accessibility/AccessibilityRenderObject.cpp:
(WebCore::AccessibilityRenderObject::ariaSelectedRows):
* accessibility/AccessibilityTable.cpp:
(WebCore::AccessibilityTable::AccessibilityTable):
(WebCore::AccessibilityTable::init):
(WebCore::AccessibilityTable::isExposable const):
(WebCore::AccessibilityTable::addChildren):
(WebCore::AccessibilityTable::headerContainer): Returns an AXCoreObject.

The following methods now return a vector of objects instead of taking
and out parameter. RVO guaranties that this does not cause extra copy.
(WebCore::AccessibilityTable::columns):
(WebCore::AccessibilityTable::rows):
(WebCore::AccessibilityTable::columnHeaders):
(WebCore::AccessibilityTable::rowHeaders):
(WebCore::AccessibilityTable::visibleRows):
(WebCore::AccessibilityTable::cells):

(WebCore::AccessibilityTable::tableLevel const):
(WebCore::AccessibilityTable::roleValue const):
(WebCore::AccessibilityTable::computeAccessibilityIsIgnored const):
(WebCore::AccessibilityTable::title const):
(WebCore::AccessibilityTable::isExposableThroughAccessibility const): Renamed to just isExposable.
* accessibility/AccessibilityTable.h:
(WebCore::AccessibilityTable::supportsSelectedRows): Deleted.
* accessibility/AccessibilityTableCell.cpp:
(WebCore::AccessibilityTableCell::parentTable const):
(WebCore::AccessibilityTableCell::isTableCell const):
(WebCore::AccessibilityTableCell::columnHeaders):
(WebCore::AccessibilityTableCell::rowHeaders):
* accessibility/AccessibilityTableCell.h:
* accessibility/AccessibilityTableColumn.cpp:
(WebCore::AccessibilityTableColumn::headerObject):
(WebCore::AccessibilityTableColumn::addChildren):
* accessibility/AccessibilityTableHeaderContainer.cpp:
(WebCore::AccessibilityTableHeaderContainer::addChildren):
* accessibility/AccessibilityTableRow.cpp:
(WebCore::AccessibilityTableRow::isTableRow const):
(WebCore::AccessibilityTableRow::parentTable const):
* accessibility/atk/WebKitAccessible.cpp:
(webkitAccessibleGetAttributes):
* accessibility/atk/WebKitAccessibleInterfaceTable.cpp:
(webkitAccessibleTableGetColumnHeader):
(webkitAccessibleTableGetRowHeader):
* accessibility/atk/WebKitAccessibleInterfaceTableCell.cpp:
(webkitAccessibleTableCellGetColumnHeaderCells):
(webkitAccessibleTableCellGetRowHeaderCells):
* accessibility/ios/WebAccessibilityObjectWrapperIOS.mm:
(-[WebAccessibilityObjectWrapper tableParent]):
(-[WebAccessibilityObjectWrapper accessibilityHeaderElements]):
* accessibility/isolatedtree/AXIsolatedObject.cpp:
(WebCore::AXIsolatedObject::initializeAttributeData):
(WebCore::AXIsolatedObject::setObjectVectorProperty):
(WebCore::AXIsolatedObject::cellForColumnAndRow):
(WebCore::AXIsolatedObject::fillChildrenVectorForProperty const):
(WebCore::AXIsolatedObject::isAccessibilityTableInstance const):
(WebCore::AXIsolatedObject::isDataTable const): Deleted.
* accessibility/isolatedtree/AXIsolatedObject.h:
* accessibility/isolatedtree/AXIsolatedTree.cpp:
(WebCore::AXIsolatedTree::nodeForID const):
(WebCore::AXIsolatedTree::objectsForIDs const):
* accessibility/isolatedtree/AXIsolatedTree.h:
* accessibility/mac/AXObjectCacheMac.mm:
(WebCore::AXObjectCache::postPlatformNotification):
* accessibility/mac/WebAccessibilityObjectWrapperMac.mm:
In addition to replacing the downcast to AccessibilityTable, cleaned up
the unnecessary calls to self.axBackingObject. This used to be a macro,
but it is now a method that check for the execution thread and returns
the appropriate AX object.
(-[WebAccessibilityObjectWrapper additionalAccessibilityAttributeNames]):
(-[WebAccessibilityObjectWrapper ALLOW_DEPRECATED_IMPLEMENTATIONS_END]):
(-[WebAccessibilityObjectWrapper accessibilityAttributeValue:]):
(-[WebAccessibilityObjectWrapper _accessibilitySetValue:forAttribute:]):
(-[WebAccessibilityObjectWrapper accessibilityAttributeValue:forParameter:]):

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

27 files changed:
Source/WebCore/ChangeLog
Source/WebCore/accessibility/AccessibilityARIAGrid.cpp
Source/WebCore/accessibility/AccessibilityARIAGrid.h
Source/WebCore/accessibility/AccessibilityARIAGridCell.cpp
Source/WebCore/accessibility/AccessibilityARIAGridRow.cpp
Source/WebCore/accessibility/AccessibilityNodeObject.cpp
Source/WebCore/accessibility/AccessibilityObject.cpp
Source/WebCore/accessibility/AccessibilityObject.h
Source/WebCore/accessibility/AccessibilityObjectInterface.h
Source/WebCore/accessibility/AccessibilityRenderObject.cpp
Source/WebCore/accessibility/AccessibilityTable.cpp
Source/WebCore/accessibility/AccessibilityTable.h
Source/WebCore/accessibility/AccessibilityTableCell.cpp
Source/WebCore/accessibility/AccessibilityTableCell.h
Source/WebCore/accessibility/AccessibilityTableColumn.cpp
Source/WebCore/accessibility/AccessibilityTableHeaderContainer.cpp
Source/WebCore/accessibility/AccessibilityTableRow.cpp
Source/WebCore/accessibility/atk/WebKitAccessible.cpp
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/isolatedtree/AXIsolatedTree.cpp
Source/WebCore/accessibility/isolatedtree/AXIsolatedTree.h
Source/WebCore/accessibility/mac/AXObjectCacheMac.mm
Source/WebCore/accessibility/mac/WebAccessibilityObjectWrapperMac.mm

index f660dcf..ab8c5de 100644 (file)
@@ -1,3 +1,118 @@
+2020-02-23  Andres Gonzalez  <andresg_22@apple.com>
+
+        AXIsolatedObject support for tables.
+        https://bugs.webkit.org/show_bug.cgi?id=208074
+
+        Reviewed by Chris Fleizach.
+
+        Covered by existing tests.
+
+        AccessibilityObjectWrapper code and some utility functions in
+        AccessibilityObject.cpp assume that AX objects can be downcast to a
+        specialized subclass like AccessibilityTable. That is not true for
+        AXIsolatedObjects, and the reason why tables don’t work in IsolatedTree
+        mode.
+
+        To solve this problem, this patch exposes the AccessibilityTable
+        interface as part of the AXCoreObject. Thus it eliminates the need to
+        downcast an AX object to an AccessibilityTable. It also implements the
+        AccessibilityTable interface in the AXIsolatedObject class. The same
+        approach will be used in subsequent patches for other specialized
+        interfaces used by client code.
+
+        * accessibility/AccessibilityARIAGrid.cpp:
+        (WebCore::AccessibilityARIAGrid::addChildren):
+        * accessibility/AccessibilityARIAGrid.h:
+        * accessibility/AccessibilityARIAGridCell.cpp:
+        (WebCore::AccessibilityARIAGridCell::parentTable const):
+        (WebCore::AccessibilityARIAGridCell::rowIndexRange const):
+        (WebCore::AccessibilityARIAGridCell::columnIndexRange const):
+        * accessibility/AccessibilityARIAGridRow.cpp:
+        (WebCore::AccessibilityARIAGridRow::disclosedRows):
+        (WebCore::AccessibilityARIAGridRow::disclosedByRow const):
+        (WebCore::AccessibilityARIAGridRow::parentTable const):
+        * accessibility/AccessibilityNodeObject.cpp:
+        (WebCore::shouldUseAccessibilityObjectInnerText):
+        * accessibility/AccessibilityObject.cpp:
+        (WebCore::appendChildrenToArray): Use AXCoreObject interface instead of downcasting.
+        (WebCore::Accessibility::isAccessibilityObjectSearchMatchAtIndex): Use AXCoreObject interface instead of downcasting.
+        * accessibility/AccessibilityObject.h:
+        * accessibility/AccessibilityObjectInterface.h: AXCoreObject now exposes the table interface.
+        * accessibility/AccessibilityRenderObject.cpp:
+        (WebCore::AccessibilityRenderObject::ariaSelectedRows):
+        * accessibility/AccessibilityTable.cpp:
+        (WebCore::AccessibilityTable::AccessibilityTable):
+        (WebCore::AccessibilityTable::init):
+        (WebCore::AccessibilityTable::isExposable const):
+        (WebCore::AccessibilityTable::addChildren):
+        (WebCore::AccessibilityTable::headerContainer): Returns an AXCoreObject.
+
+        The following methods now return a vector of objects instead of taking
+        and out parameter. RVO guaranties that this does not cause extra copy.
+        (WebCore::AccessibilityTable::columns):
+        (WebCore::AccessibilityTable::rows):
+        (WebCore::AccessibilityTable::columnHeaders):
+        (WebCore::AccessibilityTable::rowHeaders):
+        (WebCore::AccessibilityTable::visibleRows):
+        (WebCore::AccessibilityTable::cells):
+
+        (WebCore::AccessibilityTable::tableLevel const):
+        (WebCore::AccessibilityTable::roleValue const):
+        (WebCore::AccessibilityTable::computeAccessibilityIsIgnored const):
+        (WebCore::AccessibilityTable::title const):
+        (WebCore::AccessibilityTable::isExposableThroughAccessibility const): Renamed to just isExposable.
+        * accessibility/AccessibilityTable.h:
+        (WebCore::AccessibilityTable::supportsSelectedRows): Deleted.
+        * accessibility/AccessibilityTableCell.cpp:
+        (WebCore::AccessibilityTableCell::parentTable const):
+        (WebCore::AccessibilityTableCell::isTableCell const):
+        (WebCore::AccessibilityTableCell::columnHeaders):
+        (WebCore::AccessibilityTableCell::rowHeaders):
+        * accessibility/AccessibilityTableCell.h:
+        * accessibility/AccessibilityTableColumn.cpp:
+        (WebCore::AccessibilityTableColumn::headerObject):
+        (WebCore::AccessibilityTableColumn::addChildren):
+        * accessibility/AccessibilityTableHeaderContainer.cpp:
+        (WebCore::AccessibilityTableHeaderContainer::addChildren):
+        * accessibility/AccessibilityTableRow.cpp:
+        (WebCore::AccessibilityTableRow::isTableRow const):
+        (WebCore::AccessibilityTableRow::parentTable const):
+        * accessibility/atk/WebKitAccessible.cpp:
+        (webkitAccessibleGetAttributes):
+        * accessibility/atk/WebKitAccessibleInterfaceTable.cpp:
+        (webkitAccessibleTableGetColumnHeader):
+        (webkitAccessibleTableGetRowHeader):
+        * accessibility/atk/WebKitAccessibleInterfaceTableCell.cpp:
+        (webkitAccessibleTableCellGetColumnHeaderCells):
+        (webkitAccessibleTableCellGetRowHeaderCells):
+        * accessibility/ios/WebAccessibilityObjectWrapperIOS.mm:
+        (-[WebAccessibilityObjectWrapper tableParent]):
+        (-[WebAccessibilityObjectWrapper accessibilityHeaderElements]):
+        * accessibility/isolatedtree/AXIsolatedObject.cpp:
+        (WebCore::AXIsolatedObject::initializeAttributeData):
+        (WebCore::AXIsolatedObject::setObjectVectorProperty):
+        (WebCore::AXIsolatedObject::cellForColumnAndRow):
+        (WebCore::AXIsolatedObject::fillChildrenVectorForProperty const):
+        (WebCore::AXIsolatedObject::isAccessibilityTableInstance const):
+        (WebCore::AXIsolatedObject::isDataTable const): Deleted.
+        * accessibility/isolatedtree/AXIsolatedObject.h:
+        * accessibility/isolatedtree/AXIsolatedTree.cpp:
+        (WebCore::AXIsolatedTree::nodeForID const):
+        (WebCore::AXIsolatedTree::objectsForIDs const):
+        * accessibility/isolatedtree/AXIsolatedTree.h:
+        * accessibility/mac/AXObjectCacheMac.mm:
+        (WebCore::AXObjectCache::postPlatformNotification):
+        * accessibility/mac/WebAccessibilityObjectWrapperMac.mm:
+        In addition to replacing the downcast to AccessibilityTable, cleaned up
+        the unnecessary calls to self.axBackingObject. This used to be a macro,
+        but it is now a method that check for the execution thread and returns
+        the appropriate AX object.
+        (-[WebAccessibilityObjectWrapper additionalAccessibilityAttributeNames]):
+        (-[WebAccessibilityObjectWrapper ALLOW_DEPRECATED_IMPLEMENTATIONS_END]):
+        (-[WebAccessibilityObjectWrapper accessibilityAttributeValue:]):
+        (-[WebAccessibilityObjectWrapper _accessibilitySetValue:forAttribute:]):
+        (-[WebAccessibilityObjectWrapper accessibilityAttributeValue:forParameter:]):
+
 2020-02-23  Adrian Perez de Castro  <aperez@igalia.com>
 
         Non-unified build fixes late February 2020 edition
index 000add4..5a2b34c 100644 (file)
@@ -103,7 +103,7 @@ void AccessibilityARIAGrid::addChildren()
 {
     ASSERT(!m_haveChildren); 
     
-    if (!isExposableThroughAccessibility()) {
+    if (!isExposable()) {
         AccessibilityRenderObject::addChildren();
         return;
     }
@@ -145,8 +145,8 @@ void AccessibilityARIAGrid::addChildren()
         if (!column.accessibilityIsIgnored())
             m_children.append(&column);
     }
-    
-    AccessibilityObject* headerContainerObject = headerContainer();
+
+    auto* headerContainerObject = headerContainer();
     if (headerContainerObject && !headerContainerObject->accessibilityIsIgnored())
         m_children.append(headerContainerObject);
 }
index f72c906..1b365d4 100644 (file)
@@ -47,7 +47,7 @@ private:
     explicit AccessibilityARIAGrid(RenderObject*);
 
     // ARIA treegrids and grids support selected rows.
-    bool supportsSelectedRows() override { return true; }
+    bool supportsSelectedRows() const override { return true; }
     bool isMultiSelectable() const override;
     bool computeIsTableExposableThroughAccessibility() const override { return true; }
     bool isAriaTable() const override { return true; }
index f819e9a..6c4af15 100644 (file)
@@ -56,7 +56,7 @@ AccessibilityTable* AccessibilityARIAGridCell::parentTable() const
     // including rows and interactive rowgroups. In addition, poorly-formed grids may contain elements
     // which pass the tests for inclusion.
     for (auto* parent = parentObjectUnignored(); parent; parent = parent->parentObjectUnignored()) {
-        if (is<AccessibilityTable>(*parent) && downcast<AccessibilityTable>(*parent).isExposableThroughAccessibility())
+        if (is<AccessibilityTable>(*parent) && downcast<AccessibilityTable>(*parent).isExposable())
             return downcast<AccessibilityTable>(parent);
     }
 
@@ -72,7 +72,7 @@ void AccessibilityARIAGridCell::rowIndexRange(std::pair<unsigned, unsigned>& row
     if (is<AccessibilityTableRow>(*parent)) {
         // We already got a table row, use its API.
         rowRange.first = downcast<AccessibilityTableRow>(*parent).rowIndex();
-    } else if (is<AccessibilityTable>(*parent) && downcast<AccessibilityTable>(*parent).isExposableThroughAccessibility()) {
+    } else if (is<AccessibilityTable>(*parent) && downcast<AccessibilityTable>(*parent).isExposable()) {
         // We reached the parent table, so we need to inspect its
         // children to determine the row index for the cell in it.
         unsigned columnCount = downcast<AccessibilityTable>(*parent).columnCount();
@@ -139,7 +139,7 @@ void AccessibilityARIAGridCell::columnIndexRange(std::pair<unsigned, unsigned>&
         return;
 
     if (!is<AccessibilityTableRow>(*parent)
-        && !(is<AccessibilityTable>(*parent) && downcast<AccessibilityTable>(*parent).isExposableThroughAccessibility()))
+        && !(is<AccessibilityTable>(*parent) && downcast<AccessibilityTable>(*parent).isExposable()))
         return;
 
     const AccessibilityChildrenVector& siblings = parent->children();
index 3283807..ebbe30f 100644 (file)
@@ -60,17 +60,17 @@ void AccessibilityARIAGridRow::disclosedRows(AccessibilityChildrenVector& disclo
     // The contiguous disclosed rows will be the rows in the table that 
     // have an aria-level of plus 1 from this row.
     AccessibilityObject* parent = parentObjectUnignored();
-    if (!is<AccessibilityTable>(*parent) || !downcast<AccessibilityTable>(*parent).isExposableThroughAccessibility())
+    if (!is<AccessibilityTable>(*parent) || !downcast<AccessibilityTable>(*parent).isExposable())
         return;
-    
+
     // Search for rows that match the correct level. 
     // Only take the subsequent rows from this one that are +1 from this row's level.
     int index = rowIndex();
     if (index < 0)
         return;
-    
+
     unsigned level = hierarchicalLevel();
-    auto& allRows = downcast<AccessibilityTable>(*parent).rows();
+    auto allRows = parent->rows();
     int rowCount = allRows.size();
     for (int k = index + 1; k < rowCount; ++k) {
         auto* row = allRows[k].get();
@@ -87,27 +87,27 @@ AXCoreObject* AccessibilityARIAGridRow::disclosedByRow() const
     // The row that discloses this one is the row in the table
     // that is aria-level subtract 1 from this row.
     AccessibilityObject* parent = parentObjectUnignored();
-    if (!is<AccessibilityTable>(*parent) || !downcast<AccessibilityTable>(*parent).isExposableThroughAccessibility())
+    if (!is<AccessibilityTable>(*parent) || !downcast<AccessibilityTable>(*parent).isExposable())
         return nullptr;
-    
+
     // If the level is 1 or less, than nothing discloses this row.
     unsigned level = hierarchicalLevel();
     if (level <= 1)
         return nullptr;
-    
+
     // Search for the previous row that matches the correct level.
     int index = rowIndex();
-    auto& allRows = downcast<AccessibilityTable>(parent)->rows();
+    auto allRows = parent->rows();
     int rowCount = allRows.size();
     if (index >= rowCount)
         return nullptr;
-    
+
     for (int k = index - 1; k >= 0; --k) {
         auto* row = allRows[k].get();
         if (row->hierarchicalLevel() == level - 1)
             return row;
     }
-    
+
     return nullptr;
 }
     
@@ -125,7 +125,7 @@ AccessibilityTable* AccessibilityARIAGridRow::parentTable() const
         // Unless the row is a native tr element.
         if (is<AccessibilityTable>(*parent)) {
             AccessibilityTable& tableParent = downcast<AccessibilityTable>(*parent);
-            if (tableParent.isExposableThroughAccessibility() && (tableParent.isAriaTable() || node()->hasTagName(HTMLNames::trTag)))
+            if (tableParent.isExposable() && (tableParent.isAriaTable() || node()->hasTagName(HTMLNames::trTag)))
                 return &tableParent;
         }
     }
index 458a405..52274ad 100644 (file)
@@ -1739,7 +1739,7 @@ static bool shouldUseAccessibilityObjectInnerText(AccessibilityObject* obj, Acce
     if (is<AccessibilityList>(*obj))
         return false;
 
-    if (is<AccessibilityTable>(*obj) && downcast<AccessibilityTable>(*obj).isExposableThroughAccessibility())
+    if (is<AccessibilityTable>(*obj) && downcast<AccessibilityTable>(*obj).isExposable())
         return false;
 
     if (obj->isTree() || obj->isCanvas())
index 8314712..952bbd7 100644 (file)
@@ -510,7 +510,7 @@ static void appendChildrenToArray(AXCoreObject* object, bool isForward, AXCoreOb
 {
     // A table's children includes elements whose own children are also the table's children (due to the way the Mac exposes tables).
     // The rows from the table should be queried, since those are direct descendants of the table, and they contain content.
-    const auto& searchChildren = is<AccessibilityTable>(*object) && downcast<AccessibilityTable>(*object).isExposableThroughAccessibility() ? downcast<AccessibilityTable>(*object).rows() : object->children();
+    const auto& searchChildren = object->isTable() && object->isExposable() ? object->rows() : object->children();
 
     size_t childrenSize = searchChildren.size();
 
@@ -3723,10 +3723,10 @@ static bool isAccessibilityObjectSearchMatchAtIndex(AXCoreObject* axObject, Acce
             && !axObject->hasSameStyle(criteria.startObject->renderer());
     case AccessibilitySearchKey::TableSameLevel:
         return criteria.startObject
-            && is<AccessibilityTable>(*axObject) && downcast<AccessibilityTable>(*axObject).isExposableThroughAccessibility()
-            && downcast<AccessibilityTable>(*axObject).tableLevel() == criteria.startObject->tableLevel();
+            && axObject->isTable() && axObject->isExposable()
+            && axObject->tableLevel() == criteria.startObject->tableLevel();
     case AccessibilitySearchKey::Table:
-        return is<AccessibilityTable>(*axObject) && downcast<AccessibilityTable>(*axObject).isExposableThroughAccessibility();
+        return axObject->isTable() && axObject->isExposable();
     case AccessibilitySearchKey::TextField:
         return axObject->isTextControl();
     case AccessibilitySearchKey::Underline:
index 03efbed..94ca59d 100644 (file)
@@ -113,6 +113,7 @@ public:
     bool isAccessibilityScrollView() const override { return false; }
     bool isAccessibilitySVGRoot() const override { return false; }
     bool isAccessibilitySVGElement() const override { return false; }
+    bool isAccessibilityTableInstance() const override { return false; }
 
     bool isAttachmentElement() const override { return false; }
     bool isHeading() const override { return false; }
@@ -148,8 +149,25 @@ public:
     bool isOrderedList() const override { return false; }
     bool isDescriptionList() const override { return false; }
 
+    // Table support.
     bool isTable() const override { return false; }
+    bool isExposable() const override { return true; }
     bool isDataTable() const override { return false; }
+    int tableLevel() const override { return 0; }
+    bool supportsSelectedRows() const override { return false; }
+    AccessibilityChildrenVector columns() override { return AccessibilityChildrenVector(); }
+    AccessibilityChildrenVector rows() override { return AccessibilityChildrenVector(); }
+    unsigned columnCount() override { return 0; }
+    unsigned rowCount() override { return 0; }
+    AccessibilityChildrenVector cells() override { return AccessibilityChildrenVector(); }
+    AXCoreObject* cellForColumnAndRow(unsigned, unsigned) override { return nullptr; }
+    AccessibilityChildrenVector columnHeaders() override { return AccessibilityChildrenVector(); }
+    AccessibilityChildrenVector rowHeaders() override { return AccessibilityChildrenVector(); }
+    AccessibilityChildrenVector visibleRows() override { return AccessibilityChildrenVector(); }
+    AXCoreObject* headerContainer() override { return nullptr; }
+    int axColumnCount() const override { return 0; }
+    int axRowCount() const override { return 0; }
+
     bool isTableRow() const override { return false; }
     bool isTableColumn() const override { return false; }
     bool isTableCell() const override { return false; }
@@ -240,7 +258,6 @@ public:
 
     unsigned blockquoteLevel() const override;
     int headingLevel() const override { return 0; }
-    int tableLevel() const override { return 0; }
     AccessibilityButtonState checkboxOrRadioValue() const override;
     String valueDescription() const override { return String(); }
     float valueForRange() const override { return 0.0f; }
index c15f8ef..8df7d2f 100644 (file)
@@ -488,6 +488,7 @@ public:
     virtual bool isAccessibilityScrollView() const = 0;
     virtual bool isAccessibilitySVGRoot() const = 0;
     virtual bool isAccessibilitySVGElement() const = 0;
+    virtual bool isAccessibilityTableInstance() const = 0;
 
     virtual bool isAttachmentElement() const = 0;
     virtual bool isHeading() const = 0;
@@ -528,11 +529,31 @@ public:
     virtual bool isOrderedList() const = 0;
     virtual bool isDescriptionList() const = 0;
 
+    // Table support.
     virtual bool isTable() const = 0;
+    virtual bool isExposable() const = 0;
     virtual bool isDataTable() const = 0;
+    virtual int tableLevel() const = 0;
+    virtual bool supportsSelectedRows() const = 0;
+    virtual AccessibilityChildrenVector columns() = 0;
+    virtual AccessibilityChildrenVector rows() = 0;
+    virtual unsigned columnCount() = 0;
+    virtual unsigned rowCount() = 0;
+    // All the cells in the table.
+    virtual AccessibilityChildrenVector cells() = 0;
+    virtual AXCoreObject* cellForColumnAndRow(unsigned column, unsigned row) = 0;
+    virtual AccessibilityChildrenVector columnHeaders() = 0;
+    virtual AccessibilityChildrenVector rowHeaders() = 0;
+    virtual AccessibilityChildrenVector visibleRows() = 0;
+    // Returns an object that contains, as children, all the objects that act as headers.
+    virtual AXCoreObject* headerContainer() = 0;
+    virtual int axColumnCount() const = 0;
+    virtual int axRowCount() const = 0;
+
     virtual bool isTableRow() const = 0;
     virtual bool isTableColumn() const = 0;
     virtual bool isTableCell() const = 0;
+
     virtual bool isFieldset() const = 0;
     virtual bool isGroup() const = 0;
     virtual bool isARIATreeGridRow() const = 0;
@@ -648,7 +669,6 @@ public:
 
     virtual unsigned blockquoteLevel() const = 0;
     virtual int headingLevel() const = 0;
-    virtual int tableLevel() const = 0;
     virtual AccessibilityButtonState checkboxOrRadioValue() const = 0;
     virtual String valueDescription() const = 0;
     virtual float valueForRange() const = 0;
index 8a8300d..c6087cc 100644 (file)
@@ -3471,7 +3471,7 @@ void AccessibilityRenderObject::ariaSelectedRows(AccessibilityChildrenVector& re
     }
 
     // Get all the rows.
-    auto rowsIteration = [&](auto& rows) {
+    auto rowsIteration = [&](const auto& rows) {
         for (auto& row : rows) {
             if (row->isSelected() || row->isActiveDescendantOfFocusedContainer()) {
                 result.append(row);
@@ -3486,7 +3486,7 @@ void AccessibilityRenderObject::ariaSelectedRows(AccessibilityChildrenVector& re
         rowsIteration(allRows);
     } else if (is<AccessibilityTable>(*this)) {
         auto& thisTable = downcast<AccessibilityTable>(*this);
-        if (thisTable.isExposableThroughAccessibility() && thisTable.supportsSelectedRows())
+        if (thisTable.isExposable() && thisTable.supportsSelectedRows())
             rowsIteration(thisTable.rows());
     }
 }
index 2731b07..225fc8e 100644 (file)
@@ -54,7 +54,7 @@ using namespace HTMLNames;
 AccessibilityTable::AccessibilityTable(RenderObject* renderer)
     : AccessibilityRenderObject(renderer)
     , m_headerContainer(nullptr)
-    , m_isExposableThroughAccessibility(true)
+    , m_isExposable(true)
 {
 }
 
@@ -63,7 +63,7 @@ AccessibilityTable::~AccessibilityTable() = default;
 void AccessibilityTable::init()
 {
     AccessibilityRenderObject::init();
-    m_isExposableThroughAccessibility = computeIsTableExposableThroughAccessibility();
+    m_isExposable = computeIsTableExposableThroughAccessibility();
 }
 
 Ref<AccessibilityTable> AccessibilityTable::create(RenderObject* renderer)
@@ -83,12 +83,12 @@ bool AccessibilityTable::hasARIARole() const
     return false;
 }
 
-bool AccessibilityTable::isExposableThroughAccessibility() const
+bool AccessibilityTable::isExposable() const
 {
     if (!m_renderer)
         return false;
     
-    return m_isExposableThroughAccessibility;
+    return m_isExposable;
 }
 
 HTMLTableElement* AccessibilityTable::tableElement() const
@@ -377,7 +377,7 @@ void AccessibilityTable::clearChildren()
 
 void AccessibilityTable::addChildren()
 {
-    if (!isExposableThroughAccessibility()) {
+    if (!isExposable()) {
         AccessibilityRenderObject::addChildren();
         return;
     }
@@ -424,8 +424,8 @@ void AccessibilityTable::addChildren()
         if (!column.accessibilityIsIgnored())
             m_children.append(&column);
     }
-    
-    AccessibilityObject* headerContainerObject = headerContainer();
+
+    auto* headerContainerObject = headerContainer();
     if (headerContainerObject && !headerContainerObject->accessibilityIsIgnored())
         m_children.append(headerContainerObject);
 
@@ -437,7 +437,6 @@ void AccessibilityTable::addChildren()
         for (const auto& cell : row->children())
             cell->updateAccessibilityRole();
     }
-
 }
 
 void AccessibilityTable::addTableCellChild(AccessibilityObject* rowObject, HashSet<AccessibilityObject*>& appendedRows, unsigned& columnCount)
@@ -501,7 +500,7 @@ void AccessibilityTable::addChildrenFromSection(RenderTableSection* tableSection
     maxColumnCount = std::max(tableSection->numColumns(), maxColumnCount);
 }
     
-AccessibilityObject* AccessibilityTable::headerContainer()
+AXCoreObject* AccessibilityTable::headerContainer()
 {
     if (m_headerContainer)
         return m_headerContainer.get();
@@ -513,74 +512,86 @@ AccessibilityObject* AccessibilityTable::headerContainer()
     return m_headerContainer.get();
 }
 
-const AccessibilityObject::AccessibilityChildrenVector& AccessibilityTable::columns()
+AXCoreObject::AccessibilityChildrenVector AccessibilityTable::columns()
 {
     updateChildrenIfNecessary();
         
     return m_columns;
 }
 
-const AccessibilityObject::AccessibilityChildrenVector& AccessibilityTable::rows()
+AXCoreObject::AccessibilityChildrenVector AccessibilityTable::rows()
 {
     updateChildrenIfNecessary();
     
     return m_rows;
 }
 
-void AccessibilityTable::columnHeaders(AccessibilityChildrenVector& headers)
+AXCoreObject::AccessibilityChildrenVector AccessibilityTable::columnHeaders()
 {
+    AccessibilityChildrenVector headers;
     if (!m_renderer)
-        return;
-    
+        return headers;
+
     updateChildrenIfNecessary();
-    
+
     // Sometimes m_columns can be reset during the iteration, we cache it here to be safe.
     AccessibilityChildrenVector columnsCopy = m_columns;
-    
+
     for (const auto& column : columnsCopy) {
         if (AXCoreObject* header = downcast<AccessibilityTableColumn>(*column).headerObject())
             headers.append(header);
     }
+
+    return headers;
 }
 
-void AccessibilityTable::rowHeaders(AccessibilityChildrenVector& headers)
+AXCoreObject::AccessibilityChildrenVector AccessibilityTable::rowHeaders()
 {
+    AccessibilityChildrenVector headers;
     if (!m_renderer)
-        return;
-    
+        return headers;
+
     updateChildrenIfNecessary();
-    
+
     // Sometimes m_rows can be reset during the iteration, we cache it here to be safe.
     AccessibilityChildrenVector rowsCopy = m_rows;
-    
+
     for (const auto& row : rowsCopy) {
         if (AXCoreObject* header = downcast<AccessibilityTableRow>(*row).headerObject())
             headers.append(header);
     }
+
+    return headers;
 }
 
-void AccessibilityTable::visibleRows(AccessibilityChildrenVector& rows)
+AXCoreObject::AccessibilityChildrenVector AccessibilityTable::visibleRows()
 {
+    AccessibilityChildrenVector rows;
     if (!m_renderer)
-        return;
-    
+        return rows;
+
     updateChildrenIfNecessary();
-    
+
     for (const auto& row : m_rows) {
         if (row && !row->isOffScreen())
             rows.append(row);
     }
+
+    return rows;
 }
 
-void AccessibilityTable::cells(AccessibilityObject::AccessibilityChildrenVector& cells)
+AXCoreObject::AccessibilityChildrenVector AccessibilityTable::cells()
 {
+    AccessibilityChildrenVector cells;
     if (!m_renderer)
-        return;
-    
+        return cells;
+
     updateChildrenIfNecessary();
-    
+
     for (const auto& row : m_rows)
         cells.appendVector(row->children());
+
+    return cells;
 }
     
 unsigned AccessibilityTable::columnCount()
@@ -601,7 +612,7 @@ int AccessibilityTable::tableLevel() const
 {
     int level = 0;
     for (AccessibilityObject* obj = static_cast<AccessibilityObject*>(const_cast<AccessibilityTable*>(this)); obj; obj = obj->parentObject()) {
-        if (is<AccessibilityTable>(*obj) && downcast<AccessibilityTable>(*obj).isExposableThroughAccessibility())
+        if (is<AccessibilityTable>(*obj) && downcast<AccessibilityTable>(*obj).isExposable())
             ++level;
     }
     
@@ -644,7 +655,7 @@ AccessibilityTableCell* AccessibilityTable::cellForColumnAndRow(unsigned column,
 
 AccessibilityRole AccessibilityTable::roleValue() const
 {
-    if (!isExposableThroughAccessibility())
+    if (!isExposable())
         return AccessibilityRenderObject::roleValue();
     
     AccessibilityRole ariaRole = ariaRoleAttribute();
@@ -662,9 +673,9 @@ bool AccessibilityTable::computeAccessibilityIsIgnored() const
     if (decision == AccessibilityObjectInclusion::IgnoreObject)
         return true;
     
-    if (!isExposableThroughAccessibility())
+    if (!isExposable())
         return AccessibilityRenderObject::computeAccessibilityIsIgnored();
-        
+
     return false;
 }
 
@@ -677,7 +688,7 @@ void AccessibilityTable::titleElementText(Vector<AccessibilityText>& textOrder)
 
 String AccessibilityTable::title() const
 {
-    if (!isExposableThroughAccessibility())
+    if (!isExposable())
         return AccessibilityRenderObject::title();
     
     String title;
index cbfca6a..0d8ed39 100644 (file)
 #pragma once
 
 #include "AccessibilityRenderObject.h"
+#include "AccessibilityTableCell.h"
 #include <wtf/Forward.h>
 
 namespace WebCore {
 
-class AccessibilityTableCell;
 class HTMLTableElement;
 class RenderTableSection;
     
@@ -46,36 +46,36 @@ public:
 
     AccessibilityRole roleValue() const final;
     virtual bool isAriaTable() const { return false; }
-    
+
     void addChildren() override;
     void clearChildren() final;
-    
-    const AccessibilityChildrenVector& columns();
-    const AccessibilityChildrenVector& rows();
-    
-    virtual bool supportsSelectedRows() { return false; }
-    unsigned columnCount();
-    unsigned rowCount();
+
+    AccessibilityChildrenVector columns() override;
+    AccessibilityChildrenVector rows() override;
+
+    unsigned columnCount() override;
+    unsigned rowCount() override;
     int tableLevel() const final;
-    
+
     String title() const final;
-    
+
     // all the cells in the table
-    void cells(AccessibilityChildrenVector&);
-    AccessibilityTableCell* cellForColumnAndRow(unsigned column, unsigned row);
-    
-    void columnHeaders(AccessibilityChildrenVector&);
-    void rowHeaders(AccessibilityChildrenVector&);
-    void visibleRows(AccessibilityChildrenVector&);
-    
-    // an object that contains, as children, all the objects that act as headers
-    AccessibilityObject* headerContainer();
+    AccessibilityChildrenVector cells() override;
+    AccessibilityTableCell* cellForColumnAndRow(unsigned column, unsigned row) override;
 
-    // isExposableThroughAccessibility() is whether it is exposed as an AccessibilityTable to the platform.
-    bool isExposableThroughAccessibility() const;
-    
-    int axColumnCount() const;
-    int axRowCount() const;
+    AccessibilityChildrenVector columnHeaders() override;
+    AccessibilityChildrenVector rowHeaders() override;
+    AccessibilityChildrenVector visibleRows() override;
+
+    // Returns an object that contains, as children, all the objects that act as headers.
+    AXCoreObject* headerContainer() override;
+
+    bool isTable() const override { return true; }
+    // Returns whether it is exposed as an AccessibilityTable to the platform.
+    bool isExposable() const override;
+
+    int axColumnCount() const override;
+    int axRowCount() const override;
 
 protected:
     explicit AccessibilityTable(RenderObject*);
@@ -84,12 +84,13 @@ protected:
     AccessibilityChildrenVector m_columns;
 
     RefPtr<AccessibilityObject> m_headerContainer;
-    bool m_isExposableThroughAccessibility;
+    bool m_isExposable;
 
     bool hasARIARole() const;
 
-    // isTable is whether it's an AccessibilityTable object.
-    bool isTable() const final { return true; }
+    // Used in type checking function is<AccessibilityTable>.
+    bool isAccessibilityTableInstance() const final { return true; }
+
     // isDataTable is whether it is exposed as an AccessibilityTable because the heuristic
     // think this "looks" like a data-based table (instead of a table used for layout).
     bool isDataTable() const final;
@@ -105,4 +106,4 @@ private:
 
 } // namespace WebCore 
 
-SPECIALIZE_TYPE_TRAITS_ACCESSIBILITY(AccessibilityTable, isTable())
+SPECIALIZE_TYPE_TRAITS_ACCESSIBILITY(AccessibilityTable, isAccessibilityTableInstance())
index db5041c..01327d2 100644 (file)
@@ -101,7 +101,7 @@ AccessibilityTable* AccessibilityTableCell::parentTable() const
             // we don't want to choose another ancestor table as this cell's table.
             if (is<AccessibilityTable>(*parent)) {
                 auto& parentTable = downcast<AccessibilityTable>(*parent);
-                if (parentTable.isExposableThroughAccessibility())
+                if (parentTable.isExposable())
                     return &parentTable;
                 if (parentTable.node())
                     break;
@@ -119,7 +119,7 @@ bool AccessibilityTableCell::isTableCell() const
     // This used to check if the unignoredParent was a row, but that exploded performance if
     // this was in nested tables. This check should be just as good.
     AccessibilityObject* parentTable = this->parentTable();
-    return is<AccessibilityTable>(parentTable) && downcast<AccessibilityTable>(*parentTable).isExposableThroughAccessibility();
+    return is<AccessibilityTable>(parentTable) && downcast<AccessibilityTable>(*parentTable).isExposable();
 }
     
 AccessibilityRole AccessibilityTableCell::determineAccessibilityRole()
@@ -243,17 +243,18 @@ bool AccessibilityTableCell::supportsExpandedTextValue() const
     return isTableHeaderCell() && hasAttribute(abbrAttr);
 }
     
-void AccessibilityTableCell::columnHeaders(AccessibilityChildrenVector& headers)
+AXCoreObject::AccessibilityChildrenVector AccessibilityTableCell::columnHeaders()
 {
+    AccessibilityChildrenVector headers;
     AccessibilityTable* parent = parentTable();
     if (!parent)
-        return;
+        return headers;
 
     // Choose columnHeaders as the place where the "headers" attribute is reported.
     ariaElementsFromAttribute(headers, headersAttr);
     // If the headers attribute returned valid values, then do not further search for column headers.
     if (!headers.isEmpty())
-        return;
+        return headers;
     
     std::pair<unsigned, unsigned> rowRange;
     rowIndexRange(rowRange);
@@ -275,13 +276,16 @@ void AccessibilityTableCell::columnHeaders(AccessibilityChildrenVector& headers)
         else if (tableCell->isColumnHeaderCell())
             headers.append(tableCell);
     }
+
+    return headers;
 }
     
-void AccessibilityTableCell::rowHeaders(AccessibilityChildrenVector& headers)
+AXCoreObject::AccessibilityChildrenVector AccessibilityTableCell::rowHeaders()
 {
+    AccessibilityChildrenVector headers;
     AccessibilityTable* parent = parentTable();
     if (!parent)
-        return;
+        return headers;
 
     std::pair<unsigned, unsigned> rowRange;
     rowIndexRange(rowRange);
@@ -300,6 +304,8 @@ void AccessibilityTableCell::rowHeaders(AccessibilityChildrenVector& headers)
         else if (tableCell->isRowHeaderCell())
             headers.append(tableCell);
     }
+
+    return headers;
 }
 
 AccessibilityTableRow* AccessibilityTableCell::parentRow() const
index 0520f22..fa361c6 100644 (file)
@@ -49,10 +49,10 @@ public:
     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;
-    
-    void columnHeaders(AccessibilityChildrenVector&);
-    void rowHeaders(AccessibilityChildrenVector&);
-    
+
+    AccessibilityChildrenVector columnHeaders() override;
+    AccessibilityChildrenVector rowHeaders() override;
+
     int axColumnIndex() const;
     int axRowIndex() const;
     int axColumnSpan() const;
index ff478fd..03d2ec7 100644 (file)
@@ -81,7 +81,7 @@ AXCoreObject* AccessibilityTableColumn::headerObject()
         return nullptr;
 
     auto& parentTable = downcast<AccessibilityTable>(*m_parent);
-    if (!parentTable.isExposableThroughAccessibility())
+    if (!parentTable.isExposable())
         return nullptr;
     
     if (parentTable.isAriaTable()) {
@@ -191,7 +191,7 @@ void AccessibilityTableColumn::addChildren()
         return;
 
     auto& parentTable = downcast<AccessibilityTable>(*m_parent);
-    if (!parentTable.isExposableThroughAccessibility())
+    if (!parentTable.isExposable())
         return;
     
     int numRows = parentTable.rowCount();
index 946ef1c..7258116 100644 (file)
@@ -70,11 +70,11 @@ void AccessibilityTableHeaderContainer::addChildren()
         return;
 
     auto& parentTable = downcast<AccessibilityTable>(*m_parent);
-    if (!parentTable.isExposableThroughAccessibility())
+    if (!parentTable.isExposable())
         return;
-    
-    parentTable.columnHeaders(m_children);
-    
+
+    m_children = parentTable.columnHeaders();
+
     for (const auto& child : m_children)
         m_headerRect.unite(child->elementRect());
 }
index 7b49c28..ecc5b48 100644 (file)
@@ -68,7 +68,7 @@ AccessibilityRole AccessibilityTableRow::determineAccessibilityRole()
 bool AccessibilityTableRow::isTableRow() const
 {
     AccessibilityObject* table = parentTable();
-    return is<AccessibilityTable>(table)  && downcast<AccessibilityTable>(*table).isExposableThroughAccessibility();
+    return is<AccessibilityTable>(table) && downcast<AccessibilityTable>(*table).isExposable();
 }
     
 AccessibilityObject* AccessibilityTableRow::observableObject() const
@@ -100,7 +100,7 @@ AccessibilityTable* AccessibilityTableRow::parentTable() const
         // choose another ancestor table as this row's table.
         if (is<AccessibilityTable>(*parent)) {
             auto& parentTable = downcast<AccessibilityTable>(*parent);
-            if (parentTable.isExposableThroughAccessibility())
+            if (parentTable.isExposable())
                 return &parentTable;
             if (parentTable.node())
                 break;
index d32c822..125c192 100644 (file)
@@ -426,7 +426,7 @@ static AtkAttributeSet* webkitAccessibleGetAttributes(AtkObject* object)
             attributeSet = addToAtkAttributeSet(attributeSet, "multiscript-type", "post");
     }
 
-    if (is<AccessibilityTable>(*coreObject) && downcast<AccessibilityTable>(*coreObject).isExposableThroughAccessibility()) {
+    if (is<AccessibilityTable>(*coreObject) && downcast<AccessibilityTable>(*coreObject).isExposable()) {
         auto& table = downcast<AccessibilityTable>(*coreObject);
         int rowCount = table.axRowCount();
         if (rowCount)
index a8a8e92..d78bf4c 100644 (file)
@@ -66,8 +66,7 @@ static gint cellIndex(AccessibilityTableCell* axCell, AccessibilityTable* axTabl
 {
     // Calculate the cell's index as if we had a traditional Gtk+ table in
     // which cells are all direct children of the table, arranged row-first.
-    AccessibilityObject::AccessibilityChildrenVector allCells;
-    axTable->cells(allCells);
+    auto allCells = axTable->cells();
     AccessibilityObject::AccessibilityChildrenVector::iterator position;
     position = std::find(allCells.begin(), allCells.end(), axCell);
     if (position == allCells.end())
@@ -79,8 +78,7 @@ static AccessibilityTableCell* cellAtIndex(AtkTable* table, gint index)
 {
     AccessibilityObject* accTable = core(table);
     if (is<AccessibilityTable>(*accTable)) {
-        AccessibilityObject::AccessibilityChildrenVector allCells;
-        downcast<AccessibilityTable>(*accTable).cells(allCells);
+        auto allCells = downcast<AccessibilityTable>(*accTable).cells();
         if (0 <= index && static_cast<unsigned>(index) < allCells.size())
             return downcast<AccessibilityTableCell>(allCells[index].get());
     }
@@ -208,8 +206,7 @@ static AtkObject* webkitAccessibleTableGetColumnHeader(AtkTable* table, gint col
 
     AccessibilityObject* accTable = core(table);
     if (is<AccessibilityTable>(*accTable)) {
-        AccessibilityObject::AccessibilityChildrenVector columnHeaders;
-        downcast<AccessibilityTable>(*accTable).columnHeaders(columnHeaders);
+        auto columnHeaders = downcast<AccessibilityTable>(*accTable).columnHeaders();
 
         for (const auto& columnHeader : columnHeaders) {
             std::pair<unsigned, unsigned> columnRange;
@@ -228,8 +225,7 @@ static AtkObject* webkitAccessibleTableGetRowHeader(AtkTable* table, gint row)
 
     AccessibilityObject* accTable = core(table);
     if (is<AccessibilityTable>(*accTable)) {
-        AccessibilityObject::AccessibilityChildrenVector rowHeaders;
-        downcast<AccessibilityTable>(*accTable).rowHeaders(rowHeaders);
+        auto rowHeaders = downcast<AccessibilityTable>(*accTable).rowHeaders();
 
         for (const auto& rowHeader : rowHeaders) {
             std::pair<unsigned, unsigned> rowRange;
index 8a8b41a..ed1925b 100644 (file)
@@ -57,8 +57,7 @@ GPtrArray* webkitAccessibleTableCellGetColumnHeaderCells(AtkTableCell* cell)
     if (!is<AccessibilityTableCell>(axObject))
         return nullptr;
 
-    AccessibilityObject::AccessibilityChildrenVector columnHeaders;
-    downcast<AccessibilityTableCell>(*axObject).columnHeaders(columnHeaders);
+    auto columnHeaders = downcast<AccessibilityTableCell>(*axObject).columnHeaders();
 
     return convertToGPtrArray(columnHeaders);
 }
@@ -72,8 +71,7 @@ GPtrArray* webkitAccessibleTableCellGetRowHeaderCells(AtkTableCell* cell)
     if (!is<AccessibilityTableCell>(axObject))
         return nullptr;
 
-    AccessibilityObject::AccessibilityChildrenVector rowHeaders;
-    downcast<AccessibilityTableCell>(*axObject).rowHeaders(rowHeaders);
+    auto rowHeaders = downcast<AccessibilityTableCell>(*axObject).rowHeaders();
 
     return convertToGPtrArray(rowHeaders);
 }
index 474e853..0b3b267 100644 (file)
@@ -1193,7 +1193,7 @@ static void appendStringToResult(NSMutableString *result, NSString *string)
 {
     // Find if the parent table for the table cell.
     if (AXCoreObject* parent = Accessibility::findAncestor<AXCoreObject>(*self.axBackingObject, true, [] (const AXCoreObject& object) {
-        return is<AccessibilityTable>(object) && downcast<AccessibilityTable>(object).isExposableThroughAccessibility();
+        return is<AccessibilityTable>(object) && downcast<AccessibilityTable>(object).isExposable();
     }))
         return static_cast<AccessibilityTable*>(parent);
     return nil;
@@ -1230,12 +1230,10 @@ static void appendStringToResult(NSMutableString *result, NSString *string)
     std::pair<unsigned, unsigned> columnRange;
     tableCell->rowIndexRange(rowRange);
     tableCell->columnIndexRange(columnRange);
-    
-    AccessibilityObject::AccessibilityChildrenVector rowHeaders;
-    AccessibilityObject::AccessibilityChildrenVector columnHeaders;
-    table->rowHeaders(rowHeaders);
-    table->columnHeaders(columnHeaders);
-    
+
+    auto rowHeaders = table->rowHeaders();
+    auto columnHeaders = table->columnHeaders();
+
     NSMutableArray *headers = [NSMutableArray array];
     
     unsigned columnRangeIndex = static_cast<unsigned>(columnRange.first);
index bd61009..9d5e7e9 100644 (file)
@@ -144,7 +144,6 @@ void AXIsolatedObject::initializeAttributeData(AXCoreObject& object, bool isRoot
     setProperty(AXPropertyName::ValidationMessage, object.validationMessage());
     setProperty(AXPropertyName::BlockquoteLevel, object.blockquoteLevel());
     setProperty(AXPropertyName::HeadingLevel, object.headingLevel());
-    setProperty(AXPropertyName::TableLevel, object.tableLevel());
     setProperty(AXPropertyName::AccessibilityButtonState, static_cast<int>(object.checkboxOrRadioValue()));
     setProperty(AXPropertyName::ValueDescription, object.valueDescription());
     setProperty(AXPropertyName::ValueForRange, object.valueForRange());
@@ -217,6 +216,26 @@ void AXIsolatedObject::initializeAttributeData(AXCoreObject& object, bool isRoot
     setProperty(AXPropertyName::LiveRegionStatus, object.liveRegionStatus());
     setProperty(AXPropertyName::LiveRegionRelevant, object.liveRegionRelevant());
     setProperty(AXPropertyName::LiveRegionAtomic, object.liveRegionAtomic());
+
+    if (object.isTable()) {
+        setProperty(AXPropertyName::IsTable, object.isTable());
+        setProperty(AXPropertyName::IsExposable, object.isExposable());
+        setProperty(AXPropertyName::IsDataTable, object.isDataTable());
+        setProperty(AXPropertyName::TableLevel, object.tableLevel());
+        setProperty(AXPropertyName::SupportsSelectedRows, object.supportsSelectedRows());
+        setObjectVectorProperty(AXPropertyName::Columns, object.columns());
+        setObjectVectorProperty(AXPropertyName::Rows, object.rows());
+        setProperty(AXPropertyName::ColumnCount, object.columnCount());
+        setProperty(AXPropertyName::RowCount, object.rowCount());
+        setObjectVectorProperty(AXPropertyName::Cells, object.cells());
+        setObjectVectorProperty(AXPropertyName::ColumnHeaders, object.columnHeaders());
+        setObjectVectorProperty(AXPropertyName::RowHeaders, object.rowHeaders());
+        setObjectVectorProperty(AXPropertyName::VisibleRows, object.visibleRows());
+        setProperty(AXPropertyName::HeaderContainer, object.headerContainer());
+        setProperty(AXPropertyName::AXColumnCount, object.axColumnCount());
+        setProperty(AXPropertyName::AXRowCount, object.axRowCount());
+    }
+
     if (object.isTextControl())
         setProperty(AXPropertyName::TextLength, object.textLength());
 
@@ -378,17 +397,16 @@ void AXIsolatedObject::setObjectProperty(AXPropertyName propertyName, AXCoreObje
         setProperty(propertyName, nullptr, true);
 }
 
-void AXIsolatedObject::setObjectVectorProperty(AXPropertyName propertyName, AccessibilityChildrenVector& children)
+void AXIsolatedObject::setObjectVectorProperty(AXPropertyName propertyName, const AccessibilityChildrenVector& children)
 {
-    size_t childrenSize = children.size();
-    if (!childrenSize)
+    if (!children.size())
         return;
-    
-    Vector<AXID> childrenVector;
-    childrenVector.reserveCapacity(childrenSize);
-    for (auto childObject : children)
-        childrenVector.uncheckedAppend(childObject->objectID());
-    setProperty(propertyName, childrenVector);
+
+    Vector<AXID> childIDs(children.size());
+    for (auto child : children)
+        childIDs.uncheckedAppend(child->objectID());
+
+    setProperty(propertyName, childIDs);
 }
 
 void AXIsolatedObject::setProperty(AXPropertyName propertyName, AttributeValueVariant&& value, bool shouldRemove)
@@ -458,6 +476,19 @@ bool AXIsolatedObject::isDetachedFromParent()
     return false;
 }
 
+AXCoreObject* AXIsolatedObject::cellForColumnAndRow(unsigned columnIndex, unsigned rowIndex)
+{
+    AXID cellID = Accessibility::retrieveValueFromMainThread<AXID>([&columnIndex, &rowIndex, this] () -> AXID {
+        if (auto* object = associatedAXObject()) {
+            if (auto cell = object->cellForColumnAndRow(columnIndex, rowIndex))
+                return cell->ojbectID();
+        }
+        return InvalidAXID;
+    });
+
+    return tree()->nodeForID(cellID);
+}
+
 void AXIsolatedObject::accessibilityText(Vector<AccessibilityText>& texts) const
 {
     auto isolatedTexts = vectorAttributeValue<AccessibilityIsolatedTreeText>(AXPropertyName::AccessibilityText);
@@ -786,12 +817,7 @@ int AXIsolatedObject::intAttributeValue(AXPropertyName propertyName) const
 
 void AXIsolatedObject::fillChildrenVectorForProperty(AXPropertyName propertyName, AccessibilityChildrenVector& children) const
 {
-    Vector<AXID> childIDs = vectorAttributeValue<AXID>(propertyName);
-    children.reserveCapacity(childIDs.size());
-    for (const auto& childID : childIDs) {
-        if (auto object = tree()->nodeForID(childID))
-            children.uncheckedAppend(object);
-    }
+    children = tree()->objectsForIDs(vectorAttributeValue<AXID>(propertyName));
 }
 
 void AXIsolatedObject::updateBackingStore()
@@ -902,6 +928,12 @@ bool AXIsolatedObject::isAccessibilitySVGElement() const
     return false;
 }
 
+bool AXIsolatedObject::isAccessibilityTableInstance() const
+{
+    ASSERT_NOT_REACHED();
+    return false;
+}
+
 bool AXIsolatedObject::isAttachmentElement() const
 {
     ASSERT_NOT_REACHED();
@@ -968,12 +1000,6 @@ bool AXIsolatedObject::isLabel() const
     return false;
 }
 
-bool AXIsolatedObject::isDataTable() const
-{
-    ASSERT_NOT_REACHED();
-    return false;
-}
-
 bool AXIsolatedObject::isImageMapLink() const
 {
     ASSERT_NOT_REACHED();
index 2f6d2dd..11e09c2 100644 (file)
@@ -98,6 +98,8 @@ private:
         ARIATreeRows,
         ARIARoleAttribute,
         ARIAOwnsElements,
+        AXColumnCount,
+        AXRowCount,
         BlockquoteLevel,
         BoundingBoxRect,
         CanHaveSelectedChildren,
@@ -112,9 +114,13 @@ private:
 #if PLATFORM(COCOA) && !PLATFORM(IOS_FAMILY)
         CaretBrowsingEnabled,
 #endif
+        Cells,
         ClassList,
         ClickPoint,
         ColorValue,
+        Columns,
+        ColumnCount,
+        ColumnHeaders,
         ComputedLabel,
         ComputedRoleString,
         CurrentState,
@@ -134,6 +140,7 @@ private:
         HasARIAValueNow,
         HasChildren,
         HasPopup,
+        HeaderContainer,
         HeadingLevel,
         HelpText,
         HierarchicalLevel,
@@ -153,9 +160,11 @@ private:
         IsChecked,
         IsCollapsed,
         IsControl,
+        IsDataTable,
         IsDescriptionList,
         IsEnabled,
         IsExpanded,
+        IsExposable,
         IsFieldset,
         IsFileUploadButton,
         IsFocused,
@@ -222,6 +231,7 @@ private:
         IsShowingValidationMessage,
         IsSlider,
         IsStyleFormatGroup,
+        IsTable,
         IsTableCell,
         IsTableColumn,
         IsTableRow,
@@ -269,6 +279,9 @@ private:
         RoleValue,
         RolePlatformString,
         RoleDescription,
+        Rows,
+        RowCount,
+        RowHeaders,
         SelectedChildren,
         SelectedRadioButton,
         SelectedTabItem,
@@ -291,6 +304,7 @@ private:
         SupportsPressAction,
         SupportsRangeValue,
         SupportsRequiredAttribute,
+        SupportsSelectedRows,
         SupportsSetSize,
         TabChildren,
         TableLevel,
@@ -305,6 +319,7 @@ private:
         ValidationMessage,
         VerticalScrollBar,
         VisibleChildren,
+        VisibleRows,
     };
     
     typedef std::pair<AXID, AXID> AccessibilityIsolatedTreeMathMultiscriptPair;
@@ -317,7 +332,7 @@ private:
     using AttributeValueVariant = Variant<std::nullptr_t, String, bool, int, unsigned, double, float, uint64_t, Color, URL, LayoutRect, AXID, IntPoint, OptionSet<SpeakAs>, Vector<AccessibilityIsolatedTreeText>, Vector<AXID>, Vector<AccessibilityIsolatedTreeMathMultiscriptPair>, Vector<String>>;
     void setProperty(AXPropertyName, AttributeValueVariant&&, bool shouldRemove = false);
     void setObjectProperty(AXPropertyName, AXCoreObject*);
-    void setObjectVectorProperty(AXPropertyName, AccessibilityChildrenVector&);
+    void setObjectVectorProperty(AXPropertyName, const AccessibilityChildrenVector&);
 
     bool boolAttributeValue(AXPropertyName) const;
     const String stringAttributeValue(AXPropertyName) const;
@@ -364,7 +379,25 @@ private:
     bool isOrderedList() const override { return boolAttributeValue(AXPropertyName::IsOrderedList); }
     bool isDescriptionList() const override { return boolAttributeValue(AXPropertyName::IsDescriptionList); }
 
-    bool isTable() const override { return false; }
+    // Table support.
+    bool isTable() const override { return boolAttributeValue(AXPropertyName::IsTable); }
+    bool isExposable() const override { return boolAttributeValue(AXPropertyName::IsExposable); }
+    bool isDataTable() const override { return boolAttributeValue(AXPropertyName::IsDataTable); }
+    int tableLevel() const override { return intAttributeValue(AXPropertyName::TableLevel); }
+    bool supportsSelectedRows() const override { return boolAttributeValue(AXPropertyName::SupportsSelectedRows); }
+    AccessibilityChildrenVector columns() override { return tree()->objectsForIDs(vectorAttributeValue<AXID>(AXPropertyName::Columns)); }
+    AccessibilityChildrenVector rows() override { return tree()->objectsForIDs(vectorAttributeValue<AXID>(AXPropertyName::Rows)); }
+    unsigned columnCount() override { return unsignedAttributeValue(AXPropertyName::ColumnCount); }
+    unsigned rowCount() override { return unsignedAttributeValue(AXPropertyName::RowCount); }
+    AccessibilityChildrenVector cells() override { return tree()->objectsForIDs(vectorAttributeValue<AXID>(AXPropertyName::Cells)); }
+    AXCoreObject* cellForColumnAndRow(unsigned, unsigned) override;
+    AccessibilityChildrenVector columnHeaders() override { return tree()->objectsForIDs(vectorAttributeValue<AXID>(AXPropertyName::ColumnHeaders)); }
+    AccessibilityChildrenVector rowHeaders() override { return tree()->objectsForIDs(vectorAttributeValue<AXID>(AXPropertyName::RowHeaders)); }
+    AccessibilityChildrenVector visibleRows() override { return tree()->objectsForIDs(vectorAttributeValue<AXID>(AXPropertyName::VisibleRows)); }
+    AXCoreObject* headerContainer() override { return objectAttributeValue(AXPropertyName::HeaderContainer); }
+    int axColumnCount() const override { return intAttributeValue(AXPropertyName::AXColumnCount); }
+    int axRowCount() const override { return intAttributeValue(AXPropertyName::AXRowCount); }
+
     bool isTableRow() const override { return boolAttributeValue(AXPropertyName::IsTableRow); }
     bool isTableColumn() const override { return boolAttributeValue(AXPropertyName::IsTableColumn); }
     bool isTableCell() const override { return boolAttributeValue(AXPropertyName::IsTableCell); }
@@ -404,7 +437,6 @@ private:
     String validationMessage() const override { return stringAttributeValue(AXPropertyName::ValidationMessage); }
     unsigned blockquoteLevel() const override { return unsignedAttributeValue(AXPropertyName::BlockquoteLevel); }
     int headingLevel() const override { return intAttributeValue(AXPropertyName::HeadingLevel); }
-    int tableLevel() const override { return intAttributeValue(AXPropertyName::TableLevel); }
     AccessibilityButtonState checkboxOrRadioValue() const override { return static_cast<AccessibilityButtonState>(intAttributeValue(AXPropertyName::AccessibilityButtonState)); }
     String valueDescription() const override { return stringAttributeValue(AXPropertyName::ValueDescription); }
     float valueForRange() const override { return floatAttributeValue(AXPropertyName::ValueForRange); }
@@ -656,6 +688,7 @@ private:
     bool isAccessibilityScrollView() const override;
     bool isAccessibilitySVGRoot() const override;
     bool isAccessibilitySVGElement() const override;
+    bool isAccessibilityTableInstance() const override;
     bool isAttachmentElement() const override;
     bool isNativeImage() const override;
     bool isImageButton() const override;
@@ -667,7 +700,6 @@ private:
     bool isSliderThumb() const override;
     bool isInputSlider() const override;
     bool isLabel() const override;
-    bool isDataTable() const override;
     bool isImageMapLink() const override;
     bool isNativeSpinButton() const override;
     bool isSpinButtonPart() const override;
index 1141567..e80cf43 100644 (file)
@@ -132,9 +132,19 @@ RefPtr<AXIsolatedTree> AXIsolatedTree::treeForPageID(PageIdentifier pageID)
 
 RefPtr<AXIsolatedObject> AXIsolatedTree::nodeForID(AXID axID) const
 {
-    if (!axID)
-        return nullptr;
-    return m_readerThreadNodeMap.get(axID);
+    return axID != InvalidAXID ? m_readerThreadNodeMap.get(axID) : nullptr;
+}
+
+Vector<RefPtr<AXCoreObject>> AXIsolatedTree::objectsForIDs(Vector<AXID> axIDs) const
+{
+    Vector<RefPtr<AXCoreObject>> result(axIDs.size());
+
+    for (const auto& axID : axIDs) {
+        if (auto object = nodeForID(axID))
+            result.uncheckedAppend(object);
+    }
+
+    return result;
 }
 
 RefPtr<AXIsolatedObject> AXIsolatedTree::focusedUIElement()
index bb8f0d3..b50a95d 100644 (file)
@@ -60,6 +60,7 @@ public:
     WEBCORE_EXPORT RefPtr<AXIsolatedObject> focusedUIElement();
     RefPtr<AXIsolatedObject> nodeForID(AXID) const;
     static RefPtr<AXIsolatedObject> nodeInTreeForID(AXIsolatedTreeID, AXID);
+    Vector<RefPtr<AXCoreObject>> objectsForIDs(Vector<AXID>) const;
 
     struct NodeChange {
         Ref<AXIsolatedObject> m_isolatedObject;
index 9d494f1..cbb8cd9 100644 (file)
@@ -303,7 +303,7 @@ void AXObjectCache::postPlatformNotification(AXCoreObject* obj, AXNotification n
             macNotification = @"AXInvalidStatusChanged";
             break;
         case AXSelectedChildrenChanged:
-            if (is<AccessibilityTable>(*obj) && downcast<AccessibilityTable>(*obj).isExposableThroughAccessibility())
+            if (obj->isTable() && obj->isExposable())
                 macNotification = NSAccessibilitySelectedRowsChangedNotification;
             else
                 macNotification = NSAccessibilitySelectedChildrenChangedNotification;
index 71e8d9c..034b60f 100644 (file)
@@ -1375,101 +1375,102 @@ ALLOW_DEPRECATED_IMPLEMENTATIONS_END
 
 - (NSArray*)additionalAccessibilityAttributeNames
 {
-    if (!self.axBackingObject)
+    auto* backingObject = self.axBackingObject;
+    if (!backingObject)
         return nil;
-    
+
     NSMutableArray *additional = [NSMutableArray array];
-    if (self.axBackingObject->supportsARIAOwns())
+    if (backingObject->supportsARIAOwns())
         [additional addObject:NSAccessibilityOwnsAttribute];
-    
-    if (self.axBackingObject->isToggleButton())
+
+    if (backingObject->isToggleButton())
         [additional addObject:NSAccessibilityValueAttribute];
-    
-    if (self.axBackingObject->supportsExpanded() || self.axBackingObject->isSummary())
+
+    if (backingObject->supportsExpanded() || backingObject->isSummary())
         [additional addObject:NSAccessibilityExpandedAttribute];
-    
-    if (self.axBackingObject->isScrollbar()
-        || self.axBackingObject->isRadioGroup()
-        || self.axBackingObject->isSplitter()
-        || self.axBackingObject->isToolbar())
+
+    if (backingObject->isScrollbar()
+        || backingObject->isRadioGroup()
+        || backingObject->isSplitter()
+        || backingObject->isToolbar())
         [additional addObject:NSAccessibilityOrientationAttribute];
-    
-    if (self.axBackingObject->supportsARIADragging())
+
+    if (backingObject->supportsARIADragging())
         [additional addObject:NSAccessibilityGrabbedAttribute];
-    
-    if (self.axBackingObject->supportsARIADropping())
+
+    if (backingObject->supportsARIADropping())
         [additional addObject:NSAccessibilityDropEffectsAttribute];
-    
-    if (is<AccessibilityTable>(*self.axBackingObject) && downcast<AccessibilityTable>(*self.axBackingObject).isExposableThroughAccessibility() && downcast<AccessibilityTable>(*self.axBackingObject).supportsSelectedRows())
+
+    if (backingObject->isTable() && backingObject->isExposable() && backingObject->supportsSelectedRows())
         [additional addObject:NSAccessibilitySelectedRowsAttribute];
-    
-    if (self.axBackingObject->supportsLiveRegion()) {
+
+    if (backingObject->supportsLiveRegion()) {
         [additional addObject:NSAccessibilityARIALiveAttribute];
         [additional addObject:NSAccessibilityARIARelevantAttribute];
     }
-    
-    if (self.axBackingObject->supportsSetSize())
+
+    if (backingObject->supportsSetSize())
         [additional addObject:NSAccessibilityARIASetSizeAttribute];
-    if (self.axBackingObject->supportsPosInSet())
+
+    if (backingObject->supportsPosInSet())
         [additional addObject:NSAccessibilityARIAPosInSetAttribute];
-    
-    AccessibilitySortDirection sortDirection = self.axBackingObject->sortDirection();
+
+    AccessibilitySortDirection sortDirection = backingObject->sortDirection();
     if (sortDirection != AccessibilitySortDirection::None && sortDirection != AccessibilitySortDirection::Invalid)
         [additional addObject:NSAccessibilitySortDirectionAttribute];
-    
+
     // If an object is a child of a live region, then add these
-    if (self.axBackingObject->isInsideLiveRegion())
+    if (backingObject->isInsideLiveRegion())
         [additional addObject:NSAccessibilityARIAAtomicAttribute];
+
     // All objects should expose the ARIA busy attribute (ARIA 1.1 with ISSUE-538).
     [additional addObject:NSAccessibilityElementBusyAttribute];
-    
+
     // Popup buttons on the Mac expose the value attribute.
-    if (self.axBackingObject->isPopUpButton()) {
+    if (backingObject->isPopUpButton())
         [additional addObject:NSAccessibilityValueAttribute];
-    }
 
-    if (self.axBackingObject->supportsDatetimeAttribute())
+    if (backingObject->supportsDatetimeAttribute())
         [additional addObject:NSAccessibilityDatetimeValueAttribute];
-    
-    if (self.axBackingObject->supportsRequiredAttribute()) {
+
+    if (backingObject->supportsRequiredAttribute())
         [additional addObject:NSAccessibilityRequiredAttribute];
-    }
-    
-    if (self.axBackingObject->hasPopup())
+
+    if (backingObject->hasPopup())
         [additional addObject:NSAccessibilityHasPopupAttribute];
-    
-    if (self.axBackingObject->isMathRoot()) {
+
+    if (backingObject->isMathRoot()) {
         // The index of a square root is always known, so there's no object associated with it.
-        if (!self.axBackingObject->isMathSquareRoot())
+        if (!backingObject->isMathSquareRoot())
             [additional addObject:NSAccessibilityMathRootIndexAttribute];
         [additional addObject:NSAccessibilityMathRootRadicandAttribute];
-    } else if (self.axBackingObject->isMathFraction()) {
+    } else if (backingObject->isMathFraction()) {
         [additional addObject:NSAccessibilityMathFractionNumeratorAttribute];
         [additional addObject:NSAccessibilityMathFractionDenominatorAttribute];
         [additional addObject:NSAccessibilityMathLineThicknessAttribute];
-    } else if (self.axBackingObject->isMathSubscriptSuperscript()) {
+    } else if (backingObject->isMathSubscriptSuperscript()) {
         [additional addObject:NSAccessibilityMathBaseAttribute];
         [additional addObject:NSAccessibilityMathSubscriptAttribute];
         [additional addObject:NSAccessibilityMathSuperscriptAttribute];
-    } else if (self.axBackingObject->isMathUnderOver()) {
+    } else if (backingObject->isMathUnderOver()) {
         [additional addObject:NSAccessibilityMathBaseAttribute];
         [additional addObject:NSAccessibilityMathUnderAttribute];
         [additional addObject:NSAccessibilityMathOverAttribute];
-    } else if (self.axBackingObject->isMathFenced()) {
+    } else if (backingObject->isMathFenced()) {
         [additional addObject:NSAccessibilityMathFencedOpenAttribute];
         [additional addObject:NSAccessibilityMathFencedCloseAttribute];
-    } else if (self.axBackingObject->isMathMultiscript()) {
+    } else if (backingObject->isMathMultiscript()) {
         [additional addObject:NSAccessibilityMathBaseAttribute];
         [additional addObject:NSAccessibilityMathPrescriptsAttribute];
         [additional addObject:NSAccessibilityMathPostscriptsAttribute];
     }
-    
-    if (self.axBackingObject->supportsPath())
+
+    if (backingObject->supportsPath())
         [additional addObject:NSAccessibilityPathAttribute];
-    
-    if (self.axBackingObject->supportsExpandedTextValue())
+
+    if (backingObject->supportsExpandedTextValue())
         [additional addObject:NSAccessibilityExpandedTextValueAttribute];
-    
+
     return additional;
 }
 
@@ -1477,12 +1478,13 @@ ALLOW_DEPRECATED_IMPLEMENTATIONS_BEGIN
 - (NSArray*)accessibilityAttributeNames
 ALLOW_DEPRECATED_IMPLEMENTATIONS_END
 {
-    if (![self updateObjectBackingStore])
+    auto* backingObject = self.axBackingObject;
+    if (!backingObject)
         return nil;
-    
-    if (self.axBackingObject->isAttachment())
+
+    if (backingObject->isAttachment())
         return [[self attachmentView] accessibilityAttributeNames];
-    
+
     static NSArray* attributes = nil;
     static NSArray* anchorAttrs = nil;
     static NSArray* webAreaAttrs = nil;
@@ -1806,86 +1808,77 @@ ALLOW_DEPRECATED_IMPLEMENTATIONS_END
         scrollViewAttrs = [[NSArray alloc] initWithArray:tempArray];
         [tempArray release];
     }
-    
+
     NSArray *objectAttributes = attributes;
-    
-    if (self.axBackingObject->isPasswordField())
+
+    if (backingObject->isPasswordField())
         objectAttributes = passwordFieldAttrs;
-    
-    else if (self.axBackingObject->isWebArea())
+    else if (backingObject->isWebArea())
         objectAttributes = webAreaAttrs;
-    
-    else if (self.axBackingObject->isTextControl())
+    else if (backingObject->isTextControl())
         objectAttributes = textAttrs;
-    
-    else if (self.axBackingObject->isLink() || self.axBackingObject->isImage())
+    else if (backingObject->isLink() || backingObject->isImage())
         objectAttributes = anchorAttrs;
-    
-    else if (is<AccessibilityTable>(*self.axBackingObject) && downcast<AccessibilityTable>(*self.axBackingObject).isExposableThroughAccessibility())
+    else if (backingObject->isTable() && backingObject->isExposable())
         objectAttributes = tableAttrs;
-    else if (self.axBackingObject->isTableColumn())
+    else if (backingObject->isTableColumn())
         objectAttributes = tableColAttrs;
-    else if (self.axBackingObject->isTableCell())
+    else if (backingObject->isTableCell())
         objectAttributes = tableCellAttrs;
-    else if (self.axBackingObject->isTableRow()) {
+    else if (backingObject->isTableRow()) {
         // An ARIA table row can be collapsed and expanded, so it needs the extra attributes.
-        if (self.axBackingObject->isARIATreeGridRow())
+        if (backingObject->isARIATreeGridRow())
             objectAttributes = outlineRowAttrs;
         else
             objectAttributes = tableRowAttrs;
-    } else if (self.axBackingObject->isTree())
+    } else if (backingObject->isTree())
         objectAttributes = outlineAttrs;
-    else if (self.axBackingObject->isTreeItem())
+    else if (backingObject->isTreeItem())
         objectAttributes = outlineRowAttrs;
-    
-    else if (self.axBackingObject->isListBox())
+    else if (backingObject->isListBox())
         objectAttributes = listBoxAttrs;
-    else if (self.axBackingObject->isList())
+    else if (backingObject->isList())
         objectAttributes = listAttrs;
-    
-    else if (self.axBackingObject->isComboBox())
+    else if (backingObject->isComboBox())
         objectAttributes = comboBoxAttrs;
-    
-    else if (self.axBackingObject->isProgressIndicator() || self.axBackingObject->isSlider())
+    else if (backingObject->isProgressIndicator() || backingObject->isSlider())
         objectAttributes = rangeAttrs;
-    
     // These are processed in order because an input image is a button, and a button is a control.
-    else if (self.axBackingObject->isInputImage())
+    else if (backingObject->isInputImage())
         objectAttributes = inputImageAttrs;
-    else if (self.axBackingObject->isButton())
+    else if (backingObject->isButton())
         objectAttributes = buttonAttrs;
-    else if (self.axBackingObject->isControl())
+    else if (backingObject->isControl())
         objectAttributes = controlAttrs;
-    
-    else if (self.axBackingObject->isGroup() || self.axBackingObject->isListItem())
+
+    else if (backingObject->isGroup() || backingObject->isListItem())
         objectAttributes = groupAttrs;
-    else if (self.axBackingObject->isTabList())
+    else if (backingObject->isTabList())
         objectAttributes = tabListAttrs;
-    else if (self.axBackingObject->isScrollView())
+    else if (backingObject->isScrollView())
         objectAttributes = scrollViewAttrs;
-    else if (self.axBackingObject->isSpinButton())
+    else if (backingObject->isSpinButton())
         objectAttributes = incrementorAttrs;
-    
-    else if (self.axBackingObject->isMenu())
+    else if (backingObject->isMenu())
         objectAttributes = menuAttrs;
-    else if (self.axBackingObject->isMenuBar())
+    else if (backingObject->isMenuBar())
         objectAttributes = menuBarAttrs;
-    else if (self.axBackingObject->isMenuButton())
+    else if (backingObject->isMenuButton())
         objectAttributes = menuButtonAttrs;
-    else if (self.axBackingObject->isMenuItem())
+    else if (backingObject->isMenuItem())
         objectAttributes = menuItemAttrs;
-    
+
     NSArray *additionalAttributes = [self additionalAccessibilityAttributeNames];
     if ([additionalAttributes count])
         objectAttributes = [objectAttributes arrayByAddingObjectsFromArray:additionalAttributes];
-    
+
     // Only expose AXARIACurrent attribute when the element is set to be current item.
-    if (self.axBackingObject->currentState() != AccessibilityCurrentState::False)
+    if (backingObject->currentState() != AccessibilityCurrentState::False)
         objectAttributes = [objectAttributes arrayByAddingObjectsFromArray:@[ NSAccessibilityARIACurrentAttribute ]];
-    
+
     // AppKit needs to know the screen height in order to do the coordinate conversion.
     objectAttributes = [objectAttributes arrayByAddingObjectsFromArray:@[ NSAccessibilityPrimaryScreenHeightAttribute ]];
-    
+
     return objectAttributes;
 }
 
@@ -2380,214 +2373,216 @@ ALLOW_DEPRECATED_IMPLEMENTATIONS_END
 {
     if (![self updateObjectBackingStore])
         return nil;
-    
-    if (self.axBackingObject->isDetachedFromParent())
+    // FIXME: make updateObjectBackingStore above return the backing object.
+    auto* backingObject = self.axBackingObject;
+
+    if (backingObject->isDetachedFromParent())
         return nil;
-    
+
     if ([attributeName isEqualToString: NSAccessibilityRoleAttribute])
         return [self role];
-    
+
     if ([attributeName isEqualToString: NSAccessibilitySubroleAttribute])
         return [self subrole];
-    
+
     if ([attributeName isEqualToString: NSAccessibilityRoleDescriptionAttribute])
         return [self roleDescription];
 
     // AXARIARole is only used by DumpRenderTree (so far).
     if ([attributeName isEqualToString:@"AXARIARole"])
         return [self computedRoleString];
-    
+
     if ([attributeName isEqualToString: NSAccessibilityParentAttribute]) {
-        
+
         // This will return the parent of the AXWebArea, if this is a web area.
         id scrollViewParent = [self scrollViewParent];
         if (scrollViewParent)
             return scrollViewParent;
-        
+
         // Tree item (changed to AXRows) can only report the tree (AXOutline) as its parent.
-        if (self.axBackingObject->isTreeItem()) {
-            auto parent = self.axBackingObject->parentObjectUnignored();
+        if (backingObject->isTreeItem()) {
+            auto parent = backingObject->parentObjectUnignored();
             while (parent) {
                 if (parent->isTree())
                     return parent->wrapper();
                 parent = parent->parentObjectUnignored();
             }
         }
-        
-        auto parent = self.axBackingObject->parentObjectUnignored();
+
+        auto parent = backingObject->parentObjectUnignored();
         if (!parent)
             return nil;
-        
+
         // In WebKit1, the scroll view is provided by the system (the attachment view), so the parent
         // should be reported directly as such.
-        if (self.axBackingObject->isWebArea() && parent->isAttachment())
+        if (backingObject->isWebArea() && parent->isAttachment())
             return [parent->wrapper() attachmentView];
-        
+
         return parent->wrapper();
     }
-    
+
     if ([attributeName isEqualToString: NSAccessibilityChildrenAttribute] || [attributeName isEqualToString: NSAccessibilityChildrenInNavigationOrderAttribute]) {
         if (!self.childrenVectorSize) {
             NSArray* children = [self renderWidgetChildren];
             if (children != nil)
                 return children;
         }
-        
+
         // The tree's (AXOutline) children are supposed to be its rows and columns.
         // The ARIA spec doesn't have columns, so we just need rows.
-        if (self.axBackingObject->isTree())
+        if (backingObject->isTree())
             return [self accessibilityAttributeValue:NSAccessibilityRowsAttribute];
-        
+
         // A tree item should only expose its content as its children (not its rows)
-        if (self.axBackingObject->isTreeItem()) {
+        if (backingObject->isTreeItem()) {
             AccessibilityObject::AccessibilityChildrenVector contentCopy;
-            self.axBackingObject->ariaTreeItemContent(contentCopy);
+            backingObject->ariaTreeItemContent(contentCopy);
             return convertToNSArray(contentCopy);
         }
-        
+
         return self.childrenVectorArray;
     }
-    
+
     if ([attributeName isEqualToString: NSAccessibilitySelectedChildrenAttribute]) {
-        if (self.axBackingObject->canHaveSelectedChildren()) {
+        if (backingObject->canHaveSelectedChildren()) {
             AccessibilityObject::AccessibilityChildrenVector selectedChildrenCopy;
-            self.axBackingObject->selectedChildren(selectedChildrenCopy);
+            backingObject->selectedChildren(selectedChildrenCopy);
             return convertToNSArray(selectedChildrenCopy);
         }
         return nil;
     }
-    
+
     if ([attributeName isEqualToString: NSAccessibilityVisibleChildrenAttribute]) {
-        if (self.axBackingObject->isListBox()) {
+        if (backingObject->isListBox()) {
             AccessibilityObject::AccessibilityChildrenVector visibleChildrenCopy;
-            self.axBackingObject->visibleChildren(visibleChildrenCopy);
+            backingObject->visibleChildren(visibleChildrenCopy);
             return convertToNSArray(visibleChildrenCopy);
         }
 
-        if (self.axBackingObject->isList())
+        if (backingObject->isList())
             return [self accessibilityAttributeValue:NSAccessibilityChildrenAttribute];
 
         return nil;
     }
-    
-    
-    if (self.axBackingObject->isWebArea()) {
+
+
+    if (backingObject->isWebArea()) {
         if ([attributeName isEqualToString:@"AXLinkUIElements"]) {
             AccessibilityObject::AccessibilityChildrenVector links;
-            downcast<AccessibilityRenderObject>(*self.axBackingObject).getDocumentLinks(links);
+            downcast<AccessibilityRenderObject>(*backingObject).getDocumentLinks(links);
             return convertToNSArray(links);
         }
         if ([attributeName isEqualToString:@"AXLoaded"])
-            return [NSNumber numberWithBool:self.axBackingObject->isLoaded()];
+            return [NSNumber numberWithBool:backingObject->isLoaded()];
         if ([attributeName isEqualToString:@"AXLayoutCount"])
-            return [NSNumber numberWithInt:self.axBackingObject->layoutCount()];
+            return [NSNumber numberWithInt:backingObject->layoutCount()];
         if ([attributeName isEqualToString:NSAccessibilityLoadingProgressAttribute])
-            return [NSNumber numberWithDouble:self.axBackingObject->estimatedLoadingProgress()];
+            return [NSNumber numberWithDouble:backingObject->estimatedLoadingProgress()];
         if ([attributeName isEqualToString:NSAccessibilityPreventKeyboardDOMEventDispatchAttribute])
-            return [NSNumber numberWithBool:self.axBackingObject->preventKeyboardDOMEventDispatch()];
+            return [NSNumber numberWithBool:backingObject->preventKeyboardDOMEventDispatch()];
         if ([attributeName isEqualToString:NSAccessibilityCaretBrowsingEnabledAttribute])
-            return [NSNumber numberWithBool:self.axBackingObject->caretBrowsingEnabled()];
+            return [NSNumber numberWithBool:backingObject->caretBrowsingEnabled()];
         if ([attributeName isEqualToString:NSAccessibilityWebSessionIDAttribute])
-            return @(self.axBackingObject->sessionID());
+            return @(backingObject->sessionID());
     }
-    
-    if (self.axBackingObject->isTextControl()) {
+
+    if (backingObject->isTextControl()) {
         if ([attributeName isEqualToString: NSAccessibilityNumberOfCharactersAttribute]) {
-            int length = self.axBackingObject->textLength();
+            int length = backingObject->textLength();
             if (length < 0)
                 return nil;
             return [NSNumber numberWithUnsignedInt:length];
         }
         if ([attributeName isEqualToString: NSAccessibilitySelectedTextAttribute]) {
-            String selectedText = self.axBackingObject->selectedText();
+            String selectedText = backingObject->selectedText();
             if (selectedText.isNull())
                 return nil;
             return (NSString*)selectedText;
         }
         if ([attributeName isEqualToString: NSAccessibilitySelectedTextRangeAttribute]) {
-            PlainTextRange textRange = self.axBackingObject->selectedTextRange();
+            PlainTextRange textRange = backingObject->selectedTextRange();
             return [NSValue valueWithRange:NSMakeRange(textRange.start, textRange.length)];
         }
         // TODO: Get actual visible range. <rdar://problem/4712101>
         if ([attributeName isEqualToString: NSAccessibilityVisibleCharacterRangeAttribute])
-            return self.axBackingObject->isPasswordField() ? nil : [NSValue valueWithRange: NSMakeRange(0, self.axBackingObject->textLength())];
+            return backingObject->isPasswordField() ? nil : [NSValue valueWithRange: NSMakeRange(0, backingObject->textLength())];
         if ([attributeName isEqualToString: NSAccessibilityInsertionPointLineNumberAttribute]) {
             // if selectionEnd > 0, then there is selected text and this question should not be answered
-            if (self.axBackingObject->isPasswordField() || self.axBackingObject->selectionEnd() > 0)
+            if (backingObject->isPasswordField() || backingObject->selectionEnd() > 0)
                 return nil;
-            
-            auto focusedObject = downcast<AccessibilityObject>(self.axBackingObject->focusedUIElement());
-            if (focusedObject != self.axBackingObject)
+
+            auto focusedObject = downcast<AccessibilityObject>(backingObject->focusedUIElement());
+            if (focusedObject != backingObject)
                 return nil;
-            
+
             VisiblePosition focusedPosition = focusedObject->visiblePositionForIndex(focusedObject->selectionStart(), true);
-            int lineNumber = self.axBackingObject->lineForPosition(focusedPosition);
+            int lineNumber = backingObject->lineForPosition(focusedPosition);
             if (lineNumber < 0)
                 return nil;
-            
+
             return [NSNumber numberWithInt:lineNumber];
         }
     }
-    
+
     if ([attributeName isEqualToString: NSAccessibilityURLAttribute]) {
-        URL url = self.axBackingObject->url();
+        URL url = backingObject->url();
         if (url.isNull())
             return nil;
         return (NSURL*)url;
     }
 
     if ([attributeName isEqualToString:NSAccessibilityIncrementButtonAttribute]) {
-        auto incrementButton = self.axBackingObject->incrementButton();
+        auto incrementButton = backingObject->incrementButton();
         return incrementButton ? incrementButton->wrapper() : nil;
     }
 
     if ([attributeName isEqualToString:NSAccessibilityDecrementButtonAttribute]) {
-        auto decrementButton = self.axBackingObject->decrementButton();
+        auto decrementButton = backingObject->decrementButton();
         return decrementButton ? decrementButton->wrapper() : nil;
     }
 
     if ([attributeName isEqualToString: @"AXVisited"])
-        return [NSNumber numberWithBool: self.axBackingObject->isVisited()];
-    
+        return [NSNumber numberWithBool: backingObject->isVisited()];
+
     if ([attributeName isEqualToString: NSAccessibilityTitleAttribute]) {
-        if (self.axBackingObject->isAttachment()) {
+        if (backingObject->isAttachment()) {
             if ([[[self attachmentView] accessibilityAttributeNames] containsObject:NSAccessibilityTitleAttribute])
                 return [[self attachmentView] accessibilityAttributeValue:NSAccessibilityTitleAttribute];
         }
-        
+
         // Meter elements should communicate their content via AXValueDescription.
-        if (self.axBackingObject->isMeter())
+        if (backingObject->isMeter())
             return [NSString string];
-        
+
         // Summary element should use its text node as AXTitle.
-        if (self.axBackingObject->isSummary())
-            return self.axBackingObject->textUnderElement();
-        
+        if (backingObject->isSummary())
+            return backingObject->textUnderElement();
+
         return [self baseAccessibilityTitle];
     }
-    
+
     if ([attributeName isEqualToString: NSAccessibilityDescriptionAttribute]) {
-        if (self.axBackingObject->isAttachment()) {
+        if (backingObject->isAttachment()) {
             if ([[[self attachmentView] accessibilityAttributeNames] containsObject:NSAccessibilityDescriptionAttribute])
                 return [[self attachmentView] accessibilityAttributeValue:NSAccessibilityDescriptionAttribute];
         }
         return [self baseAccessibilityDescription];
     }
-    
+
     if ([attributeName isEqualToString: NSAccessibilityValueAttribute]) {
-        if (self.axBackingObject->isAttachment()) {
+        if (backingObject->isAttachment()) {
             if ([[[self attachmentView] accessibilityAttributeNames] containsObject:NSAccessibilityValueAttribute])
                 return [[self attachmentView] accessibilityAttributeValue:NSAccessibilityValueAttribute];
         }
-        if (self.axBackingObject->supportsRangeValue())
-            return [NSNumber numberWithFloat:self.axBackingObject->valueForRange()];
-        if (self.axBackingObject->roleValue() == AccessibilityRole::SliderThumb)
-            return [NSNumber numberWithFloat:self.axBackingObject->parentObject()->valueForRange()];
-        if (self.axBackingObject->isHeading())
-            return [NSNumber numberWithInt:self.axBackingObject->headingLevel()];
-        
-        if (self.axBackingObject->isCheckboxOrRadio() || self.axBackingObject->isMenuItem() || self.axBackingObject->isSwitch() || self.axBackingObject->isToggleButton()) {
-            switch (self.axBackingObject->checkboxOrRadioValue()) {
+        if (backingObject->supportsRangeValue())
+            return [NSNumber numberWithFloat:backingObject->valueForRange()];
+        if (backingObject->roleValue() == AccessibilityRole::SliderThumb)
+            return [NSNumber numberWithFloat:backingObject->parentObject()->valueForRange()];
+        if (backingObject->isHeading())
+            return [NSNumber numberWithInt:backingObject->headingLevel()];
+
+        if (backingObject->isCheckboxOrRadio() || backingObject->isMenuItem() || backingObject->isSwitch() || backingObject->isToggleButton()) {
+            switch (backingObject->checkboxOrRadioValue()) {
             case AccessibilityButtonState::Off:
                 return [NSNumber numberWithInt:0];
             case AccessibilityButtonState::On:
@@ -2596,67 +2591,67 @@ ALLOW_DEPRECATED_IMPLEMENTATIONS_END
                 return [NSNumber numberWithInt:2];
             }
         }
-        
+
         // radio groups return the selected radio button as the AXValue
-        if (self.axBackingObject->isRadioGroup()) {
-            AXCoreObject* radioButton = self.axBackingObject->selectedRadioButton();
+        if (backingObject->isRadioGroup()) {
+            AXCoreObject* radioButton = backingObject->selectedRadioButton();
             if (!radioButton)
                 return nil;
             return radioButton->wrapper();
         }
-        
-        if (self.axBackingObject->isTabList()) {
-            AXCoreObject* tabItem = self.axBackingObject->selectedTabItem();
+
+        if (backingObject->isTabList()) {
+            AXCoreObject* tabItem = backingObject->selectedTabItem();
             if (!tabItem)
                 return nil;
             return tabItem->wrapper();
         }
-        
-        if (self.axBackingObject->isTabItem())
-            return [NSNumber numberWithInt:self.axBackingObject->isSelected()];
-        
-        if (self.axBackingObject->isColorWell()) {
+
+        if (backingObject->isTabItem())
+            return [NSNumber numberWithInt:backingObject->isSelected()];
+
+        if (backingObject->isColorWell()) {
             int r, g, b;
-            self.axBackingObject->colorValue(r, g, b);
+            backingObject->colorValue(r, g, b);
             return [NSString stringWithFormat:@"rgb %7.5f %7.5f %7.5f 1", r / 255., g / 255., b / 255.];
         }
-        
-        return self.axBackingObject->stringValue();
+
+        return backingObject->stringValue();
     }
 
     if ([attributeName isEqualToString:(NSString *)kAXMenuItemMarkCharAttribute]) {
         const unichar ch = 0x2713; // ✓ used on Mac for selected menu items.
-        return (self.axBackingObject->isChecked()) ? [NSString stringWithCharacters:&ch length:1] : nil;
+        return (backingObject->isChecked()) ? [NSString stringWithCharacters:&ch length:1] : nil;
     }
-    
+
     if ([attributeName isEqualToString: NSAccessibilityMinValueAttribute]) {
         // Indeterminate progress indicator should return 0.
-        if (self.axBackingObject->ariaRoleAttribute() == AccessibilityRole::ProgressIndicator && !self.axBackingObject->hasARIAValueNow())
+        if (backingObject->ariaRoleAttribute() == AccessibilityRole::ProgressIndicator && !backingObject->hasARIAValueNow())
             return @0;
-        return [NSNumber numberWithFloat:self.axBackingObject->minValueForRange()];
+        return [NSNumber numberWithFloat:backingObject->minValueForRange()];
     }
-    
+
     if ([attributeName isEqualToString: NSAccessibilityMaxValueAttribute]) {
         // Indeterminate progress indicator should return 0.
-        if (self.axBackingObject->ariaRoleAttribute() == AccessibilityRole::ProgressIndicator && !self.axBackingObject->hasARIAValueNow())
+        if (backingObject->ariaRoleAttribute() == AccessibilityRole::ProgressIndicator && !backingObject->hasARIAValueNow())
             return @0;
-        return [NSNumber numberWithFloat:self.axBackingObject->maxValueForRange()];
+        return [NSNumber numberWithFloat:backingObject->maxValueForRange()];
     }
-    
+
     if ([attributeName isEqualToString: NSAccessibilityHelpAttribute])
         return [self baseAccessibilityHelpText];
-    
+
     if ([attributeName isEqualToString: NSAccessibilityFocusedAttribute])
-        return [NSNumber numberWithBool: self.axBackingObject->isFocused()];
-    
+        return [NSNumber numberWithBool: backingObject->isFocused()];
+
     if ([attributeName isEqualToString: NSAccessibilityEnabledAttribute])
-        return [NSNumber numberWithBool: self.axBackingObject->isEnabled()];
-    
+        return [NSNumber numberWithBool: backingObject->isEnabled()];
+
     if ([attributeName isEqualToString: NSAccessibilitySizeAttribute]) {
-        IntSize s = snappedIntRect(self.axBackingObject->elementRect()).size();
+        IntSize s = snappedIntRect(backingObject->elementRect()).size();
         return [NSValue valueWithSize: NSMakeSize(s.width(), s.height())];
     }
-    
+
     if ([attributeName isEqualToString: NSAccessibilityPrimaryScreenHeightAttribute])
         return [self primaryScreenHeight];
     if ([attributeName isEqualToString: NSAccessibilityPositionAttribute])
@@ -2669,29 +2664,29 @@ ALLOW_DEPRECATED_IMPLEMENTATIONS_END
         return [self windowElement:attributeName];
 
     if ([attributeName isEqualToString:NSAccessibilityAccessKeyAttribute]) {
-        AtomString accessKey = self.axBackingObject->accessKey();
+        AtomString accessKey = backingObject->accessKey();
         if (accessKey.isNull())
             return nil;
         return accessKey;
     }
-    
+
     if ([attributeName isEqualToString:NSAccessibilityLinkRelationshipTypeAttribute])
-        return self.axBackingObject->linkRelValue();
-    
+        return backingObject->linkRelValue();
+
     if ([attributeName isEqualToString:NSAccessibilityTabsAttribute]) {
-        if (self.axBackingObject->isTabList()) {
+        if (backingObject->isTabList()) {
             AccessibilityObject::AccessibilityChildrenVector tabsChildren;
-            self.axBackingObject->tabChildren(tabsChildren);
+            backingObject->tabChildren(tabsChildren);
             return convertToNSArray(tabsChildren);
         }
     }
-    
+
     if ([attributeName isEqualToString:NSAccessibilityContentsAttribute]) {
         // The contents of a tab list are all the children except the tabs.
-        if (self.axBackingObject->isTabList()) {
+        if (backingObject->isTabList()) {
             auto children = self.childrenVectorArray;
             AccessibilityObject::AccessibilityChildrenVector tabs;
-            self.axBackingObject->tabChildren(tabs);
+            backingObject->tabChildren(tabs);
             auto tabsChildren = convertToNSArray(tabs);
 
             NSMutableArray *contents = [NSMutableArray array];
@@ -2702,7 +2697,7 @@ ALLOW_DEPRECATED_IMPLEMENTATIONS_END
             return contents;
         }
 
-        if (self.axBackingObject->isScrollView()) {
+        if (backingObject->isScrollView()) {
             // A scrollView's contents are everything except the scroll bars.
             auto children = self.childrenVectorArray;
             NSMutableArray *contents = [NSMutableArray array];
@@ -2716,78 +2711,62 @@ ALLOW_DEPRECATED_IMPLEMENTATIONS_END
             return contents;
         }
     }
-    
-    if (is<AccessibilityTable>(*self.axBackingObject) && downcast<AccessibilityTable>(*self.axBackingObject).isExposableThroughAccessibility()) {
-        auto& table = downcast<AccessibilityTable>(*self.axBackingObject);
+
+    if (backingObject->isTable() && backingObject->isExposable()) {
         if ([attributeName isEqualToString:NSAccessibilityRowsAttribute])
-            return convertToNSArray(table.rows());
-        
-        if ([attributeName isEqualToString:NSAccessibilityVisibleRowsAttribute]) {
-            AccessibilityObject::AccessibilityChildrenVector visibleRows;
-            table.visibleRows(visibleRows);
-            return convertToNSArray(visibleRows);
-        }
-        
+            return convertToNSArray(backingObject->rows());
+
+        if ([attributeName isEqualToString:NSAccessibilityVisibleRowsAttribute])
+            return convertToNSArray(backingObject->visibleRows());
+
         // TODO: distinguish between visible and non-visible columns
-        if ([attributeName isEqualToString:NSAccessibilityColumnsAttribute] ||
-            [attributeName isEqualToString:NSAccessibilityVisibleColumnsAttribute]) {
-            return convertToNSArray(table.columns());
-        }
-        
+        if ([attributeName isEqualToString:NSAccessibilityColumnsAttribute]
+            || [attributeName isEqualToString:NSAccessibilityVisibleColumnsAttribute])
+            return convertToNSArray(backingObject->columns());
+
         if ([attributeName isEqualToString:NSAccessibilitySelectedRowsAttribute]) {
             AccessibilityObject::AccessibilityChildrenVector selectedChildrenCopy;
-            self.axBackingObject->selectedChildren(selectedChildrenCopy);
+            backingObject->selectedChildren(selectedChildrenCopy);
             return convertToNSArray(selectedChildrenCopy);
         }
-        
-        // HTML tables don't support these
-        if ([attributeName isEqualToString:NSAccessibilitySelectedColumnsAttribute] ||
-            [attributeName isEqualToString:NSAccessibilitySelectedCellsAttribute])
+
+        // HTML tables don't support these attributes.
+        if ([attributeName isEqualToString:NSAccessibilitySelectedColumnsAttribute]
+            || [attributeName isEqualToString:NSAccessibilitySelectedCellsAttribute])
             return nil;
-        
-        if ([attributeName isEqualToString:NSAccessibilityColumnHeaderUIElementsAttribute]) {
-            AccessibilityObject::AccessibilityChildrenVector columnHeaders;
-            table.columnHeaders(columnHeaders);
-            return convertToNSArray(columnHeaders);
-        }
-        
+
+        if ([attributeName isEqualToString:NSAccessibilityColumnHeaderUIElementsAttribute])
+            return convertToNSArray(backingObject->columnHeaders());
+
         if ([attributeName isEqualToString:NSAccessibilityHeaderAttribute]) {
-            AccessibilityObject* headerContainer = table.headerContainer();
-            if (headerContainer)
-                return headerContainer->wrapper();
-            return nil;
-        }
-        
-        if ([attributeName isEqualToString:NSAccessibilityRowHeaderUIElementsAttribute]) {
-            AccessibilityObject::AccessibilityChildrenVector rowHeaders;
-            table.rowHeaders(rowHeaders);
-            return convertToNSArray(rowHeaders);
+            auto* headerContainer = backingObject->headerContainer();
+            return headerContainer ? headerContainer->wrapper() : nil;
         }
-        
-        if ([attributeName isEqualToString:NSAccessibilityVisibleCellsAttribute]) {
-            AccessibilityObject::AccessibilityChildrenVector cells;
-            table.cells(cells);
-            return convertToNSArray(cells);
-        }
-        
+
+        if ([attributeName isEqualToString:NSAccessibilityRowHeaderUIElementsAttribute])
+            return convertToNSArray(backingObject->rowHeaders());
+
+        if ([attributeName isEqualToString:NSAccessibilityVisibleCellsAttribute])
+            return convertToNSArray(backingObject->cells());
+
         if ([attributeName isEqualToString:NSAccessibilityColumnCountAttribute])
-            return @(table.columnCount());
-        
+            return @(backingObject->columnCount());
+
         if ([attributeName isEqualToString:NSAccessibilityRowCountAttribute])
-            return @(table.rowCount());
-        
+            return @(backingObject->rowCount());
+
         if ([attributeName isEqualToString:NSAccessibilityARIAColumnCountAttribute])
-            return @(table.axColumnCount());
-        
+            return @(backingObject->axColumnCount());
+
         if ([attributeName isEqualToString:NSAccessibilityARIARowCountAttribute])
-            return @(table.axRowCount());
+            return @(backingObject->axRowCount());
     }
-    
-    if (is<AccessibilityTableColumn>(*self.axBackingObject)) {
-        auto& column = downcast<AccessibilityTableColumn>(*self.axBackingObject);
+
+    if (is<AccessibilityTableColumn>(*backingObject)) {
+        auto& column = downcast<AccessibilityTableColumn>(*backingObject);
         if ([attributeName isEqualToString:NSAccessibilityIndexAttribute])
             return [NSNumber numberWithInt:column.columnIndex()];
-        
+
         // rows attribute for a column is the list of all the elements in that column at each row
         if ([attributeName isEqualToString:NSAccessibilityRowsAttribute] ||
             [attributeName isEqualToString:NSAccessibilityVisibleRowsAttribute]) {
@@ -2800,9 +2779,9 @@ ALLOW_DEPRECATED_IMPLEMENTATIONS_END
             return header->wrapper();
         }
     }
-    
-    if (is<AccessibilityTableCell>(*self.axBackingObject)) {
-        auto& cell = downcast<AccessibilityTableCell>(*self.axBackingObject);
+
+    if (is<AccessibilityTableCell>(*backingObject)) {
+        auto& cell = downcast<AccessibilityTableCell>(*backingObject);
         if ([attributeName isEqualToString:NSAccessibilityRowIndexRangeAttribute]) {
             std::pair<unsigned, unsigned> rowRange;
             cell.rowIndexRange(rowRange);
@@ -2813,49 +2792,45 @@ ALLOW_DEPRECATED_IMPLEMENTATIONS_END
             cell.columnIndexRange(columnRange);
             return [NSValue valueWithRange:NSMakeRange(columnRange.first, columnRange.second)];
         }
-        if ([attributeName isEqualToString:NSAccessibilityColumnHeaderUIElementsAttribute]) {
-            AccessibilityObject::AccessibilityChildrenVector columnHeaders;
-            cell.columnHeaders(columnHeaders);
-            return convertToNSArray(columnHeaders);
-        }
-        if ([attributeName isEqualToString:NSAccessibilityRowHeaderUIElementsAttribute]) {
-            AccessibilityObject::AccessibilityChildrenVector rowHeaders;
-            cell.rowHeaders(rowHeaders);
-            return convertToNSArray(rowHeaders);
-        }
+        if ([attributeName isEqualToString:NSAccessibilityColumnHeaderUIElementsAttribute])
+            return convertToNSArray(cell.columnHeaders());
+
+        if ([attributeName isEqualToString:NSAccessibilityRowHeaderUIElementsAttribute])
+            return convertToNSArray(cell.rowHeaders());
+
         if ([attributeName isEqualToString:NSAccessibilityARIAColumnIndexAttribute])
             return @(cell.axColumnIndex());
-        
+
         if ([attributeName isEqualToString:NSAccessibilityARIARowIndexAttribute])
             return @(cell.axRowIndex());
     }
-    
-    if (self.axBackingObject->isTree()) {
+
+    if (backingObject->isTree()) {
         if ([attributeName isEqualToString:NSAccessibilitySelectedRowsAttribute]) {
             AccessibilityObject::AccessibilityChildrenVector selectedChildrenCopy;
-            self.axBackingObject->selectedChildren(selectedChildrenCopy);
+            backingObject->selectedChildren(selectedChildrenCopy);
             return convertToNSArray(selectedChildrenCopy);
         }
         if ([attributeName isEqualToString:NSAccessibilityRowsAttribute]) {
             AccessibilityObject::AccessibilityChildrenVector rowsCopy;
-            self.axBackingObject->ariaTreeRows(rowsCopy);
+            backingObject->ariaTreeRows(rowsCopy);
             return convertToNSArray(rowsCopy);
         }
-        
+
         // TreeRoles do not support columns, but Mac AX expects to be able to ask about columns at the least.
         if ([attributeName isEqualToString:NSAccessibilityColumnsAttribute])
             return [NSArray array];
     }
-    
+
     if ([attributeName isEqualToString:NSAccessibilityIndexAttribute]) {
-        if (self.axBackingObject->isTreeItem()) {
-            AXCoreObject* parent = self.axBackingObject->parentObject();
+        if (backingObject->isTreeItem()) {
+            AXCoreObject* parent = backingObject->parentObject();
             for (; parent && !parent->isTree(); parent = parent->parentObject())
             { }
-            
+
             if (!parent)
                 return nil;
-            
+
             // Find the index of this item by iterating the parents.
             AccessibilityObject::AccessibilityChildrenVector rowsCopy;
             parent->ariaTreeRows(rowsCopy);
@@ -2863,34 +2838,34 @@ ALLOW_DEPRECATED_IMPLEMENTATIONS_END
             for (size_t k = 0; k < count; ++k)
                 if (rowsCopy[k]->wrapper() == self)
                     return [NSNumber numberWithUnsignedInt:k];
-            
+
             return nil;
         }
-        if (is<AccessibilityTableRow>(*self.axBackingObject)) {
+        if (is<AccessibilityTableRow>(*backingObject)) {
             if ([attributeName isEqualToString:NSAccessibilityIndexAttribute])
-                return [NSNumber numberWithInt:downcast<AccessibilityTableRow>(*self.axBackingObject).rowIndex()];
+                return [NSNumber numberWithInt:downcast<AccessibilityTableRow>(*backingObject).rowIndex()];
         }
     }
-    
+
     // The rows that are considered inside this row.
     if ([attributeName isEqualToString:NSAccessibilityDisclosedRowsAttribute]) {
-        if (self.axBackingObject->isTreeItem()) {
+        if (backingObject->isTreeItem()) {
             AccessibilityObject::AccessibilityChildrenVector rowsCopy;
-            self.axBackingObject->ariaTreeItemDisclosedRows(rowsCopy);
+            backingObject->ariaTreeItemDisclosedRows(rowsCopy);
             return convertToNSArray(rowsCopy);
         }
 
-        if (is<AccessibilityARIAGridRow>(*self.axBackingObject)) {
+        if (is<AccessibilityARIAGridRow>(*backingObject)) {
             AccessibilityObject::AccessibilityChildrenVector rowsCopy;
-            downcast<AccessibilityARIAGridRow>(*self.axBackingObject).disclosedRows(rowsCopy);
+            downcast<AccessibilityARIAGridRow>(*backingObject).disclosedRows(rowsCopy);
             return convertToNSArray(rowsCopy);
         }
     }
-    
+
     // The row that contains this row. It should be the same as the first parent that is a treeitem.
     if ([attributeName isEqualToString:NSAccessibilityDisclosedByRowAttribute]) {
-        if (self.axBackingObject->isTreeItem()) {
-            AXCoreObject* parent = self.axBackingObject->parentObject();
+        if (backingObject->isTreeItem()) {
+            AXCoreObject* parent = backingObject->parentObject();
             while (parent) {
                 if (parent->isTreeItem())
                     return parent->wrapper();
@@ -2902,76 +2877,76 @@ ALLOW_DEPRECATED_IMPLEMENTATIONS_END
             return nil;
         }
 
-        if (is<AccessibilityARIAGridRow>(*self.axBackingObject)) {
-            AXCoreObject* row = downcast<AccessibilityARIAGridRow>(*self.axBackingObject).disclosedByRow();
+        if (is<AccessibilityARIAGridRow>(*backingObject)) {
+            AXCoreObject* row = downcast<AccessibilityARIAGridRow>(*backingObject).disclosedByRow();
             if (!row)
                 return nil;
             return row->wrapper();
         }
     }
-    
+
     if ([attributeName isEqualToString:NSAccessibilityDisclosureLevelAttribute]) {
         // Convert from 1-based level (from aria-level spec) to 0-based level (Mac)
-        int level = self.axBackingObject->hierarchicalLevel();
+        int level = backingObject->hierarchicalLevel();
         if (level > 0)
             level -= 1;
         return [NSNumber numberWithInt:level];
     }
     if ([attributeName isEqualToString:NSAccessibilityDisclosingAttribute])
-        return [NSNumber numberWithBool:self.axBackingObject->isExpanded()];
-    
-    if (self.axBackingObject->isList() && [attributeName isEqualToString:NSAccessibilityOrientationAttribute])
+        return [NSNumber numberWithBool:backingObject->isExpanded()];
+
+    if (backingObject->isList() && [attributeName isEqualToString:NSAccessibilityOrientationAttribute])
         return NSAccessibilityVerticalOrientationValue;
-    
+
     if ([attributeName isEqualToString: @"AXSelectedTextMarkerRange"])
         return [self textMarkerRangeForSelection];
-    
+
     if ([attributeName isEqualToString: @"AXStartTextMarker"])
-        return [self textMarkerForVisiblePosition:startOfDocument(self.axBackingObject->document())];
+        return [self textMarkerForVisiblePosition:startOfDocument(backingObject->document())];
     if ([attributeName isEqualToString: @"AXEndTextMarker"])
-        return [self textMarkerForVisiblePosition:endOfDocument(self.axBackingObject->document())];
-    
+        return [self textMarkerForVisiblePosition:endOfDocument(backingObject->document())];
+
     if ([attributeName isEqualToString:NSAccessibilityBlockQuoteLevelAttribute])
-        return [NSNumber numberWithUnsignedInt:self.axBackingObject->blockquoteLevel()];
+        return [NSNumber numberWithUnsignedInt:backingObject->blockquoteLevel()];
     if ([attributeName isEqualToString:@"AXTableLevel"])
-        return [NSNumber numberWithInt:self.axBackingObject->tableLevel()];
-    
+        return [NSNumber numberWithInt:backingObject->tableLevel()];
+
     if ([attributeName isEqualToString: NSAccessibilityLinkedUIElementsAttribute]) {
         AccessibilityObject::AccessibilityChildrenVector linkedUIElements;
-        self.axBackingObject->linkedUIElements(linkedUIElements);
+        backingObject->linkedUIElements(linkedUIElements);
         return convertToNSArray(linkedUIElements);
     }
-    
+
     if ([attributeName isEqualToString: NSAccessibilitySelectedAttribute])
-        return [NSNumber numberWithBool:self.axBackingObject->isSelected()];
-    
+        return [NSNumber numberWithBool:backingObject->isSelected()];
+
     if ([attributeName isEqualToString: NSAccessibilityARIACurrentAttribute])
-        return self.axBackingObject->currentValue();
-    
-    if ([attributeName isEqualToString: NSAccessibilityServesAsTitleForUIElementsAttribute] && self.axBackingObject->isMenuButton()) {
-        AccessibilityObject* uiElement = downcast<AccessibilityRenderObject>(*self.axBackingObject).menuForMenuButton();
+        return backingObject->currentValue();
+
+    if ([attributeName isEqualToString: NSAccessibilityServesAsTitleForUIElementsAttribute] && backingObject->isMenuButton()) {
+        AccessibilityObject* uiElement = downcast<AccessibilityRenderObject>(*backingObject).menuForMenuButton();
         if (uiElement)
             return [NSArray arrayWithObject:uiElement->wrapper()];
     }
-    
+
     if ([attributeName isEqualToString:NSAccessibilityTitleUIElementAttribute]) {
-        if (!self.axBackingObject->exposesTitleUIElement())
+        if (!backingObject->exposesTitleUIElement())
             return nil;
 
-        AXCoreObject* obj = self.axBackingObject->titleUIElement();
+        AXCoreObject* obj = backingObject->titleUIElement();
         if (obj)
             return obj->wrapper();
         return nil;
     }
-    
+
     if ([attributeName isEqualToString:NSAccessibilityValueDescriptionAttribute]) {
-        if (self.axBackingObject->isMeter())
+        if (backingObject->isMeter())
             return [self valueDescriptionForMeter];
-        return self.axBackingObject->valueDescription();
+        return backingObject->valueDescription();
     }
-    
+
     if ([attributeName isEqualToString:NSAccessibilityOrientationAttribute]) {
-        AccessibilityOrientation elementOrientation = self.axBackingObject->orientation();
+        AccessibilityOrientation elementOrientation = backingObject->orientation();
         if (elementOrientation == AccessibilityOrientation::Vertical)
             return NSAccessibilityVerticalOrientationValue;
         if (elementOrientation == AccessibilityOrientation::Horizontal)
@@ -2980,22 +2955,22 @@ ALLOW_DEPRECATED_IMPLEMENTATIONS_END
             return NSAccessibilityUnknownOrientationValue;
         return nil;
     }
-    
+
     if ([attributeName isEqualToString:NSAccessibilityHorizontalScrollBarAttribute]) {
-        AXCoreObject* scrollBar = self.axBackingObject->scrollBar(AccessibilityOrientation::Horizontal);
+        AXCoreObject* scrollBar = backingObject->scrollBar(AccessibilityOrientation::Horizontal);
         if (scrollBar)
             return scrollBar->wrapper();
         return nil;
     }
     if ([attributeName isEqualToString:NSAccessibilityVerticalScrollBarAttribute]) {
-        AXCoreObject* scrollBar = self.axBackingObject->scrollBar(AccessibilityOrientation::Vertical);
+        AXCoreObject* scrollBar = backingObject->scrollBar(AccessibilityOrientation::Vertical);
         if (scrollBar)
             return scrollBar->wrapper();
         return nil;
     }
-    
+
     if ([attributeName isEqualToString:NSAccessibilitySortDirectionAttribute]) {
-        switch (self.axBackingObject->sortDirection()) {
+        switch (backingObject->sortDirection()) {
         case AccessibilitySortDirection::Ascending:
             return NSAccessibilityAscendingSortDirectionValue;
         case AccessibilitySortDirection::Descending:
@@ -3004,46 +2979,46 @@ ALLOW_DEPRECATED_IMPLEMENTATIONS_END
             return NSAccessibilityUnknownSortDirectionValue;
         }
     }
-    
+
     if ([attributeName isEqualToString:NSAccessibilityLanguageAttribute])
-        return self.axBackingObject->language();
-    
+        return backingObject->language();
+
     if ([attributeName isEqualToString:NSAccessibilityExpandedAttribute])
-        return [NSNumber numberWithBool:self.axBackingObject->isExpanded()];
-    
+        return [NSNumber numberWithBool:backingObject->isExpanded()];
+
     if ([attributeName isEqualToString:NSAccessibilityRequiredAttribute])
-        return [NSNumber numberWithBool:self.axBackingObject->isRequired()];
-    
+        return [NSNumber numberWithBool:backingObject->isRequired()];
+
     if ([attributeName isEqualToString:NSAccessibilityInvalidAttribute])
-        return self.axBackingObject->invalidStatus();
-    
+        return backingObject->invalidStatus();
+
     if ([attributeName isEqualToString:NSAccessibilityOwnsAttribute]) {
         AccessibilityObject::AccessibilityChildrenVector ariaOwns;
-        self.axBackingObject->ariaOwnsElements(ariaOwns);
+        backingObject->ariaOwnsElements(ariaOwns);
         return convertToNSArray(ariaOwns);
     }
-    
+
     if ([attributeName isEqualToString:NSAccessibilityARIAPosInSetAttribute])
-        return [NSNumber numberWithInt:self.axBackingObject->posInSet()];
+        return [NSNumber numberWithInt:backingObject->posInSet()];
     if ([attributeName isEqualToString:NSAccessibilityARIASetSizeAttribute])
-        return [NSNumber numberWithInt:self.axBackingObject->setSize()];
-    
+        return [NSNumber numberWithInt:backingObject->setSize()];
+
     if ([attributeName isEqualToString:NSAccessibilityGrabbedAttribute])
-        return [NSNumber numberWithBool:self.axBackingObject->isARIAGrabbed()];
-    
+        return [NSNumber numberWithBool:backingObject->isARIAGrabbed()];
+
     if ([attributeName isEqualToString:NSAccessibilityDropEffectsAttribute]) {
-        Vector<String> dropEffects = self.axBackingObject->determineARIADropEffects();
+        Vector<String> dropEffects = backingObject->determineARIADropEffects();
         return convertStringsToNSArray(dropEffects);
     }
-    
+
     if ([attributeName isEqualToString:NSAccessibilityPlaceholderValueAttribute])
-        return self.axBackingObject->placeholderValue();
+        return backingObject->placeholderValue();
 
     if ([attributeName isEqualToString:NSAccessibilityValueAutofillAvailableAttribute])
-        return @(self.axBackingObject->isValueAutofillAvailable());
-    
+        return @(backingObject->isValueAutofillAvailable());
+
     if ([attributeName isEqualToString:NSAccessibilityValueAutofillTypeAttribute]) {
-        switch (self.axBackingObject->valueAutofillButtonType()) {
+        switch (backingObject->valueAutofillButtonType()) {
         case AutoFillButtonType::None:
             return @"none";
         case AutoFillButtonType::Credentials:
@@ -3056,154 +3031,154 @@ ALLOW_DEPRECATED_IMPLEMENTATIONS_END
             return @"credit card";
         }
     }
-    
+
     if ([attributeName isEqualToString:NSAccessibilityValueAutofilledAttribute])
-        return @(self.axBackingObject->isValueAutofilled());
+        return @(backingObject->isValueAutofilled());
 
     if ([attributeName isEqualToString:NSAccessibilityHasPopupAttribute])
-        return [NSNumber numberWithBool:self.axBackingObject->hasPopup()];
+        return [NSNumber numberWithBool:backingObject->hasPopup()];
 
     if ([attributeName isEqualToString:NSAccessibilityDatetimeValueAttribute])
-        return self.axBackingObject->datetimeAttributeValue();
-    
+        return backingObject->datetimeAttributeValue();
+
     if ([attributeName isEqualToString:NSAccessibilityInlineTextAttribute])
-        return @(self.axBackingObject->isInlineText());
-    
+        return @(backingObject->isInlineText());
+
     // ARIA Live region attributes.
     if ([attributeName isEqualToString:NSAccessibilityARIALiveAttribute])
-        return self.axBackingObject->liveRegionStatus();
+        return backingObject->liveRegionStatus();
     if ([attributeName isEqualToString:NSAccessibilityARIARelevantAttribute])
-        return self.axBackingObject->liveRegionRelevant();
+        return backingObject->liveRegionRelevant();
     if ([attributeName isEqualToString:NSAccessibilityARIAAtomicAttribute])
-        return [NSNumber numberWithBool:self.axBackingObject->liveRegionAtomic()];
+        return [NSNumber numberWithBool:backingObject->liveRegionAtomic()];
     if ([attributeName isEqualToString:NSAccessibilityElementBusyAttribute])
-        return [NSNumber numberWithBool:self.axBackingObject->isBusy()];
-    
+        return [NSNumber numberWithBool:backingObject->isBusy()];
+
     // MathML Attributes.
-    if (self.axBackingObject->isMathElement()) {
+    if (backingObject->isMathElement()) {
         if ([attributeName isEqualToString:NSAccessibilityMathRootIndexAttribute])
-            return (self.axBackingObject->mathRootIndexObject()) ? self.axBackingObject->mathRootIndexObject()->wrapper() : 0;
+            return (backingObject->mathRootIndexObject()) ? backingObject->mathRootIndexObject()->wrapper() : 0;
         if ([attributeName isEqualToString:NSAccessibilityMathRootRadicandAttribute])
-            return (self.axBackingObject->mathRadicandObject()) ? self.axBackingObject->mathRadicandObject()->wrapper() : 0;
+            return (backingObject->mathRadicandObject()) ? backingObject->mathRadicandObject()->wrapper() : 0;
         if ([attributeName isEqualToString:NSAccessibilityMathFractionNumeratorAttribute])
-            return (self.axBackingObject->mathNumeratorObject()) ? self.axBackingObject->mathNumeratorObject()->wrapper() : 0;
+            return (backingObject->mathNumeratorObject()) ? backingObject->mathNumeratorObject()->wrapper() : 0;
         if ([attributeName isEqualToString:NSAccessibilityMathFractionDenominatorAttribute])
-            return (self.axBackingObject->mathDenominatorObject()) ? self.axBackingObject->mathDenominatorObject()->wrapper() : 0;
+            return (backingObject->mathDenominatorObject()) ? backingObject->mathDenominatorObject()->wrapper() : 0;
         if ([attributeName isEqualToString:NSAccessibilityMathBaseAttribute])
-            return (self.axBackingObject->mathBaseObject()) ? self.axBackingObject->mathBaseObject()->wrapper() : 0;
+            return (backingObject->mathBaseObject()) ? backingObject->mathBaseObject()->wrapper() : 0;
         if ([attributeName isEqualToString:NSAccessibilityMathSubscriptAttribute])
-            return (self.axBackingObject->mathSubscriptObject()) ? self.axBackingObject->mathSubscriptObject()->wrapper() : 0;
+            return (backingObject->mathSubscriptObject()) ? backingObject->mathSubscriptObject()->wrapper() : 0;
         if ([attributeName isEqualToString:NSAccessibilityMathSuperscriptAttribute])
-            return (self.axBackingObject->mathSuperscriptObject()) ? self.axBackingObject->mathSuperscriptObject()->wrapper() : 0;
+            return (backingObject->mathSuperscriptObject()) ? backingObject->mathSuperscriptObject()->wrapper() : 0;
         if ([attributeName isEqualToString:NSAccessibilityMathUnderAttribute])
-            return (self.axBackingObject->mathUnderObject()) ? self.axBackingObject->mathUnderObject()->wrapper() : 0;
+            return (backingObject->mathUnderObject()) ? backingObject->mathUnderObject()->wrapper() : 0;
         if ([attributeName isEqualToString:NSAccessibilityMathOverAttribute])
-            return (self.axBackingObject->mathOverObject()) ? self.axBackingObject->mathOverObject()->wrapper() : 0;
+            return (backingObject->mathOverObject()) ? backingObject->mathOverObject()->wrapper() : 0;
         if ([attributeName isEqualToString:NSAccessibilityMathFencedOpenAttribute])
-            return self.axBackingObject->mathFencedOpenString();
+            return backingObject->mathFencedOpenString();
         if ([attributeName isEqualToString:NSAccessibilityMathFencedCloseAttribute])
-            return self.axBackingObject->mathFencedCloseString();
+            return backingObject->mathFencedCloseString();
         if ([attributeName isEqualToString:NSAccessibilityMathLineThicknessAttribute])
-            return [NSNumber numberWithInteger:self.axBackingObject->mathLineThickness()];
+            return [NSNumber numberWithInteger:backingObject->mathLineThickness()];
         if ([attributeName isEqualToString:NSAccessibilityMathPostscriptsAttribute])
             return [self accessibilityMathPostscriptPairs];
         if ([attributeName isEqualToString:NSAccessibilityMathPrescriptsAttribute])
             return [self accessibilityMathPrescriptPairs];
     }
-    
+
     if ([attributeName isEqualToString:NSAccessibilityExpandedTextValueAttribute])
-        return self.axBackingObject->expandedTextValue();
-    
+        return backingObject->expandedTextValue();
+
     if ([attributeName isEqualToString:NSAccessibilityDOMIdentifierAttribute])
-        return self.axBackingObject->identifierAttribute();
+        return backingObject->identifierAttribute();
     if ([attributeName isEqualToString:NSAccessibilityDOMClassListAttribute]) {
         Vector<String> classList;
-        self.axBackingObject->classList(classList);
+        backingObject->classList(classList);
         return convertStringsToNSArray(classList);
     }
-    
+
     // This allows us to connect to a plugin that creates a shadow node for editing (like PDFs).
     if ([attributeName isEqualToString:@"_AXAssociatedPluginParent"])
         return [self associatedPluginParent];
-    
+
     // this is used only by DumpRenderTree for testing
     if ([attributeName isEqualToString:@"AXClickPoint"])
-        return [NSValue valueWithPoint:self.axBackingObject->clickPoint()];
-    
+        return [NSValue valueWithPoint:backingObject->clickPoint()];
+
     // This is used by DRT to verify CSS3 speech works.
     if ([attributeName isEqualToString:@"AXDRTSpeechAttribute"])
         return [self baseAccessibilitySpeechHint];
-    
+
     // Used by DRT to find an accessible node by its element id.
     if ([attributeName isEqualToString:@"AXDRTElementIdAttribute"])
-        return self.axBackingObject->identifierAttribute();
-    
+        return backingObject->identifierAttribute();
+
     if ([attributeName isEqualToString:@"AXAutocompleteValue"])
-        return self.axBackingObject->autoCompleteValue();
+        return backingObject->autoCompleteValue();
 
     if ([attributeName isEqualToString:NSAccessibilityPopupValueAttribute])
-        return self.axBackingObject->popupValue();
+        return backingObject->popupValue();
 
     if ([attributeName isEqualToString:@"AXKeyShortcutsValue"])
-        return self.axBackingObject->keyShortcutsValue();
-    
+        return backingObject->keyShortcutsValue();
+
     if ([attributeName isEqualToString:@"AXARIAPressedIsPresent"])
-        return [NSNumber numberWithBool:self.axBackingObject->pressedIsPresent()];
-    
+        return [NSNumber numberWithBool:backingObject->pressedIsPresent()];
+
     if ([attributeName isEqualToString:@"AXIsMultiline"])
-        return [NSNumber numberWithBool:self.axBackingObject->ariaIsMultiline()];
-    
+        return [NSNumber numberWithBool:backingObject->ariaIsMultiline()];
+
     if ([attributeName isEqualToString:@"AXReadOnlyValue"])
-        return self.axBackingObject->readOnlyValue();
+        return backingObject->readOnlyValue();
 
     if ([attributeName isEqualToString:@"AXIsActiveDescendantOfFocusedContainer"])
-        return [NSNumber numberWithBool:self.axBackingObject->isActiveDescendantOfFocusedContainer()];
+        return [NSNumber numberWithBool:backingObject->isActiveDescendantOfFocusedContainer()];
 
     if ([attributeName isEqualToString:@"AXDetailsElements"]) {
         AccessibilityObject::AccessibilityChildrenVector details;
-        self.axBackingObject->ariaDetailsElements(details);
+        backingObject->ariaDetailsElements(details);
         return convertToNSArray(details);
     }
 
     if ([attributeName isEqualToString:NSAccessibilityRelativeFrameAttribute])
-        return [NSValue valueWithRect:NSRectFromCGRect(self.axBackingObject->relativeFrame())];
+        return [NSValue valueWithRect:NSRectFromCGRect(backingObject->relativeFrame())];
 
     if ([attributeName isEqualToString:@"AXErrorMessageElements"]) {
         AccessibilityObject::AccessibilityChildrenVector errorMessages;
-        self.axBackingObject->ariaErrorMessageElements(errorMessages);
+        backingObject->ariaErrorMessageElements(errorMessages);
         return convertToNSArray(errorMessages);
     }
 
     // Multi-selectable
     if ([attributeName isEqualToString:NSAccessibilityIsMultiSelectableAttribute])
-        return [NSNumber numberWithBool:self.axBackingObject->isMultiSelectable()];
-    
+        return [NSNumber numberWithBool:backingObject->isMultiSelectable()];
+
     // Document attributes
     if ([attributeName isEqualToString:NSAccessibilityDocumentURIAttribute])
-        return self.axBackingObject->documentURI();
-    
+        return backingObject->documentURI();
+
     if ([attributeName isEqualToString:NSAccessibilityDocumentEncodingAttribute])
-        return self.axBackingObject->documentEncoding();
-    
+        return backingObject->documentEncoding();
+
     // Aria controls element
     if ([attributeName isEqualToString:NSAccessibilityAriaControlsAttribute]) {
         AccessibilityObject::AccessibilityChildrenVector ariaControls;
-        self.axBackingObject->ariaControlsElements(ariaControls);
+        backingObject->ariaControlsElements(ariaControls);
         return convertToNSArray(ariaControls);
     }
 
     if ([attributeName isEqualToString:NSAccessibilityFocusableAncestorAttribute]) {
-        AXCoreObject* object = self.axBackingObject->focusableAncestor();
+        AXCoreObject* object = backingObject->focusableAncestor();
         return object ? object->wrapper() : nil;
     }
 
     if ([attributeName isEqualToString:NSAccessibilityEditableAncestorAttribute]) {
-        AXCoreObject* object = self.axBackingObject->editableAncestor();
+        AXCoreObject* object = backingObject->editableAncestor();
         return object ? object->wrapper() : nil;
     }
 
     if ([attributeName isEqualToString:NSAccessibilityHighestEditableAncestorAttribute]) {
-        AXCoreObject* object = self.axBackingObject->highestEditableAncestor();
+        AXCoreObject* object = backingObject->highestEditableAncestor();
         return object ? object->wrapper() : nil;
     }
 
@@ -3320,10 +3295,12 @@ ALLOW_DEPRECATED_IMPLEMENTATIONS_END
 {
     if (![self updateObjectBackingStore])
         return nil;
-    
-    if (self.axBackingObject->isAttachment())
+    // FIXME: make updateObjectBackingStore above return the backing object.
+    auto* backingObject = self.axBackingObject;
+
+    if (backingObject->isAttachment())
         return nil;
-    
+
     static NSArray* paramAttrs = nil;
     static NSArray* textParamAttrs = nil;
     static NSArray* tableParamAttrs = nil;
@@ -3370,7 +3347,7 @@ ALLOW_DEPRECATED_IMPLEMENTATIONS_END
             NSAccessibilityTextOperationParameterizedAttribute,
             nil];
     }
-    
+
     if (textParamAttrs == nil) {
         NSMutableArray* tempArray = [[NSMutableArray alloc] initWithArray:paramAttrs];
         [tempArray addObject:(NSString*)kAXLineForIndexParameterizedAttribute];
@@ -3399,22 +3376,22 @@ ALLOW_DEPRECATED_IMPLEMENTATIONS_END
         webAreaParamAttrs = [[NSArray alloc] initWithArray:tempArray];
         [tempArray release];
     }
-    
-    if (self.axBackingObject->isPasswordField())
+
+    if (backingObject->isPasswordField())
         return @[ NSAccessibilityUIElementsForSearchPredicateParameterizedAttribute ];
-    
-    if (self.axBackingObject->isTextControl())
+
+    if (backingObject->isTextControl())
         return textParamAttrs;
-    
-    if (is<AccessibilityTable>(*self.axBackingObject) && downcast<AccessibilityTable>(*self.axBackingObject).isExposableThroughAccessibility())
+
+    if (backingObject->isTable() && backingObject->isExposable())
         return tableParamAttrs;
-    
-    if (self.axBackingObject->isMenuRelated())
+
+    if (backingObject->isMenuRelated())
         return nil;
-    
-    if (self.axBackingObject->isWebArea())
+
+    if (backingObject->isWebArea())
         return webAreaParamAttrs;
-    
+
     return paramAttrs;
 }
 
@@ -3614,73 +3591,71 @@ ALLOW_DEPRECATED_IMPLEMENTATIONS_END
 {
     if (![self updateObjectBackingStore])
         return;
-    
+    // FIXME: make updateObjectBackingStore above return the backing object.
+    auto* backingObject = self.axBackingObject;
+
     id textMarkerRange = nil;
     NSNumber*               number = nil;
     NSString*               string = nil;
     NSRange                 range = {0, 0};
     NSArray*                array = nil;
-    
+
     // decode the parameter
     if (AXObjectIsTextMarkerRange(value))
         textMarkerRange = value;
-    
     else if ([value isKindOfClass:[NSNumber self]])
         number = value;
-    
     else if ([value isKindOfClass:[NSString self]])
         string = value;
-    
     else if ([value isKindOfClass:[NSValue self]])
         range = [value rangeValue];
-    
     else if ([value isKindOfClass:[NSArray self]])
         array = value;
-    
+
     // handle the command
     if ([attributeName isEqualToString: @"AXSelectedTextMarkerRange"]) {
         ASSERT(textMarkerRange);
-        self.axBackingObject->setSelectedVisiblePositionRange([self visiblePositionRangeForTextMarkerRange:textMarkerRange]);
+        backingObject->setSelectedVisiblePositionRange([self visiblePositionRangeForTextMarkerRange:textMarkerRange]);
     } else if ([attributeName isEqualToString: NSAccessibilityFocusedAttribute]) {
         [self baseAccessibilitySetFocus:[number boolValue]];
     } else if ([attributeName isEqualToString: NSAccessibilityValueAttribute]) {
-        if (number && self.axBackingObject->canSetNumericValue())
-            self.axBackingObject->setValue([number floatValue]);
+        if (number && backingObject->canSetNumericValue())
+            backingObject->setValue([number floatValue]);
         else if (string)
-            self.axBackingObject->setValue(string);
+            backingObject->setValue(string);
     } else if ([attributeName isEqualToString: NSAccessibilitySelectedAttribute]) {
         if (!number)
             return;
-        self.axBackingObject->setSelected([number boolValue]);
+        backingObject->setSelected([number boolValue]);
     } else if ([attributeName isEqualToString: NSAccessibilitySelectedChildrenAttribute]) {
         if (!array)
             return;
-        if (self.axBackingObject->roleValue() != AccessibilityRole::ListBox)
+        if (backingObject->roleValue() != AccessibilityRole::ListBox)
             return;
         AccessibilityObject::AccessibilityChildrenVector selectedChildren;
         convertToVector(array, selectedChildren);
-        downcast<AccessibilityListBox>(*self.axBackingObject).setSelectedChildren(selectedChildren);
-    } else if (self.axBackingObject->isTextControl()) {
+        downcast<AccessibilityListBox>(*backingObject).setSelectedChildren(selectedChildren);
+    } else if (backingObject->isTextControl()) {
         if ([attributeName isEqualToString: NSAccessibilitySelectedTextAttribute]) {
-            self.axBackingObject->setSelectedText(string);
+            backingObject->setSelectedText(string);
         } else if ([attributeName isEqualToString: NSAccessibilitySelectedTextRangeAttribute]) {
-            self.axBackingObject->setSelectedTextRange(PlainTextRange(range.location, range.length));
+            backingObject->setSelectedTextRange(PlainTextRange(range.location, range.length));
         } else if ([attributeName isEqualToString: NSAccessibilityVisibleCharacterRangeAttribute]) {
-            self.axBackingObject->makeRangeVisible(PlainTextRange(range.location, range.length));
+            backingObject->makeRangeVisible(PlainTextRange(range.location, range.length));
         }
     } else if ([attributeName isEqualToString:NSAccessibilityDisclosingAttribute] || [attributeName isEqualToString:NSAccessibilityExpandedAttribute])
-        self.axBackingObject->setIsExpanded([number boolValue]);
+        backingObject->setIsExpanded([number boolValue]);
     else if ([attributeName isEqualToString:NSAccessibilitySelectedRowsAttribute]) {
         AccessibilityObject::AccessibilityChildrenVector selectedRows;
         convertToVector(array, selectedRows);
-        if (self.axBackingObject->isTree() || (is<AccessibilityTable>(*self.axBackingObject) && downcast<AccessibilityTable>(*self.axBackingObject).isExposableThroughAccessibility()))
-            self.axBackingObject->setSelectedRows(selectedRows);
+        if (backingObject->isTree() || (backingObject->isTable() && backingObject->isExposable()))
+            backingObject->setSelectedRows(selectedRows);
     } else if ([attributeName isEqualToString:NSAccessibilityGrabbedAttribute])
-        self.axBackingObject->setARIAGrabbed([number boolValue]);
-    else if (self.axBackingObject->isWebArea() && [attributeName isEqualToString:NSAccessibilityPreventKeyboardDOMEventDispatchAttribute])
-        self.axBackingObject->setPreventKeyboardDOMEventDispatch([number boolValue]);
-    else if (self.axBackingObject->isWebArea() && [attributeName isEqualToString:NSAccessibilityCaretBrowsingEnabledAttribute])
-        self.axBackingObject->setCaretBrowsingEnabled([number boolValue]);
+        backingObject->setARIAGrabbed([number boolValue]);
+    else if (backingObject->isWebArea() && [attributeName isEqualToString:NSAccessibilityPreventKeyboardDOMEventDispatchAttribute])
+        backingObject->setPreventKeyboardDOMEventDispatch([number boolValue]);
+    else if (backingObject->isWebArea() && [attributeName isEqualToString:NSAccessibilityCaretBrowsingEnabledAttribute])
+        backingObject->setCaretBrowsingEnabled([number boolValue]);
 }
 
 // Used to set attributes synchronously on accessibility elements within tests.
@@ -3858,6 +3833,15 @@ ALLOW_DEPRECATED_IMPLEMENTATIONS_BEGIN
 - (id)accessibilityAttributeValue:(NSString*)attribute forParameter:(id)parameter
 ALLOW_DEPRECATED_IMPLEMENTATIONS_END
 {
+    if (![self updateObjectBackingStore])
+        return nil;
+    // FIXME: make updateObjectBackingStore above return the backing object.
+    auto* backingObject = self.axBackingObject;
+
+    // Basic parameter validation.
+    if (!attribute || !parameter)
+        return nil;
+
     id textMarker = nil;
     id textMarkerRange = nil;
     NSNumber* number = nil;
@@ -3869,39 +3853,25 @@ ALLOW_DEPRECATED_IMPLEMENTATIONS_END
     NSRange range = {0, 0};
     bool rangeSet = false;
     NSRect rect = NSZeroRect;
-    
-    // basic parameter validation
-    if (!self.axBackingObject || !attribute || !parameter)
-        return nil;
-    
-    if (![self updateObjectBackingStore])
-        return nil;
-    
+
     // common parameter type check/casting.  Nil checks in handlers catch wrong type case.
     // NOTE: This assumes nil is not a valid parameter, because it is indistinguishable from
     // a parameter of the wrong type.
     if (AXObjectIsTextMarker(parameter))
         textMarker = parameter;
-    
     else if (AXObjectIsTextMarkerRange(parameter))
         textMarkerRange = parameter;
-    
     else if ([parameter isKindOfClass:[WebAccessibilityObjectWrapper self]])
         uiElement = [(WebAccessibilityObjectWrapper*)parameter axBackingObject];
-
     else if ([parameter isKindOfClass:[NSNumber self]])
         number = parameter;
-    
     else if ([parameter isKindOfClass:[NSArray self]])
         array = parameter;
-    
     else if ([parameter isKindOfClass:[NSDictionary self]])
         dictionary = parameter;
-    
     else if ([parameter isKindOfClass:[NSValue self]] && !strcmp([(NSValue*)parameter objCType], @encode(NSPoint))) {
         pointSet = true;
         point = [(NSValue*)parameter pointValue];
-        
     } else if ([parameter isKindOfClass:[NSValue self]] && !strcmp([(NSValue*)parameter objCType], @encode(NSRange))) {
         rangeSet = true;
         range = [(NSValue*)parameter rangeValue];
@@ -3911,15 +3881,19 @@ ALLOW_DEPRECATED_IMPLEMENTATIONS_END
         // Attribute type is not supported. Allow super to handle.
         return [super accessibilityAttributeValue:attribute forParameter:parameter];
     }
-    
+
     // dispatch
     if ([attribute isEqualToString:NSAccessibilitySelectTextWithCriteriaParameterizedAttribute]) {
         // To be deprecated.
-        auto result = Accessibility::retrieveValueFromMainThread<Vector<String>>([dictionary, self] () -> Vector<String> {
+        auto result = Accessibility::retrieveValueFromMainThread<Vector<String>>([dictionary, protectedSelf = RetainPtr<WebAccessibilityObjectWrapper>(self)] () -> Vector<String> {
+            auto* backingObject = protectedSelf.get().axBackingObject;
+            if (!backingObject)
+                return Vector<String>();
+
             auto criteria = accessibilityTextCriteriaForParameterizedAttribute(dictionary);
-            criteria.second.textRanges = self.axBackingObject->findTextRanges(criteria.first);
+            criteria.second.textRanges = backingObject->findTextRanges(criteria.first);
             ASSERT(criteria.second.textRanges.size() <= 1);
-            return self.axBackingObject->performTextOperation(criteria.second);
+            return backingObject->performTextOperation(criteria.second);
         });
         ASSERT(result.size() <= 1);
         if (result.size() > 0)
@@ -3929,13 +3903,17 @@ ALLOW_DEPRECATED_IMPLEMENTATIONS_END
 
     if ([attribute isEqualToString:NSAccessibilitySearchTextWithCriteriaParameterizedAttribute]) {
         auto criteria = accessibilitySearchTextCriteriaForParameterizedAttribute(dictionary);
-        return Accessibility::retrieveValueFromMainThread<NSArray *>([&criteria, self] () -> NSArray * {
-            auto ranges = self.axBackingObject->findTextRanges(criteria);
+        return Accessibility::retrieveValueFromMainThread<NSArray *>([&criteria, protectedSelf = RetainPtr<WebAccessibilityObjectWrapper>(self)] () -> NSArray * {
+            auto* backingObject = protectedSelf.get().axBackingObject;
+            if (!backingObject)
+                return nil;
+
+            auto ranges = backingObject->findTextRanges(criteria);
             if (ranges.isEmpty())
                 return nil;
             NSMutableArray *markers = [NSMutableArray arrayWithCapacity:ranges.size()];
             for (auto range : ranges) {
-                if (id marker = [self textMarkerRangeFromRange:range])
+                if (id marker = [protectedSelf textMarkerRangeFromRange:range])
                     [markers addObject:marker];
             }
             return markers;
@@ -3943,9 +3921,13 @@ ALLOW_DEPRECATED_IMPLEMENTATIONS_END
     }
 
     if ([attribute isEqualToString:NSAccessibilityTextOperationParameterizedAttribute]) {
-        auto operationResult = Accessibility::retrieveValueFromMainThread<Vector<String>>([dictionary, self] () -> Vector<String> {
-            auto textOperation = accessibilityTextOperationForParameterizedAttribute(self, dictionary);
-            return self.axBackingObject->performTextOperation(textOperation);
+        auto operationResult = Accessibility::retrieveValueFromMainThread<Vector<String>>([dictionary, protectedSelf = RetainPtr<WebAccessibilityObjectWrapper>(self)] () -> Vector<String> {
+            auto* backingObject = protectedSelf.get().axBackingObject;
+            if (!backingObject)
+                return Vector<String>();
+
+            auto textOperation = accessibilityTextOperationForParameterizedAttribute(protectedSelf.get(), dictionary);
+            return backingObject->performTextOperation(textOperation);
         });
         if (operationResult.isEmpty())
             return nil;
@@ -3958,14 +3940,14 @@ ALLOW_DEPRECATED_IMPLEMENTATIONS_END
     if ([attribute isEqualToString:NSAccessibilityUIElementCountForSearchPredicateParameterizedAttribute]) {
         AccessibilitySearchCriteria criteria = accessibilitySearchCriteriaForSearchPredicateParameterizedAttribute(dictionary);
         AccessibilityObject::AccessibilityChildrenVector results;
-        self.axBackingObject->findMatchingObjects(&criteria, results);
+        backingObject->findMatchingObjects(&criteria, results);
         return @(results.size());
     }
-    
+
     if ([attribute isEqualToString:NSAccessibilityUIElementsForSearchPredicateParameterizedAttribute]) {
         AccessibilitySearchCriteria criteria = accessibilitySearchCriteriaForSearchPredicateParameterizedAttribute(dictionary);
         AccessibilityObject::AccessibilityChildrenVector results;
-        self.axBackingObject->findMatchingObjects(&criteria, results);
+        backingObject->findMatchingObjects(&criteria, results);
         return convertToNSArray(results);
     }
 
@@ -3995,13 +3977,13 @@ ALLOW_DEPRECATED_IMPLEMENTATIONS_END
 
     if ([attribute isEqualToString:NSAccessibilityLineTextMarkerRangeForTextMarkerParameterizedAttribute]) {
         VisiblePosition visiblePosition = [self visiblePositionForTextMarker:textMarker];
-        VisiblePositionRange visiblePositionRange = self.axBackingObject->lineRangeForPosition(visiblePosition);
+        VisiblePositionRange visiblePositionRange = backingObject->lineRangeForPosition(visiblePosition);
         return [self textMarkerRangeFromVisiblePositions:visiblePositionRange.start endPosition:visiblePositionRange.end];
     }
 
     if ([attribute isEqualToString:NSAccessibilityMisspellingTextMarkerRangeParameterizedAttribute]) {
         auto criteria = accessibilityMisspellingSearchCriteriaForParameterizedAttribute(self, dictionary);
-        if (auto misspellingRange = self.axBackingObject->getMisspellingRange(criteria.first, criteria.second))
+        if (auto misspellingRange = backingObject->getMisspellingRange(criteria.first, criteria.second))
             return [self textMarkerRangeFromRange:misspellingRange];
         return nil;
     }
@@ -4016,7 +3998,7 @@ ALLOW_DEPRECATED_IMPLEMENTATIONS_END
     if ([attribute isEqualToString:NSAccessibilityTextMarkerForIndexParameterizedAttribute]) {
         return [self _textMarkerForIndex:[number integerValue]];
     }
-    
+
     if ([attribute isEqualToString:@"AXUIElementForTextMarker"]) {
         AccessibilityObject* axObject = [self accessibilityObjectForTextMarker:textMarker];
         if (!axObject)
@@ -4035,19 +4017,19 @@ ALLOW_DEPRECATED_IMPLEMENTATIONS_END
 
     if ([attribute isEqualToString:@"AXLineForTextMarker"]) {
         VisiblePosition visiblePos = [self visiblePositionForTextMarker:(textMarker)];
-        return [NSNumber numberWithUnsignedInt:self.axBackingObject->lineForPosition(visiblePos)];
+        return [NSNumber numberWithUnsignedInt:backingObject->lineForPosition(visiblePos)];
     }
-    
+
     if ([attribute isEqualToString:@"AXTextMarkerRangeForLine"]) {
         VisiblePositionRange vpRange;
         if ([number unsignedIntegerValue] != NSNotFound)
-            vpRange = self.axBackingObject->visiblePositionRangeForLine([number unsignedIntValue]);
+            vpRange = backingObject->visiblePositionRangeForLine([number unsignedIntValue]);
         return [self textMarkerRangeFromVisiblePositions:vpRange.start endPosition:vpRange.end];
     }
-    
+
     if ([attribute isEqualToString:@"AXStringForTextMarkerRange"]) {
         RefPtr<Range> range = [self rangeForTextMarkerRange:textMarkerRange];
-        return self.axBackingObject->stringForRange(range);
+        return backingObject->stringForRange(range);
     }
 
     if ([attribute isEqualToString:@"AXTextMarkerForPosition"]) {
@@ -4067,7 +4049,7 @@ ALLOW_DEPRECATED_IMPLEMENTATIONS_END
 
     if ([attribute isEqualToString:@"AXBoundsForTextMarkerRange"]) {
         RefPtr<Range> range = [self rangeForTextMarkerRange:textMarkerRange];
-        auto bounds = FloatRect(self.axBackingObject->boundsForRange(range));
+        auto bounds = FloatRect(backingObject->boundsForRange(range));
         NSRect rect = [self convertRectToSpace:bounds space:AccessibilityConversionSpace::Screen];
         return [NSValue valueWithRect:rect];
     }
@@ -4095,9 +4077,9 @@ ALLOW_DEPRECATED_IMPLEMENTATIONS_END
     }
 
     if ([attribute isEqualToString:NSAccessibilityStringForRangeParameterizedAttribute]) {
-        if (self.axBackingObject->isTextControl()) {
+        if (backingObject->isTextControl()) {
             PlainTextRange plainTextRange = PlainTextRange(range.location, range.length);
-            return self.axBackingObject->doAXStringForRange(plainTextRange);
+            return backingObject->doAXStringForRange(plainTextRange);
         }
 
         return Accessibility::retrieveValueFromMainThread<NSString *>([&range, protectedSelf = RetainPtr<WebAccessibilityObjectWrapper>(self)] () -> NSString * {
@@ -4160,7 +4142,7 @@ ALLOW_DEPRECATED_IMPLEMENTATIONS_END
         CharacterOffset characterOffset = [self characterOffsetForTextMarker:textMarker];
         return [self nextTextMarkerForCharacterOffset:characterOffset];
     }
-    
+
     if ([attribute isEqualToString:@"AXPreviousTextMarkerForTextMarker"]) {
         CharacterOffset characterOffset = [self characterOffsetForTextMarker:textMarker];
         return [self previousTextMarkerForCharacterOffset:characterOffset];
@@ -4192,13 +4174,13 @@ ALLOW_DEPRECATED_IMPLEMENTATIONS_END
 
     if ([attribute isEqualToString:@"AXLeftLineTextMarkerRangeForTextMarker"]) {
         VisiblePosition visiblePos = [self visiblePositionForTextMarker:(textMarker)];
-        VisiblePositionRange vpRange = self.axBackingObject->leftLineVisiblePositionRange(visiblePos);
+        VisiblePositionRange vpRange = backingObject->leftLineVisiblePositionRange(visiblePos);
         return [self textMarkerRangeFromVisiblePositions:vpRange.start endPosition:vpRange.end];
     }
-    
+
     if ([attribute isEqualToString:@"AXRightLineTextMarkerRangeForTextMarker"]) {
         VisiblePosition visiblePos = [self visiblePositionForTextMarker:(textMarker)];
-        VisiblePositionRange vpRange = self.axBackingObject->rightLineVisiblePositionRange(visiblePos);
+        VisiblePositionRange vpRange = backingObject->rightLineVisiblePositionRange(visiblePos);
         return [self textMarkerRangeFromVisiblePositions:vpRange.start endPosition:vpRange.end];
     }
 
@@ -4252,20 +4234,20 @@ ALLOW_DEPRECATED_IMPLEMENTATIONS_END
 
     if ([attribute isEqualToString:@"AXNextLineEndTextMarkerForTextMarker"]) {
         VisiblePosition visiblePos = [self visiblePositionForTextMarker:(textMarker)];
-        return [self textMarkerForVisiblePosition:self.axBackingObject->nextLineEndPosition(visiblePos)];
+        return [self textMarkerForVisiblePosition:backingObject->nextLineEndPosition(visiblePos)];
     }
-    
+
     if ([attribute isEqualToString:@"AXPreviousLineStartTextMarkerForTextMarker"]) {
         VisiblePosition visiblePos = [self visiblePositionForTextMarker:(textMarker)];
-        return [self textMarkerForVisiblePosition:self.axBackingObject->previousLineStartPosition(visiblePos)];
+        return [self textMarkerForVisiblePosition:backingObject->previousLineStartPosition(visiblePos)];
     }
-    
+
     if ([attribute isEqualToString:@"AXNextSentenceEndTextMarkerForTextMarker"]) {
         return Accessibility::retrieveAutoreleasedValueFromMainThread<id>([textMarker, protectedSelf = RetainPtr<WebAccessibilityObjectWrapper>(self)] () -> RetainPtr<id> {
             auto* cache = protectedSelf.get().axBackingObject->axObjectCache();
             if (!cache)
                 return nil;
-            
+
             CharacterOffset characterOffset = [protectedSelf characterOffsetForTextMarker:textMarker];
             CharacterOffset nextEnd = cache->nextSentenceEndCharacterOffset(characterOffset);
             return [protectedSelf textMarkerForCharacterOffset:nextEnd];
@@ -4310,10 +4292,10 @@ ALLOW_DEPRECATED_IMPLEMENTATIONS_END
 
     if ([attribute isEqualToString:@"AXStyleTextMarkerRangeForTextMarker"]) {
         VisiblePosition visiblePos = [self visiblePositionForTextMarker:(textMarker)];
-        VisiblePositionRange vpRange = self.axBackingObject->styleRangeForPosition(visiblePos);
+        VisiblePositionRange vpRange = backingObject->styleRangeForPosition(visiblePos);
         return [self textMarkerRangeFromVisiblePositions:vpRange.start endPosition:vpRange.end];
     }
-    
+
     if ([attribute isEqualToString:@"AXLengthForTextMarkerRange"]) {
         RefPtr<Range> range = [self rangeForTextMarkerRange:textMarkerRange];
         int length = AXObjectCache::lengthForRange(range.get());
@@ -4321,13 +4303,13 @@ ALLOW_DEPRECATED_IMPLEMENTATIONS_END
             return nil;
         return [NSNumber numberWithInt:length];
     }
-    
+
     // Used only by DumpRenderTree (so far).
     if ([attribute isEqualToString:@"AXStartTextMarkerForTextMarkerRange"]) {
         RefPtr<Range> range = [self rangeForTextMarkerRange:textMarkerRange];
         return [self startOrEndTextMarkerForRange:range isStart:YES];
     }
-    
+
     if ([attribute isEqualToString:@"AXEndTextMarkerForTextMarkerRange"]) {
         RefPtr<Range> range = [self rangeForTextMarkerRange:textMarkerRange];
         return [self startOrEndTextMarkerForRange:range isStart:NO];
@@ -4351,70 +4333,67 @@ ALLOW_DEPRECATED_IMPLEMENTATIONS_END
     }
 #endif
 
-    if (is<AccessibilityTable>(*self.axBackingObject) && downcast<AccessibilityTable>(*self.axBackingObject).isExposableThroughAccessibility()) {
+    if (backingObject->isTable() && backingObject->isExposable()) {
         if ([attribute isEqualToString:NSAccessibilityCellForColumnAndRowParameterizedAttribute]) {
             if (array == nil || [array count] != 2)
                 return nil;
-            AccessibilityTableCell* cell = downcast<AccessibilityTable>(*self.axBackingObject).cellForColumnAndRow([[array objectAtIndex:0] unsignedIntValue], [[array objectAtIndex:1] unsignedIntValue]);
-            if (!cell)
-                return nil;
-            
-            return cell->wrapper();
+            auto* cell = backingObject->cellForColumnAndRow([[array objectAtIndex:0] unsignedIntValue], [[array objectAtIndex:1] unsignedIntValue]);
+            return cell ? cell->wrapper() : nil;
         }
     }
-    
-    if (self.axBackingObject->isTextControl()) {
+
+    if (backingObject->isTextControl()) {
         if ([attribute isEqualToString: (NSString *)kAXLineForIndexParameterizedAttribute]) {
-            int lineNumber = self.axBackingObject->doAXLineForIndex([number intValue]);
+            int lineNumber = backingObject->doAXLineForIndex([number intValue]);
             if (lineNumber < 0)
                 return nil;
             return [NSNumber numberWithUnsignedInt:lineNumber];
         }
-        
+
         if ([attribute isEqualToString: (NSString *)kAXRangeForLineParameterizedAttribute]) {
-            PlainTextRange textRange = self.axBackingObject->doAXRangeForLine([number intValue]);
+            PlainTextRange textRange = backingObject->doAXRangeForLine([number intValue]);
             return [NSValue valueWithRange: NSMakeRange(textRange.start, textRange.length)];
         }
-        
+
         if ([attribute isEqualToString: (NSString*)kAXStringForRangeParameterizedAttribute]) {
             PlainTextRange plainTextRange = PlainTextRange(range.location, range.length);
-            return rangeSet ? (id)(self.axBackingObject->doAXStringForRange(plainTextRange)) : nil;
+            return rangeSet ? (id)(backingObject->doAXStringForRange(plainTextRange)) : nil;
         }
-        
+
         if ([attribute isEqualToString: (NSString*)kAXRangeForPositionParameterizedAttribute]) {
             if (!pointSet)
                 return nil;
             IntPoint webCorePoint = IntPoint(point);
-            PlainTextRange textRange = self.axBackingObject->doAXRangeForPosition(webCorePoint);
+            PlainTextRange textRange = backingObject->doAXRangeForPosition(webCorePoint);
             return [NSValue valueWithRange: NSMakeRange(textRange.start, textRange.length)];
         }
-        
+
         if ([attribute isEqualToString: (NSString*)kAXRangeForIndexParameterizedAttribute]) {
-            PlainTextRange textRange = self.axBackingObject->doAXRangeForIndex([number intValue]);
+            PlainTextRange textRange = backingObject->doAXRangeForIndex([number intValue]);
             return [NSValue valueWithRange: NSMakeRange(textRange.start, textRange.length)];
         }
-        
+
         if ([attribute isEqualToString: (NSString*)kAXBoundsForRangeParameterizedAttribute]) {
             if (!rangeSet)
                 return nil;
             PlainTextRange plainTextRange = PlainTextRange(range.location, range.length);
-            auto bounds = FloatRect(self.axBackingObject->doAXBoundsForRangeUsingCharacterOffset(plainTextRange));
+            auto bounds = FloatRect(backingObject->doAXBoundsForRangeUsingCharacterOffset(plainTextRange));
             NSRect rect = [self convertRectToSpace:bounds space:AccessibilityConversionSpace::Screen];
             return [NSValue valueWithRect:rect];
         }
-        
+
         if ([attribute isEqualToString: (NSString*)kAXRTFForRangeParameterizedAttribute])
             return rangeSet ? [self doAXRTFForRange:range] : nil;
-        
+
         if ([attribute isEqualToString: (NSString*)kAXAttributedStringForRangeParameterizedAttribute])
             return rangeSet ? [self doAXAttributedStringForRange:range] : nil;
-        
+
         if ([attribute isEqualToString: (NSString*)kAXStyleRangeForIndexParameterizedAttribute]) {
-            PlainTextRange textRange = self.axBackingObject->doAXStyleRangeForIndex([number intValue]);
+            PlainTextRange textRange = backingObject->doAXStyleRangeForIndex([number intValue]);
             return [NSValue valueWithRange: NSMakeRange(textRange.start, textRange.length)];
         }
     }
-    
+
     // There are some parameters that super handles that are not explicitly returned by the list of the element's attributes.
     // In that case it must be passed to super.
     return [super accessibilityAttributeValue:attribute forParameter:parameter];