Cleanup: Pass std::string as const reference from chromeos/
[chromium-blink-merge.git] / ui / accessibility / ax_node_data.cc
blob262e19253f376cc30f2350e1e0d727974901c69a
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"
7 #include <set>
9 #include "base/strings/string_number_conversions.h"
10 #include "base/strings/string_util.h"
11 #include "base/strings/stringprintf.h"
12 #include "base/strings/utf_string_conversions.h"
14 using base::DoubleToString;
15 using base::IntToString;
17 namespace ui {
19 namespace {
21 std::string IntVectorToString(const std::vector<int>& items) {
22 std::string str;
23 for (size_t i = 0; i < items.size(); ++i) {
24 if (i > 0)
25 str += ",";
26 str += IntToString(items[i]);
28 return str;
31 // Predicate that returns true if the first value of a pair is |first|.
32 template<typename FirstType, typename SecondType>
33 struct FirstIs {
34 FirstIs(FirstType first)
35 : first_(first) {}
36 bool operator()(std::pair<FirstType, SecondType> const& p) {
37 return p.first == first_;
39 FirstType first_;
42 // Helper function that finds a key in a vector of pairs by matching on the
43 // first value, and returns an iterator.
44 template<typename FirstType, typename SecondType>
45 typename std::vector<std::pair<FirstType, SecondType>>::const_iterator
46 FindInVectorOfPairs(
47 FirstType first,
48 const std::vector<std::pair<FirstType, SecondType>>& vector) {
49 return std::find_if(vector.begin(),
50 vector.end(),
51 FirstIs<FirstType, SecondType>(first));
54 } // namespace
56 AXNodeData::AXNodeData()
57 : id(-1),
58 role(AX_ROLE_UNKNOWN),
59 state(0xFFFFFFFF) {
62 AXNodeData::~AXNodeData() {
65 bool AXNodeData::HasBoolAttribute(AXBoolAttribute attribute) const {
66 auto iter = FindInVectorOfPairs(attribute, bool_attributes);
67 return iter != bool_attributes.end();
70 bool AXNodeData::GetBoolAttribute(AXBoolAttribute attribute) const {
71 bool result;
72 if (GetBoolAttribute(attribute, &result))
73 return result;
74 return false;
77 bool AXNodeData::GetBoolAttribute(
78 AXBoolAttribute attribute, bool* value) const {
79 auto iter = FindInVectorOfPairs(attribute, bool_attributes);
80 if (iter != bool_attributes.end()) {
81 *value = iter->second;
82 return true;
85 return false;
88 bool AXNodeData::HasFloatAttribute(AXFloatAttribute attribute) const {
89 auto iter = FindInVectorOfPairs(attribute, float_attributes);
90 return iter != float_attributes.end();
93 float AXNodeData::GetFloatAttribute(AXFloatAttribute attribute) const {
94 float result;
95 if (GetFloatAttribute(attribute, &result))
96 return result;
97 return 0.0;
100 bool AXNodeData::GetFloatAttribute(
101 AXFloatAttribute attribute, float* value) const {
102 auto iter = FindInVectorOfPairs(attribute, float_attributes);
103 if (iter != float_attributes.end()) {
104 *value = iter->second;
105 return true;
108 return false;
111 bool AXNodeData::HasIntAttribute(AXIntAttribute attribute) const {
112 auto iter = FindInVectorOfPairs(attribute, int_attributes);
113 return iter != int_attributes.end();
116 int AXNodeData::GetIntAttribute(AXIntAttribute attribute) const {
117 int result;
118 if (GetIntAttribute(attribute, &result))
119 return result;
120 return 0;
123 bool AXNodeData::GetIntAttribute(
124 AXIntAttribute attribute, int* value) const {
125 auto iter = FindInVectorOfPairs(attribute, int_attributes);
126 if (iter != int_attributes.end()) {
127 *value = iter->second;
128 return true;
131 return false;
134 bool AXNodeData::HasStringAttribute(AXStringAttribute attribute) const {
135 auto iter = FindInVectorOfPairs(attribute, string_attributes);
136 return iter != string_attributes.end();
139 const std::string& AXNodeData::GetStringAttribute(
140 AXStringAttribute attribute) const {
141 CR_DEFINE_STATIC_LOCAL(std::string, empty_string, ());
142 auto iter = FindInVectorOfPairs(attribute, string_attributes);
143 return iter != string_attributes.end() ? iter->second : empty_string;
146 bool AXNodeData::GetStringAttribute(
147 AXStringAttribute attribute, std::string* value) const {
148 auto iter = FindInVectorOfPairs(attribute, string_attributes);
149 if (iter != string_attributes.end()) {
150 *value = iter->second;
151 return true;
154 return false;
157 base::string16 AXNodeData::GetString16Attribute(
158 AXStringAttribute attribute) const {
159 std::string value_utf8;
160 if (!GetStringAttribute(attribute, &value_utf8))
161 return base::string16();
162 return base::UTF8ToUTF16(value_utf8);
165 bool AXNodeData::GetString16Attribute(
166 AXStringAttribute attribute,
167 base::string16* value) const {
168 std::string value_utf8;
169 if (!GetStringAttribute(attribute, &value_utf8))
170 return false;
171 *value = base::UTF8ToUTF16(value_utf8);
172 return true;
175 bool AXNodeData::HasIntListAttribute(AXIntListAttribute attribute) const {
176 auto iter = FindInVectorOfPairs(attribute, intlist_attributes);
177 return iter != intlist_attributes.end();
180 const std::vector<int32>& AXNodeData::GetIntListAttribute(
181 AXIntListAttribute attribute) const {
182 CR_DEFINE_STATIC_LOCAL(std::vector<int32>, empty_vector, ());
183 auto iter = FindInVectorOfPairs(attribute, intlist_attributes);
184 if (iter != intlist_attributes.end())
185 return iter->second;
186 return empty_vector;
189 bool AXNodeData::GetIntListAttribute(
190 AXIntListAttribute attribute, std::vector<int32>* value) const {
191 auto iter = FindInVectorOfPairs(attribute, intlist_attributes);
192 if (iter != intlist_attributes.end()) {
193 *value = iter->second;
194 return true;
197 return false;
200 bool AXNodeData::GetHtmlAttribute(
201 const char* html_attr, std::string* value) const {
202 for (size_t i = 0; i < html_attributes.size(); ++i) {
203 const std::string& attr = html_attributes[i].first;
204 if (base::LowerCaseEqualsASCII(attr, html_attr)) {
205 *value = html_attributes[i].second;
206 return true;
210 return false;
213 bool AXNodeData::GetHtmlAttribute(
214 const char* html_attr, base::string16* value) const {
215 std::string value_utf8;
216 if (!GetHtmlAttribute(html_attr, &value_utf8))
217 return false;
218 *value = base::UTF8ToUTF16(value_utf8);
219 return true;
222 void AXNodeData::AddStringAttribute(
223 AXStringAttribute attribute, const std::string& value) {
224 string_attributes.push_back(std::make_pair(attribute, value));
227 void AXNodeData::AddIntAttribute(
228 AXIntAttribute attribute, int value) {
229 int_attributes.push_back(std::make_pair(attribute, value));
232 void AXNodeData::AddFloatAttribute(
233 AXFloatAttribute attribute, float value) {
234 float_attributes.push_back(std::make_pair(attribute, value));
237 void AXNodeData::AddBoolAttribute(
238 AXBoolAttribute attribute, bool value) {
239 bool_attributes.push_back(std::make_pair(attribute, value));
242 void AXNodeData::AddIntListAttribute(
243 AXIntListAttribute attribute, const std::vector<int32>& value) {
244 intlist_attributes.push_back(std::make_pair(attribute, value));
247 void AXNodeData::SetName(std::string name) {
248 string_attributes.push_back(std::make_pair(AX_ATTR_NAME, name));
251 void AXNodeData::SetValue(std::string value) {
252 string_attributes.push_back(std::make_pair(AX_ATTR_VALUE, value));
255 std::string AXNodeData::ToString() const {
256 std::string result;
258 result += "id=" + IntToString(id);
259 result += " " + ui::ToString(role);
261 if (state & (1 << AX_STATE_BUSY))
262 result += " BUSY";
263 if (state & (1 << AX_STATE_CHECKED))
264 result += " CHECKED";
265 if (state & (1 << AX_STATE_COLLAPSED))
266 result += " COLLAPSED";
267 if (state & (1 << AX_STATE_EDITABLE))
268 result += " EDITABLE";
269 if (state & (1 << AX_STATE_EXPANDED))
270 result += " EXPANDED";
271 if (state & (1 << AX_STATE_FOCUSABLE))
272 result += " FOCUSABLE";
273 if (state & (1 << AX_STATE_FOCUSED))
274 result += " FOCUSED";
275 if (state & (1 << AX_STATE_HASPOPUP))
276 result += " HASPOPUP";
277 if (state & (1 << AX_STATE_HOVERED))
278 result += " HOVERED";
279 if (state & (1 << AX_STATE_INDETERMINATE))
280 result += " INDETERMINATE";
281 if (state & (1 << AX_STATE_INVISIBLE))
282 result += " INVISIBLE";
283 if (state & (1 << AX_STATE_LINKED))
284 result += " LINKED";
285 if (state & (1 << AX_STATE_MULTISELECTABLE))
286 result += " MULTISELECTABLE";
287 if (state & (1 << AX_STATE_OFFSCREEN))
288 result += " OFFSCREEN";
289 if (state & (1 << AX_STATE_PRESSED))
290 result += " PRESSED";
291 if (state & (1 << AX_STATE_PROTECTED))
292 result += " PROTECTED";
293 if (state & (1 << AX_STATE_READ_ONLY))
294 result += " READONLY";
295 if (state & (1 << AX_STATE_REQUIRED))
296 result += " REQUIRED";
297 if (state & (1 << AX_STATE_RICHLY_EDITABLE))
298 result += " RICHLY_EDITABLE";
299 if (state & (1 << AX_STATE_SELECTABLE))
300 result += " SELECTABLE";
301 if (state & (1 << AX_STATE_SELECTED))
302 result += " SELECTED";
303 if (state & (1 << AX_STATE_VERTICAL))
304 result += " VERTICAL";
305 if (state & (1 << AX_STATE_VISITED))
306 result += " VISITED";
308 result += " (" + IntToString(location.x()) + ", " +
309 IntToString(location.y()) + ")-(" +
310 IntToString(location.width()) + ", " +
311 IntToString(location.height()) + ")";
313 for (size_t i = 0; i < int_attributes.size(); ++i) {
314 std::string value = IntToString(int_attributes[i].second);
315 switch (int_attributes[i].first) {
316 case AX_ATTR_SCROLL_X:
317 result += " scroll_x=" + value;
318 break;
319 case AX_ATTR_SCROLL_X_MIN:
320 result += " scroll_x_min=" + value;
321 break;
322 case AX_ATTR_SCROLL_X_MAX:
323 result += " scroll_x_max=" + value;
324 break;
325 case AX_ATTR_SCROLL_Y:
326 result += " scroll_y=" + value;
327 break;
328 case AX_ATTR_SCROLL_Y_MIN:
329 result += " scroll_y_min=" + value;
330 break;
331 case AX_ATTR_SCROLL_Y_MAX:
332 result += " scroll_y_max=" + value;
333 break;
334 case AX_ATTR_HIERARCHICAL_LEVEL:
335 result += " level=" + value;
336 break;
337 case AX_ATTR_ANCHOR_OBJECT_ID:
338 result += " anchor_object_id=" + value;
339 break;
340 case AX_ATTR_ANCHOR_OFFSET:
341 result += " anchor_offset=" + value;
342 break;
343 case AX_ATTR_FOCUS_OBJECT_ID:
344 result += " focus_object_id=" + value;
345 break;
346 case AX_ATTR_FOCUS_OFFSET:
347 result += " focus_offset=" + value;
348 break;
349 case AX_ATTR_TEXT_SEL_START:
350 result += " sel_start=" + value;
351 break;
352 case AX_ATTR_TEXT_SEL_END:
353 result += " sel_end=" + value;
354 break;
355 case AX_ATTR_TABLE_ROW_COUNT:
356 result += " rows=" + value;
357 break;
358 case AX_ATTR_TABLE_COLUMN_COUNT:
359 result += " cols=" + value;
360 break;
361 case AX_ATTR_TABLE_CELL_COLUMN_INDEX:
362 result += " col=" + value;
363 break;
364 case AX_ATTR_TABLE_CELL_ROW_INDEX:
365 result += " row=" + value;
366 break;
367 case AX_ATTR_TABLE_CELL_COLUMN_SPAN:
368 result += " colspan=" + value;
369 break;
370 case AX_ATTR_TABLE_CELL_ROW_SPAN:
371 result += " rowspan=" + value;
372 break;
373 case AX_ATTR_TABLE_COLUMN_HEADER_ID:
374 result += " column_header_id=" + value;
375 break;
376 case AX_ATTR_TABLE_COLUMN_INDEX:
377 result += " column_index=" + value;
378 break;
379 case AX_ATTR_TABLE_HEADER_ID:
380 result += " header_id=" + value;
381 break;
382 case AX_ATTR_TABLE_ROW_HEADER_ID:
383 result += " row_header_id=" + value;
384 break;
385 case AX_ATTR_TABLE_ROW_INDEX:
386 result += " row_index=" + value;
387 break;
388 case AX_ATTR_SORT_DIRECTION:
389 switch (int_attributes[i].second) {
390 case AX_SORT_DIRECTION_UNSORTED:
391 result += " sort_direction=none";
392 break;
393 case AX_SORT_DIRECTION_ASCENDING:
394 result += " sort_direction=ascending";
395 break;
396 case AX_SORT_DIRECTION_DESCENDING:
397 result += " sort_direction=descending";
398 break;
399 case AX_SORT_DIRECTION_OTHER:
400 result += " sort_direction=other";
401 break;
403 break;
404 case AX_ATTR_TITLE_UI_ELEMENT:
405 result += " title_elem=" + value;
406 break;
407 case AX_ATTR_ACTIVEDESCENDANT_ID:
408 result += " activedescendant=" + value;
409 break;
410 case AX_ATTR_TREE_ID:
411 result += " tree_id=" + value;
412 break;
413 case AX_ATTR_CHILD_TREE_ID:
414 result += " child_tree_id=" + value;
415 break;
416 case AX_ATTR_PARENT_TREE_ID:
417 result += " parent_tree_id=" + value;
418 break;
419 case AX_ATTR_COLOR_VALUE:
420 result += base::StringPrintf(" color_value=&%X",
421 int_attributes[i].second);
422 break;
423 case AX_ATTR_BACKGROUND_COLOR:
424 result += base::StringPrintf(" background_color=&%X",
425 int_attributes[i].second);
426 break;
427 case AX_ATTR_COLOR:
428 result += base::StringPrintf(" color=&%X", int_attributes[i].second);
429 break;
430 case AX_ATTR_TEXT_DIRECTION:
431 switch (int_attributes[i].second) {
432 case AX_TEXT_DIRECTION_LTR:
433 result += " text_direction=ltr";
434 break;
435 case AX_TEXT_DIRECTION_RTL:
436 result += " text_direction=rtl";
437 break;
438 case AX_TEXT_DIRECTION_TTB:
439 result += " text_direction=ttb";
440 break;
441 case AX_TEXT_DIRECTION_BTT:
442 result += " text_direction=btt";
443 break;
445 case AX_ATTR_TEXT_STYLE: {
446 unsigned int text_style = int_attributes[i].second;
447 if (text_style == AX_TEXT_STYLE_NONE)
448 break;
449 std::string text_style_value(" text_style=");
450 if (text_style & AX_TEXT_STYLE_BOLD)
451 text_style_value += "bold,";
452 if (text_style & AX_TEXT_STYLE_ITALIC)
453 text_style_value += "italic,";
454 if (text_style & AX_TEXT_STYLE_UNDERLINE)
455 text_style_value += "underline,";
456 if (text_style & AX_TEXT_STYLE_LINE_THROUGH)
457 text_style_value += "line-through,";
458 result += text_style_value.substr(0, text_style_value.size() - 1);;
460 break;
461 case AX_ATTR_SET_SIZE:
462 result += " setsize=" + value;
463 break;
464 case AX_ATTR_POS_IN_SET:
465 result += " posinset=" + value;
466 break;
467 case AX_ATTR_INVALID_STATE:
468 switch (int_attributes[i].second) {
469 case AX_INVALID_STATE_FALSE:
470 result += " invalid_state=false";
471 break;
472 case AX_INVALID_STATE_TRUE:
473 result += " invalid_state=true";
474 break;
475 case AX_INVALID_STATE_SPELLING:
476 result += " invalid_state=spelling";
477 break;
478 case AX_INVALID_STATE_GRAMMAR:
479 result += " invalid_state=grammar";
480 break;
481 case AX_INVALID_STATE_OTHER:
482 result += " invalid_state=other";
483 break;
485 break;
486 case AX_INT_ATTRIBUTE_NONE:
487 break;
491 for (size_t i = 0; i < string_attributes.size(); ++i) {
492 std::string value = string_attributes[i].second;
493 switch (string_attributes[i].first) {
494 case AX_ATTR_DOC_URL:
495 result += " doc_url=" + value;
496 break;
497 case AX_ATTR_DOC_TITLE:
498 result += " doc_title=" + value;
499 break;
500 case AX_ATTR_DOC_MIMETYPE:
501 result += " doc_mimetype=" + value;
502 break;
503 case AX_ATTR_DOC_DOCTYPE:
504 result += " doc_doctype=" + value;
505 break;
506 case AX_ATTR_ACCESS_KEY:
507 result += " access_key=" + value;
508 break;
509 case AX_ATTR_ACTION:
510 result += " action=" + value;
511 break;
512 case AX_ATTR_AUTO_COMPLETE:
513 result += " autocomplete=" + value;
514 break;
515 case AX_ATTR_DESCRIPTION:
516 result += " description=" + value;
517 break;
518 case AX_ATTR_DISPLAY:
519 result += " display=" + value;
520 break;
521 case AX_ATTR_HELP:
522 result += " help=" + value;
523 break;
524 case AX_ATTR_HTML_TAG:
525 result += " html_tag=" + value;
526 break;
527 case AX_ATTR_ARIA_INVALID_VALUE:
528 result += " aria_invalid_value=" + value;
529 break;
530 case AX_ATTR_LIVE_RELEVANT:
531 result += " relevant=" + value;
532 break;
533 case AX_ATTR_LIVE_STATUS:
534 result += " live=" + value;
535 break;
536 case AX_ATTR_CONTAINER_LIVE_RELEVANT:
537 result += " container_relevant=" + value;
538 break;
539 case AX_ATTR_CONTAINER_LIVE_STATUS:
540 result += " container_live=" + value;
541 break;
542 case AX_ATTR_PLACEHOLDER:
543 result += "placeholder" + value;
544 break;
545 case AX_ATTR_ROLE:
546 result += " role=" + value;
547 break;
548 case AX_ATTR_SHORTCUT:
549 result += " shortcut=" + value;
550 break;
551 case AX_ATTR_URL:
552 result += " url=" + value;
553 break;
554 case AX_ATTR_NAME:
555 result += " name=" + value;
556 break;
557 case AX_ATTR_VALUE:
558 result += " value=" + value;
559 break;
560 case AX_STRING_ATTRIBUTE_NONE:
561 break;
565 for (size_t i = 0; i < float_attributes.size(); ++i) {
566 std::string value = DoubleToString(float_attributes[i].second);
567 switch (float_attributes[i].first) {
568 case AX_ATTR_DOC_LOADING_PROGRESS:
569 result += " doc_progress=" + value;
570 break;
571 case AX_ATTR_VALUE_FOR_RANGE:
572 result += " value_for_range=" + value;
573 break;
574 case AX_ATTR_MAX_VALUE_FOR_RANGE:
575 result += " max_value=" + value;
576 break;
577 case AX_ATTR_MIN_VALUE_FOR_RANGE:
578 result += " min_value=" + value;
579 break;
580 case AX_ATTR_FONT_SIZE:
581 result += " font_size=" + value;
582 break;
583 case AX_FLOAT_ATTRIBUTE_NONE:
584 break;
588 for (size_t i = 0; i < bool_attributes.size(); ++i) {
589 std::string value = bool_attributes[i].second ? "true" : "false";
590 switch (bool_attributes[i].first) {
591 case AX_ATTR_DOC_LOADED:
592 result += " doc_loaded=" + value;
593 break;
594 case AX_ATTR_BUTTON_MIXED:
595 result += " mixed=" + value;
596 break;
597 case AX_ATTR_LIVE_ATOMIC:
598 result += " atomic=" + value;
599 break;
600 case AX_ATTR_LIVE_BUSY:
601 result += " busy=" + value;
602 break;
603 case AX_ATTR_CONTAINER_LIVE_ATOMIC:
604 result += " container_atomic=" + value;
605 break;
606 case AX_ATTR_CONTAINER_LIVE_BUSY:
607 result += " container_busy=" + value;
608 break;
609 case AX_ATTR_ARIA_READONLY:
610 result += " aria_readonly=" + value;
611 break;
612 case AX_ATTR_CAN_SET_VALUE:
613 result += " can_set_value=" + value;
614 break;
615 case AX_ATTR_UPDATE_LOCATION_ONLY:
616 result += " update_location_only=" + value;
617 break;
618 case AX_ATTR_CANVAS_HAS_FALLBACK:
619 result += " has_fallback=" + value;
620 break;
621 case AX_BOOL_ATTRIBUTE_NONE:
622 break;
626 for (size_t i = 0; i < intlist_attributes.size(); ++i) {
627 const std::vector<int32>& values = intlist_attributes[i].second;
628 switch (intlist_attributes[i].first) {
629 case AX_ATTR_INDIRECT_CHILD_IDS:
630 result += " indirect_child_ids=" + IntVectorToString(values);
631 break;
632 case AX_ATTR_CONTROLS_IDS:
633 result += " controls_ids=" + IntVectorToString(values);
634 break;
635 case AX_ATTR_DESCRIBEDBY_IDS:
636 result += " describedby_ids=" + IntVectorToString(values);
637 break;
638 case AX_ATTR_FLOWTO_IDS:
639 result += " flowto_ids=" + IntVectorToString(values);
640 break;
641 case AX_ATTR_LABELLEDBY_IDS:
642 result += " labelledby_ids=" + IntVectorToString(values);
643 break;
644 case AX_ATTR_OWNS_IDS:
645 result += " owns_ids=" + IntVectorToString(values);
646 break;
647 case AX_ATTR_LINE_BREAKS:
648 result += " line_breaks=" + IntVectorToString(values);
649 break;
650 case AX_ATTR_CELL_IDS:
651 result += " cell_ids=" + IntVectorToString(values);
652 break;
653 case AX_ATTR_UNIQUE_CELL_IDS:
654 result += " unique_cell_ids=" + IntVectorToString(values);
655 break;
656 case AX_ATTR_CHARACTER_OFFSETS:
657 result += " character_offsets=" + IntVectorToString(values);
658 break;
659 case AX_ATTR_WORD_STARTS:
660 result += " word_starts=" + IntVectorToString(values);
661 break;
662 case AX_ATTR_WORD_ENDS:
663 result += " word_ends=" + IntVectorToString(values);
664 break;
665 case AX_INT_LIST_ATTRIBUTE_NONE:
666 break;
670 if (!child_ids.empty())
671 result += " child_ids=" + IntVectorToString(child_ids);
673 return result;
676 bool AXNodeData::IsRoot() const {
677 return (role == AX_ROLE_ROOT_WEB_AREA ||
678 role == AX_ROLE_DESKTOP);
681 void AXNodeData::SetRoot() {
682 role = AX_ROLE_ROOT_WEB_AREA;
685 } // namespace ui