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_SORT_DIRECTION
:
192 switch (int_attributes
[i
].second
) {
193 case AX_SORT_DIRECTION_UNSORTED
:
194 result
+= " sort_direction=none";
196 case AX_SORT_DIRECTION_ASCENDING
:
197 result
+= " sort_direction=ascending";
199 case AX_SORT_DIRECTION_DESCENDING
:
200 result
+= " sort_direction=descending";
202 case AX_SORT_DIRECTION_OTHER
:
203 result
+= " sort_direction=other";
207 case AX_ATTR_TITLE_UI_ELEMENT
:
208 result
+= " title_elem=" + value
;
210 case AX_ATTR_ACTIVEDESCENDANT_ID
:
211 result
+= " activedescendant=" + value
;
213 case AX_ATTR_COLOR_VALUE_RED
:
214 result
+= " color_value_red=" + value
;
216 case AX_ATTR_COLOR_VALUE_GREEN
:
217 result
+= " color_value_green=" + value
;
219 case AX_ATTR_COLOR_VALUE_BLUE
:
220 result
+= " color_value_blue=" + value
;
222 case AX_ATTR_TREE_ID
:
223 result
+= " tree_id=" + value
;
225 case AX_ATTR_CHILD_TREE_ID
:
226 result
+= " child_tree_id=" + value
;
228 case AX_ATTR_TEXT_DIRECTION
:
229 switch (int_attributes
[i
].second
) {
230 case AX_TEXT_DIRECTION_LR
:
232 result
+= " text_direction=lr";
234 case AX_TEXT_DIRECTION_RL
:
235 result
+= " text_direction=rl";
237 case AX_TEXT_DIRECTION_TB
:
238 result
+= " text_direction=tb";
240 case AX_TEXT_DIRECTION_BT
:
241 result
+= " text_direction=bt";
245 case AX_ATTR_INVALID_STATE
:
246 switch (int_attributes
[i
].second
) {
247 case AX_INVALID_STATE_FALSE
:
248 result
+= " invalid_state=false";
250 case AX_INVALID_STATE_TRUE
:
251 result
+= " invalid_state=true";
253 case AX_INVALID_STATE_SPELLING
:
254 result
+= " invalid_state=spelling";
256 case AX_INVALID_STATE_GRAMMAR
:
257 result
+= " invalid_state=grammar";
259 case AX_INVALID_STATE_OTHER
:
260 result
+= " invalid_state=other";
264 case AX_INT_ATTRIBUTE_NONE
:
269 for (size_t i
= 0; i
< string_attributes
.size(); ++i
) {
270 std::string value
= string_attributes
[i
].second
;
271 switch (string_attributes
[i
].first
) {
272 case AX_ATTR_DOC_URL
:
273 result
+= " doc_url=" + value
;
275 case AX_ATTR_DOC_TITLE
:
276 result
+= " doc_title=" + value
;
278 case AX_ATTR_DOC_MIMETYPE
:
279 result
+= " doc_mimetype=" + value
;
281 case AX_ATTR_DOC_DOCTYPE
:
282 result
+= " doc_doctype=" + value
;
284 case AX_ATTR_ACCESS_KEY
:
285 result
+= " access_key=" + value
;
288 result
+= " action=" + value
;
290 case AX_ATTR_AUTO_COMPLETE
:
291 result
+= " autocomplete=" + value
;
293 case AX_ATTR_DESCRIPTION
:
294 result
+= " description=" + value
;
296 case AX_ATTR_DISPLAY
:
297 result
+= " display=" + value
;
299 case AX_ATTR_DROPEFFECT
:
300 result
+= " dropeffect=" + value
;
303 result
+= " help=" + value
;
305 case AX_ATTR_HTML_TAG
:
306 result
+= " html_tag=" + value
;
308 case AX_ATTR_ARIA_INVALID_VALUE
:
309 result
+= " aria_invalid_value=" + value
;
311 case AX_ATTR_LIVE_RELEVANT
:
312 result
+= " relevant=" + value
;
314 case AX_ATTR_LIVE_STATUS
:
315 result
+= " live=" + value
;
317 case AX_ATTR_CONTAINER_LIVE_RELEVANT
:
318 result
+= " container_relevant=" + value
;
320 case AX_ATTR_CONTAINER_LIVE_STATUS
:
321 result
+= " container_live=" + value
;
323 case AX_ATTR_PLACEHOLDER
:
324 result
+= "placeholder" + value
;
327 result
+= " role=" + value
;
329 case AX_ATTR_SHORTCUT
:
330 result
+= " shortcut=" + value
;
332 case AX_ATTR_TEXT_INPUT_TYPE
:
333 result
+= " text_input_type=" + value
;
336 result
+= " url=" + value
;
339 result
+= " name=" + value
;
342 result
+= " value=" + value
;
344 case AX_STRING_ATTRIBUTE_NONE
:
349 for (size_t i
= 0; i
< float_attributes
.size(); ++i
) {
350 std::string value
= DoubleToString(float_attributes
[i
].second
);
351 switch (float_attributes
[i
].first
) {
352 case AX_ATTR_DOC_LOADING_PROGRESS
:
353 result
+= " doc_progress=" + value
;
355 case AX_ATTR_VALUE_FOR_RANGE
:
356 result
+= " value_for_range=" + value
;
358 case AX_ATTR_MAX_VALUE_FOR_RANGE
:
359 result
+= " max_value=" + value
;
361 case AX_ATTR_MIN_VALUE_FOR_RANGE
:
362 result
+= " min_value=" + value
;
364 case AX_FLOAT_ATTRIBUTE_NONE
:
369 for (size_t i
= 0; i
< bool_attributes
.size(); ++i
) {
370 std::string value
= bool_attributes
[i
].second
? "true" : "false";
371 switch (bool_attributes
[i
].first
) {
372 case AX_ATTR_DOC_LOADED
:
373 result
+= " doc_loaded=" + value
;
375 case AX_ATTR_BUTTON_MIXED
:
376 result
+= " mixed=" + value
;
378 case AX_ATTR_LIVE_ATOMIC
:
379 result
+= " atomic=" + value
;
381 case AX_ATTR_LIVE_BUSY
:
382 result
+= " busy=" + value
;
384 case AX_ATTR_CONTAINER_LIVE_ATOMIC
:
385 result
+= " container_atomic=" + value
;
387 case AX_ATTR_CONTAINER_LIVE_BUSY
:
388 result
+= " container_busy=" + value
;
390 case AX_ATTR_ARIA_READONLY
:
391 result
+= " aria_readonly=" + value
;
393 case AX_ATTR_CAN_SET_VALUE
:
394 result
+= " can_set_value=" + value
;
396 case AX_ATTR_UPDATE_LOCATION_ONLY
:
397 result
+= " update_location_only=" + value
;
399 case AX_ATTR_CANVAS_HAS_FALLBACK
:
400 result
+= " has_fallback=" + value
;
402 case AX_ATTR_IS_AX_TREE_HOST
:
403 result
+= " is_ax_tree_host=" + value
;
405 case AX_ATTR_GRABBED
:
406 result
+= " grabbed=" + value
;
408 case AX_BOOL_ATTRIBUTE_NONE
:
413 for (size_t i
= 0; i
< intlist_attributes
.size(); ++i
) {
414 const std::vector
<int32
>& values
= intlist_attributes
[i
].second
;
415 switch (intlist_attributes
[i
].first
) {
416 case AX_ATTR_INDIRECT_CHILD_IDS
:
417 result
+= " indirect_child_ids=" + IntVectorToString(values
);
419 case AX_ATTR_CONTROLS_IDS
:
420 result
+= " controls_ids=" + IntVectorToString(values
);
422 case AX_ATTR_DESCRIBEDBY_IDS
:
423 result
+= " describedby_ids=" + IntVectorToString(values
);
425 case AX_ATTR_FLOWTO_IDS
:
426 result
+= " flowto_ids=" + IntVectorToString(values
);
428 case AX_ATTR_LABELLEDBY_IDS
:
429 result
+= " labelledby_ids=" + IntVectorToString(values
);
431 case AX_ATTR_OWNS_IDS
:
432 result
+= " owns_ids=" + IntVectorToString(values
);
434 case AX_ATTR_LINE_BREAKS
:
435 result
+= " line_breaks=" + IntVectorToString(values
);
437 case AX_ATTR_CELL_IDS
:
438 result
+= " cell_ids=" + IntVectorToString(values
);
440 case AX_ATTR_UNIQUE_CELL_IDS
:
441 result
+= " unique_cell_ids=" + IntVectorToString(values
);
443 case AX_ATTR_CHARACTER_OFFSETS
:
444 result
+= " character_offsets=" + IntVectorToString(values
);
446 case AX_ATTR_WORD_STARTS
:
447 result
+= " word_starts=" + IntVectorToString(values
);
449 case AX_ATTR_WORD_ENDS
:
450 result
+= " word_ends=" + IntVectorToString(values
);
452 case AX_INT_LIST_ATTRIBUTE_NONE
:
457 if (!child_ids
.empty())
458 result
+= " child_ids=" + IntVectorToString(child_ids
);