Exemple #1
0
void AXTableColumn::headerObjectsForColumn(AXObjectVector& headers) {
  if (!m_parent)
    return;

  LayoutObject* layoutObject = m_parent->getLayoutObject();
  if (!layoutObject)
    return;

  if (!m_parent->isAXTable())
    return;

  if (toAXTable(m_parent)->isAriaTable()) {
    for (const auto& cell : children()) {
      if (cell->roleValue() == ColumnHeaderRole)
        headers.append(cell);
    }
    return;
  }

  if (!layoutObject->isTable())
    return;

  LayoutTable* table = toLayoutTable(layoutObject);
  LayoutTableSection* tableSection = table->topSection();
  for (; tableSection;
       tableSection = table->sectionBelow(tableSection, SkipEmptySections)) {
    unsigned numCols = tableSection->numEffectiveColumns();
    if (m_columnIndex >= numCols)
      continue;
    unsigned numRows = tableSection->numRows();
    for (unsigned r = 0; r < numRows; r++) {
      LayoutTableCell* layoutCell =
          tableSection->primaryCellAt(r, m_columnIndex);
      if (!layoutCell)
        continue;

      AXObject* cell = axObjectCache().getOrCreate(layoutCell->node());
      if (!cell || !cell->isTableCell() || headers.contains(cell))
        continue;

      if (toAXTableCell(cell)->scanToDecideHeaderRole() == ColumnHeaderRole)
        headers.append(cell);
    }
  }
}
void AXTable::addChildren()
{
    ASSERT(!isDetached());
    if (!isAXTable()) {
        AXLayoutObject::addChildren();
        return;
    }

    ASSERT(!m_haveChildren);

    m_haveChildren = true;
    if (!m_layoutObject || !m_layoutObject->isTable())
        return;

    LayoutTable* table = toLayoutTable(m_layoutObject);
    AXObjectCacheImpl& axCache = axObjectCache();

    Node* tableNode = table->node();
    if (!isHTMLTableElement(tableNode))
        return;

    // Add caption
    if (HTMLTableCaptionElement* caption  = toHTMLTableElement(tableNode)->caption()) {
        AXObject* captionObject = axCache.getOrCreate(caption);
        if (captionObject && !captionObject->accessibilityIsIgnored())
            m_children.append(captionObject);
    }

    // Go through all the available sections to pull out the rows and add them as children.
    table->recalcSectionsIfNeeded();
    LayoutTableSection* tableSection = table->topSection();
    if (!tableSection)
        return;

    LayoutTableSection* initialTableSection = tableSection;
    while (tableSection) {

        HeapHashSet<Member<AXObject>> appendedRows;
        unsigned numRows = tableSection->numRows();
        for (unsigned rowIndex = 0; rowIndex < numRows; ++rowIndex) {

            LayoutTableRow* layoutRow = tableSection->rowLayoutObjectAt(rowIndex);
            if (!layoutRow)
                continue;

            AXObject* rowObject = axCache.getOrCreate(layoutRow);
            if (!rowObject || !rowObject->isTableRow())
                continue;

            AXTableRow* row = toAXTableRow(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);
            appendedRows.add(row);
        }

        tableSection = table->sectionBelow(tableSection, SkipEmptySections);
    }

    // make the columns based on the number of columns in the first body
    unsigned length = initialTableSection->numEffectiveColumns();
    for (unsigned i = 0; i < length; ++i) {
        AXTableColumn* column = toAXTableColumn(axCache.getOrCreate(ColumnRole));
        column->setColumnIndex((int)i);
        column->setParent(this);
        m_columns.append(column);
        if (!column->accessibilityIsIgnored())
            m_children.append(column);
    }

    AXObject* headerContainerObject = headerContainer();
    if (headerContainerObject && !headerContainerObject->accessibilityIsIgnored())
        m_children.append(headerContainerObject);
}