void AccessibilityTableCell::rowIndexRange(pair<int, int>& rowRange) { if (!m_renderer || !m_renderer->isTableCell()) return; RenderTableCell* renderCell = toRenderTableCell(m_renderer); rowRange.first = renderCell->rowIndex(); rowRange.second = renderCell->rowSpan(); // since our table might have multiple sections, we have to offset our row appropriately RenderTableSection* section = renderCell->section(); RenderTable* table = renderCell->table(); if (!table || !section) return; // FIXME: This will skip a table with just a tfoot. Should fix by using RenderTable::topSection. RenderTableSection* tableSection = table->header(); if (!tableSection) tableSection = table->firstBody(); unsigned rowOffset = 0; while (tableSection) { if (tableSection == section) break; rowOffset += tableSection->numRows(); tableSection = table->sectionBelow(tableSection, SkipEmptySections); } rowRange.first += rowOffset; }
void AccessibilityTableCell::rowIndexRange(std::pair<unsigned, unsigned>& rowRange) { if (!m_renderer || !m_renderer->isTableCell()) return; RenderTableCell* renderCell = toRenderTableCell(m_renderer); rowRange.first = renderCell->rowIndex(); rowRange.second = renderCell->rowSpan(); // since our table might have multiple sections, we have to offset our row appropriately RenderTableSection* section = renderCell->section(); RenderTable* table = renderCell->table(); if (!table || !section) return; RenderTableSection* tableSection = table->topSection(); unsigned rowOffset = 0; while (tableSection) { if (tableSection == section) break; rowOffset += tableSection->numRows(); tableSection = table->sectionBelow(tableSection, SkipEmptySections); } rowRange.first += rowOffset; }
void AccessibilityTableCell::rowIndexRange(pair<int, int>& rowRange) { if (!m_renderer) return; RenderTableCell* renderCell = static_cast<RenderTableCell*>(m_renderer); rowRange.first = renderCell->row(); rowRange.second = renderCell->rowSpan(); // since our table might have multiple sections, we have to offset our row appropriately RenderTableSection* section = renderCell->section(); RenderTable* table = renderCell->table(); if (!table || !section) return; RenderTableSection* tableSection = table->header(); if (!tableSection) tableSection = table->firstBody(); unsigned rowOffset = 0; while (tableSection) { if (tableSection == section) break; rowOffset += tableSection->numRows(); tableSection = table->sectionBelow(tableSection, true); } rowRange.first += rowOffset; }
void AccessibilityTable::addChildren() { if (!isAccessibilityTable()) { AccessibilityRenderObject::addChildren(); return; } ASSERT(!m_haveChildren); m_haveChildren = true; if (!m_renderer || !m_renderer->isTable()) return; RenderTable* table = toRenderTable(m_renderer); AXObjectCache* axCache = m_renderer->document().axObjectCache(); // Go through all the available sections to pull out the rows and add them as children. table->recalcSectionsIfNeeded(); RenderTableSection* tableSection = table->topSection(); if (!tableSection) return; unsigned maxColumnCount = 0; while (tableSection) { HashSet<AccessibilityObject*> appendedRows; unsigned numRows = tableSection->numRows(); for (unsigned rowIndex = 0; rowIndex < numRows; ++rowIndex) { RenderTableRow* renderRow = tableSection->rowRendererAt(rowIndex); if (!renderRow) continue; AccessibilityObject* rowObject = axCache->getOrCreate(renderRow); if (!rowObject->isTableRow()) continue; AccessibilityTableRow* row = toAccessibilityTableRow(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)) continue; 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()); #endif appendedRows.add(row); } maxColumnCount = std::max(tableSection->numColumns(), maxColumnCount); tableSection = table->sectionBelow(tableSection, SkipEmptySections); } // 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); } AccessibilityObject* headerContainerObject = headerContainer(); if (headerContainerObject && !headerContainerObject->accessibilityIsIgnored()) m_children.append(headerContainerObject); }
CollapsedBorderValue RenderTableCell::collapsedAfterBorder() const { RenderTable* table = this->table(); // For after border, we need to check, in order of precedence: // (1) Our after border. int before = CSSProperty::resolveDirectionAwareProperty(CSSPropertyWebkitBorderBeforeColor, table->style()->direction(), table->style()->writingMode()); int after = CSSProperty::resolveDirectionAwareProperty(CSSPropertyWebkitBorderAfterColor, table->style()->direction(), table->style()->writingMode()); CollapsedBorderValue result = CollapsedBorderValue(&style()->borderAfter(), style()->visitedDependentColor(after), BCELL); RenderTableCell* nextCell = table->cellBelow(this); if (nextCell) { // (2) An after cell's before border. result = chooseBorder(result, CollapsedBorderValue(&nextCell->style()->borderBefore(), nextCell->style()->visitedDependentColor(before), BCELL)); if (!result.exists()) return result; } // (3) Our row's after border. (FIXME: Deal with rowspan!) result = chooseBorder(result, CollapsedBorderValue(&parent()->style()->borderAfter(), parent()->style()->visitedDependentColor(after), BROW)); if (!result.exists()) return result; // (4) The next row's before border. if (nextCell) { result = chooseBorder(result, CollapsedBorderValue(&nextCell->parent()->style()->borderBefore(), nextCell->parent()->style()->visitedDependentColor(before), BROW)); if (!result.exists()) return result; } // Now check row groups. RenderTableSection* currSection = section(); if (row() + rowSpan() >= currSection->numRows()) { // (5) Our row group's after border. result = chooseBorder(result, CollapsedBorderValue(&currSection->style()->borderAfter(), currSection->style()->visitedDependentColor(after), BROWGROUP)); if (!result.exists()) return result; // (6) Following row group's before border. currSection = table->sectionBelow(currSection); if (currSection) { result = chooseBorder(result, CollapsedBorderValue(&currSection->style()->borderBefore(), currSection->style()->visitedDependentColor(before), BROWGROUP)); if (!result.exists()) return result; } } if (!currSection) { // (8) Our column and column group's after borders. RenderTableCol* colElt = table->colElement(col()); if (colElt) { result = chooseBorder(result, CollapsedBorderValue(&colElt->style()->borderAfter(), colElt->style()->visitedDependentColor(after), BCOL)); if (!result.exists()) return result; if (colElt->parent()->isTableCol()) { result = chooseBorder(result, CollapsedBorderValue(&colElt->parent()->style()->borderAfter(), colElt->parent()->style()->visitedDependentColor(after), BCOLGROUP)); if (!result.exists()) return result; } } // (9) The table's after border. result = chooseBorder(result, CollapsedBorderValue(&table->style()->borderAfter(), table->style()->visitedDependentColor(after), BTABLE)); if (!result.exists()) return result; } return result; }
AccessibilityTableCell* AccessibilityTable::cellForColumnAndRow(unsigned column, unsigned row) { if (!m_renderer) return 0; if (!hasChildren()) addChildren(); RenderTable* table = static_cast<RenderTable*>(m_renderer); RenderTableSection* tableSection = table->header(); if (!tableSection) tableSection = table->firstBody(); RenderTableCell* cell = 0; unsigned rowCount = 0; unsigned rowOffset = 0; while (tableSection) { rowCount += tableSection->numRows(); unsigned numCols = tableSection->numColumns(); if (row < rowCount && column < numCols) { int sectionSpecificRow = row - rowOffset; cell = tableSection->cellAt(sectionSpecificRow, column).cell; // we didn't find the cell, which means there's spanning happening // search backwards to find the spanning cell if (!cell) { // first try rows for (int testRow = sectionSpecificRow-1; testRow >= 0; --testRow) { cell = tableSection->cellAt(testRow, column).cell; // cell overlapped. use this one if (cell && ((cell->row() + (cell->rowSpan()-1)) >= (int)sectionSpecificRow)) break; cell = 0; } if (!cell) { // try cols for (int testCol = column-1; testCol >= 0; --testCol) { cell = tableSection->cellAt(sectionSpecificRow, testCol).cell; // cell overlapped. use this one if (cell && ((cell->col() + (cell->colSpan()-1)) >= (int)column)) break; cell = 0; } } } } if (cell) break; rowOffset += rowCount; // we didn't find anything between the rows we should have if (row < rowOffset) break; tableSection = table->sectionBelow(tableSection, true); } if (!cell) return 0; AccessibilityObject* cellObject = axObjectCache()->get(cell); ASSERT(cellObject->isTableCell()); return static_cast<AccessibilityTableCell*>(cellObject); }
void AccessibilityTable::addChildren() { if (!isDataTable()) { AccessibilityRenderObject::addChildren(); return; } ASSERT(!m_haveChildren); m_haveChildren = true; if (!m_renderer) return; RenderTable* table = static_cast<RenderTable*>(m_renderer); AXObjectCache* axCache = m_renderer->document()->axObjectCache(); // go through all the available sections to pull out the rows // and add them as children RenderTableSection* tableSection = table->header(); if (!tableSection) tableSection = table->firstBody(); if (!tableSection) return; RenderTableSection* initialTableSection = tableSection; while (tableSection) { HashSet<AccessibilityObject*> appendedRows; unsigned numRows = tableSection->numRows(); unsigned numCols = tableSection->numColumns(); for (unsigned rowIndex = 0; rowIndex < numRows; ++rowIndex) { for (unsigned colIndex = 0; colIndex < numCols; ++colIndex) { RenderTableCell* cell = tableSection->cellAt(rowIndex, colIndex).cell; if (!cell) continue; AccessibilityObject* rowObject = axCache->get(cell->parent()); if (!rowObject->isTableRow()) continue; AccessibilityTableRow* row = static_cast<AccessibilityTableRow*>(rowObject); // we need to check every cell for a new row, because cell spans // can cause us to mess rows if we just check the first column if (appendedRows.contains(row)) continue; row->setRowIndex((int)m_rows.size()); m_rows.append(row); m_children.append(row); appendedRows.add(row); } } tableSection = table->sectionBelow(tableSection, true); } // make the columns based on the number of columns in the first body unsigned length = initialTableSection->numColumns(); for (unsigned i = 0; i < length; ++i) { AccessibilityTableColumn* column = static_cast<AccessibilityTableColumn*>(axCache->get(ColumnRole)); column->setColumnIndex((int)i); column->setParentTable(this); m_columns.append(column); m_children.append(column); } AccessibilityObject* headerContainerObject = headerContainer(); if (headerContainerObject) m_children.append(headerContainerObject); }
AccessibilityTableCell* AccessibilityTable::cellForColumnAndRow(unsigned column, unsigned row) { if (!m_renderer || !m_renderer->isTable()) return 0; updateChildrenIfNecessary(); RenderTable* table = toRenderTable(m_renderer); // FIXME: This will skip a table with just a tfoot. Should fix by using RenderTable::topSection. RenderTableSection* tableSection = table->header(); if (!tableSection) tableSection = table->firstBody(); RenderTableCell* cell = 0; unsigned rowCount = 0; unsigned rowOffset = 0; while (tableSection) { unsigned numRows = tableSection->numRows(); unsigned numCols = tableSection->numColumns(); rowCount += numRows; unsigned sectionSpecificRow = row - rowOffset; if (row < rowCount && column < numCols && sectionSpecificRow < numRows) { cell = tableSection->primaryCellAt(sectionSpecificRow, column); // we didn't find the cell, which means there's spanning happening // search backwards to find the spanning cell if (!cell) { // first try rows for (int testRow = sectionSpecificRow - 1; testRow >= 0; --testRow) { cell = tableSection->primaryCellAt(testRow, column); // cell overlapped. use this one ASSERT(cell->rowSpan() >= 1); if (cell && ((cell->rowIndex() + (cell->rowSpan() - 1)) >= sectionSpecificRow)) break; cell = 0; } if (!cell) { // try cols for (int testCol = column - 1; testCol >= 0; --testCol) { cell = tableSection->primaryCellAt(sectionSpecificRow, testCol); // cell overlapped. use this one ASSERT(cell->rowSpan() >= 1); if (cell && ((cell->col() + (cell->colSpan() - 1)) >= column)) break; cell = 0; } } } } if (cell) break; rowOffset += numRows; // we didn't find anything between the rows we should have if (row < rowCount) break; tableSection = table->sectionBelow(tableSection, SkipEmptySections); } if (!cell) return 0; AccessibilityObject* cellObject = axObjectCache()->getOrCreate(cell); ASSERT(cellObject->isTableCell()); return static_cast<AccessibilityTableCell*>(cellObject); }
void AccessibilityTable::addChildren() { if (!isAccessibilityTable()) { AccessibilityRenderObject::addChildren(); return; } ASSERT(!m_haveChildren); m_haveChildren = true; if (!m_renderer || !m_renderer->isTable()) return; RenderTable* table = toRenderTable(m_renderer); AXObjectCache* axCache = m_renderer->document()->axObjectCache(); // go through all the available sections to pull out the rows // and add them as children // FIXME: This will skip a table with just a tfoot. Should fix by using RenderTable::topSection. RenderTableSection* tableSection = table->header(); if (!tableSection) tableSection = table->firstBody(); if (!tableSection) return; RenderTableSection* initialTableSection = tableSection; while (tableSection) { HashSet<AccessibilityObject*> appendedRows; unsigned numRows = tableSection->numRows(); unsigned numCols = tableSection->numColumns(); for (unsigned rowIndex = 0; rowIndex < numRows; ++rowIndex) { for (unsigned colIndex = 0; colIndex < numCols; ++colIndex) { RenderTableCell* cell = tableSection->primaryCellAt(rowIndex, colIndex); if (!cell) continue; AccessibilityObject* rowObject = axCache->getOrCreate(cell->parent()); if (!rowObject->isTableRow()) continue; AccessibilityTableRow* row = static_cast<AccessibilityTableRow*>(rowObject); // we need to check every cell for a new row, because cell spans // can cause us to mess rows if we just check the first column if (appendedRows.contains(row)) continue; row->setRowIndex((int)m_rows.size()); m_rows.append(row); if (!row->accessibilityIsIgnored()) m_children.append(row); #if PLATFORM(GTK) else m_children.append(row->children()); #endif appendedRows.add(row); } } tableSection = table->sectionBelow(tableSection, SkipEmptySections); } // make the columns based on the number of columns in the first body unsigned length = initialTableSection->numColumns(); for (unsigned i = 0; i < length; ++i) { AccessibilityTableColumn* column = static_cast<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(); if (headerContainerObject && !headerContainerObject->accessibilityIsIgnored()) m_children.append(headerContainerObject); }
void AccessibilityTable::addChildren() { if (!isAccessibilityTable()) { AccessibilityRenderObject::addChildren(); return; } ASSERT(!m_haveChildren); m_haveChildren = true; if (!m_renderer || !m_renderer->isTable()) return; RenderTable* table = toRenderTable(m_renderer); // Go through all the available sections to pull out the rows and add them as children. table->recalcSectionsIfNeeded(); unsigned maxColumnCount = 0; RenderTableSection* footer = table->footer(); for (RenderTableSection* tableSection = table->topSection(); tableSection; tableSection = table->sectionBelow(tableSection, SkipEmptySections)) { if (tableSection == footer) continue; addChildrenFromSection(tableSection, maxColumnCount); } // Process the footer last, in case it was ordered earlier in the DOM. if (footer) addChildrenFromSection(footer, maxColumnCount); AXObjectCache* axCache = m_renderer->document().axObjectCache(); // 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); } AccessibilityObject* headerContainerObject = headerContainer(); if (headerContainerObject && !headerContainerObject->accessibilityIsIgnored()) m_children.append(headerContainerObject); }
void AccessibilityTableCell::rowIndexRange(std::pair<unsigned, unsigned>& rowRange) { if (!m_renderer || !m_renderer->isTableCell()) return; RenderTableCell* renderCell = toRenderTableCell(m_renderer); rowRange.first = renderCell->rowIndex(); rowRange.second = renderCell->rowSpan(); // since our table might have multiple sections, we have to offset our row appropriately RenderTableSection* section = renderCell->section(); RenderTable* table = renderCell->table(); if (!table || !section) return; RenderTableSection* footerSection = table->footer(); unsigned rowOffset = 0; for (RenderTableSection* tableSection = table->topSection(); tableSection; tableSection = table->sectionBelow(tableSection, SkipEmptySections)) { // Don't add row offsets for bottom sections that are placed in before the body section. if (tableSection == footerSection) continue; if (tableSection == section) break; rowOffset += tableSection->numRows(); } rowRange.first += rowOffset; }