Use is<>() / downcast<>() for Accessibility objects
[WebKit-https.git] / Source / WebCore / accessibility / AccessibilityTable.cpp
index 6b7e6cf..0b7be3a 100644 (file)
@@ -92,21 +92,21 @@ bool AccessibilityTable::isAccessibilityTable() const
 
 HTMLTableElement* AccessibilityTable::tableElement() const
 {
-    if (!m_renderer->isTable())
+    if (!is<RenderTable>(*m_renderer))
         return nullptr;
     
-    RenderTable* table = toRenderTable(m_renderer);
-    if (table->element() && is<HTMLTableElement>(table->element()))
-        return downcast<HTMLTableElement>(table->element());
+    RenderTable& table = downcast<RenderTable>(*m_renderer);
+    if (is<HTMLTableElement>(table.element()))
+        return downcast<HTMLTableElement>(table.element());
     
     // If the table has a display:table-row-group, then the RenderTable does not have a pointer to it's HTMLTableElement.
     // We can instead find it by asking the firstSection for its parent.
-    RenderTableSection* firstBody = table->firstBody();
+    RenderTableSection* firstBody = table.firstBody();
     if (!firstBody || !firstBody->element())
         return nullptr;
     
     Element* actualTable = firstBody->element()->parentElement();
-    if (!actualTable || !is<HTMLTableElement>(actualTable))
+    if (!is<HTMLTableElement>(actualTable))
         return nullptr;
     
     return downcast<HTMLTableElement>(actualTable);
@@ -127,16 +127,14 @@ bool AccessibilityTable::isDataTable() const
     if (node() && node()->hasEditableStyle())
         return true;
 
-    if (!m_renderer->isTable())
+    if (!is<RenderTable>(*m_renderer))
         return false;
 
     // This employs a heuristic to determine if this table should appear.
     // Only "data" tables should be exposed as tables.
     // Unfortunately, there is no good way to determine the difference
     // between a "layout" table and a "data" table.
-    RenderTable* table = toRenderTable(m_renderer);
-    HTMLTableElement* tableElement = this->tableElement();
-    if (tableElement) {
+    if (HTMLTableElement* tableElement = this->tableElement()) {
         // If there is a caption element, summary, THEAD, or TFOOT section, it's most certainly a data table.
         if (!tableElement->summary().isEmpty() || tableElement->tHead() || tableElement->tFoot() || tableElement->caption())
             return true;
@@ -146,16 +144,17 @@ bool AccessibilityTable::isDataTable() const
             return true;
 
         // If there's a colgroup or col element, it's probably a data table.
-        for (const auto& child : childrenOfType<Element>(*tableElement)) {
+        for (const auto& child : childrenOfType<HTMLElement>(*tableElement)) {
             if (child.hasTagName(colTag) || child.hasTagName(colgroupTag))
                 return true;
         }
     }
     
+    RenderTable& table = downcast<RenderTable>(*m_renderer);
     // go through the cell's and check for tell-tale signs of "data" table status
     // cells have borders, or use attributes like headers, abbr, scope or axis
-    table->recalcSectionsIfNeeded();
-    RenderTableSection* firstBody = table->firstBody();
+    table.recalcSectionsIfNeeded();
+    RenderTableSection* firstBody = table.firstBody();
     if (!firstBody)
         return false;
     
@@ -171,7 +170,7 @@ bool AccessibilityTable::isDataTable() const
         return true;
     
     // Store the background color of the table to check against cell's background colors.
-    const RenderStyle& tableStyle = table->style();
+    const RenderStyle& tableStyle = table.style();
     Color tableBGColor = tableStyle.visitedDependentColor(CSSPropertyBackgroundColor);
     
     // check enough of the cells to find if the table matches our criteria
@@ -206,22 +205,22 @@ bool AccessibilityTable::isDataTable() const
             if (cell->width() < 1 || cell->height() < 1)
                 continue;
             
-            validCellCount++;
+            ++validCellCount;
             
             bool isTHCell = cellElement->hasTagName(thTag);
             // If the first row is comprised of all <th> tags, assume it is a data table.
             if (!row && isTHCell)
-                headersInFirstRowCount++;
+                ++headersInFirstRowCount;
 
             // If the first column is comprised of all <th> tags, assume it is a data table.
             if (!col && isTHCell)
-                headersInFirstColumnCount++;
+                ++headersInFirstColumnCount;
             
             // In this case, the developer explicitly assigned a "data" table attribute.
-            if (cellElement->hasTagName(tdTag) || cellElement->hasTagName(thTag)) {
-                HTMLTableCellElement* tableCellElement = toHTMLTableCellElement(cellElement);
-                if (!tableCellElement->headers().isEmpty() || !tableCellElement->abbr().isEmpty()
-                    || !tableCellElement->axis().isEmpty() || !tableCellElement->scope().isEmpty())
+            if (is<HTMLTableCellElement>(*cellElement)) {
+                HTMLTableCellElement& tableCellElement = downcast<HTMLTableCellElement>(*cellElement);
+                if (!tableCellElement.headers().isEmpty() || !tableCellElement.abbr().isEmpty()
+                    || !tableCellElement.axis().isEmpty() || !tableCellElement.scope().isEmpty())
                     return true;
             }
             const RenderStyle& renderStyle = cell->style();
@@ -233,25 +232,25 @@ bool AccessibilityTable::isDataTable() const
             // If a cell has matching bordered sides, call it a (fully) bordered cell.
             if ((cell->borderTop() > 0 && cell->borderBottom() > 0)
                 || (cell->borderLeft() > 0 && cell->borderRight() > 0))
-                borderedCellCount++;
+                ++borderedCellCount;
 
             // Also keep track of each individual border, so we can catch tables where most
             // cells have a bottom border, for example.
             if (cell->borderTop() > 0)
-                cellsWithTopBorder++;
+                ++cellsWithTopBorder;
             if (cell->borderBottom() > 0)
-                cellsWithBottomBorder++;
+                ++cellsWithBottomBorder;
             if (cell->borderLeft() > 0)
-                cellsWithLeftBorder++;
+                ++cellsWithLeftBorder;
             if (cell->borderRight() > 0)
-                cellsWithRightBorder++;
+                ++cellsWithRightBorder;
             
             // If the cell has a different color from the table and there is cell spacing,
             // then it is probably a data table cell (spacing and colors take the place of borders).
             Color cellColor = renderStyle.visitedDependentColor(CSSPropertyBackgroundColor);
-            if (table->hBorderSpacing() > 0 && table->vBorderSpacing() > 0
+            if (table.hBorderSpacing() > 0 && table.vBorderSpacing() > 0
                 && tableBGColor != cellColor && cellColor.alpha() != 1)
-                backgroundDifferenceCellCount++;
+                ++backgroundDifferenceCellCount;
             
             // If we've found 10 "good" cells, we don't need to keep searching.
             if (borderedCellCount >= 10 || backgroundDifferenceCellCount >= 10)
@@ -259,13 +258,13 @@ bool AccessibilityTable::isDataTable() const
             
             // For the first 5 rows, cache the background color so we can check if this table has zebra-striped rows.
             if (row < 5 && row == alternatingRowColorCount) {
-                RenderObject* renderRow = cell->parent();
-                if (!renderRow || !renderRow->isBoxModelObject() || !toRenderBoxModelObject(renderRow)->isTableRow())
+                RenderElement* renderRow = cell->parent();
+                if (!is<RenderTableRow>(renderRow))
                     continue;
                 const RenderStyle& rowRenderStyle = renderRow->style();
                 Color rowColor = rowRenderStyle.visitedDependentColor(CSSPropertyBackgroundColor);
                 alternatingRowColors[alternatingRowColorCount] = rowColor;
-                alternatingRowColorCount++;
+                ++alternatingRowColorCount;
             }
         }
         
@@ -327,8 +326,8 @@ bool AccessibilityTable::isTableExposableThroughAccessibility() const
 
     // Gtk+ ATs expect all tables to be exposed as tables.
 #if PLATFORM(GTK) || PLATFORM(EFL)
-    Element* tableNode = toRenderTable(m_renderer)->element();
-    return tableNode && is<HTMLTableElement>(tableNode);
+    Element* tableNode = downcast<RenderTable>(*m_renderer).element();
+    return is<HTMLTableElement>(tableNode);
 #endif
 
     return isDataTable();
@@ -356,17 +355,17 @@ void AccessibilityTable::addChildren()
     ASSERT(!m_haveChildren); 
     
     m_haveChildren = true;
-    if (!m_renderer || !m_renderer->isTable())
+    if (!is<RenderTable>(m_renderer))
         return;
     
-    RenderTable* table = toRenderTable(m_renderer);
+    RenderTable& table = downcast<RenderTable>(*m_renderer);
     // Go through all the available sections to pull out the rows and add them as children.
-    table->recalcSectionsIfNeeded();
+    table.recalcSectionsIfNeeded();
     
     unsigned maxColumnCount = 0;
-    RenderTableSection* footer = table->footer();
+    RenderTableSection* footer = table.footer();
     
-    for (RenderTableSection* tableSection = table->topSection(); tableSection; tableSection = table->sectionBelow(tableSection, SkipEmptySections)) {
+    for (RenderTableSection* tableSection = table.topSection(); tableSection; tableSection = table.sectionBelow(tableSection, SkipEmptySections)) {
         if (tableSection == footer)
             continue;
         addChildrenFromSection(tableSection, maxColumnCount);
@@ -380,12 +379,12 @@ void AccessibilityTable::addChildren()
     // make the columns based on the number of columns in the first body
     unsigned length = maxColumnCount;
     for (unsigned i = 0; i < length; ++i) {
-        AccessibilityTableColumn* column = toAccessibilityTableColumn(axCache->getOrCreate(ColumnRole));
-        column->setColumnIndex((int)i);
-        column->setParent(this);
-        m_columns.append(column);
-        if (!column->accessibilityIsIgnored())
-            m_children.append(column);
+        auto& column = downcast<AccessibilityTableColumn>(*axCache->getOrCreate(ColumnRole));
+        column.setColumnIndex((int)i);
+        column.setParent(this);
+        m_columns.append(&column);
+        if (!column.accessibilityIsIgnored())
+            m_children.append(&column);
     }
     
     AccessibilityObject* headerContainerObject = headerContainer();
@@ -408,25 +407,25 @@ void AccessibilityTable::addChildrenFromSection(RenderTableSection* tableSection
         if (!renderRow)
             continue;
         
-        AccessibilityObject* rowObject = axCache->getOrCreate(renderRow);
-        if (!rowObject->isTableRow())
+        AccessibilityObject& rowObject = *axCache->getOrCreate(renderRow);
+        if (!is<AccessibilityTableRow>(rowObject))
             continue;
         
-        AccessibilityTableRow* row = toAccessibilityTableRow(rowObject);
+        auto& row = downcast<AccessibilityTableRow>(rowObject);
         // We need to check every cell for a new row, because cell spans
         // can cause us to miss rows if we just check the first column.
-        if (appendedRows.contains(row))
+        if (appendedRows.contains(&row))
             continue;
         
-        row->setRowIndex(static_cast<int>(m_rows.size()));
-        m_rows.append(row);
-        if (!row->accessibilityIsIgnored())
-            m_children.append(row);
+        row.setRowIndex(static_cast<int>(m_rows.size()));
+        m_rows.append(&row);
+        if (!row.accessibilityIsIgnored())
+            m_children.append(&row);
 #if PLATFORM(GTK) || PLATFORM(EFL)
         else
-            m_children.appendVector(row->children());
+            m_children.appendVector(row.children());
 #endif
-        appendedRows.add(row);
+        appendedRows.add(&row);
     }
     
     maxColumnCount = std::max(tableSection->numColumns(), maxColumnCount);
@@ -437,10 +436,10 @@ AccessibilityObject* AccessibilityTable::headerContainer()
     if (m_headerContainer)
         return m_headerContainer.get();
     
-    AccessibilityMockObject* tableHeader = toAccessibilityMockObject(axObjectCache()->getOrCreate(TableHeaderContainerRole));
-    tableHeader->setParent(this);
+    auto& tableHeader = downcast<AccessibilityMockObject>(*axObjectCache()->getOrCreate(TableHeaderContainerRole));
+    tableHeader.setParent(this);
 
-    m_headerContainer = tableHeader;
+    m_headerContainer = &tableHeader;
     return m_headerContainer.get();
 }
 
@@ -466,7 +465,7 @@ void AccessibilityTable::columnHeaders(AccessibilityChildrenVector& headers)
     updateChildrenIfNecessary();
     
     for (const auto& column : m_columns) {
-        if (AccessibilityObject* header = toAccessibilityTableColumn(column.get())->headerObject())
+        if (AccessibilityObject* header = downcast<AccessibilityTableColumn>(*column).headerObject())
             headers.append(header);
     }
 }
@@ -479,7 +478,7 @@ void AccessibilityTable::rowHeaders(AccessibilityChildrenVector& headers)
     updateChildrenIfNecessary();
     
     for (const auto& row : m_rows) {
-        if (AccessibilityObject* header = toAccessibilityTableRow(row.get())->headerObject())
+        if (AccessibilityObject* header = downcast<AccessibilityTableRow>(*row).headerObject())
             headers.append(header);
     }
 }
@@ -548,19 +547,19 @@ AccessibilityTableCell* AccessibilityTable::cellForColumnAndRow(unsigned column,
         for (unsigned colIndexCounter = std::min(static_cast<unsigned>(children.size()), column + 1); colIndexCounter > 0; --colIndexCounter) {
             unsigned colIndex = colIndexCounter - 1;
             AccessibilityObject* child = children[colIndex].get();
-            ASSERT(child->isTableCell());
-            if (!child->isTableCell())
+            ASSERT(is<AccessibilityTableCell>(*child));
+            if (!is<AccessibilityTableCell>(*child))
                 continue;
             
             std::pair<unsigned, unsigned> columnRange;
             std::pair<unsigned, unsigned> rowRange;
-            AccessibilityTableCell* tableCellChild = toAccessibilityTableCell(child);
-            tableCellChild->columnIndexRange(columnRange);
-            tableCellChild->rowIndexRange(rowRange);
+            auto& tableCellChild = downcast<AccessibilityTableCell>(*child);
+            tableCellChild.columnIndexRange(columnRange);
+            tableCellChild.rowIndexRange(rowRange);
             
             if ((column >= columnRange.first && column < (columnRange.first + columnRange.second))
                 && (row >= rowRange.first && row < (rowRange.first + rowRange.second)))
-                return tableCellChild;
+                return &tableCellChild;
         }
     }
     
@@ -607,7 +606,7 @@ String AccessibilityTable::title() const
     
     // see if there is a caption
     Node* tableElement = m_renderer->node();
-    if (tableElement && is<HTMLTableElement>(tableElement)) {
+    if (is<HTMLTableElement>(tableElement)) {
         if (HTMLTableCaptionElement* caption = downcast<HTMLTableElement>(*tableElement).caption())
             title = caption->innerText();
     }