AccessibilityTableCell* AccessibilityTable::cellForColumnAndRow(unsigned column, unsigned row) { updateChildrenIfNecessary(); if (column >= columnCount() || row >= rowCount()) return 0; // Iterate backwards through the rows in case the desired cell has a rowspan and exists in a previous row. for (unsigned rowIndexCounter = row + 1; rowIndexCounter > 0; --rowIndexCounter) { unsigned rowIndex = rowIndexCounter - 1; const auto& children = m_rows[rowIndex]->children(); // Since some cells may have colspans, we have to check the actual range of each // cell to determine which is the right one. 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()) continue; std::pair<unsigned, unsigned> columnRange; std::pair<unsigned, unsigned> rowRange; AccessibilityTableCell* tableCellChild = toAccessibilityTableCell(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 0; }
void AccessibilityTableCell::columnHeaders(AccessibilityChildrenVector& headers) { AccessibilityTable* parent = parentTable(); if (!parent) return; // 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; std::pair<unsigned, unsigned> rowRange; rowIndexRange(rowRange); std::pair<unsigned, unsigned> colRange; columnIndexRange(colRange); for (unsigned row = 0; row < rowRange.first; row++) { AccessibilityTableCell* tableCell = parent->cellForColumnAndRow(colRange.first, row); if (!tableCell || tableCell == this || headers.contains(tableCell)) continue; std::pair<unsigned, unsigned> childRowRange; tableCell->rowIndexRange(childRowRange); const AtomicString& scope = tableCell->getAttribute(scopeAttr); if (scope == "col" || tableCell->isTableHeaderCell()) headers.append(tableCell); else if (scope == "colgroup" && isTableCellInSameColGroup(tableCell)) headers.append(tableCell); } }
void AccessibilityTableCell::columnHeaders(AccessibilityChildrenVector& headers) { AccessibilityTable* parent = parentTable(); if (!parent) return; std::pair<unsigned, unsigned> rowRange; rowIndexRange(rowRange); std::pair<unsigned, unsigned> colRange; columnIndexRange(colRange); for (unsigned row = 0; row < rowRange.first; row++) { AccessibilityTableCell* tableCell = parent->cellForColumnAndRow(colRange.first, row); if (tableCell == this || headers.contains(tableCell)) continue; std::pair<unsigned, unsigned> childRowRange; tableCell->rowIndexRange(childRowRange); const AtomicString& scope = tableCell->getAttribute(scopeAttr); if (scope == "col" || tableCell->isTableHeaderCell()) headers.append(tableCell); else if (scope == "colgroup" && isTableCellInSameColGroup(tableCell)) headers.append(tableCell); } }
void AccessibilityTableColumn::addChildren() { ASSERT(!m_haveChildren); m_haveChildren = true; if (!is<AccessibilityTable>(m_parent)) return; auto& parentTable = downcast<AccessibilityTable>(*m_parent); if (!parentTable.isExposableThroughAccessibility()) return; int numRows = parentTable.rowCount(); for (int i = 0; i < numRows; ++i) { AccessibilityTableCell* cell = parentTable.cellForColumnAndRow(m_columnIndex, i); if (!cell) continue; // make sure the last one isn't the same as this one (rowspan cells) if (m_children.size() > 0 && m_children.last() == cell) continue; m_children.append(cell); m_columnRect.unite(cell->elementRect()); } }
static AtkObject* webkit_accessible_table_ref_at(AtkTable* table, gint row, gint column) { AccessibilityTableCell* AXCell = cell(table, row, column); if (!AXCell) return 0; return AXCell->wrapper(); }
static gint webkit_accessible_table_get_row_extent_at(AtkTable* table, gint row, gint column) { AccessibilityTableCell* AXCell = cell(table, row, column); if (AXCell) { pair<int, int> rowRange; AXCell->rowIndexRange(rowRange); return rowRange.second; } return 0; }
static gint webkitAccessibleTableGetRowExtentAt(AtkTable* table, gint row, gint column) { AccessibilityTableCell* axCell = cell(table, row, column); if (axCell) { pair<unsigned, unsigned> rowRange; axCell->rowIndexRange(rowRange); return rowRange.second; } return 0; }
static gint webkitAccessibleTableGetRowAtIndex(AtkTable* table, gint index) { AccessibilityTableCell* axCell = cellAtIndex(table, index); if (axCell) { pair<unsigned, unsigned> rowRange; axCell->rowIndexRange(rowRange); return rowRange.first; } return -1; }
static gint webkitAccessibleTableGetColumnAtIndex(AtkTable* table, gint index) { AccessibilityTableCell* axCell = cellAtIndex(table, index); if (axCell) { pair<unsigned, unsigned> columnRange; axCell->columnIndexRange(columnRange); return columnRange.first; } return -1; }
static gint webkitAccessibleTableGetRowExtentAt(AtkTable* table, gint row, gint column) { g_return_val_if_fail(ATK_TABLE(table), 0); returnValIfWebKitAccessibleIsInvalid(WEBKIT_ACCESSIBLE(table), 0); AccessibilityTableCell* axCell = cell(table, row, column); if (axCell) { pair<unsigned, unsigned> rowRange; axCell->rowIndexRange(rowRange); return rowRange.second; } return 0; }
static gint webkitAccessibleTableGetRowAtIndex(AtkTable* table, gint index) { g_return_val_if_fail(ATK_TABLE(table), -1); returnValIfWebKitAccessibleIsInvalid(WEBKIT_ACCESSIBLE(table), -1); AccessibilityTableCell* axCell = cellAtIndex(table, index); if (axCell) { pair<unsigned, unsigned> rowRange; axCell->rowIndexRange(rowRange); return rowRange.first; } return -1; }
static AtkObject* webkitAccessibleTableRefAt(AtkTable* table, gint row, gint column) { AccessibilityTableCell* axCell = cell(table, row, column); if (!axCell) return 0; AtkObject* cell = axCell->wrapper(); if (!cell) return 0; // This method transfers full ownership over the returned // AtkObject, so an extra reference is needed here. return ATK_OBJECT(g_object_ref(cell)); }
static AtkObject* webkitAccessibleTableGetRowHeader(AtkTable* table, gint row) { AccessibilityObject* accTable = core(table); if (accTable->isAccessibilityRenderObject()) { AccessibilityObject::AccessibilityChildrenVector allRowHeaders; static_cast<AccessibilityTable*>(accTable)->rowHeaders(allRowHeaders); unsigned rowCount = allRowHeaders.size(); for (unsigned k = 0; k < rowCount; ++k) { pair<unsigned, unsigned> rowRange; AccessibilityTableCell* cell = static_cast<AccessibilityTableCell*>(allRowHeaders.at(k).get()); cell->rowIndexRange(rowRange); if (rowRange.first <= static_cast<unsigned>(row) && static_cast<unsigned>(row) < rowRange.first + rowRange.second) return allRowHeaders[k]->wrapper(); } } return 0; }
static AtkObject* webkitAccessibleTableRefAt(AtkTable* table, gint row, gint column) { g_return_val_if_fail(ATK_TABLE(table), 0); returnValIfWebKitAccessibleIsInvalid(WEBKIT_ACCESSIBLE(table), 0); AccessibilityTableCell* axCell = cell(table, row, column); if (!axCell) return 0; AtkObject* cell = axCell->wrapper(); if (!cell) return 0; // This method transfers full ownership over the returned // AtkObject, so an extra reference is needed here. return ATK_OBJECT(g_object_ref(cell)); }
AccessibilityTableCell* AccessibilityARIAGrid::cellForColumnAndRow(unsigned column, unsigned row) { if (!m_renderer) return 0; updateChildrenIfNecessary(); if (column >= columnCount() || row >= rowCount()) return 0; int intRow = (int)row; int intColumn = (int)column; pair<int, int> columnRange; pair<int, int> rowRange; // Iterate backwards through the rows in case the desired cell has a rowspan and exists // in a previous row. for (; intRow >= 0; --intRow) { AccessibilityObject* tableRow = m_rows[intRow].get(); if (!tableRow) continue; AccessibilityChildrenVector children = tableRow->children(); unsigned childrenLength = children.size(); // Since some cells may have colspans, we have to check the actual range of each // cell to determine which is the right one. for (unsigned k = 0; k < childrenLength; ++k) { AccessibilityObject* child = children[k].get(); if (!child->isTableCell()) continue; AccessibilityTableCell* tableCellChild = static_cast<AccessibilityTableCell*>(child); tableCellChild->columnIndexRange(columnRange); tableCellChild->rowIndexRange(rowRange); if ((intColumn >= columnRange.first && intColumn < (columnRange.first + columnRange.second)) && (intRow >= rowRange.first && intRow < (rowRange.first + rowRange.second))) return tableCellChild; } } return 0; }
static AtkObject* webkitAccessibleTableGetRowHeader(AtkTable* table, gint row) { g_return_val_if_fail(ATK_TABLE(table), 0); returnValIfWebKitAccessibleIsInvalid(WEBKIT_ACCESSIBLE(table), 0); AccessibilityObject* accTable = core(table); if (accTable->isAccessibilityRenderObject()) { AccessibilityObject::AccessibilityChildrenVector allRowHeaders; toAccessibilityTable(accTable)->rowHeaders(allRowHeaders); unsigned rowCount = allRowHeaders.size(); for (unsigned k = 0; k < rowCount; ++k) { pair<unsigned, unsigned> rowRange; AccessibilityTableCell* cell = toAccessibilityTableCell(allRowHeaders.at(k).get()); cell->rowIndexRange(rowRange); if (rowRange.first <= static_cast<unsigned>(row) && static_cast<unsigned>(row) < rowRange.first + rowRange.second) return allRowHeaders[k]->wrapper(); } } return 0; }
void AccessibilityTableColumn::addChildren() { ASSERT(!m_haveChildren); m_haveChildren = true; if (!m_parentTable) return; int numRows = m_parentTable->rowCount(); for (int i = 0; i < numRows; i++) { AccessibilityTableCell* cell = m_parentTable->cellForColumnAndRow(m_columnIndex, i); if (!cell) continue; // make sure the last one isn't the same as this one (rowspan cells) if (m_children.size() > 0 && m_children.last() == cell) continue; m_children.append(cell); m_columnRect.unite(cell->elementRect()); } }
void AccessibilityTableCell::rowHeaders(AccessibilityChildrenVector& headers) { AccessibilityTable* parent = parentTable(); if (!parent) return; std::pair<unsigned, unsigned> rowRange; rowIndexRange(rowRange); std::pair<unsigned, unsigned> colRange; columnIndexRange(colRange); for (unsigned column = 0; column < colRange.first; column++) { AccessibilityTableCell* tableCell = parent->cellForColumnAndRow(column, rowRange.first); if (tableCell == this || headers.contains(tableCell)) continue; const AtomicString& scope = tableCell->getAttribute(scopeAttr); if (scope == "row") headers.append(tableCell); else if (scope == "rowgroup" && isTableCellInSameRowGroup(tableCell)) headers.append(tableCell); } }