26 size_t index_in_parent,
27 size_t unignored_index_in_parent)
29 index_in_parent_(index_in_parent),
30 unignored_index_in_parent_(unignored_index_in_parent),
40 return unignored_child_count_;
44 return std::move(data_);
68 return unignored_index_in_parent_;
73 return index_in_parent_;
78 return ComputeFirstUnignoredChildRecursive();
83 return ComputeLastUnignoredChildRecursive();
107 return deepest_child;
157 const AXNode* current =
this;
160 bool considerChildren =
false;
168 if (considerChildren && (candidate = current->
GetFirstChild())) {
179 considerChildren =
true;
203 current = current->
parent();
208 considerChildren =
false;
226 const AXNode* current =
this;
229 bool considerChildren =
false;
237 if (considerChildren && (candidate = current->
GetLastChild())) {
248 considerChildren =
true;
272 current = current->
parent();
277 considerChildren =
false;
288 const AXNode* node =
this;
384 std::make_unique<gfx::Transform>(*
transform);
396 UpdateUnignoredCachedValuesRecursive(0);
408 if (
this == ancestor)
417 std::vector<int> line_offsets;
423 int start_offset = 0;
424 ComputeLineStartOffsets(&line_offsets, &start_offset);
430void AXNode::ComputeLineStartOffsets(std::vector<int>* line_offsets,
431 int* start_offset)
const {
436 if (!child->children().empty()) {
437 child->ComputeLineStartOffsets(line_offsets, start_offset);
442 if (*start_offset && !child->data().HasIntAttribute(
446 if (line_offsets->empty() || line_offsets->back() != *start_offset)
447 line_offsets->push_back(*start_offset);
450 std::u16string
text =
452 *start_offset +=
static_cast<int>(
text.length());
458 const AXNode* current_node =
this;
462 current_node = current_node->
parent();
463 }
while (current_node);
477 const bool is_plain_text_field_without_descendants =
479 if (is_plain_text_field_without_descendants) {
493 const bool is_plain_text_field_with_descendants =
495 if (
IsLeaf() && !is_plain_text_field_with_descendants) {
512 return std::string();
525 std::string inner_text;
527 inner_text += it->GetInnerText();
533 return std::string();
545 const AXTableInfo* table_info = GetAncestorTableInfo();
548 return static_cast<int>(table_info->
col_count);
552 const AXTableInfo* table_info = GetAncestorTableInfo();
555 return static_cast<int>(table_info->
row_count);
559 const AXTableInfo* table_info = GetAncestorTableInfo();
566 const AXTableInfo* table_info = GetAncestorTableInfo();
573 const AXTableInfo* table_info = GetAncestorTableInfo();
581 const AXTableInfo* table_info = GetAncestorTableInfo();
589 const AXTableInfo* table_info = GetAncestorTableInfo();
604 const AXTableInfo* table_info = GetAncestorTableInfo();
612 const AXTableInfo* table_info = GetAncestorTableInfo();
618 static_cast<size_t>(row_index) >= table_info->
row_count ||
620 static_cast<size_t>(col_index) >= table_info->
col_count) {
625 [
static_cast<size_t>(col_index)]);
629 const AXTableInfo* table_info = GetAncestorTableInfo();
631 return std::vector<AXNode::AXID>();
633 std::vector<AXNode::AXID> col_header_ids;
635 for (std::vector<AXNode::AXID> col_headers_at_index :
637 col_header_ids.insert(col_header_ids.end(), col_headers_at_index.begin(),
638 col_headers_at_index.end());
641 return col_header_ids;
645 int col_index)
const {
646 const AXTableInfo* table_info = GetAncestorTableInfo();
648 return std::vector<AXNode::AXID>();
650 if (col_index < 0 ||
static_cast<size_t>(col_index) >= table_info->
col_count)
651 return std::vector<AXNode::AXID>();
653 return std::vector<AXNode::AXID>(
654 table_info->
col_headers[
static_cast<size_t>(col_index)]);
658 int row_index)
const {
659 const AXTableInfo* table_info = GetAncestorTableInfo();
661 return std::vector<AXNode::AXID>();
663 if (row_index < 0 ||
static_cast<size_t>(row_index) >= table_info->
row_count)
664 return std::vector<AXNode::AXID>();
666 return std::vector<AXNode::AXID>(
667 table_info->
row_headers[
static_cast<size_t>(row_index)]);
671 const AXTableInfo* table_info = GetAncestorTableInfo();
673 return std::vector<AXNode::AXID>();
699 const AXTableInfo* table_info = GetAncestorTableInfo();
706 return static_cast<int>(iter->second);
710 std::vector<AXNode::AXID> row_node_ids;
711 const AXTableInfo* table_info = GetAncestorTableInfo();
716 row_node_ids.push_back(node->data().id);
727bool AXNode::IsTableColumn()
const {
731std::optional<int> AXNode::GetTableColColIndex()
const {
735 const AXTableInfo* table_info = GetAncestorTableInfo();
740 for (
const AXNode* node : table_info->extra_mac_nodes) {
762 const AXTableInfo* table_info = GetAncestorTableInfo();
768 return static_cast<int>(iter->second);
773 const AXTableInfo* table_info = GetAncestorTableInfo();
785 const AXTableInfo* table_info = GetAncestorTableInfo();
823 const AXTableInfo* table_info = GetAncestorTableInfo();
831 return static_cast<int>(table_info->
cell_data_vector[*index].aria_col_index);
835 const AXTableInfo* table_info = GetAncestorTableInfo();
843 return static_cast<int>(table_info->
cell_data_vector[*index].aria_row_index);
847 const AXTableInfo* table_info = GetAncestorTableInfo();
848 if (!table_info || table_info->
col_count <= 0)
849 return std::vector<AXNode::AXID>();
854 return std::vector<AXNode::AXID>(table_info->
col_headers[col_index]);
861 IdVectorToNodeVector(col_header_ids, col_headers);
865 const AXTableInfo* table_info = GetAncestorTableInfo();
866 if (!table_info || table_info->
row_count <= 0)
867 return std::vector<AXNode::AXID>();
872 return std::vector<AXNode::AXID>(table_info->
row_headers[row_index]);
879 IdVectorToNodeVector(row_header_ids, row_headers);
886 const AXNode* node =
this;
887 while (node && !node->
IsTable())
899 const AXNode* node =
this;
900 while (node && !node->
IsTable())
910 const AXNode* node =
this;
911 while (node && !node->
IsTable())
918void AXNode::IdVectorToNodeVector(
const std::vector<int32_t>& ids,
919 std::vector<AXNode*>* nodes)
const {
920 for (int32_t
id : ids) {
923 nodes->push_back(node);
928 int hierarchical_level =
934 if (hierarchical_level > 0)
935 return hierarchical_level;
1016int AXNode::UpdateUnignoredCachedValuesRecursive(
int startIndex) {
1018 for (
AXNode* child : children_) {
1019 if (child->IsIgnored()) {
1020 child->unignored_index_in_parent_ = 0;
1021 count += child->UpdateUnignoredCachedValuesRecursive(startIndex +
count);
1023 child->unignored_index_in_parent_ = startIndex +
count++;
1026 unignored_child_count_ =
count;
1036 while (
result &&
result->IsIgnoredContainerForOrderedSet()) {
1043AXNode* AXNode::ComputeLastUnignoredChildRecursive()
const {
1048 for (
int i =
static_cast<int>(
children().size()) - 1; i >= 0; --i) {
1049 AXNode* child = children_[i];
1053 AXNode* descendant = child->ComputeLastUnignoredChildRecursive();
1060AXNode* AXNode::ComputeFirstUnignoredChildRecursive()
const {
1062 for (
size_t i = 0; i <
children().size(); i++) {
1063 AXNode* child = children_[i];
1064 if (!child->IsIgnored())
1067 AXNode* descendant = child->ComputeFirstUnignoredChildRecursive();
1112 switch (
data().role) {
1158 return grandparent_node &&
1204 AXNode* lowest_unignored_node = current_node;
1205 for (; lowest_unignored_node && lowest_unignored_node->
IsIgnored();
1206 lowest_unignored_node = lowest_unignored_node->
parent()) {
1210 AXNode* highest_leaf_node = lowest_unignored_node;
1213 for (
AXNode* ancestor_node = lowest_unignored_node; ancestor_node;
1215 if (ancestor_node->IsLeaf())
1216 highest_leaf_node = ancestor_node;
1218 if (highest_leaf_node)
1219 return highest_leaf_node;
1221 if (lowest_unignored_node)
1222 return lowest_unignored_node;
1223 return current_node;
1242 if (
this == ancestor)
1256 return manager->GetParentNodeFromParentTreeAsAXNode();
1262 <<
"Cannot retrieve the current selection if the node is not "
1263 "attached to an accessibility tree.\n"
1273 if (anchor && !anchor->
IsLeaf()) {
1288 if (focus && !focus->
IsLeaf()) {
virtual AXTableInfo * GetTableInfo(const AXNode *table_node) const =0
virtual bool GetTreeUpdateInProgressState() const =0
virtual std::optional< int > GetSetSize(const AXNode &node)=0
virtual AXNode * GetFromId(int32_t id) const =0
virtual AXTreeID GetAXTreeID() const =0
virtual std::optional< int > GetPosInSet(const AXNode &node)=0
virtual Selection GetUnignoredSelection() const =0
std::optional< int > GetSetSize()
AXNode * GetCollapsedMenuListPopUpButtonAncestor() const
std::vector< AXNode::AXID > GetTableCellColHeaderNodeIds() const
void UpdateUnignoredCachedValues()
AXNode * GetDeepestLastUnignoredChild() const
size_t GetUnignoredChildCount() const
ChildIteratorBase< AXNode, &AXNode::GetNextUnignoredSibling, &AXNode::GetPreviousUnignoredSibling, &AXNode::GetFirstUnignoredChild, &AXNode::GetLastUnignoredChild > UnignoredChildIterator
std::vector< AXNode::AXID > GetTableColHeaderNodeIds() const
std::vector< AXNode::AXID > GetTableCellRowHeaderNodeIds() const
UnignoredChildIterator UnignoredChildrenEnd() const
bool IsCellOrHeaderOfARIATable() const
std::vector< AXNode::AXID > GetTableUniqueCellIds() const
size_t GetIndexInParent() const
AXNode * GetLowestPlatformAncestor() const
bool IsOrderedSetItem() const
std::optional< int > GetTableCellIndex() const
void SetData(const AXNodeData &src)
std::optional< int > GetTableCellRowIndex() const
void SetIndexInParent(size_t index_in_parent)
AXNode * GetParentCrossingTreeBoundary() const
bool IsEmbeddedGroup() const
size_t GetUnignoredIndexInParent() const
AXNode * GetLastUnignoredChild() const
bool IsCellOrHeaderOfARIAGrid() const
bool IsTableCellOrHeader() const
bool IsIgnoredContainerForOrderedSet() const
std::optional< int > GetTableCellAriaColIndex() const
static constexpr AXID kInvalidAXID
std::vector< AXNode::AXID > GetTableRowHeaderNodeIds(int row_index) const
AXNode * GetNextUnignoredInTreeOrder() const
OwnerTree::Selection GetUnignoredSelection() const
std::optional< int > GetTableRowCount() const
std::optional< bool > GetTableHasColumnOrRowHeaderNode() const
AXNode * GetUnignoredParent() const
bool IsInListMarker() const
AXNode * GetFirstUnignoredChild() const
AXNode * GetTextFieldAncestor() const
std::optional< int > GetTableRowRowIndex() const
std::vector< int > GetOrComputeLineStartOffsets()
AXNode * GetNextSibling() const
void GetTableCellColHeaders(std::vector< AXNode * > *col_headers) const
const std::vector< int32_t > & GetIntListAttribute(ax::mojom::IntListAttribute attribute) const
std::vector< AXNode::AXID > GetTableRowNodeIds() const
AXNode * GetLastChild() const
AXNode * GetDeepestFirstUnignoredChild() const
void SetLocation(int32_t offset_container_id, const gfx::RectF &location, gfx::Transform *transform)
AXNode * GetUnignoredChildAtIndex(size_t index) const
AXNode * GetTableCaption() const
std::optional< int > GetTableCellAriaRowIndex() const
std::optional< int > GetTableAriaColCount() const
std::optional< int > GetTableColCount() const
const std::vector< AXNode * > & children() const
std::string GetLanguage() const
std::optional< int > GetHierarchicalLevel() const
void GetTableCellRowHeaders(std::vector< AXNode * > *row_headers) const
std::optional< int > GetTableCellColSpan() const
AXNode * GetPreviousUnignoredSibling() const
UnignoredChildIterator UnignoredChildrenBegin() const
std::optional< int > GetTableCellRowSpan() const
const std::string & GetInheritedStringAttribute(ax::mojom::StringAttribute attribute) const
std::u16string GetInheritedString16Attribute(ax::mojom::StringAttribute attribute) const
bool SetRoleMatchesItemRole(const AXNode *ordered_set) const
bool IsCollapsedMenuListPopUpButton() const
AXNode(OwnerTree *tree, AXNode *parent, int32_t id, size_t index_in_parent, size_t unignored_index_in_parent=0)
int GetIntAttribute(ax::mojom::IntAttribute attribute) const
bool IsDescendantOfCrossingTreeBoundary(const AXNode *ancestor) const
bool IsChildOfLeaf() const
void SwapChildren(std::vector< AXNode * > *children)
AXNode * GetFirstChild() const
AXNode * GetPreviousSibling() const
std::optional< int > GetTableCellCount() const
bool IsOrderedSet() const
std::optional< int > GetTableCellColIndex() const
AXNode * GetPreviousUnignoredInTreeOrder() const
AXNode * GetNextUnignoredSibling() const
size_t index_in_parent() const
bool IsDescendantOf(const AXNode *ancestor) const
AXNode * GetTableCellFromIndex(int index) const
std::optional< int > GetPosInSet()
AXNode * GetOrderedSet() const
AXNode * GetTableCellFromCoords(int row_index, int col_index) const
const AXNodeData & data() const
const std::vector< AXNode * > * GetExtraMacNodes() const
std::string GetInnerText() const
std::optional< int > GetTableAriaRowCount() const
std::vector< std::vector< int32_t > > col_headers
std::vector< CellData > cell_data_vector
std::vector< std::vector< int32_t > > cell_ids
std::unordered_map< int32_t, size_t > row_id_to_index
std::vector< AXNode * > extra_mac_nodes
std::unordered_map< int32_t, size_t > cell_id_to_index
std::vector< AXNode * > row_nodes
std::vector< int32_t > all_headers
std::vector< std::vector< int32_t > > row_headers
std::vector< int32_t > unique_cell_ids
AXTreeManager * GetManager(AXTreeID tree_id)
static AXTreeManagerMap & GetInstance()
EMSCRIPTEN_KEEPALIVE void empty()
@ kAttributeExplicitlyEmpty
const std::string & EmptyString()
std::u16string UTF8ToUTF16(std::string src)
bool IsTableColumn(ax::mojom::Role role)
bool IsCellOrTableHeader(const ax::mojom::Role role)
bool IsTableRow(ax::mojom::Role role)
bool IsItemLike(const ax::mojom::Role role)
bool IsTableLike(const ax::mojom::Role role)
std::ostream & operator<<(std::ostream &os, AXEventGenerator::Event event)
bool IsSetLike(const ax::mojom::Role role)
bool IsText(ax::mojom::Role role)
static SkColor4f transform(SkColor4f c, SkColorSpace *src, SkColorSpace *dst)
AXRelativeBounds relative_bounds
bool IsPlainTextField() const
bool HasState(ax::mojom::State state) const
void AddIntListAttribute(ax::mojom::IntListAttribute attribute, const std::vector< int32_t > &value)
bool HasStringAttribute(ax::mojom::StringAttribute attribute) const
ax::mojom::NameFrom GetNameFrom() const
bool IsRichTextField() const
virtual std::string ToString() const
bool GetBoolAttribute(ax::mojom::BoolAttribute attribute) const
const std::string & GetStringAttribute(ax::mojom::StringAttribute attribute) const
std::unique_ptr< gfx::Transform > transform
int32_t offset_container_id
#define BASE_DCHECK(condition)