OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 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 #include "ui/accessibility/ax_node_data.h" | 5 #include "ui/accessibility/ax_node_data.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 | 8 |
9 #include <algorithm> | 9 #include <algorithm> |
10 #include <set> | 10 #include <set> |
11 | 11 |
12 #include "base/strings/string_number_conversions.h" | 12 #include "base/strings/string_number_conversions.h" |
13 #include "base/strings/string_util.h" | 13 #include "base/strings/string_util.h" |
14 #include "base/strings/stringprintf.h" | 14 #include "base/strings/stringprintf.h" |
15 #include "base/strings/utf_string_conversions.h" | 15 #include "base/strings/utf_string_conversions.h" |
16 #include "ui/accessibility/ax_text_utils.h" | 16 #include "ui/accessibility/ax_text_utils.h" |
17 #include "ui/gfx/transform.h" | 17 #include "ui/gfx/transform.h" |
18 | 18 |
19 using base::DoubleToString; | 19 using base::DoubleToString; |
20 using base::IntToString; | 20 using base::IntToString; |
21 | 21 |
22 namespace ui { | 22 namespace ui { |
23 | 23 |
24 namespace { | 24 namespace { |
25 | 25 |
26 bool IsFlagSet(uint32_t bitfield, uint32_t flag) { | 26 bool IsFlagSet(uint32_t bitfield, uint32_t flag) { |
27 return 0 != (bitfield & (1 << flag)); | 27 return 0 != (bitfield & (1 << flag)); |
28 } | 28 } |
29 | 29 |
| 30 uint32_t ModifyFlag(uint32_t bitfield, uint32_t flag, bool set) { |
| 31 return set ? (bitfield |= (1 << flag)) : (bitfield &= ~(1 << flag)); |
| 32 } |
| 33 |
30 std::string StateBitfieldToString(uint32_t state) { | 34 std::string StateBitfieldToString(uint32_t state) { |
31 std::string str; | 35 std::string str; |
32 for (uint32_t i = AX_STATE_NONE + 1; i <= AX_STATE_LAST; ++i) { | 36 for (uint32_t i = AX_STATE_NONE + 1; i <= AX_STATE_LAST; ++i) { |
33 if (IsFlagSet(state, i)) | 37 if (IsFlagSet(state, i)) |
34 str += " " + base::ToUpperASCII(ToString(static_cast<AXState>(i))); | 38 str += " " + base::ToUpperASCII(ToString(static_cast<AXState>(i))); |
35 } | 39 } |
36 return str; | 40 return str; |
37 } | 41 } |
38 | 42 |
| 43 std::string ActionsBitfieldToString(uint32_t actions) { |
| 44 std::string str; |
| 45 for (uint32_t i = AX_ACTION_NONE + 1; i <= AX_ACTION_LAST; ++i) { |
| 46 if (IsFlagSet(actions, i)) { |
| 47 str += ToString(static_cast<AXAction>(i)); |
| 48 actions = ModifyFlag(actions, i, false); |
| 49 str += actions ? "," : ""; |
| 50 } |
| 51 } |
| 52 return str; |
| 53 } |
| 54 |
39 std::string IntVectorToString(const std::vector<int>& items) { | 55 std::string IntVectorToString(const std::vector<int>& items) { |
40 std::string str; | 56 std::string str; |
41 for (size_t i = 0; i < items.size(); ++i) { | 57 for (size_t i = 0; i < items.size(); ++i) { |
42 if (i > 0) | 58 if (i > 0) |
43 str += ","; | 59 str += ","; |
44 str += IntToString(items[i]); | 60 str += IntToString(items[i]); |
45 } | 61 } |
46 return str; | 62 return str; |
47 } | 63 } |
48 | 64 |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
163 case AX_ATTR_WORD_STARTS: | 179 case AX_ATTR_WORD_STARTS: |
164 case AX_ATTR_WORD_ENDS: | 180 case AX_ATTR_WORD_ENDS: |
165 return false; | 181 return false; |
166 } | 182 } |
167 | 183 |
168 NOTREACHED(); | 184 NOTREACHED(); |
169 return false; | 185 return false; |
170 } | 186 } |
171 | 187 |
172 AXNodeData::AXNodeData() | 188 AXNodeData::AXNodeData() |
173 : id(-1), role(AX_ROLE_UNKNOWN), state(0), offset_container_id(-1) {} | 189 : id(-1), |
| 190 role(AX_ROLE_UNKNOWN), |
| 191 state(AX_STATE_NONE), |
| 192 actions(AX_ACTION_NONE), |
| 193 offset_container_id(-1) {} |
174 | 194 |
175 AXNodeData::~AXNodeData() { | 195 AXNodeData::~AXNodeData() { |
176 } | 196 } |
177 | 197 |
178 AXNodeData::AXNodeData(const AXNodeData& other) { | 198 AXNodeData::AXNodeData(const AXNodeData& other) { |
179 id = other.id; | 199 id = other.id; |
180 role = other.role; | 200 role = other.role; |
181 state = other.state; | 201 state = other.state; |
| 202 actions = other.actions; |
182 string_attributes = other.string_attributes; | 203 string_attributes = other.string_attributes; |
183 int_attributes = other.int_attributes; | 204 int_attributes = other.int_attributes; |
184 float_attributes = other.float_attributes; | 205 float_attributes = other.float_attributes; |
185 bool_attributes = other.bool_attributes; | 206 bool_attributes = other.bool_attributes; |
186 intlist_attributes = other.intlist_attributes; | 207 intlist_attributes = other.intlist_attributes; |
187 html_attributes = other.html_attributes; | 208 html_attributes = other.html_attributes; |
188 child_ids = other.child_ids; | 209 child_ids = other.child_ids; |
189 location = other.location; | 210 location = other.location; |
190 offset_container_id = other.offset_container_id; | 211 offset_container_id = other.offset_container_id; |
191 if (other.transform) | 212 if (other.transform) |
192 transform.reset(new gfx::Transform(*other.transform)); | 213 transform.reset(new gfx::Transform(*other.transform)); |
193 } | 214 } |
194 | 215 |
195 AXNodeData& AXNodeData::operator=(AXNodeData other) { | 216 AXNodeData& AXNodeData::operator=(AXNodeData other) { |
196 id = other.id; | 217 id = other.id; |
197 role = other.role; | 218 role = other.role; |
198 state = other.state; | 219 state = other.state; |
| 220 actions = other.actions; |
199 string_attributes = other.string_attributes; | 221 string_attributes = other.string_attributes; |
200 int_attributes = other.int_attributes; | 222 int_attributes = other.int_attributes; |
201 float_attributes = other.float_attributes; | 223 float_attributes = other.float_attributes; |
202 bool_attributes = other.bool_attributes; | 224 bool_attributes = other.bool_attributes; |
203 intlist_attributes = other.intlist_attributes; | 225 intlist_attributes = other.intlist_attributes; |
204 html_attributes = other.html_attributes; | 226 html_attributes = other.html_attributes; |
205 child_ids = other.child_ids; | 227 child_ids = other.child_ids; |
206 location = other.location; | 228 location = other.location; |
207 offset_container_id = other.offset_container_id; | 229 offset_container_id = other.offset_container_id; |
208 if (other.transform) | 230 if (other.transform) |
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
417 } | 439 } |
418 } | 440 } |
419 | 441 |
420 string_attributes.push_back(std::make_pair(AX_ATTR_VALUE, value)); | 442 string_attributes.push_back(std::make_pair(AX_ATTR_VALUE, value)); |
421 } | 443 } |
422 | 444 |
423 void AXNodeData::SetValue(const base::string16& value) { | 445 void AXNodeData::SetValue(const base::string16& value) { |
424 SetValue(base::UTF16ToUTF8(value)); | 446 SetValue(base::UTF16ToUTF8(value)); |
425 } | 447 } |
426 | 448 |
427 bool AXNodeData::HasState(AXState state_flag) const { | 449 bool AXNodeData::HasState(AXState state_enum) const { |
428 return IsFlagSet(state, state_flag); | 450 return IsFlagSet(state, state_enum); |
429 } | 451 } |
430 | 452 |
431 void AXNodeData::AddState(AXState state_flag) { | 453 bool AXNodeData::HasAction(AXAction action_enum) const { |
432 DCHECK_NE(state_flag, AX_STATE_NONE); | 454 return IsFlagSet(actions, action_enum); |
433 state |= (1 << state_flag); | 455 } |
| 456 |
| 457 void AXNodeData::AddState(AXState state_enum) { |
| 458 DCHECK_NE(state_enum, AX_STATE_NONE); |
| 459 state = ModifyFlag(state, state_enum, true); |
| 460 } |
| 461 |
| 462 void AXNodeData::AddAction(AXAction action_enum) { |
| 463 switch (action_enum) { |
| 464 case AX_ACTION_NONE: |
| 465 NOTREACHED(); |
| 466 break; |
| 467 |
| 468 // Note: all of the attributes are included here explicitly, rather than |
| 469 // using "default:", so that it's a compiler error to add a new action |
| 470 // without explicitly considering whether there are mutually exclusive |
| 471 // actions that can be performed on a UI control at the same time. |
| 472 case AX_ACTION_BLUR: |
| 473 case AX_ACTION_FOCUS: { |
| 474 AXAction excluded_action = |
| 475 (action_enum == AX_ACTION_BLUR) ? AX_ACTION_FOCUS : AX_ACTION_BLUR; |
| 476 DCHECK(HasAction(excluded_action)); |
| 477 } break; |
| 478 case AX_ACTION_DECREMENT: |
| 479 case AX_ACTION_DO_DEFAULT: |
| 480 case AX_ACTION_GET_IMAGE_DATA: |
| 481 case AX_ACTION_HIT_TEST: |
| 482 case AX_ACTION_INCREMENT: |
| 483 case AX_ACTION_REPLACE_SELECTED_TEXT: |
| 484 case AX_ACTION_SCROLL_TO_MAKE_VISIBLE: |
| 485 case AX_ACTION_SCROLL_TO_POINT: |
| 486 case AX_ACTION_SET_ACCESSIBILITY_FOCUS: |
| 487 case AX_ACTION_SET_SCROLL_OFFSET: |
| 488 case AX_ACTION_SET_SELECTION: |
| 489 case AX_ACTION_SET_SEQUENTIAL_FOCUS_NAVIGATION_STARTING_POINT: |
| 490 case AX_ACTION_SET_VALUE: |
| 491 case AX_ACTION_SHOW_CONTEXT_MENU: |
| 492 break; |
| 493 } |
| 494 |
| 495 actions = ModifyFlag(actions, action_enum, true); |
434 } | 496 } |
435 | 497 |
436 std::string AXNodeData::ToString() const { | 498 std::string AXNodeData::ToString() const { |
437 std::string result; | 499 std::string result; |
438 | 500 |
439 result += "id=" + IntToString(id); | 501 result += "id=" + IntToString(id); |
440 result += " " + ui::ToString(role); | 502 result += " " + ui::ToString(role); |
441 | 503 |
442 result += StateBitfieldToString(state); | 504 result += StateBitfieldToString(state); |
443 | 505 |
(...skipping 356 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
800 break; | 862 break; |
801 case AX_ATTR_CONTAINER_LIVE_ATOMIC: | 863 case AX_ATTR_CONTAINER_LIVE_ATOMIC: |
802 result += " container_atomic=" + value; | 864 result += " container_atomic=" + value; |
803 break; | 865 break; |
804 case AX_ATTR_CONTAINER_LIVE_BUSY: | 866 case AX_ATTR_CONTAINER_LIVE_BUSY: |
805 result += " container_busy=" + value; | 867 result += " container_busy=" + value; |
806 break; | 868 break; |
807 case AX_ATTR_ARIA_READONLY: | 869 case AX_ATTR_ARIA_READONLY: |
808 result += " aria_readonly=" + value; | 870 result += " aria_readonly=" + value; |
809 break; | 871 break; |
810 case AX_ATTR_CAN_SET_VALUE: | |
811 result += " can_set_value=" + value; | |
812 break; | |
813 case AX_ATTR_UPDATE_LOCATION_ONLY: | 872 case AX_ATTR_UPDATE_LOCATION_ONLY: |
814 result += " update_location_only=" + value; | 873 result += " update_location_only=" + value; |
815 break; | 874 break; |
816 case AX_ATTR_CANVAS_HAS_FALLBACK: | 875 case AX_ATTR_CANVAS_HAS_FALLBACK: |
817 result += " has_fallback=" + value; | 876 result += " has_fallback=" + value; |
818 break; | 877 break; |
819 case AX_ATTR_MODAL: | 878 case AX_ATTR_MODAL: |
820 result += " modal=" + value; | 879 result += " modal=" + value; |
821 break; | 880 break; |
822 case AX_BOOL_ATTRIBUTE_NONE: | 881 case AX_BOOL_ATTRIBUTE_NONE: |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
898 result += " word_starts=" + IntVectorToString(values); | 957 result += " word_starts=" + IntVectorToString(values); |
899 break; | 958 break; |
900 case AX_ATTR_WORD_ENDS: | 959 case AX_ATTR_WORD_ENDS: |
901 result += " word_ends=" + IntVectorToString(values); | 960 result += " word_ends=" + IntVectorToString(values); |
902 break; | 961 break; |
903 case AX_INT_LIST_ATTRIBUTE_NONE: | 962 case AX_INT_LIST_ATTRIBUTE_NONE: |
904 break; | 963 break; |
905 } | 964 } |
906 } | 965 } |
907 | 966 |
| 967 result += " actions=" + ActionsBitfieldToString(actions); |
| 968 |
908 if (!child_ids.empty()) | 969 if (!child_ids.empty()) |
909 result += " child_ids=" + IntVectorToString(child_ids); | 970 result += " child_ids=" + IntVectorToString(child_ids); |
910 | 971 |
911 return result; | 972 return result; |
912 } | 973 } |
913 | 974 |
914 } // namespace ui | 975 } // namespace ui |
OLD | NEW |