1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178
|
// Copyright 2021 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef UI_ACCESSIBILITY_AX_COMPUTED_NODE_DATA_H_
#define UI_ACCESSIBILITY_AX_COMPUTED_NODE_DATA_H_
#include <stdint.h>
#include <string>
#include <vector>
#include "base/memory/raw_ptr.h"
#include "third_party/abseil-cpp/absl/types/optional.h"
#include "ui/accessibility/ax_enums.mojom-forward.h"
#include "ui/accessibility/ax_export.h"
#include "ui/accessibility/ax_node_data.h"
#include "ui/accessibility/ax_node_id_forward.h"
namespace ui {
class AXNode;
// Computes and stores information about an `AXNode` that is slow or error-prone
// to compute in the tree's source, e.g. in Blink. This class holds cached
// values that should be re-computed when the associated `AXNode` is in any way
// modified.
class AX_EXPORT AXComputedNodeData final {
public:
explicit AXComputedNodeData(const AXNode& node);
virtual ~AXComputedNodeData();
AXComputedNodeData(const AXComputedNodeData& other) = delete;
AXComputedNodeData& operator=(const AXComputedNodeData& other) = delete;
// If the associated node is unignored, i.e. exposed to the platform's
// assistive software, its position in the list of unignored children of its
// lowest unignored parent. Naturally, this value is not defined when the
// associated node is ignored.
int GetOrComputeUnignoredIndexInParent() const;
// The lowest unignored parent. This value should be computed for all
// associated nodes, ignored and unignored. Only the rootnode should not have
// an unignored parent.
AXNodeID GetOrComputeUnignoredParentID() const;
AXNode* GetOrComputeUnignoredParent() const;
// If the associated node is unignored, i.e. exposed to the platform's
// assistive software, the number of its children that are also unignored.
// Naturally, this value is not defined when the associated node is ignored.
int GetOrComputeUnignoredChildCount() const;
// If the associated node is unignored, i.e. exposed to the platform's
// assistive software, the IDs of its children that are also unignored.
const std::vector<AXNodeID>& GetOrComputeUnignoredChildIDs() const;
// Whether the associated node is a descendant of a platform leaf. The set of
// platform leaves are the lowest nodes that are exposed to the platform's
// assistive software.
bool GetOrComputeIsDescendantOfPlatformLeaf() const;
// Given an accessibility attribute, returns whether the attribute is
// currently present in the node's data, or if it can always be computed on
// demand.
bool HasOrCanComputeAttribute(
const ax::mojom::StringAttribute attribute) const;
bool HasOrCanComputeAttribute(
const ax::mojom::IntListAttribute attribute) const;
// Given an accessibility attribute, returns the attribute's value. The
// attribute is computed if not provided by the tree's source, otherwise it is
// simply returned from the node's data. String and intlist attributes are
// potentially the slowest to compute at the tree's source, e.g. in Blink.
const std::string& GetOrComputeAttributeUTF8(
const ax::mojom::StringAttribute attribute) const;
std::u16string GetOrComputeAttributeUTF16(
const ax::mojom::StringAttribute attribute) const;
const std::vector<int32_t>& GetOrComputeAttribute(
const ax::mojom::IntListAttribute attribute) const;
// Retrieves from the cache or computes the on-screen text that is found
// inside the associated node and all its descendants, caches the result, and
// returns a reference to the cached text.
//
// Takes into account any formatting changes, such as paragraph breaks, that
// have been introduced by layout. For example, in the Web context,
// "A<div>B</div>C" would produce "A\nB\nC". Note that since hidden elements
// are not in the accessibility tree, they are not included in the result.
const std::string& GetOrComputeTextContentWithParagraphBreaksUTF8() const;
const std::u16string& GetOrComputeTextContentWithParagraphBreaksUTF16() const;
// Retrieves from the cache or computes the on-screen text that is found
// inside the associated node and all its descendants, caches the result, and
// returns a reference to the cached text.
//
// Does not take into account any formatting changes, such as extra paragraph
// breaks, that have been introduced by layout. For example, in the Web
// context, "A<div>B</div>C" would produce "ABC".
const std::string& GetOrComputeTextContentUTF8() const;
const std::u16string& GetOrComputeTextContentUTF16() const;
// Returns the length of the on-screen text that is found inside the
// associated node and all its descendants. The text is either retrieved from
// the cache, or computed and then cached.
//
// Does not take into account line breaks that have been introduced by layout.
// For example, in the Web context, "A<div>B</div>C" would produce 3 and
// not 5.
int GetOrComputeTextContentLengthUTF8() const;
int GetOrComputeTextContentLengthUTF16() const;
private:
// Computes and caches the `unignored_index_in_parent_`, `unignored_parent_`,
// `unignored_child_count_` and `unignored_child_ids_` for the associated
// node.
void ComputeUnignoredValues(AXNodeID unignored_parent_id = kInvalidAXNodeID,
int starting_index_in_parent = 0) const;
// Walks up the accessibility tree from the associated node until it finds the
// lowest unignored ancestor.
AXNode* SlowGetUnignoredParent() const;
// Computes and caches (if not already in the cache) whether the associated
// node is a descendant of a platform leaf. The set of platform leaves are the
// lowest nodes that are exposed to the platform's assistive software.
void ComputeIsDescendantOfPlatformLeaf() const;
// Computes and caches (if not already in the cache) the character offsets
// where each line in the associated node's on-screen text starts and ends.
void ComputeLineOffsetsIfNeeded() const;
// Computes and caches (if not already in the cache) the character offsets
// where each sentence in the associated node's on-screen text starts and
// ends.
void ComputeSentenceOffsetsIfNeeded() const;
// Computes and caches (if not already in the cache) the character offsets
// where each word in the associated node's on-screen text starts and ends.
// Note that the end offsets are always after the last character of each word,
// so e.g. the end offset for the word "Hello" is 5, not 4.
void ComputeWordOffsetsIfNeeded() const;
// Computes the on-screen text that is found inside the associated node and
// all its descendants.
std::string ComputeTextContentUTF8() const;
std::u16string ComputeTextContentUTF16() const;
// The node that is associated with this instance. Weak, owns us.
const raw_ptr<const AXNode> owner_;
mutable absl::optional<int> unignored_index_in_parent_;
mutable absl::optional<AXNodeID> unignored_parent_id_;
mutable absl::optional<int> unignored_child_count_;
mutable absl::optional<std::vector<AXNodeID>> unignored_child_ids_;
mutable absl::optional<bool> is_descendant_of_leaf_;
mutable absl::optional<std::vector<int32_t>> line_starts_;
mutable absl::optional<std::vector<int32_t>> line_ends_;
mutable absl::optional<std::vector<int32_t>> sentence_starts_;
mutable absl::optional<std::vector<int32_t>> sentence_ends_;
mutable absl::optional<std::vector<int32_t>> word_starts_;
mutable absl::optional<std::vector<int32_t>> word_ends_;
// There are two types of "text content". The first takes into
// account any formatting changes, such as paragraph breaks, that have been
// introduced by layout, whilst the other doesn't.
//
// Only one copy (either UTF8 or UTF16) should be cached as each platform
// should only need one of the encodings. This applies to both text content as
// well as text content with paragraph breaks.
mutable absl::optional<std::string> text_content_with_paragraph_breaks_utf8_;
mutable absl::optional<std::u16string>
text_content_with_paragraph_breaks_utf16_;
mutable absl::optional<std::string> text_content_utf8_;
mutable absl::optional<std::u16string> text_content_utf16_;
};
} // namespace ui
#endif // UI_ACCESSIBILITY_AX_COMPUTED_NODE_DATA_H_
|