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 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()); } }
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 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); } }
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); } }
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); } }
void AccessibilityTable::visibleRows(AccessibilityChildrenVector& rows) { if (!m_renderer) return; updateChildrenIfNecessary(); for (const auto& row : m_rows) { if (row && !row->isOffScreen()) rows.append(row); } }
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()); } }
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]); } }
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); } }
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); } }
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()); } } }
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); } }
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); } }
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); } }
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); } }
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); } }
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); } }