ax_node.h 41 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995
  1. // Copyright 2013 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #ifndef UI_ACCESSIBILITY_AX_NODE_H_
  5. #define UI_ACCESSIBILITY_AX_NODE_H_
  6. #include <stdint.h>
  7. #include <iterator>
  8. #include <memory>
  9. #include <ostream>
  10. #include <string>
  11. #include <utility>
  12. #include <vector>
  13. #include "base/containers/stack.h"
  14. #include "base/memory/raw_ptr.h"
  15. #include "build/build_config.h"
  16. #include "third_party/abseil-cpp/absl/types/optional.h"
  17. #include "third_party/skia/include/core/SkColor.h"
  18. #include "ui/accessibility/ax_export.h"
  19. #include "ui/accessibility/ax_hypertext.h"
  20. #include "ui/accessibility/ax_node_data.h"
  21. #include "ui/accessibility/ax_text_attributes.h"
  22. #include "ui/accessibility/ax_tree_id.h"
  23. #include "ui/gfx/geometry/rect_f.h"
  24. namespace ui {
  25. class AXComputedNodeData;
  26. class AXTableInfo;
  27. class AXTreeManager;
  28. struct AXLanguageInfo;
  29. struct AXTreeData;
  30. // This class is used to represent a node in an accessibility tree (`AXTree`).
  31. class AX_EXPORT AXNode final {
  32. public:
  33. // Replacement character used to represent an embedded (or, additionally for
  34. // text navigation, an empty) object. Part of the Unicode Standard.
  35. //
  36. // On some platforms, most objects are represented in the text of their
  37. // parents with a special "embedded object character" and not with their
  38. // actual text contents. Also on the same platforms, if a node has only
  39. // ignored descendants, i.e., it appears to be empty to assistive software, we
  40. // need to treat it as a character and a word boundary.
  41. static constexpr char kEmbeddedObjectCharacterUTF8[] = "\xEF\xBF\xBC";
  42. static constexpr char16_t kEmbeddedObjectCharacterUTF16[] = u"\xFFFC";
  43. // We compute the embedded characters' length instead of manually typing it in
  44. // order to avoid the variable pairs getting out of sync in a future update.
  45. static constexpr int kEmbeddedObjectCharacterLengthUTF8 =
  46. std::char_traits<char>::length(kEmbeddedObjectCharacterUTF8);
  47. static constexpr int kEmbeddedObjectCharacterLengthUTF16 =
  48. std::char_traits<char16_t>::length(kEmbeddedObjectCharacterUTF16);
  49. // Interface to the tree class that owns an AXNode. We use this instead
  50. // of letting AXNode have a pointer to its AXTree directly so that we're
  51. // forced to think twice before calling an AXTree interface that might not
  52. // be necessary.
  53. class OwnerTree {
  54. public:
  55. // A data structure that can store either the selected range of nodes in the
  56. // accessibility tree, or the location of the caret in the case of a
  57. // "collapsed" selection.
  58. //
  59. // TODO(nektar): Move this struct into its own file called "AXSelection",
  60. // turn it into a class and make it compute the unignored selection given
  61. // the `AXTreeData`.
  62. struct Selection final {
  63. // Returns true if this instance represents the position of the caret.
  64. constexpr bool IsCollapsed() const {
  65. return focus_object_id != kInvalidAXNodeID &&
  66. anchor_object_id == focus_object_id &&
  67. anchor_offset == focus_offset;
  68. }
  69. bool is_backward = false;
  70. AXNodeID anchor_object_id = kInvalidAXNodeID;
  71. int anchor_offset = -1;
  72. ax::mojom::TextAffinity anchor_affinity;
  73. AXNodeID focus_object_id = kInvalidAXNodeID;
  74. int focus_offset = -1;
  75. ax::mojom::TextAffinity focus_affinity;
  76. };
  77. // See AXTree::GetAXTreeID.
  78. virtual const AXTreeID& GetAXTreeID() const = 0;
  79. // See `AXTree::GetTableInfo`.
  80. virtual AXTableInfo* GetTableInfo(const AXNode* table_node) const = 0;
  81. // See AXTree::GetFromId.
  82. virtual AXNode* GetFromId(AXNodeID id) const = 0;
  83. // See AXTree::data.
  84. virtual const AXTreeData& data() const = 0;
  85. virtual absl::optional<int> GetPosInSet(const AXNode& node) = 0;
  86. virtual absl::optional<int> GetSetSize(const AXNode& node) = 0;
  87. // See `AXTree::GetSelection`.
  88. virtual Selection GetSelection() const = 0;
  89. // See `AXTree::GetUnignoredSelection`.
  90. virtual Selection GetUnignoredSelection() const = 0;
  91. // See `AXTree::GetTreeUpdateInProgressState`.
  92. virtual bool GetTreeUpdateInProgressState() const = 0;
  93. // See `AXTree::HasPaginationSupport`.
  94. virtual bool HasPaginationSupport() const = 0;
  95. };
  96. template <typename NodeType,
  97. NodeType* (NodeType::*NextSibling)() const,
  98. NodeType* (NodeType::*PreviousSibling)() const,
  99. NodeType* (NodeType::*FirstChild)() const,
  100. NodeType* (NodeType::*LastChild)() const>
  101. class ChildIteratorBase {
  102. public:
  103. using iterator_category = std::bidirectional_iterator_tag;
  104. using difference_type = int;
  105. using value_type = NodeType;
  106. using pointer = NodeType*;
  107. using reference = NodeType&;
  108. ChildIteratorBase(const NodeType* parent, NodeType* child);
  109. ChildIteratorBase(const ChildIteratorBase& it);
  110. ~ChildIteratorBase() {}
  111. bool operator==(const ChildIteratorBase& rhs) const;
  112. bool operator!=(const ChildIteratorBase& rhs) const;
  113. ChildIteratorBase& operator++();
  114. ChildIteratorBase& operator--();
  115. NodeType* get() const;
  116. NodeType& operator*() const;
  117. NodeType* operator->() const;
  118. protected:
  119. raw_ptr<const NodeType> parent_;
  120. raw_ptr<NodeType, DanglingUntriaged> child_;
  121. };
  122. // The constructor requires a parent, id, and index in parent, but
  123. // the data is not required. After initialization, only index_in_parent
  124. // and unignored_index_in_parent is allowed to change, the others are
  125. // guaranteed to never change.
  126. AXNode(OwnerTree* tree,
  127. AXNode* parent,
  128. AXNodeID id,
  129. size_t index_in_parent,
  130. size_t unignored_index_in_parent = 0u);
  131. virtual ~AXNode();
  132. // Accessors.
  133. OwnerTree* tree() const { return tree_; }
  134. AXNodeID id() const { return data_.id; }
  135. const AXNodeData& data() const { return data_; }
  136. // Returns ownership of |data_| to the caller; effectively clearing |data_|.
  137. AXNodeData&& TakeData();
  138. //
  139. // Methods for walking the tree.
  140. //
  141. // These come in four flavors: Methods that walk all the nodes, methods that
  142. // walk only the unignored nodes (effectively re-structuring the tree to
  143. // remove all ignored nodes), and another two variants that do the above plus
  144. // cross tree boundaries, effectively stiching together all accessibility
  145. // trees that are part of the same webpage, PDF or window into a large global
  146. // tree.
  147. const std::vector<AXNode*>& GetAllChildren() const;
  148. size_t GetChildCount() const;
  149. size_t GetChildCountCrossingTreeBoundary() const;
  150. size_t GetUnignoredChildCount() const;
  151. size_t GetUnignoredChildCountCrossingTreeBoundary() const;
  152. AXNode* GetChildAtIndex(size_t index) const;
  153. AXNode* GetChildAtIndexCrossingTreeBoundary(size_t index) const;
  154. AXNode* GetUnignoredChildAtIndex(size_t index) const;
  155. AXNode* GetUnignoredChildAtIndexCrossingTreeBoundary(size_t index) const;
  156. AXNode* GetParent() const;
  157. AXNode* GetParentCrossingTreeBoundary() const;
  158. AXNode* GetUnignoredParent() const;
  159. AXNode* GetUnignoredParentCrossingTreeBoundary() const;
  160. base::stack<AXNode*> GetAncestorsCrossingTreeBoundary() const;
  161. size_t GetIndexInParent() const;
  162. size_t GetUnignoredIndexInParent() const;
  163. AXNode* GetFirstChild() const;
  164. AXNode* GetFirstChildCrossingTreeBoundary() const;
  165. AXNode* GetFirstUnignoredChild() const;
  166. AXNode* GetFirstUnignoredChildCrossingTreeBoundary() const;
  167. AXNode* GetLastChild() const;
  168. AXNode* GetLastChildCrossingTreeBoundary() const;
  169. AXNode* GetLastUnignoredChild() const;
  170. AXNode* GetLastUnignoredChildCrossingTreeBoundary() const;
  171. // TODO(accessibility): Consider renaming all "GetDeepest...Child" methods to
  172. // "GetDeepest...Descendant".
  173. AXNode* GetDeepestFirstChild() const;
  174. AXNode* GetDeepestFirstChildCrossingTreeBoundary() const;
  175. AXNode* GetDeepestFirstUnignoredChild() const;
  176. AXNode* GetDeepestFirstUnignoredChildCrossingTreeBoundary() const;
  177. AXNode* GetDeepestLastChild() const;
  178. AXNode* GetDeepestLastChildCrossingTreeBoundary() const;
  179. AXNode* GetDeepestLastUnignoredChild() const;
  180. AXNode* GetDeepestLastUnignoredChildCrossingTreeBoundary() const;
  181. AXNode* GetNextSibling() const;
  182. AXNode* GetNextUnignoredSibling() const;
  183. AXNode* GetPreviousSibling() const;
  184. AXNode* GetPreviousUnignoredSibling() const;
  185. // Traverse the tree in depth-first pre-order.
  186. AXNode* GetNextUnignoredInTreeOrder() const;
  187. AXNode* GetPreviousUnignoredInTreeOrder() const;
  188. //
  189. // Deprecated methods for walking the tree.
  190. //
  191. const std::vector<AXNode*>& children() const { return children_; }
  192. AXNode* parent() const { return parent_; }
  193. size_t index_in_parent() const { return index_in_parent_; }
  194. //
  195. // Iterators for walking the tree in depth-first pre-order.
  196. //
  197. using AllChildIterator = ChildIteratorBase<AXNode,
  198. &AXNode::GetNextSibling,
  199. &AXNode::GetPreviousSibling,
  200. &AXNode::GetFirstChild,
  201. &AXNode::GetLastChild>;
  202. AllChildIterator AllChildrenBegin() const;
  203. AllChildIterator AllChildrenEnd() const;
  204. using AllChildCrossingTreeBoundaryIterator =
  205. ChildIteratorBase<AXNode,
  206. &AXNode::GetNextSibling,
  207. &AXNode::GetPreviousSibling,
  208. &AXNode::GetFirstChildCrossingTreeBoundary,
  209. &AXNode::GetLastChildCrossingTreeBoundary>;
  210. AllChildCrossingTreeBoundaryIterator AllChildrenCrossingTreeBoundaryBegin()
  211. const;
  212. AllChildCrossingTreeBoundaryIterator AllChildrenCrossingTreeBoundaryEnd()
  213. const;
  214. using UnignoredChildIterator =
  215. ChildIteratorBase<AXNode,
  216. &AXNode::GetNextUnignoredSibling,
  217. &AXNode::GetPreviousUnignoredSibling,
  218. &AXNode::GetFirstUnignoredChild,
  219. &AXNode::GetLastUnignoredChild>;
  220. UnignoredChildIterator UnignoredChildrenBegin() const;
  221. UnignoredChildIterator UnignoredChildrenEnd() const;
  222. using UnignoredChildCrossingTreeBoundaryIterator =
  223. ChildIteratorBase<AXNode,
  224. &AXNode::GetNextUnignoredSibling,
  225. &AXNode::GetPreviousUnignoredSibling,
  226. &AXNode::GetFirstUnignoredChildCrossingTreeBoundary,
  227. &AXNode::GetLastUnignoredChildCrossingTreeBoundary>;
  228. UnignoredChildCrossingTreeBoundaryIterator
  229. UnignoredChildrenCrossingTreeBoundaryBegin() const;
  230. UnignoredChildCrossingTreeBoundaryIterator
  231. UnignoredChildrenCrossingTreeBoundaryEnd() const;
  232. // Returns true if this is a node on which accessibility events make sense to
  233. // be fired. Events are not needed on nodes that will, for example, never
  234. // appear in a tree that is visible to assistive software, as there will be no
  235. // software to handle the event on the other end.
  236. bool CanFireEvents() const;
  237. // Returns an optional integer indicating the logical order of this node
  238. // compared to another node, or returns an empty optional if the nodes are not
  239. // comparable. Nodes are not comparable if they do not share a common
  240. // ancestor.
  241. //
  242. // 0: if this node is logically equivalent to the other node.
  243. // <0: if this node is logically less than the other node.
  244. // >0: if this node is logically greater than the other node.
  245. //
  246. // Another way to look at the nodes' relative positions/logical orders is that
  247. // they are equivalent to pre-order traversal of the tree. If we pre-order
  248. // traverse from the root, the node that we visited earlier is always going to
  249. // be before (logically less) the node we visit later.
  250. absl::optional<int> CompareTo(const AXNode& other) const;
  251. bool IsDataValid() const { return data_.id != kInvalidAXNodeID; }
  252. // Returns true if the node has any of the text related roles, including
  253. // kStaticText, kInlineTextBox and kListMarker (for Legacy Layout). Does not
  254. // include any text field roles.
  255. bool IsText() const;
  256. // Returns true if the node has any line break related roles or is the child
  257. // of a node with line break related roles.
  258. bool IsLineBreak() const;
  259. // Set the node's accessibility data. This may be done during initialization
  260. // or later when the node data changes.
  261. void SetData(const AXNodeData& src);
  262. // Update this node's location. This is separate from |SetData| just because
  263. // changing only the location is common and should be more efficient than
  264. // re-copying all of the data.
  265. //
  266. // The node's location is stored as a relative bounding box, the ID of
  267. // the element it's relative to, and an optional transformation matrix.
  268. // See ax_node_data.h for details.
  269. void SetLocation(AXNodeID offset_container_id,
  270. const gfx::RectF& location,
  271. gfx::Transform* transform);
  272. // Set the index in parent, for example if siblings were inserted or deleted.
  273. void SetIndexInParent(size_t index_in_parent);
  274. // When the node's `IsIgnored()` value changes, updates the cached values for
  275. // the unignored index in parent and the unignored child count.
  276. void UpdateUnignoredCachedValues();
  277. // Swap the internal children vector with |children|. This instance
  278. // now owns all of the passed children.
  279. void SwapChildren(std::vector<AXNode*>* children);
  280. // Returns true if this node is equal to or a descendant of |ancestor|.
  281. bool IsDescendantOf(const AXNode* ancestor) const;
  282. bool IsDescendantOfCrossingTreeBoundary(const AXNode* ancestor) const;
  283. // If the color is transparent, blends with the ancestor's color.
  284. // Note that this is imperfect; it won't work if a node is absolute-
  285. // positioned outside of its ancestor. However, it handles the most
  286. // common cases.
  287. SkColor ComputeColor() const;
  288. SkColor ComputeBackgroundColor() const;
  289. AXTreeManager* GetManager() const;
  290. //
  291. // Methods for accessing caret and selection information.
  292. //
  293. // Returns true if the caret is visible or there is an active selection inside
  294. // this node.
  295. bool HasVisibleCaretOrSelection() const;
  296. // Gets the current selection from the accessibility tree.
  297. OwnerTree::Selection GetSelection() const;
  298. // Gets the unignored selection from the accessibility tree, meaning the
  299. // selection whose endpoints are on unignored nodes. (An "ignored" node is a
  300. // node that is not exposed to platform APIs: See `IsIgnored`.)
  301. OwnerTree::Selection GetUnignoredSelection() const;
  302. //
  303. // Methods for accessing accessibility attributes including attributes that
  304. // are computed on the browser side. (See `AXNodeData` and
  305. // `AXComputedNodeData` for more information.)
  306. //
  307. // Please prefer using the methods in this file for retrieving attributes, as
  308. // computed attributes would be automatically returned if available.
  309. //
  310. ax::mojom::Role GetRole() const { return data().role; }
  311. bool HasBoolAttribute(ax::mojom::BoolAttribute attribute) const {
  312. return data().HasBoolAttribute(attribute);
  313. }
  314. bool GetBoolAttribute(ax::mojom::BoolAttribute attribute) const {
  315. return data().GetBoolAttribute(attribute);
  316. }
  317. bool GetBoolAttribute(ax::mojom::BoolAttribute attribute, bool* value) const {
  318. return data().GetBoolAttribute(attribute, value);
  319. }
  320. bool HasFloatAttribute(ax::mojom::FloatAttribute attribute) const {
  321. return data().HasFloatAttribute(attribute);
  322. }
  323. float GetFloatAttribute(ax::mojom::FloatAttribute attribute) const {
  324. return data().GetFloatAttribute(attribute);
  325. }
  326. bool GetFloatAttribute(ax::mojom::FloatAttribute attribute,
  327. float* value) const {
  328. return data().GetFloatAttribute(attribute, value);
  329. }
  330. const std::vector<std::pair<ax::mojom::IntAttribute, int32_t>>&
  331. GetIntAttributes() const {
  332. return data().int_attributes;
  333. }
  334. bool HasIntAttribute(ax::mojom::IntAttribute attribute) const {
  335. return data().HasIntAttribute(attribute);
  336. }
  337. int GetIntAttribute(ax::mojom::IntAttribute attribute) const {
  338. return data().GetIntAttribute(attribute);
  339. }
  340. bool GetIntAttribute(ax::mojom::IntAttribute attribute, int* value) const {
  341. return data().GetIntAttribute(attribute, value);
  342. }
  343. const std::vector<std::pair<ax::mojom::StringAttribute, std::string>>&
  344. GetStringAttributes() const {
  345. return data().string_attributes;
  346. }
  347. bool HasStringAttribute(ax::mojom::StringAttribute attribute) const;
  348. const std::string& GetStringAttribute(
  349. ax::mojom::StringAttribute attribute) const;
  350. bool GetStringAttribute(ax::mojom::StringAttribute attribute,
  351. std::string* value) const;
  352. std::u16string GetString16Attribute(
  353. ax::mojom::StringAttribute attribute) const;
  354. bool GetString16Attribute(ax::mojom::StringAttribute attribute,
  355. std::u16string* value) const;
  356. bool HasInheritedStringAttribute(ax::mojom::StringAttribute attribute) const;
  357. const std::string& GetInheritedStringAttribute(
  358. ax::mojom::StringAttribute attribute) const;
  359. std::u16string GetInheritedString16Attribute(
  360. ax::mojom::StringAttribute attribute) const;
  361. const std::vector<
  362. std::pair<ax::mojom::IntListAttribute, std::vector<int32_t>>>&
  363. GetIntListAttributes() const {
  364. return data().intlist_attributes;
  365. }
  366. bool HasIntListAttribute(ax::mojom::IntListAttribute attribute) const;
  367. const std::vector<int32_t>& GetIntListAttribute(
  368. ax::mojom::IntListAttribute attribute) const;
  369. bool GetIntListAttribute(ax::mojom::IntListAttribute attribute,
  370. std::vector<int32_t>* value) const;
  371. bool HasStringListAttribute(ax::mojom::StringListAttribute attribute) const {
  372. return data().HasStringListAttribute(attribute);
  373. }
  374. const std::vector<std::string>& GetStringListAttribute(
  375. ax::mojom::StringListAttribute attribute) const {
  376. return data().GetStringListAttribute(attribute);
  377. }
  378. bool GetStringListAttribute(ax::mojom::StringListAttribute attribute,
  379. std::vector<std::string>* value) const {
  380. return data().GetStringListAttribute(attribute, value);
  381. }
  382. const base::StringPairs& GetHtmlAttributes() const {
  383. return data().html_attributes;
  384. }
  385. bool HasHtmlAttribute(const char* attribute) const {
  386. return data().HasHtmlAttribute(attribute);
  387. }
  388. std::u16string GetHtmlAttribute(const char* attribute) const {
  389. return data().GetHtmlAttribute(attribute);
  390. }
  391. bool GetHtmlAttribute(const char* attribute, std::string* value) const {
  392. return data().GetHtmlAttribute(attribute, value);
  393. }
  394. bool GetHtmlAttribute(const char* attribute, std::u16string* value) const {
  395. return data().GetHtmlAttribute(attribute, value);
  396. }
  397. AXTextAttributes GetTextAttributes() const {
  398. return data().GetTextAttributes();
  399. }
  400. bool HasState(ax::mojom::State state) const { return data().HasState(state); }
  401. ax::mojom::State GetState() const {
  402. return static_cast<ax::mojom::State>(data().state);
  403. }
  404. bool HasAction(ax::mojom::Action action) const {
  405. return data().HasAction(action);
  406. }
  407. bool HasTextStyle(ax::mojom::TextStyle text_style) const {
  408. return data().HasTextStyle(text_style);
  409. }
  410. ax::mojom::NameFrom GetNameFrom() const { return data().GetNameFrom(); }
  411. ax::mojom::InvalidState GetInvalidState() const {
  412. return data().GetInvalidState();
  413. }
  414. // Return the hierarchical level if supported.
  415. absl::optional<int> GetHierarchicalLevel() const;
  416. // PosInSet and SetSize public methods.
  417. bool IsOrderedSetItem() const;
  418. bool IsOrderedSet() const;
  419. absl::optional<int> GetPosInSet();
  420. absl::optional<int> GetSetSize();
  421. // Helpers for GetPosInSet and GetSetSize.
  422. // Returns true if the role of ordered set matches the role of item.
  423. // Returns false otherwise.
  424. bool SetRoleMatchesItemRole(const AXNode* ordered_set) const;
  425. // Container objects that should be ignored for computing PosInSet and SetSize
  426. // for ordered sets.
  427. bool IsIgnoredContainerForOrderedSet() const;
  428. // Helper functions that returns true when we are on a row/row group inside of
  429. // a tree grid. Also works for rows that are part of a row group inside a tree
  430. // grid. Returns false otherwise.
  431. bool IsRowInTreeGrid(const AXNode* ordered_set) const;
  432. bool IsRowGroupInTreeGrid() const;
  433. // Returns the accessible name for this node. This could have originated from
  434. // e.g. an onscreen label, or an ARIA label.
  435. const std::string& GetNameUTF8() const;
  436. std::u16string GetNameUTF16() const;
  437. // If this node is a leaf, returns the text content of this node. This is
  438. // equivalent to its visible accessible name. Otherwise, if this node is not a
  439. // leaf, represents every non-textual child node with a special "embedded
  440. // object character", and every textual child node with its text content.
  441. // Textual nodes include e.g. static text and white space.
  442. //
  443. // This is how displayed text and embedded objects are represented in
  444. // ATK and IAccessible2 APIs.
  445. //
  446. // TODO(nektar): Consider changing the return value to std::string.
  447. const std::u16string& GetHypertext() const;
  448. // Temporary method that marks `hypertext_` dirty. This will eventually be
  449. // handled by the AX tree in a followup patch.
  450. void SetNeedsToUpdateHypertext();
  451. // Temporary accessor methods until hypertext is fully migrated to this class.
  452. // Hypertext won't eventually need to be accessed outside this class.
  453. const std::map<int, int>& GetHypertextOffsetToHyperlinkChildIndex() const;
  454. const AXHypertext& GetOldHypertext() const;
  455. // Returns the text that is found inside this node and all its descendants;
  456. // including text found in embedded objects.
  457. //
  458. // Only text displayed on screen is included. Text from ARIA and HTML
  459. // attributes that is either not displayed on screen, or outside this node, is
  460. // not returned.
  461. //
  462. // Does not take into account line breaks that have been introduced by layout.
  463. // For example, in the Web context, "A<div>B</div>C" would produce "ABC".
  464. const std::string& GetTextContentUTF8() const;
  465. const std::u16string& GetTextContentUTF16() const;
  466. // Returns the length of the text (in code units) that is found inside
  467. // this node and all its descendants; including text found in embedded
  468. // objects.
  469. //
  470. // Only text displayed on screen is counted. Text from ARIA and HTML
  471. // attributes that is either not displayed on screen, or outside this node, is
  472. // not included.
  473. //
  474. // The length of the text is either in UTF8 or UTF16 code units, not in
  475. // grapheme clusters.
  476. int GetTextContentLengthUTF8() const;
  477. int GetTextContentLengthUTF16() const;
  478. // Returns the smallest bounding box that can enclose the given range of
  479. // characters in the node's text contents. The bounding box is relative to
  480. // this node's coordinate system as specified in
  481. // `AXNodeData::relative_bounds`.
  482. //
  483. // Note that `start_offset` and `end_offset` are either in UTF8 or UTF16 code
  484. // units, not in grapheme clusters.
  485. gfx::RectF GetTextContentRangeBoundsUTF8(int start_offset,
  486. int end_offset) const;
  487. gfx::RectF GetTextContentRangeBoundsUTF16(int start_offset,
  488. int end_offset) const;
  489. // Returns a string representing the language code.
  490. //
  491. // This will consider the language declared in the DOM, and may eventually
  492. // attempt to automatically detect the language from the text.
  493. //
  494. // This language code will be BCP 47.
  495. //
  496. // Returns empty string if no appropriate language was found.
  497. std::string GetLanguage() const;
  498. // Returns the value of a control such as an atomic text field (<input> or
  499. // <textarea>), a content editable, a submit button, a slider, a progress bar,
  500. // a scroll bar, a meter, a spinner, a <select> element, a date picker or an
  501. // ARIA combo box. In order to minimize cross-process communication between
  502. // the renderer and the browser, this method may compute the value from the
  503. // control's inner text in the case of a content editable. For range controls,
  504. // such as sliders and scroll bars, the value of aria-valuetext takes priority
  505. // over the value of aria-valuenow.
  506. std::string GetValueForControl() const;
  507. //
  508. // Helper functions for tables, table rows, and table cells.
  509. // Most of these functions construct and cache an AXTableInfo behind
  510. // the scenes to infer many properties of tables.
  511. //
  512. // These interfaces use attributes provided by the source of the
  513. // AX tree where possible, but fills in missing details and ignores
  514. // specified attributes when they're bad or inconsistent. That way
  515. // you're guaranteed to get a valid, consistent table when using these
  516. // interfaces.
  517. //
  518. // Table-like nodes (including grids). All indices are 0-based except
  519. // ARIA indices are all 1-based. In other words, the top-left corner
  520. // of the table is row 0, column 0, cell index 0 - but that same cell
  521. // has a minimum ARIA row index of 1 and column index of 1.
  522. //
  523. // The below methods return absl::nullopt if the AXNode they are called on is
  524. // not inside a table.
  525. bool IsTable() const;
  526. absl::optional<int> GetTableColCount() const;
  527. absl::optional<int> GetTableRowCount() const;
  528. absl::optional<int> GetTableAriaColCount() const;
  529. absl::optional<int> GetTableAriaRowCount() const;
  530. absl::optional<int> GetTableCellCount() const;
  531. absl::optional<bool> GetTableHasColumnOrRowHeaderNode() const;
  532. AXNode* GetTableCaption() const;
  533. AXNode* GetTableCellFromIndex(int index) const;
  534. AXNode* GetTableCellFromCoords(int row_index, int col_index) const;
  535. // Get all the column header node ids of the table.
  536. std::vector<AXNodeID> GetTableColHeaderNodeIds() const;
  537. // Get the column header node ids associated with |col_index|.
  538. std::vector<AXNodeID> GetTableColHeaderNodeIds(int col_index) const;
  539. // Get the row header node ids associated with |row_index|.
  540. std::vector<AXNodeID> GetTableRowHeaderNodeIds(int row_index) const;
  541. std::vector<AXNodeID> GetTableUniqueCellIds() const;
  542. // Extra computed nodes for the accessibility tree for macOS:
  543. // one column node for each table column, followed by one
  544. // table header container node, or nullptr if not applicable.
  545. const std::vector<AXNode*>* GetExtraMacNodes() const;
  546. // Table row-like nodes.
  547. bool IsTableRow() const;
  548. absl::optional<int> GetTableRowRowIndex() const;
  549. // Get the node ids that represent rows in a table.
  550. std::vector<AXNodeID> GetTableRowNodeIds() const;
  551. #if BUILDFLAG(IS_APPLE)
  552. // Table column-like nodes. These nodes are only present on macOS.
  553. bool IsTableColumn() const;
  554. absl::optional<int> GetTableColColIndex() const;
  555. #endif // BUILDFLAG(IS_APPLE)
  556. // Table cell-like nodes.
  557. bool IsTableCellOrHeader() const;
  558. absl::optional<int> GetTableCellIndex() const;
  559. absl::optional<int> GetTableCellColIndex() const;
  560. absl::optional<int> GetTableCellRowIndex() const;
  561. absl::optional<int> GetTableCellColSpan() const;
  562. absl::optional<int> GetTableCellRowSpan() const;
  563. absl::optional<int> GetTableCellAriaColIndex() const;
  564. absl::optional<int> GetTableCellAriaRowIndex() const;
  565. std::vector<AXNodeID> GetTableCellColHeaderNodeIds() const;
  566. std::vector<AXNodeID> GetTableCellRowHeaderNodeIds() const;
  567. void GetTableCellColHeaders(std::vector<AXNode*>* col_headers) const;
  568. void GetTableCellRowHeaders(std::vector<AXNode*>* row_headers) const;
  569. // Returns true if this node is a cell or a row/column header in an ARIA grid
  570. // or treegrid.
  571. bool IsCellOrHeaderOfAriaGrid() const;
  572. // Return an object containing information about the languages detected on
  573. // this node.
  574. // Callers should not retain this pointer, instead they should request it
  575. // every time it is needed.
  576. //
  577. // Returns nullptr if the node has no language info.
  578. AXLanguageInfo* GetLanguageInfo() const;
  579. // This should only be called by LabelLanguageForSubtree and is used as part
  580. // of the language detection feature.
  581. void SetLanguageInfo(std::unique_ptr<AXLanguageInfo> lang_info);
  582. // Destroy the language info for this node.
  583. void ClearLanguageInfo();
  584. // Get a reference to the cached information stored for this node.
  585. const AXComputedNodeData& GetComputedNodeData() const;
  586. // Clear the cached information stored for this node because it is
  587. // out-of-date.
  588. void ClearComputedNodeData();
  589. // Returns true if node is a group and is a direct descendant of a set-like
  590. // element.
  591. bool IsEmbeddedGroup() const;
  592. // Returns true if this node has the ignored state or a presentational ARIA
  593. // role. Focused nodes are, by design, not ignored.
  594. bool IsIgnored() const;
  595. // Some nodes are not ignored but should be skipped during text navigation.
  596. // For example, on some platforms screen readers should not stop when
  597. // encountering a splitter during character and word navigation.
  598. bool IsIgnoredForTextNavigation() const;
  599. // Returns true if node is invisible, or if it is ignored as determined by
  600. // `AXNode::IsIgnored()`.
  601. bool IsInvisibleOrIgnored() const;
  602. // Returns true if an ancestor of this node (not including itself) is a
  603. // leaf node, meaning that this node is not actually exposed to any
  604. // platform's accessibility layer.
  605. bool IsChildOfLeaf() const;
  606. // Returns true if this is a leaf node that has no text content. Note that all
  607. // descendants of a leaf node are not exposed to any platform's accessibility
  608. // layer, but they may be used to compute the node's text content. Note also
  609. // that, ignored nodes (leaf or otherwise) do not expose their text content or
  610. // hypertext to the platforms' accessibility layer, but they expose the text
  611. // content or hypertext of their unignored descendants.
  612. //
  613. // For example, empty text fields might have a set of unignored nested divs
  614. // inside them:
  615. // ++kTextField
  616. // ++++kGenericContainer
  617. // ++++++kGenericContainer
  618. bool IsEmptyLeaf() const;
  619. // Returns true if this is a leaf node, meaning all its
  620. // descendants should not be exposed to any platform's accessibility
  621. // layer.
  622. //
  623. // The definition of a leaf includes nodes with children that are exclusively
  624. // an internal renderer implementation, such as the children of an HTML-based
  625. // text field (<input> and <textarea>), as well as nodes with presentational
  626. // children according to the ARIA and HTML5 Specs. Also returns true if all of
  627. // the node's descendants are ignored.
  628. //
  629. // A leaf node should never have children that are focusable or
  630. // that might send notifications.
  631. bool IsLeaf() const;
  632. // Returns true if this node is a list marker or if it's a descendant
  633. // of a list marker node. Returns false otherwise.
  634. bool IsInListMarker() const;
  635. // Returns true if this node is a popup button that is a parent to a menu list
  636. // popup.
  637. bool IsMenuListPopUpButton() const;
  638. // Returns true if this node is a collapsed popup button that is parent to a
  639. // menu list popup.
  640. bool IsCollapsedMenuListPopUpButton() const;
  641. // Returns true if this node is at the root of an accessibility tree that is
  642. // hosted by a presentational iframe.
  643. bool IsRootWebAreaForPresentationalIframe() const;
  644. // Returns the popup button ancestor of this current node if any. The popup
  645. // button needs to be the parent of a menu list popup and needs to be
  646. // collapsed.
  647. AXNode* GetCollapsedMenuListPopUpButtonAncestor() const;
  648. // If this node is exposed to the platform's accessibility layer, returns this
  649. // node. Otherwise, returns the lowest ancestor that is exposed to the
  650. // platform. (See `IsLeaf()` and `IsIgnored()` for information on what is
  651. // exposed to platform APIs.)
  652. AXNode* GetLowestPlatformAncestor() const;
  653. // If this node is within an editable region, returns the node that is at the
  654. // root of that editable region, otherwise returns nullptr. In accessibility,
  655. // an editable region is synonymous to a node with the kTextField role, or a
  656. // contenteditable without the role, (see `AXNodeData::IsTextField()`).
  657. AXNode* GetTextFieldAncestor() const;
  658. // Get the native text field's deepest container; the lowest descendant that
  659. // contains all its text. Returns nullptr if the text field is empty, or if it
  660. // is not an atomic text field, (e.g., <input> or <textarea>).
  661. AXNode* GetTextFieldInnerEditorElement() const;
  662. // If this node is within a container (or widget) that supports either single
  663. // or multiple selection, returns the node that represents the container.
  664. AXNode* GetSelectionContainer() const;
  665. // If this node is within a table, returns the node that represents the table.
  666. AXNode* GetTableAncestor() const;
  667. // Returns true if this node is either an atomic text field , or one of its
  668. // ancestors is. An atomic text field does not expose its internal
  669. // implementation to assistive software, appearing as a single leaf node in
  670. // the accessibility tree. Examples include: An <input> or a <textarea> on the
  671. // Web, a text field in a PDF form, a Views-based text field, or a native
  672. // Android one.
  673. bool IsDescendantOfAtomicTextField() const;
  674. // Finds and returns a pointer to ordered set containing node.
  675. AXNode* GetOrderedSet() const;
  676. // Returns true if the node supports the read-only attribute.
  677. bool IsReadOnlySupported() const;
  678. // Returns true if the node is marked read-only or is disabled. By default,
  679. // all nodes that can't be edited are read-only.
  680. bool IsReadOnlyOrDisabled() const;
  681. private:
  682. AXTableInfo* GetAncestorTableInfo() const;
  683. void IdVectorToNodeVector(const std::vector<AXNodeID>& ids,
  684. std::vector<AXNode*>* nodes) const;
  685. int UpdateUnignoredCachedValuesRecursive(int start_index);
  686. AXNode* ComputeLastUnignoredChildRecursive() const;
  687. AXNode* ComputeFirstUnignoredChildRecursive() const;
  688. // Returns the value of a range control such as a slider or a scroll bar in
  689. // text format.
  690. std::string GetTextForRangeValue() const;
  691. // Returns the value of a color well (a color chooser control) in a human
  692. // readable format. For example: "50% red 40% green 90% blue".
  693. std::string GetValueForColorWell() const;
  694. // Compute the actual value of a color attribute that needs to be
  695. // blended with ancestor colors.
  696. SkColor ComputeColorAttribute(ax::mojom::IntAttribute color_attr) const;
  697. const raw_ptr<OwnerTree> tree_; // Owns this.
  698. size_t index_in_parent_;
  699. size_t unignored_index_in_parent_;
  700. size_t unignored_child_count_ = 0;
  701. const raw_ptr<AXNode> parent_;
  702. std::vector<AXNode*> children_;
  703. // Stores information about this node that is immutable and which has been
  704. // computed by the tree's source, such as `content::BlinkAXTreeSource`.
  705. AXNodeData data_;
  706. // See the class comment in "ax_hypertext.h" for an explanation of this
  707. // member.
  708. mutable AXHypertext hypertext_;
  709. mutable AXHypertext old_hypertext_;
  710. // Stores information about this node that can be computed on demand and
  711. // cached.
  712. mutable std::unique_ptr<AXComputedNodeData> computed_node_data_;
  713. // Stores the detected language computed from the node's text.
  714. std::unique_ptr<AXLanguageInfo> language_info_;
  715. };
  716. AX_EXPORT std::ostream& operator<<(std::ostream& stream, const AXNode& node);
  717. template <typename NodeType,
  718. NodeType* (NodeType::*NextSibling)() const,
  719. NodeType* (NodeType::*PreviousSibling)() const,
  720. NodeType* (NodeType::*FirstChild)() const,
  721. NodeType* (NodeType::*LastChild)() const>
  722. AXNode::ChildIteratorBase<NodeType,
  723. NextSibling,
  724. PreviousSibling,
  725. FirstChild,
  726. LastChild>::ChildIteratorBase(const NodeType* parent,
  727. NodeType* child)
  728. : parent_(parent), child_(child) {}
  729. template <typename NodeType,
  730. NodeType* (NodeType::*NextSibling)() const,
  731. NodeType* (NodeType::*PreviousSibling)() const,
  732. NodeType* (NodeType::*FirstChild)() const,
  733. NodeType* (NodeType::*LastChild)() const>
  734. AXNode::ChildIteratorBase<NodeType,
  735. NextSibling,
  736. PreviousSibling,
  737. FirstChild,
  738. LastChild>::ChildIteratorBase(const ChildIteratorBase&
  739. it)
  740. : parent_(it.parent_), child_(it.child_) {}
  741. template <typename NodeType,
  742. NodeType* (NodeType::*NextSibling)() const,
  743. NodeType* (NodeType::*PreviousSibling)() const,
  744. NodeType* (NodeType::*FirstChild)() const,
  745. NodeType* (NodeType::*LastChild)() const>
  746. bool AXNode::ChildIteratorBase<NodeType,
  747. NextSibling,
  748. PreviousSibling,
  749. FirstChild,
  750. LastChild>::operator==(const ChildIteratorBase&
  751. rhs) const {
  752. return parent_ == rhs.parent_ && child_ == rhs.child_;
  753. }
  754. template <typename NodeType,
  755. NodeType* (NodeType::*NextSibling)() const,
  756. NodeType* (NodeType::*PreviousSibling)() const,
  757. NodeType* (NodeType::*FirstChild)() const,
  758. NodeType* (NodeType::*LastChild)() const>
  759. bool AXNode::ChildIteratorBase<NodeType,
  760. NextSibling,
  761. PreviousSibling,
  762. FirstChild,
  763. LastChild>::operator!=(const ChildIteratorBase&
  764. rhs) const {
  765. return parent_ != rhs.parent_ || child_ != rhs.child_;
  766. }
  767. template <typename NodeType,
  768. NodeType* (NodeType::*NextSibling)() const,
  769. NodeType* (NodeType::*PreviousSibling)() const,
  770. NodeType* (NodeType::*FirstChild)() const,
  771. NodeType* (NodeType::*LastChild)() const>
  772. AXNode::ChildIteratorBase<NodeType,
  773. NextSibling,
  774. PreviousSibling,
  775. FirstChild,
  776. LastChild>&
  777. AXNode::ChildIteratorBase<NodeType,
  778. NextSibling,
  779. PreviousSibling,
  780. FirstChild,
  781. LastChild>::operator++() {
  782. // |child_ = nullptr| denotes the iterator's past-the-end condition. When we
  783. // increment the iterator past the end, we remain at the past-the-end iterator
  784. // condition.
  785. if (child_ && parent_) {
  786. if (child_ == (parent_.get()->*LastChild)())
  787. child_ = nullptr;
  788. else
  789. child_ = (child_.get()->*NextSibling)();
  790. }
  791. return *this;
  792. }
  793. template <typename NodeType,
  794. NodeType* (NodeType::*NextSibling)() const,
  795. NodeType* (NodeType::*PreviousSibling)() const,
  796. NodeType* (NodeType::*FirstChild)() const,
  797. NodeType* (NodeType::*LastChild)() const>
  798. AXNode::ChildIteratorBase<NodeType,
  799. NextSibling,
  800. PreviousSibling,
  801. FirstChild,
  802. LastChild>&
  803. AXNode::ChildIteratorBase<NodeType,
  804. NextSibling,
  805. PreviousSibling,
  806. FirstChild,
  807. LastChild>::operator--() {
  808. if (parent_) {
  809. // If the iterator is past the end, |child_=nullptr|, decrement the iterator
  810. // gives us the last iterator element.
  811. if (!child_)
  812. child_ = (parent_.get()->*LastChild)();
  813. // Decrement the iterator gives us the previous element, except when the
  814. // iterator is at the beginning; in which case, decrementing the iterator
  815. // remains at the beginning.
  816. else if (child_ != (parent_.get()->*FirstChild)())
  817. child_ = (child_.get()->*PreviousSibling)();
  818. }
  819. return *this;
  820. }
  821. template <typename NodeType,
  822. NodeType* (NodeType::*NextSibling)() const,
  823. NodeType* (NodeType::*PreviousSibling)() const,
  824. NodeType* (NodeType::*FirstChild)() const,
  825. NodeType* (NodeType::*LastChild)() const>
  826. NodeType* AXNode::ChildIteratorBase<NodeType,
  827. NextSibling,
  828. PreviousSibling,
  829. FirstChild,
  830. LastChild>::get() const {
  831. DCHECK(child_);
  832. return child_;
  833. }
  834. template <typename NodeType,
  835. NodeType* (NodeType::*NextSibling)() const,
  836. NodeType* (NodeType::*PreviousSibling)() const,
  837. NodeType* (NodeType::*FirstChild)() const,
  838. NodeType* (NodeType::*LastChild)() const>
  839. NodeType& AXNode::ChildIteratorBase<NodeType,
  840. NextSibling,
  841. PreviousSibling,
  842. FirstChild,
  843. LastChild>::operator*() const {
  844. DCHECK(child_);
  845. return *child_;
  846. }
  847. template <typename NodeType,
  848. NodeType* (NodeType::*NextSibling)() const,
  849. NodeType* (NodeType::*PreviousSibling)() const,
  850. NodeType* (NodeType::*FirstChild)() const,
  851. NodeType* (NodeType::*LastChild)() const>
  852. NodeType* AXNode::ChildIteratorBase<NodeType,
  853. NextSibling,
  854. PreviousSibling,
  855. FirstChild,
  856. LastChild>::operator->() const {
  857. DCHECK(child_);
  858. return child_;
  859. }
  860. } // namespace ui
  861. #endif // UI_ACCESSIBILITY_AX_NODE_H_