OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef UI_ACCESSIBILITY_AX_POSITION_H_ | 5 #ifndef UI_ACCESSIBILITY_AX_POSITION_H_ |
6 #define UI_ACCESSIBILITY_AX_POSITION_H_ | 6 #define UI_ACCESSIBILITY_AX_POSITION_H_ |
7 | 7 |
8 #include <stdint.h> | 8 #include <stdint.h> |
9 | 9 |
10 #include <memory> | 10 #include <memory> |
11 #include <stack> | 11 #include <stack> |
12 #include <string> | 12 #include <string> |
13 #include <utility> | 13 #include <utility> |
14 #include <vector> | 14 #include <vector> |
15 | 15 |
16 #include "base/stl_util.h" | 16 #include "base/stl_util.h" |
17 #include "base/strings/string16.h" | 17 #include "base/strings/string16.h" |
18 #include "base/strings/string_number_conversions.h" | 18 #include "base/strings/string_number_conversions.h" |
19 #include "base/strings/utf_string_conversions.h" | 19 #include "base/strings/utf_string_conversions.h" |
| 20 #include "ui/accessibility/ax_abstract_position.h" |
20 #include "ui/accessibility/ax_enums.h" | 21 #include "ui/accessibility/ax_enums.h" |
21 | 22 |
22 namespace ui { | 23 namespace ui { |
23 | 24 |
24 // Defines the type of position in the accessibility tree. | |
25 // A tree position is used when referring to a specific child of a node in the | |
26 // accessibility tree. | |
27 // A text position is used when referring to a specific character of text inside | |
28 // a particular node. | |
29 // A null position is used to signify that the provided data is invalid or that | |
30 // a boundary has been reached. | |
31 enum class AXPositionKind { NULL_POSITION, TREE_POSITION, TEXT_POSITION }; | |
32 | |
33 // Forward declarations. | 25 // Forward declarations. |
34 template <class AXPositionType, class AXNodeType> | 26 template <class AXPositionType, class AXNodeType> |
35 class AXPosition; | 27 class AXPosition; |
36 template <class AXPositionType, class AXNodeType> | 28 template <class AXPositionType, class AXNodeType> |
37 bool operator==(const AXPosition<AXPositionType, AXNodeType>& first, | 29 bool operator==(const AXPosition<AXPositionType, AXNodeType>& first, |
38 const AXPosition<AXPositionType, AXNodeType>& second); | 30 const AXPosition<AXPositionType, AXNodeType>& second); |
39 template <class AXPositionType, class AXNodeType> | 31 template <class AXPositionType, class AXNodeType> |
40 bool operator!=(const AXPosition<AXPositionType, AXNodeType>& first, | 32 bool operator!=(const AXPosition<AXPositionType, AXNodeType>& first, |
41 const AXPosition<AXPositionType, AXNodeType>& second); | 33 const AXPosition<AXPositionType, AXNodeType>& second); |
42 | 34 |
(...skipping 20 matching lines...) Expand all Loading... |
63 // This class template uses static polymorphism in order to allow sub-classes to | 55 // This class template uses static polymorphism in order to allow sub-classes to |
64 // be created from the base class without the base class knowing the type of the | 56 // be created from the base class without the base class knowing the type of the |
65 // sub-class in advance. | 57 // sub-class in advance. |
66 // The template argument |AXPositionType| should always be set to the type of | 58 // The template argument |AXPositionType| should always be set to the type of |
67 // any class that inherits from this template, making this a | 59 // any class that inherits from this template, making this a |
68 // "curiously recursive template". | 60 // "curiously recursive template". |
69 // | 61 // |
70 // This class can be copied using the |Clone| method. It is designed to be | 62 // This class can be copied using the |Clone| method. It is designed to be |
71 // immutable. | 63 // immutable. |
72 template <class AXPositionType, class AXNodeType> | 64 template <class AXPositionType, class AXNodeType> |
73 class AXPosition { | 65 class AXPosition : public AXAbstractPosition { |
74 public: | 66 public: |
75 using AXPositionInstance = | 67 using AXPositionInstance = |
76 std::unique_ptr<AXPosition<AXPositionType, AXNodeType>>; | 68 std::unique_ptr<AXPosition<AXPositionType, AXNodeType>>; |
77 | 69 |
78 static const int INVALID_TREE_ID = -1; | |
79 static const int32_t INVALID_ANCHOR_ID = -1; | |
80 static const int BEFORE_TEXT = -1; | |
81 static const int INVALID_INDEX = -2; | |
82 static const int INVALID_OFFSET = -1; | |
83 | |
84 static AXPositionInstance CreateNullPosition() { | 70 static AXPositionInstance CreateNullPosition() { |
85 AXPositionInstance new_position(new AXPositionType()); | 71 return CreateFromData(kNullData); |
86 new_position->Initialize(AXPositionKind::NULL_POSITION, INVALID_TREE_ID, | |
87 INVALID_ANCHOR_ID, INVALID_INDEX, INVALID_OFFSET, | |
88 AX_TEXT_AFFINITY_DOWNSTREAM); | |
89 return new_position; | |
90 } | 72 } |
91 | 73 |
92 static AXPositionInstance CreateTreePosition(int tree_id, | 74 static AXPositionInstance CreateTreePosition(int tree_id, |
93 int32_t anchor_id, | 75 int32_t anchor_id, |
94 int child_index) { | 76 int child_index) { |
95 AXPositionInstance new_position(new AXPositionType()); | 77 AXPositionInstance new_position(new AXPositionType()); |
96 new_position->Initialize(AXPositionKind::TREE_POSITION, tree_id, anchor_id, | 78 new_position->Initialize(AXPositionKind::TREE_POSITION, tree_id, anchor_id, |
97 child_index, INVALID_OFFSET, | 79 child_index, INVALID_OFFSET, |
98 AX_TEXT_AFFINITY_DOWNSTREAM); | 80 AX_TEXT_AFFINITY_DOWNSTREAM); |
99 return new_position; | 81 return new_position; |
100 } | 82 } |
101 | 83 |
102 static AXPositionInstance CreateTextPosition(int tree_id, | 84 static AXPositionInstance CreateTextPosition(int tree_id, |
103 int32_t anchor_id, | 85 int32_t anchor_id, |
104 int text_offset, | 86 int text_offset, |
105 AXTextAffinity affinity) { | 87 AXTextAffinity affinity) { |
106 AXPositionInstance new_position(new AXPositionType()); | 88 AXPositionInstance new_position(new AXPositionType()); |
107 new_position->Initialize(AXPositionKind::TEXT_POSITION, tree_id, anchor_id, | 89 new_position->Initialize(AXPositionKind::TEXT_POSITION, tree_id, anchor_id, |
108 INVALID_INDEX, text_offset, affinity); | 90 INVALID_INDEX, text_offset, affinity); |
109 return new_position; | 91 return new_position; |
110 } | 92 } |
111 | 93 |
| 94 static AXPositionInstance CreateFromData(const AXPositionData& data) { |
| 95 AXPositionInstance new_position(new AXPositionType()); |
| 96 // Skip Initialize() when creating from data. |
| 97 new_position->kind_ = data.kind; |
| 98 new_position->tree_id_ = data.tree_id; |
| 99 new_position->anchor_id_ = data.anchor_id; |
| 100 new_position->child_index_ = data.child_index; |
| 101 new_position->text_offset_ = data.text_offset; |
| 102 new_position->affinity_ = data.affinity; |
| 103 return new_position; |
| 104 } |
| 105 |
112 AXPosition() {} | 106 AXPosition() {} |
113 virtual ~AXPosition() {} | 107 virtual ~AXPosition() {} |
114 | 108 |
115 virtual AXPositionInstance Clone() const = 0; | 109 virtual AXPositionInstance Clone() const = 0; |
116 | 110 |
117 std::string ToString() const { | 111 std::string ToString() const { |
118 std::string str; | 112 std::string str; |
119 switch (kind_) { | 113 switch (kind_) { |
120 case AXPositionKind::NULL_POSITION: | 114 case AXPositionKind::NULL_POSITION: |
121 return "NullPosition"; | 115 return "NullPosition"; |
(...skipping 842 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
964 | 958 |
965 // Returns the text that is present inside the anchor node, including any text | 959 // Returns the text that is present inside the anchor node, including any text |
966 // found in descendant nodes. | 960 // found in descendant nodes. |
967 virtual base::string16 GetInnerText() const = 0; | 961 virtual base::string16 GetInnerText() const = 0; |
968 | 962 |
969 protected: | 963 protected: |
970 AXPosition(const AXPosition<AXPositionType, AXNodeType>& other) = default; | 964 AXPosition(const AXPosition<AXPositionType, AXNodeType>& other) = default; |
971 virtual AXPosition<AXPositionType, AXNodeType>& operator=( | 965 virtual AXPosition<AXPositionType, AXNodeType>& operator=( |
972 const AXPosition<AXPositionType, AXNodeType>& other) = default; | 966 const AXPosition<AXPositionType, AXNodeType>& other) = default; |
973 | 967 |
974 virtual void Initialize(AXPositionKind kind, | 968 void Initialize(AXPositionKind kind, |
975 int tree_id, | 969 int tree_id, |
976 int32_t anchor_id, | 970 int32_t anchor_id, |
977 int child_index, | 971 int child_index, |
978 int text_offset, | 972 int text_offset, |
979 AXTextAffinity affinity) { | 973 AXTextAffinity affinity) { |
980 kind_ = kind; | 974 kind_ = kind; |
981 tree_id_ = tree_id; | 975 tree_id_ = tree_id; |
982 anchor_id_ = anchor_id; | 976 anchor_id_ = anchor_id; |
983 child_index_ = child_index; | 977 child_index_ = child_index; |
984 text_offset_ = text_offset; | 978 text_offset_ = text_offset; |
985 affinity_ = affinity; | 979 affinity_ = affinity; |
986 | 980 |
987 if (!GetAnchor() || kind_ == AXPositionKind::NULL_POSITION || | 981 if (!GetAnchor() || kind_ == AXPositionKind::NULL_POSITION || |
988 (kind_ == AXPositionKind::TREE_POSITION && | 982 (kind_ == AXPositionKind::TREE_POSITION && |
989 (child_index_ != BEFORE_TEXT && | 983 (child_index_ != BEFORE_TEXT && |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1099 // On some platforms, embedded objects are represented in their parent with a | 1093 // On some platforms, embedded objects are represented in their parent with a |
1100 // single embedded object character. | 1094 // single embedded object character. |
1101 virtual int MaxTextOffsetInParent() const { return MaxTextOffset(); } | 1095 virtual int MaxTextOffsetInParent() const { return MaxTextOffset(); } |
1102 virtual bool IsInLineBreak() const = 0; | 1096 virtual bool IsInLineBreak() const = 0; |
1103 virtual std::vector<int32_t> GetWordStartOffsets() const = 0; | 1097 virtual std::vector<int32_t> GetWordStartOffsets() const = 0; |
1104 virtual std::vector<int32_t> GetWordEndOffsets() const = 0; | 1098 virtual std::vector<int32_t> GetWordEndOffsets() const = 0; |
1105 virtual int32_t GetNextOnLineID(int32_t node_id) const = 0; | 1099 virtual int32_t GetNextOnLineID(int32_t node_id) const = 0; |
1106 virtual int32_t GetPreviousOnLineID(int32_t node_id) const = 0; | 1100 virtual int32_t GetPreviousOnLineID(int32_t node_id) const = 0; |
1107 | 1101 |
1108 private: | 1102 private: |
| 1103 // AXAbstractPosition: |
| 1104 void ToData(AXPositionData* data) const override { |
| 1105 *data = {kind_, tree_id_, anchor_id_, |
| 1106 child_index_, text_offset_, affinity_}; |
| 1107 } |
| 1108 bool IsNull() const override { return IsNullPosition(); } |
| 1109 bool Compare(const AXPositionPointer& other) const override { |
| 1110 return *this < *other.DownCastTo<AXPosition>(); |
| 1111 } |
| 1112 |
| 1113 AXPositionPointer PositionAtEndOfAnchor() const override { |
| 1114 return CreatePositionAtEndOfAnchor(); |
| 1115 } |
| 1116 AXPositionPointer PositionAtStartOfAnchor() const override { |
| 1117 return CreatePositionAtStartOfAnchor(); |
| 1118 } |
| 1119 |
| 1120 AXPositionPointer NextCharacterPosition() const override { |
| 1121 return CreateNextCharacterPosition(); |
| 1122 } |
| 1123 AXPositionPointer PreviousCharacterPosition() const override { |
| 1124 return CreatePreviousCharacterPosition(); |
| 1125 } |
| 1126 |
| 1127 AXPositionPointer NextWordStartPosition() const override { |
| 1128 return CreateNextWordStartPosition(); |
| 1129 } |
| 1130 AXPositionPointer PreviousWordStartPosition() const override { |
| 1131 return CreatePreviousWordStartPosition(); |
| 1132 } |
| 1133 AXPositionPointer NextWordEndPosition() const override { |
| 1134 return CreateNextWordEndPosition(); |
| 1135 } |
| 1136 AXPositionPointer PreviousWordEndPosition() const override { |
| 1137 return CreatePreviousWordEndPosition(); |
| 1138 } |
| 1139 |
| 1140 AXPositionPointer NextLineStartPosition() const override { |
| 1141 return CreateNextLineStartPosition(); |
| 1142 } |
| 1143 AXPositionPointer PreviousLineStartPosition() const override { |
| 1144 return CreatePreviousLineStartPosition(); |
| 1145 } |
| 1146 AXPositionPointer NextLineEndPosition() const override { |
| 1147 return CreateNextLineEndPosition(); |
| 1148 } |
| 1149 AXPositionPointer PreviousLineEndPosition() const override { |
| 1150 return CreatePreviousLineEndPosition(); |
| 1151 } |
| 1152 |
1109 AXPositionKind kind_; | 1153 AXPositionKind kind_; |
1110 int tree_id_; | 1154 int tree_id_; |
1111 int32_t anchor_id_; | 1155 int32_t anchor_id_; |
1112 | 1156 |
1113 // For text positions, |child_index_| is initially set to |-1| and only | 1157 // For text positions, |child_index_| is initially set to |-1| and only |
1114 // computed on demand. The same with tree positions and |text_offset_|. | 1158 // computed on demand. The same with tree positions and |text_offset_|. |
1115 int child_index_; | 1159 int child_index_; |
1116 int text_offset_; | 1160 int text_offset_; |
1117 | 1161 |
1118 // TODO(nektar): Get rid of affinity and make Blink handle affinity | 1162 // TODO(nektar): Get rid of affinity and make Blink handle affinity |
1119 // internally since inline text objects don't span lines. | 1163 // internally since inline text objects don't span lines. |
1120 AXTextAffinity affinity_; | 1164 AXTextAffinity affinity_; |
1121 }; | 1165 }; |
1122 | 1166 |
1123 template <class AXPositionType, class AXNodeType> | 1167 template <class AXPositionType, class AXNodeType> |
1124 const int AXPosition<AXPositionType, AXNodeType>::INVALID_TREE_ID; | |
1125 template <class AXPositionType, class AXNodeType> | |
1126 const int32_t AXPosition<AXPositionType, AXNodeType>::INVALID_ANCHOR_ID; | |
1127 template <class AXPositionType, class AXNodeType> | |
1128 const int AXPosition<AXPositionType, AXNodeType>::BEFORE_TEXT; | |
1129 template <class AXPositionType, class AXNodeType> | |
1130 const int AXPosition<AXPositionType, AXNodeType>::INVALID_INDEX; | |
1131 template <class AXPositionType, class AXNodeType> | |
1132 const int AXPosition<AXPositionType, AXNodeType>::INVALID_OFFSET; | |
1133 | |
1134 template <class AXPositionType, class AXNodeType> | |
1135 bool operator==(const AXPosition<AXPositionType, AXNodeType>& first, | 1168 bool operator==(const AXPosition<AXPositionType, AXNodeType>& first, |
1136 const AXPosition<AXPositionType, AXNodeType>& second) { | 1169 const AXPosition<AXPositionType, AXNodeType>& second) { |
1137 if (first.IsNullPosition() && second.IsNullPosition()) | 1170 if (first.IsNullPosition() && second.IsNullPosition()) |
1138 return true; | 1171 return true; |
1139 return first.tree_id() == second.tree_id() && | 1172 return first.tree_id() == second.tree_id() && |
1140 first.anchor_id() == second.anchor_id() && | 1173 first.anchor_id() == second.anchor_id() && |
1141 first.child_index() == second.child_index() && | 1174 first.child_index() == second.child_index() && |
1142 first.text_offset() == second.text_offset() && | 1175 first.text_offset() == second.text_offset() && |
1143 first.affinity() == second.affinity(); | 1176 first.affinity() == second.affinity(); |
1144 } | 1177 } |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1189 | 1222 |
1190 template <class AXPositionType, class AXNodeType> | 1223 template <class AXPositionType, class AXNodeType> |
1191 bool operator>=(const AXPosition<AXPositionType, AXNodeType>& first, | 1224 bool operator>=(const AXPosition<AXPositionType, AXNodeType>& first, |
1192 const AXPosition<AXPositionType, AXNodeType>& second) { | 1225 const AXPosition<AXPositionType, AXNodeType>& second) { |
1193 return first == second || first > second; | 1226 return first == second || first > second; |
1194 } | 1227 } |
1195 | 1228 |
1196 } // namespace ui | 1229 } // namespace ui |
1197 | 1230 |
1198 #endif // UI_ACCESSIBILITY_AX_POSITION_H_ | 1231 #endif // UI_ACCESSIBILITY_AX_POSITION_H_ |
OLD | NEW |