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);
    }
}
Пример #2
0
void AccessibilityObject::accessibleObjectsWithAccessibilitySearchPredicate(AccessibilitySearchPredicate* axSearchPredicate, AccessibilityChildrenVector& axResults)
{
    ASSERT(AXObjectCache::accessibilityEnabled());
    
    if (!axSearchPredicate)
        return;
    
    AccessibilityChildrenVector axChildren;
    if (axSearchPredicate->axContainerObject)
        axChildren.append(axSearchPredicate->axContainerObject);
    
    bool isSearchDirectionNext = (axSearchPredicate->axSearchDirection == SearchDirectionNext);
    bool didFindAXStartObject = (!axSearchPredicate->axStartObject);
    
    // FIXME: Iterate the AccessibilityObject cache creating and adding objects if nessesary.
    while (!axChildren.isEmpty() && axResults.size() < axSearchPredicate->resultsLimit) {
        AccessibilityObject* axChild = axChildren.last().get();
        axChildren.removeLast();
        
        if (didFindAXStartObject) {
            if (isAccessibilityObjectSearchMatch(axChild, axSearchPredicate)
                && isAccessibilityTextSearchMatch(axChild, axSearchPredicate))
                axResults.append(axChild);
        } else if (axChild == axSearchPredicate->axStartObject)
            didFindAXStartObject = true;
        
        AccessibilityChildrenVector axGrandchildren = axChild->children();
        unsigned axGrandchildrenSize = axChild->children().size();
        for (unsigned i = (isSearchDirectionNext) ? axGrandchildrenSize : 0; (isSearchDirectionNext) ? i > 0 : i < axGrandchildrenSize; (isSearchDirectionNext) ? i-- : i++)
            // FIXME: Handle attachments.
            axChildren.append(axGrandchildren.at((isSearchDirectionNext) ? i - 1 : i).get());
    }
}
Пример #3
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);
    }
}
Пример #4
0
void AccessibilityARIAGridRow::disclosedRows(AccessibilityChildrenVector& disclosedRows)
{
    // 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())
        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();
    int rowCount = allRows.size();
    for (int k = index + 1; k < rowCount; ++k) {
        AccessibilityObject* row = allRows[k].get();
        // Stop at the first row that doesn't match the correct level.
        if (row->hierarchicalLevel() != level + 1)
            break;

        disclosedRows.append(row);
    }
}
Пример #5
0
void AccessibilityTable::columnHeaders(AccessibilityChildrenVector& headers)
{
    if (!m_renderer)
        return;
    
    updateChildrenIfNecessary();
    
    for (const auto& column : m_columns) {
        if (AccessibilityObject* header = toAccessibilityTableColumn(column.get())->headerObject())
            headers.append(header);
    }
}
Пример #6
0
void AccessibilityTable::rowHeaders(AccessibilityChildrenVector& headers)
{
    if (!m_renderer)
        return;
    
    updateChildrenIfNecessary();
    
    for (const auto& row : m_rows) {
        if (AccessibilityObject* header = toAccessibilityTableRow(row.get())->headerObject())
            headers.append(header);
    }
}
Пример #7
0
void AccessibilityTable::visibleRows(AccessibilityChildrenVector& rows)
{
    if (!m_renderer)
        return;
    
    updateChildrenIfNecessary();
    
    for (const auto& row : m_rows) {
        if (row && !row->isOffScreen())
            rows.append(row);
    }
}
Пример #8
0
void AccessibilityListBox::selectedChildren(AccessibilityChildrenVector& result)
{
    ASSERT(result.isEmpty());

    if (!hasChildren())
        addChildren();
        
    for (const auto& child : m_children) {
        if (toAccessibilityListBoxOption(child.get())->isSelected())
            result.append(child.get());
    }    
}
Пример #9
0
void AccessibilityARIAGrid::addChildren()
{
    ASSERT(!m_haveChildren); 
    
    if (!isAccessibilityTable()) {
        AccessibilityRenderObject::addChildren();
        return;
    }
    
    m_haveChildren = true;
    if (!m_renderer)
        return;
    
    AXObjectCache* axCache = m_renderer->document().axObjectCache();
    
    // Add the children rows but be mindful in case there are footer sections in this table.
    HashSet<AccessibilityObject*> appendedRows;
    unsigned columnCount = 0;
    AccessibilityChildrenVector footerSections;
    for (RefPtr<AccessibilityObject> child = firstChild(); child; child = child->nextSibling()) {
        bool footerSection = false;
        if (RenderObject* childRenderer = child->renderer()) {
            if (childRenderer->isTableSection()) {
                if (RenderTableSection* childSection = toRenderTableSection(childRenderer)) {
                    if (childSection == childSection->table()->footer()) {
                        footerSections.append(child);
                        footerSection = true;
                    }
                }
            }
        }
        if (!footerSection)
            addRowDescendant(child.get(), appendedRows, columnCount);
    }
    
    for (const auto& footerSection : footerSections)
        addRowDescendant(footerSection.get(), appendedRows, columnCount);
    
    // make the columns based on the number of columns in the first body
    for (unsigned i = 0; i < columnCount; ++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 AccessibilityListBox::visibleChildren(AccessibilityChildrenVector& result)
{
    ASSERT(result.isEmpty());
    
    if (!hasChildren())
        addChildren();
    
    unsigned length = m_children.size();
    for (unsigned i = 0; i < length; i++) {
        if (toRenderListBox(m_renderer)->listIndexIsVisible(i))
            result.append(m_children[i]);
    }
}
void AccessibilityListBox::selectedChildren(AccessibilityChildrenVector& result)
{
    ASSERT(result.isEmpty());

    if (!hasChildren())
        addChildren();
        
    unsigned length = m_children.size();
    for (unsigned i = 0; i < length; i++) {
        if (static_cast<AccessibilityListBoxOption*>(m_children[i].get())->isSelected())
            result.append(m_children[i]);
    }    
}
Пример #12
0
void AccessibilityTable::rowHeaders(AccessibilityChildrenVector& headers)
{
    if (!m_renderer)
        return;
    
    updateChildrenIfNecessary();
    
    size_t rowCount = m_rows.size();
    for (size_t i = 0; i < rowCount; ++i) {
        if (AccessibilityObject* header = toAccessibilityTableRow(m_rows[i].get())->headerObject())
            headers.append(header);
    }
}
Пример #13
0
void AccessibilityTable::columnHeaders(AccessibilityChildrenVector& headers)
{
    if (!m_renderer)
        return;
    
    updateChildrenIfNecessary();
    
    size_t columnCount = m_columns.size();
    for (size_t i = 0; i < columnCount; ++i) {
        if (AccessibilityObject* header = toAccessibilityTableColumn(m_columns[i].get())->headerObject())
            headers.append(header);
    }
}
Пример #14
0
void AccessibilityObject::findMatchingObjects(AccessibilitySearchCriteria* criteria, AccessibilityChildrenVector& results)
{
    ASSERT(criteria);
    
    if (!criteria)
        return;
    
    AccessibilityObject* startObject = criteria->startObject;
    AccessibilityChildrenVector searchStack;
    searchStack.append(this);
    
    bool isForward = criteria->searchDirection == SearchDirectionNext;
    bool didFindStartObject = !criteria->startObject;
    
    // FIXME: Iterate the AccessibilityObject cache creating and adding objects if nessesary.
    while (!searchStack.isEmpty()) {
        AccessibilityObject* searchObject = searchStack.last().get();
        searchStack.removeLast();
        
        if (didFindStartObject) {
            if (isAccessibilityObjectSearchMatch(searchObject, criteria) && isAccessibilityTextSearchMatch(searchObject, criteria)) {
                results.append(searchObject);
             
                // Enough results were found to stop searching.
                if (results.size() >= criteria->resultsLimit)
                    break;
            }
        } else if (searchObject == startObject)
            didFindStartObject = true;
        
        AccessibilityChildrenVector searchChildren = searchObject->children();
        size_t childrenSize = searchChildren.size();
        for (size_t i = isForward ? childrenSize : 0; isForward ? i > 0 : i < childrenSize; isForward ? i-- : i++) {
            // FIXME: Handle attachments.
            searchStack.append(searchChildren.at(isForward ? i - 1 : i).get());
        }
    }
}
Пример #15
0
void AccessibilityTable::visibleRows(AccessibilityChildrenVector& rows)
{
    if (!m_renderer)
        return;
    
    updateChildrenIfNecessary();
    
    size_t rowCount = m_rows.size();
    for (size_t i = 0; i < rowCount; ++i) {
        AccessibilityObject* row = m_rows[i].get();
        if (row && !row->isOffScreen())
            rows.append(row);
    }
}
Пример #16
0
void AccessibilityObject::ariaTreeItemContent(AccessibilityChildrenVector& result)
{
    // The ARIA tree item content are the item that are not other tree items or their containing groups.
    AccessibilityChildrenVector axChildren = children();
    unsigned count = axChildren.size();
    for (unsigned k = 0; k < count; ++k) {
        AccessibilityObject* obj = axChildren[k].get();
        AccessibilityRole role = obj->roleValue();
        if (role == TreeItemRole || role == GroupRole)
            continue;
        
        result.append(obj);
    }
}
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);
    }
}
Пример #18
0
void AccessibilityTable::rowHeaders(AccessibilityChildrenVector& headers)
{
    if (!m_renderer)
        return;
    
    updateChildrenIfNecessary();
    
    unsigned rowCount = m_rows.size();
    for (unsigned k = 0; k < rowCount; ++k) {
        AccessibilityObject* header = toAccessibilityTableRow(m_rows[k].get())->headerObject();
        if (!header)
            continue;
        headers.append(header);
    }
}
Пример #19
0
void AXTable::columnHeaders(AccessibilityChildrenVector& headers)
{
    if (!m_renderer)
        return;

    updateChildrenIfNecessary();

    unsigned colCount = m_columns.size();
    for (unsigned k = 0; k < colCount; ++k) {
        AXObject* header = toAXTableColumn(m_columns[k].get())->headerObject();
        if (!header)
            continue;
        headers.append(header);
    }
}
Пример #20
0
void AccessibilityObject::ariaTreeItemDisclosedRows(AccessibilityChildrenVector& result)
{
    AccessibilityChildrenVector axChildren = children();
    unsigned count = axChildren.size();
    for (unsigned k = 0; k < count; ++k) {
        AccessibilityObject* obj = axChildren[k].get();
        
        // Add tree items as the rows.
        if (obj->roleValue() == TreeItemRole)
            result.append(obj);
        // If it's not a tree item, then descend into the group to find more tree items.
        else 
            obj->ariaTreeRows(result);
    }    
}
void AccessibilityObject::ariaTreeRows(AccessibilityChildrenVector& result)
{
    AccessibilityChildrenVector axChildren = children();
    unsigned count = axChildren.size();
    for (unsigned k = 0; k < count; ++k) {
        AccessibilityObject* obj = axChildren[k].get();

        // Add tree items as the rows.
        if (obj->roleValue() == TreeItemRole)
            result.append(obj);

        // Now see if this item also has rows hiding inside of it.
        obj->ariaTreeRows(result);
    }
}
Пример #22
0
void AccessibilityTable::columnHeaders(AccessibilityChildrenVector& headers)
{
    if (!m_renderer)
        return;
    
    if (!hasChildren())
        addChildren();
    
    unsigned colCount = m_columns.size();
    for (unsigned k = 0; k < colCount; ++k) {
        AccessibilityObject* header = static_cast<AccessibilityTableColumn*>(m_columns[k].get())->headerObject();
        if (!header)
            continue;
        headers.append(header);
    }
}