Flutter Engine
The Flutter Engine
ax_platform_node_base.h
Go to the documentation of this file.
1// Copyright 2014 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
5#ifndef UI_ACCESSIBILITY_PLATFORM_AX_PLATFORM_NODE_BASE_H_
6#define UI_ACCESSIBILITY_PLATFORM_AX_PLATFORM_NODE_BASE_H_
7
8#include <map>
9#include <string>
10#include <vector>
11
12#include "ax/ax_enums.h"
13#include "ax/ax_node.h"
15#include "ax_platform_node.h"
17#include "base/macros.h"
18#include "gfx/geometry/point.h"
20
21namespace ui {
22
23struct AXNodeData;
24
28 AXHypertext(const AXHypertext& other);
30
31 // A flag that should be set if the hypertext information in this struct is
32 // out-of-date and needs to be updated. This flag should always be set upon
33 // construction because constructing this struct doesn't compute the
34 // hypertext.
35 bool needs_update = true;
36
37 // Maps an embedded character offset in |hypertext| to an index in
38 // |hyperlinks|.
39 std::map<int32_t, int32_t> hyperlink_offset_to_index;
40
41 // The unique id of a AXPlatformNodes for each hyperlink.
42 // TODO(nektar): Replace object IDs with child indices if we decide that
43 // we are not implementing IA2 hyperlinks for anything other than IA2
44 // Hypertext.
45 std::vector<int32_t> hyperlinks;
46
47 std::u16string hypertext;
48};
49
51 public:
54
55 virtual void Init(AXPlatformNodeDelegate* delegate);
56
57 // These are simple wrappers to our delegate.
58 const AXNodeData& GetData() const;
60 gfx::NativeViewAccessible GetParent() const;
61 int GetChildCount() const;
62 gfx::NativeViewAccessible ChildAtIndex(int index) const;
63
64 std::string GetName() const;
65 std::u16string GetNameAsString16() const;
66
67 // This returns nullopt if there's no parent, it's unable to find the child in
68 // the list of its parent's children, or its parent doesn't have children.
69 virtual std::optional<int> GetIndexInParent();
70
71 // Returns a stack of ancestors of this node. The node at the top of the stack
72 // is the top most ancestor.
73 std::stack<gfx::NativeViewAccessible> GetAncestors();
74
75 // Returns an optional integer indicating the logical order of this node
76 // compared to another node or returns an empty optional if the nodes
77 // are not comparable.
78 // 0: if this position is logically equivalent to the other node
79 // <0: if this position is logically less than (before) the other node
80 // >0: if this position is logically greater than (after) the other node
81 std::optional<int> CompareTo(AXPlatformNodeBase& other);
82
83 // AXPlatformNode.
84 void Destroy() override;
85 gfx::NativeViewAccessible GetNativeViewAccessible() override;
86 void NotifyAccessibilityEvent(ax::mojom::Event event_type) override;
87
88#if defined(OS_APPLE)
89 void AnnounceText(const std::u16string& text) override;
90#endif
91
92 AXPlatformNodeDelegate* GetDelegate() const override;
93 bool IsDescendantOf(AXPlatformNode* ancestor) const override;
94
95 // Helpers.
96 AXPlatformNodeBase* GetPreviousSibling() const;
97 AXPlatformNodeBase* GetNextSibling() const;
98 AXPlatformNodeBase* GetFirstChild() const;
99 AXPlatformNodeBase* GetLastChild() const;
100 bool IsDescendant(AXPlatformNodeBase* descendant);
101
108 AXPlatformNodeChildIterator AXPlatformNodeChildrenBegin() const;
109 AXPlatformNodeChildIterator AXPlatformNodeChildrenEnd() const;
110
111 bool HasBoolAttribute(ax::mojom::BoolAttribute attr) const;
112 bool GetBoolAttribute(ax::mojom::BoolAttribute attr) const;
113 bool GetBoolAttribute(ax::mojom::BoolAttribute attr, bool* value) const;
114
115 bool HasFloatAttribute(ax::mojom::FloatAttribute attr) const;
116 float GetFloatAttribute(ax::mojom::FloatAttribute attr) const;
117 bool GetFloatAttribute(ax::mojom::FloatAttribute attr, float* value) const;
118
119 bool HasIntAttribute(ax::mojom::IntAttribute attribute) const;
120 int GetIntAttribute(ax::mojom::IntAttribute attribute) const;
121 bool GetIntAttribute(ax::mojom::IntAttribute attribute, int* value) const;
122
123 bool HasStringAttribute(ax::mojom::StringAttribute attribute) const;
124 const std::string& GetStringAttribute(
125 ax::mojom::StringAttribute attribute) const;
126 bool GetStringAttribute(ax::mojom::StringAttribute attribute,
127 std::string* value) const;
128 bool GetString16Attribute(ax::mojom::StringAttribute attribute,
129 std::u16string* value) const;
130 std::u16string GetString16Attribute(
131 ax::mojom::StringAttribute attribute) const;
132 bool HasInheritedStringAttribute(ax::mojom::StringAttribute attribute) const;
133 const std::string& GetInheritedStringAttribute(
134 ax::mojom::StringAttribute attribute) const;
135 std::u16string GetInheritedString16Attribute(
136 ax::mojom::StringAttribute attribute) const;
137 bool GetInheritedStringAttribute(ax::mojom::StringAttribute attribute,
138 std::string* value) const;
139 bool GetInheritedString16Attribute(ax::mojom::StringAttribute attribute,
140 std::u16string* value) const;
141
142 bool HasIntListAttribute(ax::mojom::IntListAttribute attribute) const;
143 const std::vector<int32_t>& GetIntListAttribute(
144 ax::mojom::IntListAttribute attribute) const;
145
146 bool GetIntListAttribute(ax::mojom::IntListAttribute attribute,
147 std::vector<int32_t>* value) const;
148
149 // Returns the selection container if inside one.
150 AXPlatformNodeBase* GetSelectionContainer() const;
151
152 // Returns the table or ARIA grid if inside one.
153 AXPlatformNodeBase* GetTable() const;
154
155 // If inside an HTML or ARIA table, returns the object containing the caption.
156 // Returns nullptr if not inside a table, or if there is no
157 // caption.
158 AXPlatformNodeBase* GetTableCaption() const;
159
160 // If inside a table or ARIA grid, returns the cell found at the given index.
161 // Indices are in row major order and each cell is counted once regardless of
162 // its span. Returns nullptr if the cell is not found or if not inside a
163 // table.
164 AXPlatformNodeBase* GetTableCell(int index) const;
165
166 // If inside a table or ARIA grid, returns the cell at the given row and
167 // column (0-based). Works correctly with cells that span multiple rows or
168 // columns. Returns nullptr if the cell is not found or if not inside a
169 // table.
170 AXPlatformNodeBase* GetTableCell(int row, int column) const;
171
172 // If inside a table or ARIA grid, returns the zero-based index of the cell.
173 // Indices are in row major order and each cell is counted once regardless of
174 // its span. Returns std::nullopt if not a cell or if not inside a table.
175 std::optional<int> GetTableCellIndex() const;
176
177 // If inside a table or ARIA grid, returns the physical column number for the
178 // current cell. In contrast to logical columns, physical columns always start
179 // from 0 and have no gaps in their numbering. Logical columns can be set
180 // using aria-colindex. Returns std::nullopt if not a cell or if not inside a
181 // table.
182 std::optional<int> GetTableColumn() const;
183
184 // If inside a table or ARIA grid, returns the number of physical columns.
185 // Returns std::nullopt if not inside a table.
186 std::optional<int> GetTableColumnCount() const;
187
188 // If inside a table or ARIA grid, returns the number of ARIA columns.
189 // Returns std::nullopt if not inside a table.
190 std::optional<int> GetTableAriaColumnCount() const;
191
192 // If inside a table or ARIA grid, returns the number of physical columns that
193 // this cell spans. Returns std::nullopt if not a cell or if not inside a
194 // table.
195 std::optional<int> GetTableColumnSpan() const;
196
197 // If inside a table or ARIA grid, returns the physical row number for the
198 // current cell. In contrast to logical rows, physical rows always start from
199 // 0 and have no gaps in their numbering. Logical rows can be set using
200 // aria-rowindex. Returns std::nullopt if not a cell or if not inside a
201 // table.
202 std::optional<int> GetTableRow() const;
203
204 // If inside a table or ARIA grid, returns the number of physical rows.
205 // Returns std::nullopt if not inside a table.
206 std::optional<int> GetTableRowCount() const;
207
208 // If inside a table or ARIA grid, returns the number of ARIA rows.
209 // Returns std::nullopt if not inside a table.
210 std::optional<int> GetTableAriaRowCount() const;
211
212 // If inside a table or ARIA grid, returns the number of physical rows that
213 // this cell spans. Returns std::nullopt if not a cell or if not inside a
214 // table.
215 std::optional<int> GetTableRowSpan() const;
216
217 // Returns the font size converted to points, if available.
218 std::optional<float> GetFontSizeInPoints() const;
219
220 // Returns true if either a descendant has selection (sel_focus_object_id) or
221 // if this node is a simple text element and has text selection attributes.
222 // Optionally accepts an unignored selection to avoid redundant computation.
223 bool HasCaret(const AXTree::Selection* unignored_selection = nullptr);
224
225 // See AXPlatformNodeDelegate::IsChildOfLeaf().
226 bool IsChildOfLeaf() const;
227
228 // See AXPlatformNodeDelegate::IsLeaf().
229 bool IsLeaf() const;
230
231 // See AXPlatformNodeDelegate::IsInvisibleOrIgnored().
232 bool IsInvisibleOrIgnored() const;
233
234 // Returns true if this node can be scrolled either in the horizontal or the
235 // vertical direction.
236 bool IsScrollable() const;
237
238 // Returns true if this node can be scrolled in the horizontal direction.
239 bool IsHorizontallyScrollable() const;
240
241 // Returns true if this node can be scrolled in the vertical direction.
242 bool IsVerticallyScrollable() const;
243
244 // See AXNodeData::IsTextField().
245 bool IsTextField() const;
246
247 // See AXNodeData::IsPlainTextField().
248 bool IsPlainTextField() const;
249
250 // See AXNodeData::IsRichTextField().
251 bool IsRichTextField() const;
252
253 // See AXNode::IsText().
254 bool IsText() const;
255
256 // Determines whether an element should be exposed with checkable state, and
257 // possibly the checked state. Examples are check box and radio button.
258 // Objects that are exposed as toggle buttons use the platform pressed state
259 // in some platform APIs, and should not be exposed as checkable. They don't
260 // expose the platform equivalent of the internal checked state.
261 virtual bool IsPlatformCheckable() const;
262
263 bool HasFocus();
264
265 // If this node is a leaf, returns the visible accessible name of this node.
266 // Otherwise represents every non-leaf child node with a special "embedded
267 // object character", and every leaf child node with its visible accessible
268 // name. This is how displayed text and embedded objects are represented in
269 // ATK and IA2 APIs.
270 std::u16string GetHypertext() const;
271
272 // Returns the text of this node and all descendant nodes; including text
273 // found in embedded objects.
274 //
275 // Only text displayed on screen is included. Text from ARIA and HTML
276 // attributes that is either not displayed on screen, or outside this node,
277 // e.g. aria-label and HTML title, is not returned.
278 std::u16string GetInnerText() const;
279
280 virtual std::u16string GetValue() const;
281
282 // Represents a non-static text node in IAccessibleHypertext (and ATK in the
283 // future). This character is embedded in the response to
284 // IAccessibleText::get_text, indicating the position where a non-static text
285 // child object appears.
286 static const char16_t kEmbeddedCharacter;
287
288 // Get a node given its unique id or null in the case that the id is unknown.
289 static AXPlatformNode* GetFromUniqueId(int32_t unique_id);
290
291 // Return the number of instances of AXPlatformNodeBase, for leak testing.
292 static size_t GetInstanceCountForTesting();
293
296 std::function<void()> callback);
297
306 };
307 bool ScrollToNode(ScrollType scroll_type);
308
309 // This will return the nearest leaf node to the point, the leaf node will not
310 // necessarily be directly under the point. This utilizes
311 // AXPlatformNodeDelegate::HitTestSync, which in the case of
312 // BrowserAccessibility, may not be accurate after a single call. See
313 // BrowserAccessibilityManager::CachingAsyncHitTest
314 AXPlatformNodeBase* NearestLeafToPoint(gfx::Point point) const;
315
316 // Return the nearest text index to a point in screen coordinates for an
317 // accessibility node. If the node is not a text only node, the implicit
318 // nearest index is zero. Note this will only find the index of text on the
319 // input node. Due to perf concerns, this should only be called on leaf nodes.
320 int NearestTextIndexToPoint(gfx::Point point);
321
322 ui::TextAttributeList ComputeTextAttributes() const;
323
324 // Get the number of items selected. It checks kMultiselectable and
325 // kFocusable. and uses GetSelectedItems to get the selected number.
326 int GetSelectionCount() const;
327
328 // If this object is a container that supports selectable children, returns
329 // the selected item at the provided index.
330 AXPlatformNodeBase* GetSelectedItem(int selected_index) const;
331
332 // If this object is a container that supports selectable children,
333 // returns the number of selected items in this container.
334 // |out_selected_items| could be set to nullptr if the caller just
335 // needs to know the number of items selected.
336 // |max_items| represents the number that the caller expects as a
337 // maximum. For a single selection list box, it will be 1.
338 int GetSelectedItems(
339 int max_items,
340 std::vector<AXPlatformNodeBase*>* out_selected_items = nullptr) const;
341
342 //
343 // Delegate. This is a weak reference which owns |this|.
344 //
346
347 protected:
348 bool IsDocument() const;
349
350 bool IsSelectionItemSupported() const;
351
352 // Get the range value text, which might come from aria-valuetext or
353 // a floating-point value. This is different from the value string
354 // attribute used in input controls such as text boxes and combo boxes.
355 std::u16string GetRangeValueText() const;
356
357 // Get the role description from the node data or from the image annotation
358 // status.
359 std::u16string GetRoleDescription() const;
360 std::u16string GetRoleDescriptionFromImageAnnotationStatusOrFromAttribute()
361 const;
362
363 // Cast a gfx::NativeViewAccessible to an AXPlatformNodeBase if it is one,
364 // or return NULL if it's not an instance of this class.
365 static AXPlatformNodeBase* FromNativeViewAccessible(
366 gfx::NativeViewAccessible accessible);
367
368 virtual void Dispose();
369
370 // Sets the hypertext selection in this object if possible.
371 bool SetHypertextSelection(int start_offset, int end_offset);
372
373 using PlatformAttributeList = std::vector<std::u16string>;
374
375 // Compute the attributes exposed via platform accessibility objects and put
376 // them into an attribute list, |attributes|. Currently only used by
377 // IAccessible2 on Windows and ATK on Aura Linux.
378 void ComputeAttributes(PlatformAttributeList* attributes);
379
380 // If the string attribute |attribute| is present, add its value as an
381 // IAccessible2 attribute with the name |name|.
382 void AddAttributeToList(const ax::mojom::StringAttribute attribute,
383 const char* name,
384 PlatformAttributeList* attributes);
385
386 // If the bool attribute |attribute| is present, add its value as an
387 // IAccessible2 attribute with the name |name|.
388 void AddAttributeToList(const ax::mojom::BoolAttribute attribute,
389 const char* name,
390 PlatformAttributeList* attributes);
391
392 // If the int attribute |attribute| is present, add its value as an
393 // IAccessible2 attribute with the name |name|.
394 void AddAttributeToList(const ax::mojom::IntAttribute attribute,
395 const char* name,
396 PlatformAttributeList* attributes);
397
398 // A helper to add the given string value to |attributes|.
399 virtual void AddAttributeToList(const char* name,
400 const std::string& value,
401 PlatformAttributeList* attributes);
402
403 // A virtual method that subclasses use to actually add the attribute to
404 // |attributes|.
405 virtual void AddAttributeToList(const char* name,
406 const char* value,
407 PlatformAttributeList* attributes);
408
409 // Escapes characters in string attributes as required by the IA2 Spec
410 // and AT-SPI2. It's okay for input to be the same as output.
411 static void SanitizeStringAttribute(const std::string& input,
412 std::string* output);
413
414 // Escapes characters in text attribute values as required by the platform.
415 // It's okay for input to be the same as output. The default implementation
416 // does nothing to the input value.
417 virtual void SanitizeTextAttributeValue(const std::string& input,
418 std::string* output) const;
419
420 // Compute the hypertext for this node to be exposed via IA2 and ATK This
421 // method is responsible for properly embedding children using the special
422 // embedded element character.
423 void UpdateComputedHypertext() const;
424
425 // Selection helper functions.
426 // The following functions retrieve the endpoints of the current selection.
427 // First they check for a local selection found on the current control, e.g.
428 // when querying the selection on a textarea.
429 // If not found they retrieve the global selection found on the current frame.
430 int GetSelectionAnchor(const AXTree::Selection* selection);
431 int GetSelectionFocus(const AXTree::Selection* selection);
432
433 // Retrieves the selection offsets in the way required by the IA2 APIs.
434 // selection_start and selection_end are -1 when there is no selection active
435 // on this object.
436 // The greatest of the two offsets is one past the last character of the
437 // selection.)
438 void GetSelectionOffsets(int* selection_start, int* selection_end);
439 void GetSelectionOffsets(const AXTree::Selection* selection,
440 int* selection_start,
441 int* selection_end);
442 void GetSelectionOffsetsFromTree(const AXTree::Selection* selection,
443 int* selection_start,
444 int* selection_end);
445
446 // Returns the hyperlink at the given text position, or nullptr if no
447 // hyperlink can be found.
448 AXPlatformNodeBase* GetHyperlinkFromHypertextOffset(int offset);
449
450 // Functions for retrieving offsets for hyperlinks and hypertext.
451 // Return -1 in case of failure.
452 int32_t GetHyperlinkIndexFromChild(AXPlatformNodeBase* child);
453 int32_t GetHypertextOffsetFromHyperlinkIndex(int32_t hyperlink_index);
454 int32_t GetHypertextOffsetFromChild(AXPlatformNodeBase* child);
455 int32_t GetHypertextOffsetFromDescendant(AXPlatformNodeBase* descendant);
456
457 // If the selection endpoint is either equal to or an ancestor of this object,
458 // returns endpoint_offset.
459 // If the selection endpoint is a descendant of this object, returns its
460 // offset. Otherwise, returns either 0 or the length of the hypertext
461 // depending on the direction of the selection.
462 // Returns -1 in case of unexpected failure, e.g. the selection endpoint
463 // cannot be found in the accessibility tree.
464 int GetHypertextOffsetFromEndpoint(AXPlatformNodeBase* endpoint_object,
465 int endpoint_offset);
466
467 bool IsSameHypertextCharacter(const AXHypertext& old_hypertext,
468 size_t old_char_index,
469 size_t new_char_index);
470
471 std::optional<int> GetPosInSet() const;
472 std::optional<int> GetSetSize() const;
473
474 std::string GetInvalidValue() const;
475
476 // Based on the characteristics of this object, such as its role and the
477 // presence of a multiselectable attribute, returns the maximum number of
478 // selectable children that this object could potentially contain.
479 int GetMaxSelectableItems() const;
480
482
483 private:
484 // Returns true if the index represents a text character.
485 bool IsText(const std::u16string& text,
486 size_t index,
487 bool is_indexed_from_end = false);
488
489 // Compute value for object attribute details-roles on aria-details nodes.
490 std::string ComputeDetailsRoles() const;
491
493};
494
495} // namespace ui
496
497#endif // UI_ACCESSIBILITY_PLATFORM_AX_PLATFORM_NODE_BASE_H_
ax::mojom::Event event_type
#define AX_EXPORT
Definition: ax_export.h:29
~AXPlatformNodeBase() override
AXPlatformNodeBase * GetLastChild() const
static const char16_t kEmbeddedCharacter
std::vector< std::u16string > PlatformAttributeList
AXPlatformNodeBase * GetPreviousSibling() const
static void SetOnNotifyEventCallbackForTesting(ax::mojom::Event event_type, std::function< void()> callback)
AXPlatformNodeBase * GetFirstChild() const
AXPlatformNodeBase * GetNextSibling() const
MockDelegate delegate_
FlKeyEvent uint64_t FlKeyResponderAsyncCallback callback
uint8_t value
Dart_NativeFunction function
Definition: fuchsia.cc:51
void Init()
std::u16string text
StringAttribute
Definition: ax_enums.h:521
FloatAttribute
Definition: ax_enums.h:699
IntListAttribute
Definition: ax_enums.h:799
static int64_t GetValue(Dart_Handle arg)
DEF_SWITCHES_START aot vmservice shared library name
Definition: switches.h:32
UnimplementedNativeViewAccessible * NativeViewAccessible
std::vector< TextAttribute > TextAttributeList
bool IsText(ax::mojom::Role role)
bool IsDocument(const ax::mojom::Role role)
SeparatedVector2 offset
AXHypertext(const AXHypertext &other)
std::vector< int32_t > hyperlinks
std::u16string hypertext
std::map< int32_t, int32_t > hyperlink_offset_to_index
AXHypertext & operator=(const AXHypertext &other)
#define BASE_DISALLOW_COPY_AND_ASSIGN(TypeName)
Definition: macros.h:8