1 // Copyright (c) 2012 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.
4
5 #include "content/browser/accessibility/accessibility_tree_formatter_utils_win.h"
6
7 #include <oleacc.h>
8
9 #include <map>
10 #include <string>
11
12 #include "base/memory/singleton.h"
13 #include "base/strings/string_util.h"
14 #include "third_party/iaccessible2/ia2_api_all.h"
15
16 namespace content {
17 namespace {
18
19 class AccessibilityRoleStateMap {
20 public:
21 static AccessibilityRoleStateMap* GetInstance();
22
23 std::map<int32, base::string16> ia_role_string_map;
24 std::map<int32, base::string16> ia2_role_string_map;
25 std::map<int32, base::string16> ia_state_string_map;
26 std::map<int32, base::string16> ia2_state_string_map;
27
28 private:
29 AccessibilityRoleStateMap();
~AccessibilityRoleStateMap()30 virtual ~AccessibilityRoleStateMap() {}
31
32 friend struct DefaultSingletonTraits<AccessibilityRoleStateMap>;
33
34 DISALLOW_COPY_AND_ASSIGN(AccessibilityRoleStateMap);
35 };
36
37 // static
GetInstance()38 AccessibilityRoleStateMap* AccessibilityRoleStateMap::GetInstance() {
39 return Singleton<AccessibilityRoleStateMap,
40 LeakySingletonTraits<AccessibilityRoleStateMap> >::get();
41 }
42
AccessibilityRoleStateMap()43 AccessibilityRoleStateMap::AccessibilityRoleStateMap() {
44 // Convenience macros for generating readable strings.
45 #define IA_ROLE_MAP(x) ia_role_string_map[x] = L###x; \
46 ia2_role_string_map[x] = L###x;
47 #define IA2_ROLE_MAP(x) ia2_role_string_map[x] = L###x;
48 #define IA_STATE_MAP(x) ia_state_string_map[STATE_SYSTEM_##x] = L###x;
49 #define IA2_STATE_MAP(x) ia2_state_string_map[x] = L###x;
50
51 // MSAA / IAccessible roles. Each one of these is also a valid
52 // IAccessible2 role, the IA_ROLE_MAP macro adds it to both.
53 IA_ROLE_MAP(ROLE_SYSTEM_ALERT)
54 IA_ROLE_MAP(ROLE_SYSTEM_ANIMATION)
55 IA_ROLE_MAP(ROLE_SYSTEM_APPLICATION)
56 IA_ROLE_MAP(ROLE_SYSTEM_BORDER)
57 IA_ROLE_MAP(ROLE_SYSTEM_BUTTONDROPDOWN)
58 IA_ROLE_MAP(ROLE_SYSTEM_BUTTONDROPDOWNGRID)
59 IA_ROLE_MAP(ROLE_SYSTEM_BUTTONMENU)
60 IA_ROLE_MAP(ROLE_SYSTEM_CARET)
61 IA_ROLE_MAP(ROLE_SYSTEM_CELL)
62 IA_ROLE_MAP(ROLE_SYSTEM_CHARACTER)
63 IA_ROLE_MAP(ROLE_SYSTEM_CHART)
64 IA_ROLE_MAP(ROLE_SYSTEM_CHECKBUTTON)
65 IA_ROLE_MAP(ROLE_SYSTEM_CLIENT)
66 IA_ROLE_MAP(ROLE_SYSTEM_CLOCK)
67 IA_ROLE_MAP(ROLE_SYSTEM_COLUMN)
68 IA_ROLE_MAP(ROLE_SYSTEM_COLUMNHEADER)
69 IA_ROLE_MAP(ROLE_SYSTEM_COMBOBOX)
70 IA_ROLE_MAP(ROLE_SYSTEM_CURSOR)
71 IA_ROLE_MAP(ROLE_SYSTEM_DIAGRAM)
72 IA_ROLE_MAP(ROLE_SYSTEM_DIAL)
73 IA_ROLE_MAP(ROLE_SYSTEM_DIALOG)
74 IA_ROLE_MAP(ROLE_SYSTEM_DOCUMENT)
75 IA_ROLE_MAP(ROLE_SYSTEM_DROPLIST)
76 IA_ROLE_MAP(ROLE_SYSTEM_EQUATION)
77 IA_ROLE_MAP(ROLE_SYSTEM_GRAPHIC)
78 IA_ROLE_MAP(ROLE_SYSTEM_GRIP)
79 IA_ROLE_MAP(ROLE_SYSTEM_GROUPING)
80 IA_ROLE_MAP(ROLE_SYSTEM_HELPBALLOON)
81 IA_ROLE_MAP(ROLE_SYSTEM_HOTKEYFIELD)
82 IA_ROLE_MAP(ROLE_SYSTEM_INDICATOR)
83 IA_ROLE_MAP(ROLE_SYSTEM_IPADDRESS)
84 IA_ROLE_MAP(ROLE_SYSTEM_LINK)
85 IA_ROLE_MAP(ROLE_SYSTEM_LIST)
86 IA_ROLE_MAP(ROLE_SYSTEM_LISTITEM)
87 IA_ROLE_MAP(ROLE_SYSTEM_MENUBAR)
88 IA_ROLE_MAP(ROLE_SYSTEM_MENUITEM)
89 IA_ROLE_MAP(ROLE_SYSTEM_MENUPOPUP)
90 IA_ROLE_MAP(ROLE_SYSTEM_OUTLINE)
91 IA_ROLE_MAP(ROLE_SYSTEM_OUTLINEBUTTON)
92 IA_ROLE_MAP(ROLE_SYSTEM_OUTLINEITEM)
93 IA_ROLE_MAP(ROLE_SYSTEM_PAGETAB)
94 IA_ROLE_MAP(ROLE_SYSTEM_PAGETABLIST)
95 IA_ROLE_MAP(ROLE_SYSTEM_PANE)
96 IA_ROLE_MAP(ROLE_SYSTEM_PROGRESSBAR)
97 IA_ROLE_MAP(ROLE_SYSTEM_PROPERTYPAGE)
98 IA_ROLE_MAP(ROLE_SYSTEM_PUSHBUTTON)
99 IA_ROLE_MAP(ROLE_SYSTEM_RADIOBUTTON)
100 IA_ROLE_MAP(ROLE_SYSTEM_ROW)
101 IA_ROLE_MAP(ROLE_SYSTEM_ROWHEADER)
102 IA_ROLE_MAP(ROLE_SYSTEM_SCROLLBAR)
103 IA_ROLE_MAP(ROLE_SYSTEM_SEPARATOR)
104 IA_ROLE_MAP(ROLE_SYSTEM_SLIDER)
105 IA_ROLE_MAP(ROLE_SYSTEM_SOUND)
106 IA_ROLE_MAP(ROLE_SYSTEM_SPINBUTTON)
107 IA_ROLE_MAP(ROLE_SYSTEM_SPLITBUTTON)
108 IA_ROLE_MAP(ROLE_SYSTEM_STATICTEXT)
109 IA_ROLE_MAP(ROLE_SYSTEM_STATUSBAR)
110 IA_ROLE_MAP(ROLE_SYSTEM_TABLE)
111 IA_ROLE_MAP(ROLE_SYSTEM_TEXT)
112 IA_ROLE_MAP(ROLE_SYSTEM_TITLEBAR)
113 IA_ROLE_MAP(ROLE_SYSTEM_TOOLBAR)
114 IA_ROLE_MAP(ROLE_SYSTEM_TOOLTIP)
115 IA_ROLE_MAP(ROLE_SYSTEM_WHITESPACE)
116 IA_ROLE_MAP(ROLE_SYSTEM_WINDOW)
117
118 // IAccessible2 roles.
119 IA2_ROLE_MAP(IA2_ROLE_CANVAS)
120 IA2_ROLE_MAP(IA2_ROLE_CAPTION)
121 IA2_ROLE_MAP(IA2_ROLE_CHECK_MENU_ITEM)
122 IA2_ROLE_MAP(IA2_ROLE_COLOR_CHOOSER)
123 IA2_ROLE_MAP(IA2_ROLE_DATE_EDITOR)
124 IA2_ROLE_MAP(IA2_ROLE_DESKTOP_ICON)
125 IA2_ROLE_MAP(IA2_ROLE_DESKTOP_PANE)
126 IA2_ROLE_MAP(IA2_ROLE_DIRECTORY_PANE)
127 IA2_ROLE_MAP(IA2_ROLE_EDITBAR)
128 IA2_ROLE_MAP(IA2_ROLE_EMBEDDED_OBJECT)
129 IA2_ROLE_MAP(IA2_ROLE_ENDNOTE)
130 IA2_ROLE_MAP(IA2_ROLE_FILE_CHOOSER)
131 IA2_ROLE_MAP(IA2_ROLE_FONT_CHOOSER)
132 IA2_ROLE_MAP(IA2_ROLE_FOOTER)
133 IA2_ROLE_MAP(IA2_ROLE_FOOTNOTE)
134 IA2_ROLE_MAP(IA2_ROLE_FORM)
135 IA2_ROLE_MAP(IA2_ROLE_FRAME)
136 IA2_ROLE_MAP(IA2_ROLE_GLASS_PANE)
137 IA2_ROLE_MAP(IA2_ROLE_HEADER)
138 IA2_ROLE_MAP(IA2_ROLE_HEADING)
139 IA2_ROLE_MAP(IA2_ROLE_ICON)
140 IA2_ROLE_MAP(IA2_ROLE_IMAGE_MAP)
141 IA2_ROLE_MAP(IA2_ROLE_INPUT_METHOD_WINDOW)
142 IA2_ROLE_MAP(IA2_ROLE_INTERNAL_FRAME)
143 IA2_ROLE_MAP(IA2_ROLE_LABEL)
144 IA2_ROLE_MAP(IA2_ROLE_LAYERED_PANE)
145 IA2_ROLE_MAP(IA2_ROLE_NOTE)
146 IA2_ROLE_MAP(IA2_ROLE_OPTION_PANE)
147 IA2_ROLE_MAP(IA2_ROLE_PAGE)
148 IA2_ROLE_MAP(IA2_ROLE_PARAGRAPH)
149 IA2_ROLE_MAP(IA2_ROLE_RADIO_MENU_ITEM)
150 IA2_ROLE_MAP(IA2_ROLE_REDUNDANT_OBJECT)
151 IA2_ROLE_MAP(IA2_ROLE_ROOT_PANE)
152 IA2_ROLE_MAP(IA2_ROLE_RULER)
153 IA2_ROLE_MAP(IA2_ROLE_SCROLL_PANE)
154 IA2_ROLE_MAP(IA2_ROLE_SECTION)
155 IA2_ROLE_MAP(IA2_ROLE_SHAPE)
156 IA2_ROLE_MAP(IA2_ROLE_SPLIT_PANE)
157 IA2_ROLE_MAP(IA2_ROLE_TEAR_OFF_MENU)
158 IA2_ROLE_MAP(IA2_ROLE_TERMINAL)
159 IA2_ROLE_MAP(IA2_ROLE_TEXT_FRAME)
160 IA2_ROLE_MAP(IA2_ROLE_TOGGLE_BUTTON)
161 IA2_ROLE_MAP(IA2_ROLE_UNKNOWN)
162 IA2_ROLE_MAP(IA2_ROLE_VIEW_PORT)
163
164 // MSAA / IAccessible states. Unlike roles, these are not also IA2 states.
165 IA_STATE_MAP(ALERT_HIGH)
166 IA_STATE_MAP(ALERT_LOW)
167 IA_STATE_MAP(ALERT_MEDIUM)
168 IA_STATE_MAP(ANIMATED)
169 IA_STATE_MAP(BUSY)
170 IA_STATE_MAP(CHECKED)
171 IA_STATE_MAP(COLLAPSED)
172 IA_STATE_MAP(DEFAULT)
173 IA_STATE_MAP(EXPANDED)
174 IA_STATE_MAP(EXTSELECTABLE)
175 IA_STATE_MAP(FLOATING)
176 IA_STATE_MAP(FOCUSABLE)
177 IA_STATE_MAP(FOCUSED)
178 IA_STATE_MAP(HASPOPUP)
179 IA_STATE_MAP(HOTTRACKED)
180 IA_STATE_MAP(INVISIBLE)
181 IA_STATE_MAP(LINKED)
182 IA_STATE_MAP(MARQUEED)
183 IA_STATE_MAP(MIXED)
184 IA_STATE_MAP(MOVEABLE)
185 IA_STATE_MAP(MULTISELECTABLE)
186 IA_STATE_MAP(OFFSCREEN)
187 IA_STATE_MAP(PRESSED)
188 IA_STATE_MAP(PROTECTED)
189 IA_STATE_MAP(READONLY)
190 IA_STATE_MAP(SELECTABLE)
191 IA_STATE_MAP(SELECTED)
192 IA_STATE_MAP(SELFVOICING)
193 IA_STATE_MAP(SIZEABLE)
194 IA_STATE_MAP(TRAVERSED)
195 IA_STATE_MAP(UNAVAILABLE)
196
197 // IAccessible2 states.
198 IA2_STATE_MAP(IA2_STATE_ACTIVE)
199 IA2_STATE_MAP(IA2_STATE_ARMED)
200 IA2_STATE_MAP(IA2_STATE_DEFUNCT)
201 IA2_STATE_MAP(IA2_STATE_EDITABLE)
202 IA2_STATE_MAP(IA2_STATE_ICONIFIED)
203 IA2_STATE_MAP(IA2_STATE_INVALID_ENTRY)
204 IA2_STATE_MAP(IA2_STATE_MANAGES_DESCENDANTS)
205 IA2_STATE_MAP(IA2_STATE_MODAL)
206 IA2_STATE_MAP(IA2_STATE_MULTI_LINE)
207 IA2_STATE_MAP(IA2_STATE_REQUIRED)
208 IA2_STATE_MAP(IA2_STATE_SELECTABLE_TEXT)
209 IA2_STATE_MAP(IA2_STATE_SINGLE_LINE)
210 IA2_STATE_MAP(IA2_STATE_STALE)
211 IA2_STATE_MAP(IA2_STATE_SUPPORTS_AUTOCOMPLETION)
212 IA2_STATE_MAP(IA2_STATE_TRANSIENT)
213
214 // Untested states include those that would be repeated on nearly every node,
215 // or would vary based on window size.
216 // IA2_STATE_MAP(IA2_STATE_HORIZONTAL) // Untested.
217 // IA2_STATE_MAP(IA2_STATE_OPAQUE) // Untested.
218 // IA2_STATE_MAP(IA2_STATE_VERTICAL) // Untested.
219 }
220
221 } // namespace.
222
IAccessibleRoleToString(int32 ia_role)223 base::string16 IAccessibleRoleToString(int32 ia_role) {
224 return AccessibilityRoleStateMap::GetInstance()->ia_role_string_map[ia_role];
225 }
226
IAccessible2RoleToString(int32 ia_role)227 base::string16 IAccessible2RoleToString(int32 ia_role) {
228 return AccessibilityRoleStateMap::GetInstance()->ia2_role_string_map[ia_role];
229 }
230
IAccessibleStateToStringVector(int32 ia_state,std::vector<base::string16> * result)231 void IAccessibleStateToStringVector(int32 ia_state,
232 std::vector<base::string16>* result) {
233 const std::map<int32, base::string16>& state_string_map =
234 AccessibilityRoleStateMap::GetInstance()->ia_state_string_map;
235 std::map<int32, base::string16>::const_iterator it;
236 for (it = state_string_map.begin(); it != state_string_map.end(); ++it) {
237 if (it->first & ia_state)
238 result->push_back(it->second);
239 }
240 }
241
IAccessibleStateToString(int32 ia_state)242 base::string16 IAccessibleStateToString(int32 ia_state) {
243 std::vector<base::string16> strings;
244 IAccessibleStateToStringVector(ia_state, &strings);
245 return JoinString(strings, ',');
246 }
247
IAccessible2StateToStringVector(int32 ia2_state,std::vector<base::string16> * result)248 void IAccessible2StateToStringVector(int32 ia2_state,
249 std::vector<base::string16>* result) {
250 const std::map<int32, base::string16>& state_string_map =
251 AccessibilityRoleStateMap::GetInstance()->ia2_state_string_map;
252 std::map<int32, base::string16>::const_iterator it;
253 for (it = state_string_map.begin(); it != state_string_map.end(); ++it) {
254 if (it->first & ia2_state)
255 result->push_back(it->second);
256 }
257 }
258
IAccessible2StateToString(int32 ia2_state)259 base::string16 IAccessible2StateToString(int32 ia2_state) {
260 std::vector<base::string16> strings;
261 IAccessible2StateToStringVector(ia2_state, &strings);
262 return JoinString(strings, ',');
263 }
264
265 } // namespace content
266