Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(158)

Side by Side Diff: webkit/glue/webaccessibility.cc

Issue 10544099: Refactor all accessibility code out of webkit/glue. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: More Mac compile errors Created 8 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « webkit/glue/webaccessibility.h ('k') | webkit/glue/webkit_glue.gypi » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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 "webkit/glue/webaccessibility.h"
6
7 #include <set>
8
9 #include "base/string_number_conversions.h"
10 #include "base/string_util.h"
11 #include "base/utf_string_conversions.h"
12 #include "third_party/WebKit/Source/WebKit/chromium/public/WebAccessibilityObjec t.h"
13 #include "third_party/WebKit/Source/WebKit/chromium/public/WebAccessibilityRole. h"
14 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h"
15 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDocumentType.h"
16 #include "third_party/WebKit/Source/WebKit/chromium/public/WebElement.h"
17 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFormControlElement .h"
18 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
19 #include "third_party/WebKit/Source/WebKit/chromium/public/WebInputElement.h"
20 #include "third_party/WebKit/Source/WebKit/chromium/public/WebNode.h"
21 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebRect.h"
22 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebSize.h"
23 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebString.h"
24 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebVector.h"
25
26 using base::DoubleToString;
27 using base::IntToString;
28 using WebKit::WebAccessibilityRole;
29 using WebKit::WebAccessibilityObject;
30
31 namespace {
32
33 std::string IntVectorToString(const std::vector<int>& items) {
34 std::string str;
35 for (size_t i = 0; i < items.size(); ++i) {
36 if (i > 0)
37 str += ",";
38 str += IntToString(items[i]);
39 }
40 return str;
41 }
42
43 } // Anonymous namespace
44
45 namespace webkit_glue {
46
47 // Provides a conversion between the WebKit::WebAccessibilityRole and a role
48 // supported on the Browser side. Listed alphabetically by the
49 // WebAccessibilityRole (except for default role).
50 WebAccessibility::Role ConvertRole(WebKit::WebAccessibilityRole role) {
51 switch (role) {
52 case WebKit::WebAccessibilityRoleAnnotation:
53 return WebAccessibility::ROLE_ANNOTATION;
54 case WebKit::WebAccessibilityRoleApplication:
55 return WebAccessibility::ROLE_APPLICATION;
56 case WebKit::WebAccessibilityRoleApplicationAlert:
57 return WebAccessibility::ROLE_ALERT;
58 case WebKit::WebAccessibilityRoleApplicationAlertDialog:
59 return WebAccessibility::ROLE_ALERT_DIALOG;
60 case WebKit::WebAccessibilityRoleApplicationDialog:
61 return WebAccessibility::ROLE_DIALOG;
62 case WebKit::WebAccessibilityRoleApplicationLog:
63 return WebAccessibility::ROLE_LOG;
64 case WebKit::WebAccessibilityRoleApplicationMarquee:
65 return WebAccessibility::ROLE_MARQUEE;
66 case WebKit::WebAccessibilityRoleApplicationStatus:
67 return WebAccessibility::ROLE_STATUS;
68 case WebKit::WebAccessibilityRoleApplicationTimer:
69 return WebAccessibility::ROLE_TIMER;
70 case WebKit::WebAccessibilityRoleBrowser:
71 return WebAccessibility::ROLE_BROWSER;
72 case WebKit::WebAccessibilityRoleBusyIndicator:
73 return WebAccessibility::ROLE_BUSY_INDICATOR;
74 case WebKit::WebAccessibilityRoleButton:
75 return WebAccessibility::ROLE_BUTTON;
76 case WebKit::WebAccessibilityRoleCell:
77 return WebAccessibility::ROLE_CELL;
78 case WebKit::WebAccessibilityRoleCheckBox:
79 return WebAccessibility::ROLE_CHECKBOX;
80 case WebKit::WebAccessibilityRoleColorWell:
81 return WebAccessibility::ROLE_COLOR_WELL;
82 case WebKit::WebAccessibilityRoleColumn:
83 return WebAccessibility::ROLE_COLUMN;
84 case WebKit::WebAccessibilityRoleColumnHeader:
85 return WebAccessibility::ROLE_COLUMN_HEADER;
86 case WebKit::WebAccessibilityRoleComboBox:
87 return WebAccessibility::ROLE_COMBO_BOX;
88 case WebKit::WebAccessibilityRoleDefinitionListDefinition:
89 return WebAccessibility::ROLE_DEFINITION_LIST_DEFINITION;
90 case WebKit::WebAccessibilityRoleDefinitionListTerm:
91 return WebAccessibility::ROLE_DEFINITION_LIST_TERM;
92 case WebKit::WebAccessibilityRoleDirectory:
93 return WebAccessibility::ROLE_DIRECTORY;
94 case WebKit::WebAccessibilityRoleDisclosureTriangle:
95 return WebAccessibility::ROLE_DISCLOSURE_TRIANGLE;
96 case WebKit::WebAccessibilityRoleDocument:
97 return WebAccessibility::ROLE_DOCUMENT;
98 case WebKit::WebAccessibilityRoleDocumentArticle:
99 return WebAccessibility::ROLE_ARTICLE;
100 case WebKit::WebAccessibilityRoleDocumentMath:
101 return WebAccessibility::ROLE_MATH;
102 case WebKit::WebAccessibilityRoleDocumentNote:
103 return WebAccessibility::ROLE_NOTE;
104 case WebKit::WebAccessibilityRoleDocumentRegion:
105 return WebAccessibility::ROLE_REGION;
106 case WebKit::WebAccessibilityRoleDrawer:
107 return WebAccessibility::ROLE_DRAWER;
108 case WebKit::WebAccessibilityRoleEditableText:
109 return WebAccessibility::ROLE_EDITABLE_TEXT;
110 case WebKit::WebAccessibilityRoleFooter:
111 return WebAccessibility::ROLE_FOOTER;
112 case WebKit::WebAccessibilityRoleGrid:
113 return WebAccessibility::ROLE_GRID;
114 case WebKit::WebAccessibilityRoleGroup:
115 return WebAccessibility::ROLE_GROUP;
116 case WebKit::WebAccessibilityRoleGrowArea:
117 return WebAccessibility::ROLE_GROW_AREA;
118 case WebKit::WebAccessibilityRoleHeading:
119 return WebAccessibility::ROLE_HEADING;
120 case WebKit::WebAccessibilityRoleHelpTag:
121 return WebAccessibility::ROLE_HELP_TAG;
122 case WebKit::WebAccessibilityRoleIgnored:
123 return WebAccessibility::ROLE_IGNORED;
124 case WebKit::WebAccessibilityRoleImage:
125 return WebAccessibility::ROLE_IMAGE;
126 case WebKit::WebAccessibilityRoleImageMap:
127 return WebAccessibility::ROLE_IMAGE_MAP;
128 case WebKit::WebAccessibilityRoleImageMapLink:
129 return WebAccessibility::ROLE_IMAGE_MAP_LINK;
130 case WebKit::WebAccessibilityRoleIncrementor:
131 return WebAccessibility::ROLE_INCREMENTOR;
132 case WebKit::WebAccessibilityRoleLandmarkApplication:
133 return WebAccessibility::ROLE_LANDMARK_APPLICATION;
134 case WebKit::WebAccessibilityRoleLandmarkBanner:
135 return WebAccessibility::ROLE_LANDMARK_BANNER;
136 case WebKit::WebAccessibilityRoleLandmarkComplementary:
137 return WebAccessibility::ROLE_LANDMARK_COMPLEMENTARY;
138 case WebKit::WebAccessibilityRoleLandmarkContentInfo:
139 return WebAccessibility::ROLE_LANDMARK_CONTENTINFO;
140 case WebKit::WebAccessibilityRoleLandmarkMain:
141 return WebAccessibility::ROLE_LANDMARK_MAIN;
142 case WebKit::WebAccessibilityRoleLandmarkNavigation:
143 return WebAccessibility::ROLE_LANDMARK_NAVIGATION;
144 case WebKit::WebAccessibilityRoleLandmarkSearch:
145 return WebAccessibility::ROLE_LANDMARK_SEARCH;
146 case WebKit::WebAccessibilityRoleLink:
147 return WebAccessibility::ROLE_LINK;
148 case WebKit::WebAccessibilityRoleList:
149 return WebAccessibility::ROLE_LIST;
150 case WebKit::WebAccessibilityRoleListBox:
151 return WebAccessibility::ROLE_LISTBOX;
152 case WebKit::WebAccessibilityRoleListBoxOption:
153 return WebAccessibility::ROLE_LISTBOX_OPTION;
154 case WebKit::WebAccessibilityRoleListItem:
155 return WebAccessibility::ROLE_LIST_ITEM;
156 case WebKit::WebAccessibilityRoleListMarker:
157 return WebAccessibility::ROLE_LIST_MARKER;
158 case WebKit::WebAccessibilityRoleMatte:
159 return WebAccessibility::ROLE_MATTE;
160 case WebKit::WebAccessibilityRoleMenu:
161 return WebAccessibility::ROLE_MENU;
162 case WebKit::WebAccessibilityRoleMenuBar:
163 return WebAccessibility::ROLE_MENU_BAR;
164 case WebKit::WebAccessibilityRoleMenuButton:
165 return WebAccessibility::ROLE_MENU_BUTTON;
166 case WebKit::WebAccessibilityRoleMenuItem:
167 return WebAccessibility::ROLE_MENU_ITEM;
168 case WebKit::WebAccessibilityRoleMenuListOption:
169 return WebAccessibility::ROLE_MENU_LIST_OPTION;
170 case WebKit::WebAccessibilityRoleMenuListPopup:
171 return WebAccessibility::ROLE_MENU_LIST_POPUP;
172 case WebKit::WebAccessibilityRoleOutline:
173 return WebAccessibility::ROLE_OUTLINE;
174 case WebKit::WebAccessibilityRolePopUpButton:
175 return WebAccessibility::ROLE_POPUP_BUTTON;
176 case WebKit::WebAccessibilityRoleProgressIndicator:
177 return WebAccessibility::ROLE_PROGRESS_INDICATOR;
178 case WebKit::WebAccessibilityRoleRadioButton:
179 return WebAccessibility::ROLE_RADIO_BUTTON;
180 case WebKit::WebAccessibilityRoleRadioGroup:
181 return WebAccessibility::ROLE_RADIO_GROUP;
182 case WebKit::WebAccessibilityRoleRow:
183 return WebAccessibility::ROLE_ROW;
184 case WebKit::WebAccessibilityRoleRowHeader:
185 return WebAccessibility::ROLE_ROW_HEADER;
186 case WebKit::WebAccessibilityRoleRuler:
187 return WebAccessibility::ROLE_RULER;
188 case WebKit::WebAccessibilityRoleRulerMarker:
189 return WebAccessibility::ROLE_RULER_MARKER;
190 case WebKit::WebAccessibilityRoleScrollArea:
191 return WebAccessibility::ROLE_SCROLLAREA;
192 case WebKit::WebAccessibilityRoleScrollBar:
193 return WebAccessibility::ROLE_SCROLLBAR;
194 case WebKit::WebAccessibilityRoleSheet:
195 return WebAccessibility::ROLE_SHEET;
196 case WebKit::WebAccessibilityRoleSlider:
197 return WebAccessibility::ROLE_SLIDER;
198 case WebKit::WebAccessibilityRoleSliderThumb:
199 return WebAccessibility::ROLE_SLIDER_THUMB;
200 case WebKit::WebAccessibilityRoleSplitGroup:
201 return WebAccessibility::ROLE_SPLIT_GROUP;
202 case WebKit::WebAccessibilityRoleSplitter:
203 return WebAccessibility::ROLE_SPLITTER;
204 case WebKit::WebAccessibilityRoleStaticText:
205 return WebAccessibility::ROLE_STATIC_TEXT;
206 case WebKit::WebAccessibilityRoleSystemWide:
207 return WebAccessibility::ROLE_SYSTEM_WIDE;
208 case WebKit::WebAccessibilityRoleTab:
209 return WebAccessibility::ROLE_TAB;
210 case WebKit::WebAccessibilityRoleTabGroup:
211 return WebAccessibility::ROLE_TAB_GROUP_UNUSED;
212 case WebKit::WebAccessibilityRoleTabList:
213 return WebAccessibility::ROLE_TAB_LIST;
214 case WebKit::WebAccessibilityRoleTabPanel:
215 return WebAccessibility::ROLE_TAB_PANEL;
216 case WebKit::WebAccessibilityRoleTable:
217 return WebAccessibility::ROLE_TABLE;
218 case WebKit::WebAccessibilityRoleTableHeaderContainer:
219 return WebAccessibility::ROLE_TABLE_HEADER_CONTAINER;
220 case WebKit::WebAccessibilityRoleTextArea:
221 return WebAccessibility::ROLE_TEXTAREA;
222 case WebKit::WebAccessibilityRoleTextField:
223 return WebAccessibility::ROLE_TEXT_FIELD;
224 case WebKit::WebAccessibilityRoleToolbar:
225 return WebAccessibility::ROLE_TOOLBAR;
226 case WebKit::WebAccessibilityRoleTreeGrid:
227 return WebAccessibility::ROLE_TREE_GRID;
228 case WebKit::WebAccessibilityRoleTreeItemRole:
229 return WebAccessibility::ROLE_TREE_ITEM;
230 case WebKit::WebAccessibilityRoleTreeRole:
231 return WebAccessibility::ROLE_TREE;
232 case WebKit::WebAccessibilityRoleUserInterfaceTooltip:
233 return WebAccessibility::ROLE_TOOLTIP;
234 case WebKit::WebAccessibilityRoleValueIndicator:
235 return WebAccessibility::ROLE_VALUE_INDICATOR;
236 case WebKit::WebAccessibilityRoleWebArea:
237 return WebAccessibility::ROLE_WEB_AREA;
238 case WebKit::WebAccessibilityRoleWebCoreLink:
239 return WebAccessibility::ROLE_WEBCORE_LINK;
240 case WebKit::WebAccessibilityRoleWindow:
241 return WebAccessibility::ROLE_WINDOW;
242
243 default:
244 return WebAccessibility::ROLE_UNKNOWN;
245 }
246 }
247
248 uint32 ConvertState(const WebAccessibilityObject& o) {
249 uint32 state = 0;
250 if (o.isChecked())
251 state |= (1 << WebAccessibility::STATE_CHECKED);
252
253 if (o.isCollapsed())
254 state |= (1 << WebAccessibility::STATE_COLLAPSED);
255
256 if (o.canSetFocusAttribute())
257 state |= (1 << WebAccessibility::STATE_FOCUSABLE);
258
259 if (o.isFocused())
260 state |= (1 << WebAccessibility::STATE_FOCUSED);
261
262 if (o.roleValue() == WebKit::WebAccessibilityRolePopUpButton ||
263 o.ariaHasPopup()) {
264 state |= (1 << WebAccessibility::STATE_HASPOPUP);
265 if (!o.isCollapsed())
266 state |= (1 << WebAccessibility::STATE_EXPANDED);
267 }
268
269 if (o.isHovered())
270 state |= (1 << WebAccessibility::STATE_HOTTRACKED);
271
272 if (o.isIndeterminate())
273 state |= (1 << WebAccessibility::STATE_INDETERMINATE);
274
275 if (!o.isVisible())
276 state |= (1 << WebAccessibility::STATE_INVISIBLE);
277
278 if (o.isLinked())
279 state |= (1 << WebAccessibility::STATE_LINKED);
280
281 if (o.isMultiSelectable())
282 state |= (1 << WebAccessibility::STATE_MULTISELECTABLE);
283
284 if (o.isOffScreen())
285 state |= (1 << WebAccessibility::STATE_OFFSCREEN);
286
287 if (o.isPressed())
288 state |= (1 << WebAccessibility::STATE_PRESSED);
289
290 if (o.isPasswordField())
291 state |= (1 << WebAccessibility::STATE_PROTECTED);
292
293 if (o.isReadOnly())
294 state |= (1 << WebAccessibility::STATE_READONLY);
295
296 if (o.isRequired())
297 state |= (1 << WebAccessibility::STATE_REQUIRED);
298
299 if (o.canSetSelectedAttribute())
300 state |= (1 << WebAccessibility::STATE_SELECTABLE);
301
302 if (o.isSelected())
303 state |= (1 << WebAccessibility::STATE_SELECTED);
304
305 if (o.isVisited())
306 state |= (1 << WebAccessibility::STATE_TRAVERSED);
307
308 if (!o.isEnabled())
309 state |= (1 << WebAccessibility::STATE_UNAVAILABLE);
310
311 if (o.isVertical())
312 state |= (1 << WebAccessibility::STATE_VERTICAL);
313
314 if (o.isVisited())
315 state |= (1 << WebAccessibility::STATE_VISITED);
316
317 return state;
318 }
319
320 WebAccessibility::WebAccessibility()
321 : id(-1),
322 role(ROLE_UNKNOWN),
323 state(-1) {
324 }
325
326 WebAccessibility::WebAccessibility(const WebKit::WebAccessibilityObject& src,
327 IncludeChildren include_children,
328 IncludeLineBreaks include_line_breaks) {
329 Init(src, include_children, include_line_breaks);
330 }
331
332 WebAccessibility::~WebAccessibility() {
333 }
334
335 #ifndef NDEBUG
336 std::string WebAccessibility::DebugString(bool recursive) const {
337 std::string result;
338 static int indent = 0;
339 result += "\n";
340 for (int i = 0; i < indent; ++i)
341 result += " ";
342
343 result += "id=" + IntToString(id);
344
345 switch (role) {
346 case ROLE_ALERT: result += " ALERT"; break;
347 case ROLE_ALERT_DIALOG: result += " ALERT_DIALOG"; break;
348 case ROLE_ANNOTATION: result += " ANNOTATION"; break;
349 case ROLE_APPLICATION: result += " APPLICATION"; break;
350 case ROLE_ARTICLE: result += " ARTICLE"; break;
351 case ROLE_BROWSER: result += " BROWSER"; break;
352 case ROLE_BUSY_INDICATOR: result += " BUSY_INDICATOR"; break;
353 case ROLE_BUTTON: result += " BUTTON"; break;
354 case ROLE_CELL: result += " CELL"; break;
355 case ROLE_CHECKBOX: result += " CHECKBOX"; break;
356 case ROLE_COLOR_WELL: result += " COLOR_WELL"; break;
357 case ROLE_COLUMN: result += " COLUMN"; break;
358 case ROLE_COLUMN_HEADER: result += " COLUMN_HEADER"; break;
359 case ROLE_COMBO_BOX: result += " COMBO_BOX"; break;
360 case ROLE_DEFINITION_LIST_DEFINITION: result += " DL_DEFINITION"; break;
361 case ROLE_DEFINITION_LIST_TERM: result += " DL_TERM"; break;
362 case ROLE_DIALOG: result += " DIALOG"; break;
363 case ROLE_DIRECTORY: result += " DIRECTORY"; break;
364 case ROLE_DISCLOSURE_TRIANGLE: result += " DISCLOSURE_TRIANGLE"; break;
365 case ROLE_DOCUMENT: result += " DOCUMENT"; break;
366 case ROLE_DRAWER: result += " DRAWER"; break;
367 case ROLE_EDITABLE_TEXT: result += " EDITABLE_TEXT"; break;
368 case ROLE_GRID: result += " GRID"; break;
369 case ROLE_GROUP: result += " GROUP"; break;
370 case ROLE_GROW_AREA: result += " GROW_AREA"; break;
371 case ROLE_HEADING: result += " HEADING"; break;
372 case ROLE_HELP_TAG: result += " HELP_TAG"; break;
373 case ROLE_IGNORED: result += " IGNORED"; break;
374 case ROLE_IMAGE: result += " IMAGE"; break;
375 case ROLE_IMAGE_MAP: result += " IMAGE_MAP"; break;
376 case ROLE_IMAGE_MAP_LINK: result += " IMAGE_MAP_LINK"; break;
377 case ROLE_INCREMENTOR: result += " INCREMENTOR"; break;
378 case ROLE_LANDMARK_APPLICATION: result += " L_APPLICATION"; break;
379 case ROLE_LANDMARK_BANNER: result += " L_BANNER"; break;
380 case ROLE_LANDMARK_COMPLEMENTARY: result += " L_COMPLEMENTARY"; break;
381 case ROLE_LANDMARK_CONTENTINFO: result += " L_CONTENTINFO"; break;
382 case ROLE_LANDMARK_MAIN: result += " L_MAIN"; break;
383 case ROLE_LANDMARK_NAVIGATION: result += " L_NAVIGATION"; break;
384 case ROLE_LANDMARK_SEARCH: result += " L_SEARCH"; break;
385 case ROLE_LINK: result += " LINK"; break;
386 case ROLE_LIST: result += " LIST"; break;
387 case ROLE_LISTBOX: result += " LISTBOX"; break;
388 case ROLE_LISTBOX_OPTION: result += " LISTBOX_OPTION"; break;
389 case ROLE_LIST_ITEM: result += " LIST_ITEM"; break;
390 case ROLE_LIST_MARKER: result += " LIST_MARKER"; break;
391 case ROLE_LOG: result += " LOG"; break;
392 case ROLE_MARQUEE: result += " MARQUEE"; break;
393 case ROLE_MATH: result += " MATH"; break;
394 case ROLE_MATTE: result += " MATTE"; break;
395 case ROLE_MENU: result += " MENU"; break;
396 case ROLE_MENU_BAR: result += " MENU_BAR"; break;
397 case ROLE_MENU_BUTTON: result += " MENU_BUTTON"; break;
398 case ROLE_MENU_ITEM: result += " MENU_ITEM"; break;
399 case ROLE_MENU_LIST_OPTION: result += " MENU_LIST_OPTION"; break;
400 case ROLE_MENU_LIST_POPUP: result += " MENU_LIST_POPUP"; break;
401 case ROLE_NOTE: result += " NOTE"; break;
402 case ROLE_OUTLINE: result += " OUTLINE"; break;
403 case ROLE_POPUP_BUTTON: result += " POPUP_BUTTON"; break;
404 case ROLE_PROGRESS_INDICATOR: result += " PROGRESS_INDICATOR"; break;
405 case ROLE_RADIO_BUTTON: result += " RADIO_BUTTON"; break;
406 case ROLE_RADIO_GROUP: result += " RADIO_GROUP"; break;
407 case ROLE_REGION: result += " REGION"; break;
408 case ROLE_ROOT_WEB_AREA: result += " ROOT_WEB_AREA"; break;
409 case ROLE_ROW: result += " ROW"; break;
410 case ROLE_ROW_HEADER: result += " ROW_HEADER"; break;
411 case ROLE_RULER: result += " RULER"; break;
412 case ROLE_RULER_MARKER: result += " RULER_MARKER"; break;
413 case ROLE_SCROLLAREA: result += " SCROLLAREA"; break;
414 case ROLE_SCROLLBAR: result += " SCROLLBAR"; break;
415 case ROLE_SHEET: result += " SHEET"; break;
416 case ROLE_SLIDER: result += " SLIDER"; break;
417 case ROLE_SLIDER_THUMB: result += " SLIDER_THUMB"; break;
418 case ROLE_SPLITTER: result += " SPLITTER"; break;
419 case ROLE_SPLIT_GROUP: result += " SPLIT_GROUP"; break;
420 case ROLE_STATIC_TEXT: result += " STATIC_TEXT"; break;
421 case ROLE_STATUS: result += " STATUS"; break;
422 case ROLE_SYSTEM_WIDE: result += " SYSTEM_WIDE"; break;
423 case ROLE_TAB: result += " TAB"; break;
424 case ROLE_TABLE: result += " TABLE"; break;
425 case ROLE_TABLE_HEADER_CONTAINER: result += " TABLE_HDR_CONTAINER"; break;
426 case ROLE_TAB_GROUP_UNUSED: result += " TAB_GROUP_UNUSED"; break;
427 case ROLE_TAB_LIST: result += " TAB_LIST"; break;
428 case ROLE_TAB_PANEL: result += " TAB_PANEL"; break;
429 case ROLE_TEXTAREA: result += " TEXTAREA"; break;
430 case ROLE_TEXT_FIELD: result += " TEXT_FIELD"; break;
431 case ROLE_TIMER: result += " TIMER"; break;
432 case ROLE_TOOLBAR: result += " TOOLBAR"; break;
433 case ROLE_TOOLTIP: result += " TOOLTIP"; break;
434 case ROLE_TREE: result += " TREE"; break;
435 case ROLE_TREE_GRID: result += " TREE_GRID"; break;
436 case ROLE_TREE_ITEM: result += " TREE_ITEM"; break;
437 case ROLE_UNKNOWN: result += " UNKNOWN"; break;
438 case ROLE_VALUE_INDICATOR: result += " VALUE_INDICATOR"; break;
439 case ROLE_WEBCORE_LINK: result += " WEBCORE_LINK"; break;
440 case ROLE_WEB_AREA: result += " WEB_AREA"; break;
441 case ROLE_WINDOW: result += " WINDOW"; break;
442 default:
443 assert(false);
444 }
445
446 if (state & (1 << STATE_BUSY))
447 result += " BUSY";
448 if (state & (1 << STATE_CHECKED))
449 result += " CHECKED";
450 if (state & (1 << STATE_COLLAPSED))
451 result += " COLLAPSED";
452 if (state & (1 << STATE_EXPANDED))
453 result += " EXPANDED";
454 if (state & (1 << STATE_FOCUSABLE))
455 result += " FOCUSABLE";
456 if (state & (1 << STATE_FOCUSED))
457 result += " FOCUSED";
458 if (state & (1 << STATE_HASPOPUP))
459 result += " HASPOPUP";
460 if (state & (1 << STATE_HOTTRACKED))
461 result += " HOTTRACKED";
462 if (state & (1 << STATE_INDETERMINATE))
463 result += " INDETERMINATE";
464 if (state & (1 << STATE_INVISIBLE))
465 result += " INVISIBLE";
466 if (state & (1 << STATE_LINKED))
467 result += " LINKED";
468 if (state & (1 << STATE_MULTISELECTABLE))
469 result += " MULTISELECTABLE";
470 if (state & (1 << STATE_OFFSCREEN))
471 result += " OFFSCREEN";
472 if (state & (1 << STATE_PRESSED))
473 result += " PRESSED";
474 if (state & (1 << STATE_PROTECTED))
475 result += " PROTECTED";
476 if (state & (1 << STATE_READONLY))
477 result += " READONLY";
478 if (state & (1 << STATE_REQUIRED))
479 result += " REQUIRED";
480 if (state & (1 << STATE_SELECTABLE))
481 result += " SELECTABLE";
482 if (state & (1 << STATE_SELECTED))
483 result += " SELECTED";
484 if (state & (1 << STATE_TRAVERSED))
485 result += " TRAVERSED";
486 if (state & (1 << STATE_UNAVAILABLE))
487 result += " UNAVAILABLE";
488 if (state & (1 << STATE_VERTICAL))
489 result += " VERTICAL";
490 if (state & (1 << STATE_VISITED))
491 result += " VISITED";
492
493 std::string tmp = UTF16ToUTF8(name);
494 RemoveChars(tmp, "\n", &tmp);
495 if (!tmp.empty())
496 result += " name=" + tmp;
497
498 tmp = UTF16ToUTF8(value);
499 RemoveChars(tmp, "\n", &tmp);
500 if (!tmp.empty())
501 result += " value=" + tmp;
502
503 result += " (" + IntToString(location.x()) + ", " +
504 IntToString(location.y()) + ")-(" +
505 IntToString(location.width()) + ", " +
506 IntToString(location.height()) + ")";
507
508 for (std::map<IntAttribute, int32>::const_iterator iter =
509 int_attributes.begin();
510 iter != int_attributes.end();
511 ++iter) {
512 std::string value = IntToString(iter->second);
513 switch (iter->first) {
514 case ATTR_SCROLL_X:
515 result += " scroll_x=" + value;
516 break;
517 case ATTR_SCROLL_X_MIN:
518 result += " scroll_x_min=" + value;
519 break;
520 case ATTR_SCROLL_X_MAX:
521 result += " scroll_x_max=" + value;
522 break;
523 case ATTR_SCROLL_Y:
524 result += " scroll_y=" + value;
525 break;
526 case ATTR_SCROLL_Y_MIN:
527 result += " scroll_y_min=" + value;
528 break;
529 case ATTR_SCROLL_Y_MAX:
530 result += " scroll_y_max=" + value;
531 break;
532 case ATTR_HIERARCHICAL_LEVEL:
533 result += " level=" + value;
534 break;
535 case ATTR_TEXT_SEL_START:
536 result += " sel_start=" + value;
537 break;
538 case ATTR_TEXT_SEL_END:
539 result += " sel_end=" + value;
540 break;
541 case ATTR_TABLE_ROW_COUNT:
542 result += " rows=" + value;
543 break;
544 case ATTR_TABLE_COLUMN_COUNT:
545 result += " cols=" + value;
546 break;
547 case ATTR_TABLE_CELL_COLUMN_INDEX:
548 result += " col=" + value;
549 break;
550 case ATTR_TABLE_CELL_ROW_INDEX:
551 result += " row=" + value;
552 break;
553 case ATTR_TABLE_CELL_COLUMN_SPAN:
554 result += " colspan=" + value;
555 break;
556 case ATTR_TABLE_CELL_ROW_SPAN:
557 result += " rowspan=" + value;
558 break;
559 case ATTR_TITLE_UI_ELEMENT:
560 result += " title_elem=" + value;
561 break;
562 }
563 }
564
565 for (std::map<StringAttribute, string16>::const_iterator iter =
566 string_attributes.begin();
567 iter != string_attributes.end();
568 ++iter) {
569 std::string value = UTF16ToUTF8(iter->second);
570 switch (iter->first) {
571 case ATTR_DOC_URL:
572 result += " doc_url=" + value;
573 break;
574 case ATTR_DOC_TITLE:
575 result += " doc_title=" + value;
576 break;
577 case ATTR_DOC_MIMETYPE:
578 result += " doc_mimetype=" + value;
579 break;
580 case ATTR_DOC_DOCTYPE:
581 result += " doc_doctype=" + value;
582 break;
583 case ATTR_ACCESS_KEY:
584 result += " access_key=" + value;
585 break;
586 case ATTR_ACTION:
587 result += " action=" + value;
588 break;
589 case ATTR_DESCRIPTION:
590 result += " description=" + value;
591 break;
592 case ATTR_DISPLAY:
593 result += " display=" + value;
594 break;
595 case ATTR_HELP:
596 result += " help=" + value;
597 break;
598 case ATTR_HTML_TAG:
599 result += " html_tag=" + value;
600 break;
601 case ATTR_LIVE_RELEVANT:
602 result += " relevant=" + value;
603 break;
604 case ATTR_LIVE_STATUS:
605 result += " live=" + value;
606 break;
607 case ATTR_CONTAINER_LIVE_RELEVANT:
608 result += " container_relevant=" + value;
609 break;
610 case ATTR_CONTAINER_LIVE_STATUS:
611 result += " container_live=" + value;
612 break;
613 case ATTR_ROLE:
614 result += " role=" + value;
615 break;
616 case ATTR_SHORTCUT:
617 result += " shortcut=" + value;
618 break;
619 case ATTR_URL:
620 result += " url=" + value;
621 break;
622 }
623 }
624
625 for (std::map<FloatAttribute, float>::const_iterator iter =
626 float_attributes.begin();
627 iter != float_attributes.end();
628 ++iter) {
629 std::string value = DoubleToString(iter->second);
630 switch (iter->first) {
631 case ATTR_DOC_LOADING_PROGRESS:
632 result += " doc_progress=" + value;
633 break;
634 case ATTR_VALUE_FOR_RANGE:
635 result += " value_for_range=" + value;
636 break;
637 case ATTR_MAX_VALUE_FOR_RANGE:
638 result += " max_value=" + value;
639 break;
640 case ATTR_MIN_VALUE_FOR_RANGE:
641 result += " min_value=" + value;
642 break;
643 }
644 }
645
646 for (std::map<BoolAttribute, bool>::const_iterator iter =
647 bool_attributes.begin();
648 iter != bool_attributes.end();
649 ++iter) {
650 std::string value = iter->second ? "true" : "false";
651 switch (iter->first) {
652 case ATTR_DOC_LOADED:
653 result += " doc_loaded=" + value;
654 break;
655 case ATTR_BUTTON_MIXED:
656 result += " mixed=" + value;
657 break;
658 case ATTR_LIVE_ATOMIC:
659 result += " atomic=" + value;
660 break;
661 case ATTR_LIVE_BUSY:
662 result += " busy=" + value;
663 break;
664 case ATTR_CONTAINER_LIVE_ATOMIC:
665 result += " container_atomic=" + value;
666 break;
667 case ATTR_CONTAINER_LIVE_BUSY:
668 result += " container_busy=" + value;
669 break;
670 case ATTR_ARIA_READONLY:
671 result += " aria_readonly=" + value;
672 break;
673 case ATTR_CAN_SET_VALUE:
674 result += " can_set_value=" + value;
675 break;
676 }
677 }
678
679 if (!children.empty())
680 result += " children=" + IntToString(children.size());
681
682 if (!indirect_child_ids.empty())
683 result += " indirect_child_ids=" + IntVectorToString(indirect_child_ids);
684
685 if (!line_breaks.empty())
686 result += " line_breaks=" + IntVectorToString(line_breaks);
687
688 if (!cell_ids.empty())
689 result += " cell_ids=" + IntVectorToString(cell_ids);
690
691 if (recursive) {
692 result += "\n";
693 ++indent;
694 for (size_t i = 0; i < children.size(); ++i)
695 result += children[i].DebugString(true);
696 --indent;
697 }
698
699 return result;
700 }
701 #endif // ifndef NDEBUG
702
703 void WebAccessibility::Init(const WebKit::WebAccessibilityObject& src,
704 IncludeChildren include_children,
705 IncludeLineBreaks include_line_breaks) {
706 name = src.title();
707 role = ConvertRole(src.roleValue());
708 state = ConvertState(src);
709 location = src.boundingBoxRect();
710 id = src.axID();
711
712 if (src.valueDescription().length())
713 value = src.valueDescription();
714 else
715 value = src.stringValue();
716
717 if (src.accessKey().length())
718 string_attributes[ATTR_ACCESS_KEY] = src.accessKey();
719 if (src.actionVerb().length())
720 string_attributes[ATTR_ACTION] = src.actionVerb();
721 if (src.isAriaReadOnly())
722 bool_attributes[ATTR_ARIA_READONLY] = true;
723 if (src.isButtonStateMixed())
724 bool_attributes[ATTR_BUTTON_MIXED] = true;
725 if (src.canSetValueAttribute())
726 bool_attributes[ATTR_CAN_SET_VALUE] = true;
727 if (src.accessibilityDescription().length())
728 string_attributes[ATTR_DESCRIPTION] = src.accessibilityDescription();
729 if (src.hasComputedStyle())
730 string_attributes[ATTR_DISPLAY] = src.computedStyleDisplay();
731 if (src.helpText().length())
732 string_attributes[ATTR_HELP] = src.helpText();
733 if (src.keyboardShortcut().length())
734 string_attributes[ATTR_SHORTCUT] = src.keyboardShortcut();
735 if (src.titleUIElement().isValid())
736 int_attributes[ATTR_TITLE_UI_ELEMENT] = src.titleUIElement().axID();
737 if (!src.url().isEmpty())
738 string_attributes[ATTR_URL] = src.url().spec().utf16();
739
740 if (role == ROLE_TREE_ITEM)
741 int_attributes[ATTR_HIERARCHICAL_LEVEL] = src.hierarchicalLevel();
742
743 if (role == ROLE_SLIDER)
744 include_children = NO_CHILDREN;
745
746 // Treat the active list box item as focused.
747 if (role == ROLE_LISTBOX_OPTION && src.isSelectedOptionActive())
748 state |= (1 << WebAccessibility::STATE_FOCUSED);
749
750 WebKit::WebNode node = src.node();
751 bool is_iframe = false;
752
753 if (!node.isNull() && node.isElementNode()) {
754 WebKit::WebElement element = node.to<WebKit::WebElement>();
755 is_iframe = (element.tagName() == ASCIIToUTF16("IFRAME"));
756
757 // TODO(ctguil): The tagName in WebKit is lower cased but
758 // HTMLElement::nodeName calls localNameUpper. Consider adding
759 // a WebElement method that returns the original lower cased tagName.
760 string_attributes[ATTR_HTML_TAG] =
761 StringToLowerASCII(string16(element.tagName()));
762 for (unsigned i = 0; i < element.attributeCount(); ++i) {
763 string16 name = StringToLowerASCII(string16(
764 element.attributeLocalName(i)));
765 string16 value = element.attributeValue(i);
766 html_attributes.push_back(std::pair<string16, string16>(name, value));
767 }
768
769 if (role == ROLE_EDITABLE_TEXT ||
770 role == ROLE_TEXTAREA ||
771 role == ROLE_TEXT_FIELD) {
772 // Jaws gets confused by children of text fields, so we ignore them.
773 include_children = NO_CHILDREN;
774
775 int_attributes[ATTR_TEXT_SEL_START] = src.selectionStart();
776 int_attributes[ATTR_TEXT_SEL_END] = src.selectionEnd();
777
778 if (include_line_breaks == INCLUDE_LINE_BREAKS) {
779 WebKit::WebVector<int> src_line_breaks;
780 src.lineBreaks(src_line_breaks);
781 line_breaks.reserve(src_line_breaks.size());
782 for (size_t i = 0; i < src_line_breaks.size(); ++i)
783 line_breaks.push_back(src_line_breaks[i]);
784 }
785 }
786
787 // ARIA role.
788 if (element.hasAttribute("role")) {
789 string_attributes[ATTR_ROLE] = element.getAttribute("role");
790 }
791
792 // Live region attributes
793 if (element.hasAttribute("aria-atomic")) {
794 bool_attributes[ATTR_LIVE_ATOMIC] =
795 LowerCaseEqualsASCII(element.getAttribute("aria-atomic"), "true");
796 }
797 if (element.hasAttribute("aria-busy")) {
798 bool_attributes[ATTR_LIVE_BUSY] =
799 LowerCaseEqualsASCII(element.getAttribute("aria-busy"), "true");
800 }
801 if (element.hasAttribute("aria-live")) {
802 string_attributes[ATTR_LIVE_STATUS] = element.getAttribute("aria-live");
803 }
804 if (element.hasAttribute("aria-relevant")) {
805 string_attributes[ATTR_LIVE_RELEVANT] =
806 element.getAttribute("aria-relevant");
807 }
808 }
809
810 // Walk up the parent chain to set live region attributes of containers
811
812 WebKit::WebAccessibilityObject container_accessible = src;
813 while (!container_accessible.isNull()) {
814 WebKit::WebNode container_node = container_accessible.node();
815 if (!container_node.isNull() && container_node.isElementNode()) {
816 WebKit::WebElement container_elem =
817 container_node.to<WebKit::WebElement>();
818 if (container_elem.hasAttribute("aria-atomic") &&
819 bool_attributes.find(ATTR_CONTAINER_LIVE_ATOMIC) ==
820 bool_attributes.end()) {
821 bool_attributes[ATTR_CONTAINER_LIVE_ATOMIC] =
822 LowerCaseEqualsASCII(container_elem.getAttribute("aria-atomic"),
823 "true");
824 }
825 if (container_elem.hasAttribute("aria-busy") &&
826 bool_attributes.find(ATTR_CONTAINER_LIVE_BUSY) ==
827 bool_attributes.end()) {
828 bool_attributes[ATTR_CONTAINER_LIVE_BUSY] =
829 LowerCaseEqualsASCII(container_elem.getAttribute("aria-busy"),
830 "true");
831 }
832 if (container_elem.hasAttribute("aria-live") &&
833 string_attributes.find(ATTR_CONTAINER_LIVE_STATUS) ==
834 string_attributes.end()) {
835 string_attributes[ATTR_CONTAINER_LIVE_STATUS] =
836 container_elem.getAttribute("aria-live");
837 }
838 if (container_elem.hasAttribute("aria-relevant") &&
839 string_attributes.find(ATTR_CONTAINER_LIVE_RELEVANT) ==
840 string_attributes.end()) {
841 string_attributes[ATTR_CONTAINER_LIVE_RELEVANT] =
842 container_elem.getAttribute("aria-relevant");
843 }
844 }
845 container_accessible = container_accessible.parentObject();
846 }
847
848 if (role == WebAccessibility::ROLE_PROGRESS_INDICATOR ||
849 role == WebAccessibility::ROLE_SCROLLBAR ||
850 role == WebAccessibility::ROLE_SLIDER) {
851 float_attributes[ATTR_VALUE_FOR_RANGE] = src.valueForRange();
852 float_attributes[ATTR_MAX_VALUE_FOR_RANGE] = src.minValueForRange();
853 float_attributes[ATTR_MIN_VALUE_FOR_RANGE] = src.maxValueForRange();
854 }
855
856 if (role == WebAccessibility::ROLE_DOCUMENT ||
857 role == WebAccessibility::ROLE_WEB_AREA) {
858 const WebKit::WebDocument& document = src.document();
859 if (name.empty())
860 name = document.title();
861 string_attributes[ATTR_DOC_TITLE] = document.title();
862 string_attributes[ATTR_DOC_URL] = document.url().spec().utf16();
863 if (document.isXHTMLDocument())
864 string_attributes[ATTR_DOC_MIMETYPE] = WebKit::WebString("text/xhtml");
865 else
866 string_attributes[ATTR_DOC_MIMETYPE] = WebKit::WebString("text/html");
867 bool_attributes[ATTR_DOC_LOADED] = src.isLoaded();
868 float_attributes[ATTR_DOC_LOADING_PROGRESS] =
869 src.estimatedLoadingProgress();
870
871 const WebKit::WebDocumentType& doctype = document.doctype();
872 if (!doctype.isNull())
873 string_attributes[ATTR_DOC_DOCTYPE] = doctype.name();
874
875 const gfx::Size& scroll_offset = document.frame()->scrollOffset();
876 int_attributes[ATTR_SCROLL_X] = scroll_offset.width();
877 int_attributes[ATTR_SCROLL_Y] = scroll_offset.height();
878
879 const gfx::Size& min_offset = document.frame()->minimumScrollOffset();
880 int_attributes[ATTR_SCROLL_X_MIN] = min_offset.width();
881 int_attributes[ATTR_SCROLL_Y_MIN] = min_offset.height();
882
883 const gfx::Size& max_offset = document.frame()->maximumScrollOffset();
884 int_attributes[ATTR_SCROLL_X_MAX] = max_offset.width();
885 int_attributes[ATTR_SCROLL_Y_MAX] = max_offset.height();
886 }
887
888 if (role == WebAccessibility::ROLE_TABLE) {
889 int column_count = src.columnCount();
890 int row_count = src.rowCount();
891 if (column_count > 0 && row_count > 0) {
892 std::set<int> unique_cell_id_set;
893 int_attributes[ATTR_TABLE_COLUMN_COUNT] = column_count;
894 int_attributes[ATTR_TABLE_ROW_COUNT] = row_count;
895 for (int i = 0; i < column_count * row_count; ++i) {
896 WebAccessibilityObject cell = src.cellForColumnAndRow(
897 i % column_count, i / column_count);
898 int cell_id = -1;
899 if (!cell.isNull()) {
900 cell_id = cell.axID();
901 if (unique_cell_id_set.find(cell_id) == unique_cell_id_set.end()) {
902 unique_cell_id_set.insert(cell_id);
903 unique_cell_ids.push_back(cell_id);
904 }
905 }
906 cell_ids.push_back(cell_id);
907 }
908 }
909 }
910
911 if (role == WebAccessibility::ROLE_CELL ||
912 role == WebAccessibility::ROLE_ROW_HEADER ||
913 role == WebAccessibility::ROLE_COLUMN_HEADER) {
914 int_attributes[ATTR_TABLE_CELL_COLUMN_INDEX] = src.cellColumnIndex();
915 int_attributes[ATTR_TABLE_CELL_COLUMN_SPAN] = src.cellColumnSpan();
916 int_attributes[ATTR_TABLE_CELL_ROW_INDEX] = src.cellRowIndex();
917 int_attributes[ATTR_TABLE_CELL_ROW_SPAN] = src.cellRowSpan();
918 }
919
920 if (include_children == INCLUDE_CHILDREN) {
921 // Recursively create children.
922 int child_count = src.childCount();
923 std::set<int32> child_ids;
924 for (int i = 0; i < child_count; ++i) {
925 WebAccessibilityObject child = src.childAt(i);
926 int32 child_id = child.axID();
927
928 // The child may be invalid due to issues in webkit accessibility code.
929 // Don't add children that are invalid thus preventing a crash.
930 // https://bugs.webkit.org/show_bug.cgi?id=44149
931 // TODO(ctguil): We may want to remove this check as webkit stabilizes.
932 if (!child.isValid())
933 continue;
934
935 // Children may duplicated in the webkit accessibility tree. Only add a
936 // child once for the web accessibility tree.
937 // https://bugs.webkit.org/show_bug.cgi?id=58930
938 if (child_ids.find(child_id) != child_ids.end())
939 continue;
940 child_ids.insert(child_id);
941
942 // Some nodes appear in the tree in more than one place: for example,
943 // a cell in a table appears as a child of both a row and a column.
944 // Only recursively add child nodes that have this node as its
945 // unignored parent. For child nodes that are actually parented to
946 // somethinng else, store only the ID.
947 //
948 // As an exception, also add children of an iframe element.
949 // https://bugs.webkit.org/show_bug.cgi?id=57066
950 if (is_iframe || IsParentUnignoredOf(src, child)) {
951 children.push_back(
952 WebAccessibility(child, include_children, include_line_breaks));
953 } else {
954 indirect_child_ids.push_back(child_id);
955 }
956 }
957 }
958 }
959
960 bool WebAccessibility::IsParentUnignoredOf(
961 const WebKit::WebAccessibilityObject& ancestor,
962 const WebKit::WebAccessibilityObject& child) {
963 WebKit::WebAccessibilityObject parent = child.parentObject();
964 while (!parent.isNull() && parent.accessibilityIsIgnored())
965 parent = parent.parentObject();
966 return parent.equals(ancestor);
967 }
968
969 } // namespace webkit_glue
OLDNEW
« no previous file with comments | « webkit/glue/webaccessibility.h ('k') | webkit/glue/webkit_glue.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698