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.
5 #include "ui/accessibility/ax_node_data.h"
9 #include "base/strings/string_number_conversions.h"
10 #include "base/strings/string_util.h"
11 #include "base/strings/utf_string_conversions.h"
13 using base::DoubleToString
;
14 using base::IntToString
;
20 std::string
IntVectorToString(const std::vector
<int>& items
) {
22 for (size_t i
= 0; i
< items
.size(); ++i
) {
25 str
+= IntToString(items
[i
]);
30 } // Anonymous namespace
32 AXNodeData::AXNodeData()
34 role(AX_ROLE_UNKNOWN
),
38 AXNodeData::~AXNodeData() {
41 void AXNodeData::AddStringAttribute(
42 AXStringAttribute attribute
, const std::string
& value
) {
43 string_attributes
.push_back(std::make_pair(attribute
, value
));
46 void AXNodeData::AddIntAttribute(
47 AXIntAttribute attribute
, int value
) {
48 int_attributes
.push_back(std::make_pair(attribute
, value
));
51 void AXNodeData::AddFloatAttribute(
52 AXFloatAttribute attribute
, float value
) {
53 float_attributes
.push_back(std::make_pair(attribute
, value
));
56 void AXNodeData::AddBoolAttribute(
57 AXBoolAttribute attribute
, bool value
) {
58 bool_attributes
.push_back(std::make_pair(attribute
, value
));
61 void AXNodeData::AddIntListAttribute(
62 AXIntListAttribute attribute
, const std::vector
<int32
>& value
) {
63 intlist_attributes
.push_back(std::make_pair(attribute
, value
));
66 void AXNodeData::SetName(std::string name
) {
67 string_attributes
.push_back(std::make_pair(AX_ATTR_NAME
, name
));
70 void AXNodeData::SetValue(std::string value
) {
71 string_attributes
.push_back(std::make_pair(AX_ATTR_VALUE
, value
));
74 std::string
AXNodeData::ToString() const {
77 result
+= "id=" + IntToString(id
);
78 result
+= " " + ui::ToString(role
);
80 if (state
& (1 << ui::AX_STATE_BUSY
))
82 if (state
& (1 << ui::AX_STATE_CHECKED
))
84 if (state
& (1 << ui::AX_STATE_COLLAPSED
))
85 result
+= " COLLAPSED";
86 if (state
& (1 << ui::AX_STATE_EXPANDED
))
87 result
+= " EXPANDED";
88 if (state
& (1 << ui::AX_STATE_FOCUSABLE
))
89 result
+= " FOCUSABLE";
90 if (state
& (1 << ui::AX_STATE_FOCUSED
))
92 if (state
& (1 << ui::AX_STATE_HASPOPUP
))
93 result
+= " HASPOPUP";
94 if (state
& (1 << ui::AX_STATE_HOVERED
))
96 if (state
& (1 << ui::AX_STATE_INDETERMINATE
))
97 result
+= " INDETERMINATE";
98 if (state
& (1 << ui::AX_STATE_INVISIBLE
))
99 result
+= " INVISIBLE";
100 if (state
& (1 << ui::AX_STATE_LINKED
))
102 if (state
& (1 << ui::AX_STATE_MULTISELECTABLE
))
103 result
+= " MULTISELECTABLE";
104 if (state
& (1 << ui::AX_STATE_OFFSCREEN
))
105 result
+= " OFFSCREEN";
106 if (state
& (1 << ui::AX_STATE_PRESSED
))
107 result
+= " PRESSED";
108 if (state
& (1 << ui::AX_STATE_PROTECTED
))
109 result
+= " PROTECTED";
110 if (state
& (1 << ui::AX_STATE_READ_ONLY
))
111 result
+= " READONLY";
112 if (state
& (1 << ui::AX_STATE_REQUIRED
))
113 result
+= " REQUIRED";
114 if (state
& (1 << ui::AX_STATE_SELECTABLE
))
115 result
+= " SELECTABLE";
116 if (state
& (1 << ui::AX_STATE_SELECTED
))
117 result
+= " SELECTED";
118 if (state
& (1 << ui::AX_STATE_VERTICAL
))
119 result
+= " VERTICAL";
120 if (state
& (1 << ui::AX_STATE_VISITED
))
121 result
+= " VISITED";
123 result
+= " (" + IntToString(location
.x()) + ", " +
124 IntToString(location
.y()) + ")-(" +
125 IntToString(location
.width()) + ", " +
126 IntToString(location
.height()) + ")";
128 for (size_t i
= 0; i
< int_attributes
.size(); ++i
) {
129 std::string value
= IntToString(int_attributes
[i
].second
);
130 switch (int_attributes
[i
].first
) {
131 case AX_ATTR_SCROLL_X
:
132 result
+= " scroll_x=" + value
;
134 case AX_ATTR_SCROLL_X_MIN
:
135 result
+= " scroll_x_min=" + value
;
137 case AX_ATTR_SCROLL_X_MAX
:
138 result
+= " scroll_x_max=" + value
;
140 case AX_ATTR_SCROLL_Y
:
141 result
+= " scroll_y=" + value
;
143 case AX_ATTR_SCROLL_Y_MIN
:
144 result
+= " scroll_y_min=" + value
;
146 case AX_ATTR_SCROLL_Y_MAX
:
147 result
+= " scroll_y_max=" + value
;
149 case AX_ATTR_HIERARCHICAL_LEVEL
:
150 result
+= " level=" + value
;
152 case AX_ATTR_TEXT_SEL_START
:
153 result
+= " sel_start=" + value
;
155 case AX_ATTR_TEXT_SEL_END
:
156 result
+= " sel_end=" + value
;
158 case AX_ATTR_TABLE_ROW_COUNT
:
159 result
+= " rows=" + value
;
161 case AX_ATTR_TABLE_COLUMN_COUNT
:
162 result
+= " cols=" + value
;
164 case AX_ATTR_TABLE_CELL_COLUMN_INDEX
:
165 result
+= " col=" + value
;
167 case AX_ATTR_TABLE_CELL_ROW_INDEX
:
168 result
+= " row=" + value
;
170 case AX_ATTR_TABLE_CELL_COLUMN_SPAN
:
171 result
+= " colspan=" + value
;
173 case AX_ATTR_TABLE_CELL_ROW_SPAN
:
174 result
+= " rowspan=" + value
;
176 case AX_ATTR_TABLE_COLUMN_HEADER_ID
:
177 result
+= " column_header_id=" + value
;
179 case AX_ATTR_TABLE_COLUMN_INDEX
:
180 result
+= " column_index=" + value
;
182 case AX_ATTR_TABLE_HEADER_ID
:
183 result
+= " header_id=" + value
;
185 case AX_ATTR_TABLE_ROW_HEADER_ID
:
186 result
+= " row_header_id=" + value
;
188 case AX_ATTR_TABLE_ROW_INDEX
:
189 result
+= " row_index=" + value
;
191 case AX_ATTR_TITLE_UI_ELEMENT
:
192 result
+= " title_elem=" + value
;
194 case AX_ATTR_ACTIVEDESCENDANT_ID
:
195 result
+= " activedescendant=" + value
;
197 case AX_ATTR_COLOR_VALUE_RED
:
198 result
+= " color_value_red=" + value
;
200 case AX_ATTR_COLOR_VALUE_GREEN
:
201 result
+= " color_value_green=" + value
;
203 case AX_ATTR_COLOR_VALUE_BLUE
:
204 result
+= " color_value_blue=" + value
;
206 case AX_ATTR_TEXT_DIRECTION
:
207 switch (int_attributes
[i
].second
) {
208 case AX_TEXT_DIRECTION_LR
:
210 result
+= " text_direction=lr";
212 case AX_TEXT_DIRECTION_RL
:
213 result
+= " text_direction=rl";
215 case AX_TEXT_DIRECTION_TB
:
216 result
+= " text_direction=tb";
218 case AX_TEXT_DIRECTION_BT
:
219 result
+= " text_direction=bt";
223 case AX_INT_ATTRIBUTE_NONE
:
228 for (size_t i
= 0; i
< string_attributes
.size(); ++i
) {
229 std::string value
= string_attributes
[i
].second
;
230 switch (string_attributes
[i
].first
) {
231 case AX_ATTR_DOC_URL
:
232 result
+= " doc_url=" + value
;
234 case AX_ATTR_DOC_TITLE
:
235 result
+= " doc_title=" + value
;
237 case AX_ATTR_DOC_MIMETYPE
:
238 result
+= " doc_mimetype=" + value
;
240 case AX_ATTR_DOC_DOCTYPE
:
241 result
+= " doc_doctype=" + value
;
243 case AX_ATTR_ACCESS_KEY
:
244 result
+= " access_key=" + value
;
247 result
+= " action=" + value
;
249 case AX_ATTR_DESCRIPTION
:
250 result
+= " description=" + value
;
252 case AX_ATTR_DISPLAY
:
253 result
+= " display=" + value
;
256 result
+= " help=" + value
;
258 case AX_ATTR_HTML_TAG
:
259 result
+= " html_tag=" + value
;
261 case AX_ATTR_LIVE_RELEVANT
:
262 result
+= " relevant=" + value
;
264 case AX_ATTR_LIVE_STATUS
:
265 result
+= " live=" + value
;
267 case AX_ATTR_CONTAINER_LIVE_RELEVANT
:
268 result
+= " container_relevant=" + value
;
270 case AX_ATTR_CONTAINER_LIVE_STATUS
:
271 result
+= " container_live=" + value
;
274 result
+= " role=" + value
;
276 case AX_ATTR_SHORTCUT
:
277 result
+= " shortcut=" + value
;
280 result
+= " url=" + value
;
283 result
+= " name=" + value
;
286 result
+= " value=" + value
;
288 case AX_STRING_ATTRIBUTE_NONE
:
293 for (size_t i
= 0; i
< float_attributes
.size(); ++i
) {
294 std::string value
= DoubleToString(float_attributes
[i
].second
);
295 switch (float_attributes
[i
].first
) {
296 case AX_ATTR_DOC_LOADING_PROGRESS
:
297 result
+= " doc_progress=" + value
;
299 case AX_ATTR_VALUE_FOR_RANGE
:
300 result
+= " value_for_range=" + value
;
302 case AX_ATTR_MAX_VALUE_FOR_RANGE
:
303 result
+= " max_value=" + value
;
305 case AX_ATTR_MIN_VALUE_FOR_RANGE
:
306 result
+= " min_value=" + value
;
308 case AX_FLOAT_ATTRIBUTE_NONE
:
313 for (size_t i
= 0; i
< bool_attributes
.size(); ++i
) {
314 std::string value
= bool_attributes
[i
].second
? "true" : "false";
315 switch (bool_attributes
[i
].first
) {
316 case AX_ATTR_DOC_LOADED
:
317 result
+= " doc_loaded=" + value
;
319 case AX_ATTR_BUTTON_MIXED
:
320 result
+= " mixed=" + value
;
322 case AX_ATTR_LIVE_ATOMIC
:
323 result
+= " atomic=" + value
;
325 case AX_ATTR_LIVE_BUSY
:
326 result
+= " busy=" + value
;
328 case AX_ATTR_CONTAINER_LIVE_ATOMIC
:
329 result
+= " container_atomic=" + value
;
331 case AX_ATTR_CONTAINER_LIVE_BUSY
:
332 result
+= " container_busy=" + value
;
334 case AX_ATTR_ARIA_READONLY
:
335 result
+= " aria_readonly=" + value
;
337 case AX_ATTR_CAN_SET_VALUE
:
338 result
+= " can_set_value=" + value
;
340 case AX_ATTR_UPDATE_LOCATION_ONLY
:
341 result
+= " update_location_only=" + value
;
343 case AX_ATTR_CANVAS_HAS_FALLBACK
:
344 result
+= " has_fallback=" + value
;
346 case AX_BOOL_ATTRIBUTE_NONE
:
351 for (size_t i
= 0; i
< intlist_attributes
.size(); ++i
) {
352 const std::vector
<int32
>& values
= intlist_attributes
[i
].second
;
353 switch (intlist_attributes
[i
].first
) {
354 case AX_ATTR_INDIRECT_CHILD_IDS
:
355 result
+= " indirect_child_ids=" + IntVectorToString(values
);
357 case AX_ATTR_CONTROLS_IDS
:
358 result
+= " controls_ids=" + IntVectorToString(values
);
360 case AX_ATTR_DESCRIBEDBY_IDS
:
361 result
+= " describedby_ids=" + IntVectorToString(values
);
363 case AX_ATTR_FLOWTO_IDS
:
364 result
+= " flowto_ids=" + IntVectorToString(values
);
366 case AX_ATTR_LABELLEDBY_IDS
:
367 result
+= " labelledby_ids=" + IntVectorToString(values
);
369 case AX_ATTR_OWNS_IDS
:
370 result
+= " owns_ids=" + IntVectorToString(values
);
372 case AX_ATTR_LINE_BREAKS
:
373 result
+= " line_breaks=" + IntVectorToString(values
);
375 case AX_ATTR_CELL_IDS
:
376 result
+= " cell_ids=" + IntVectorToString(values
);
378 case AX_ATTR_UNIQUE_CELL_IDS
:
379 result
+= " unique_cell_ids=" + IntVectorToString(values
);
381 case AX_ATTR_CHARACTER_OFFSETS
:
382 result
+= " character_offsets=" + IntVectorToString(values
);
384 case AX_ATTR_WORD_STARTS
:
385 result
+= " word_starts=" + IntVectorToString(values
);
387 case AX_ATTR_WORD_ENDS
:
388 result
+= " word_ends=" + IntVectorToString(values
);
390 case AX_INT_LIST_ATTRIBUTE_NONE
:
395 if (!child_ids
.empty())
396 result
+= " child_ids=" + IntVectorToString(child_ids
);