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

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

Issue 7745035: Add a big grab bag of missing web accessibility functionality... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 9 years, 3 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') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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 "webkit/glue/webaccessibility.h" 5 #include "webkit/glue/webaccessibility.h"
6 6
7 #include <set> 7 #include <set>
8 8
9 #include "base/string_number_conversions.h" 9 #include "base/string_number_conversions.h"
10 #include "base/string_util.h" 10 #include "base/string_util.h"
11 #include "base/utf_string_conversions.h" 11 #include "base/utf_string_conversions.h"
12 #include "third_party/WebKit/Source/WebKit/chromium/public/WebAccessibilityCache .h" 12 #include "third_party/WebKit/Source/WebKit/chromium/public/WebAccessibilityCache .h"
13 #include "third_party/WebKit/Source/WebKit/chromium/public/WebAccessibilityObjec t.h" 13 #include "third_party/WebKit/Source/WebKit/chromium/public/WebAccessibilityObjec t.h"
14 #include "third_party/WebKit/Source/WebKit/chromium/public/WebAccessibilityRole. h" 14 #include "third_party/WebKit/Source/WebKit/chromium/public/WebAccessibilityRole. h"
15 #include "third_party/WebKit/Source/WebKit/chromium/public/WebAttribute.h" 15 #include "third_party/WebKit/Source/WebKit/chromium/public/WebAttribute.h"
16 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h" 16 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h"
17 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDocumentType.h" 17 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDocumentType.h"
18 #include "third_party/WebKit/Source/WebKit/chromium/public/WebElement.h" 18 #include "third_party/WebKit/Source/WebKit/chromium/public/WebElement.h"
19 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFormControlElement .h" 19 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFormControlElement .h"
20 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h" 20 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
21 #include "third_party/WebKit/Source/WebKit/chromium/public/WebInputElement.h" 21 #include "third_party/WebKit/Source/WebKit/chromium/public/WebInputElement.h"
22 #include "third_party/WebKit/Source/WebKit/chromium/public/WebNamedNodeMap.h" 22 #include "third_party/WebKit/Source/WebKit/chromium/public/WebNamedNodeMap.h"
23 #include "third_party/WebKit/Source/WebKit/chromium/public/WebNode.h" 23 #include "third_party/WebKit/Source/WebKit/chromium/public/WebNode.h"
24 #include "third_party/WebKit/Source/WebKit/chromium/public/WebRect.h" 24 #include "third_party/WebKit/Source/WebKit/chromium/public/WebRect.h"
25 #include "third_party/WebKit/Source/WebKit/chromium/public/WebSize.h" 25 #include "third_party/WebKit/Source/WebKit/chromium/public/WebSize.h"
26 #include "third_party/WebKit/Source/WebKit/chromium/public/WebString.h" 26 #include "third_party/WebKit/Source/WebKit/chromium/public/WebString.h"
27 #include "third_party/WebKit/Source/WebKit/chromium/public/WebVector.h" 27 #include "third_party/WebKit/Source/WebKit/chromium/public/WebVector.h"
28 28
29 using base::DoubleToString;
30 using base::IntToString;
29 using WebKit::WebAccessibilityCache; 31 using WebKit::WebAccessibilityCache;
30 using WebKit::WebAccessibilityRole; 32 using WebKit::WebAccessibilityRole;
31 using WebKit::WebAccessibilityObject; 33 using WebKit::WebAccessibilityObject;
32 34
33 namespace webkit_glue { 35 namespace webkit_glue {
34 36
37 static std::string IntVectorToString(const std::vector<int>& items) {
tony 2011/08/29 18:46:21 Nit: Chrome style prefers anonymous namespaces to
dmazzoni 2011/08/29 19:38:35 Done.
38 std::string str;
39 for (size_t i = 0; i < items.size(); ++i) {
40 if (i > 0)
41 str += ",";
42 str += IntToString(items[i]);
43 }
44 return str;
45 }
46
35 // Provides a conversion between the WebKit::WebAccessibilityRole and a role 47 // Provides a conversion between the WebKit::WebAccessibilityRole and a role
36 // supported on the Browser side. Listed alphabetically by the 48 // supported on the Browser side. Listed alphabetically by the
37 // WebAccessibilityRole (except for default role). 49 // WebAccessibilityRole (except for default role).
38 WebAccessibility::Role ConvertRole(WebKit::WebAccessibilityRole role) { 50 WebAccessibility::Role ConvertRole(WebKit::WebAccessibilityRole role) {
39 switch (role) { 51 switch (role) {
40 case WebKit::WebAccessibilityRoleAnnotation: 52 case WebKit::WebAccessibilityRoleAnnotation:
41 return WebAccessibility::ROLE_ANNOTATION; 53 return WebAccessibility::ROLE_ANNOTATION;
42 case WebKit::WebAccessibilityRoleApplication: 54 case WebKit::WebAccessibilityRoleApplication:
43 return WebAccessibility::ROLE_APPLICATION; 55 return WebAccessibility::ROLE_APPLICATION;
44 case WebKit::WebAccessibilityRoleApplicationAlert: 56 case WebKit::WebAccessibilityRoleApplicationAlert:
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after
238 250
239 if (o.isCollapsed()) 251 if (o.isCollapsed())
240 state |= (1 << WebAccessibility::STATE_COLLAPSED); 252 state |= (1 << WebAccessibility::STATE_COLLAPSED);
241 253
242 if (o.canSetFocusAttribute()) 254 if (o.canSetFocusAttribute())
243 state |= (1 << WebAccessibility::STATE_FOCUSABLE); 255 state |= (1 << WebAccessibility::STATE_FOCUSABLE);
244 256
245 if (o.isFocused()) 257 if (o.isFocused())
246 state |= (1 << WebAccessibility::STATE_FOCUSED); 258 state |= (1 << WebAccessibility::STATE_FOCUSED);
247 259
248 if (o.roleValue() == WebKit::WebAccessibilityRolePopUpButton) { 260 if (o.roleValue() == WebKit::WebAccessibilityRolePopUpButton ||
261 o.ariaHasPopup()) {
249 state |= (1 << WebAccessibility::STATE_HASPOPUP); 262 state |= (1 << WebAccessibility::STATE_HASPOPUP);
250
251 if (!o.isCollapsed()) 263 if (!o.isCollapsed())
252 state |= (1 << WebAccessibility::STATE_EXPANDED); 264 state |= (1 << WebAccessibility::STATE_EXPANDED);
253 } 265 }
254 266
255 if (o.isHovered()) 267 if (o.isHovered())
256 state |= (1 << WebAccessibility::STATE_HOTTRACKED); 268 state |= (1 << WebAccessibility::STATE_HOTTRACKED);
257 269
258 if (o.isIndeterminate()) 270 if (o.isIndeterminate())
259 state |= (1 << WebAccessibility::STATE_INDETERMINATE); 271 state |= (1 << WebAccessibility::STATE_INDETERMINATE);
260 272
261 if (!o.isVisible()) 273 if (!o.isVisible())
262 state |= (1 << WebAccessibility::STATE_INVISIBLE); 274 state |= (1 << WebAccessibility::STATE_INVISIBLE);
263 275
264 if (o.isLinked()) 276 if (o.isLinked())
265 state |= (1 << WebAccessibility::STATE_LINKED); 277 state |= (1 << WebAccessibility::STATE_LINKED);
266 278
267 if (o.isMultiSelectable()) 279 if (o.isMultiSelectable())
268 state |= (1 << WebAccessibility::STATE_MULTISELECTABLE); 280 state |= (1 << WebAccessibility::STATE_MULTISELECTABLE);
269 281
270 if (o.isOffScreen()) 282 if (o.isOffScreen())
271 state |= (1 << WebAccessibility::STATE_OFFSCREEN); 283 state |= (1 << WebAccessibility::STATE_OFFSCREEN);
272 284
273 if (o.isPressed()) 285 if (o.isPressed())
274 state |= (1 << WebAccessibility::STATE_PRESSED); 286 state |= (1 << WebAccessibility::STATE_PRESSED);
275 287
276 if (o.isPasswordField()) 288 if (o.isPasswordField())
277 state |= (1 << WebAccessibility::STATE_PROTECTED); 289 state |= (1 << WebAccessibility::STATE_PROTECTED);
278 290
279 if (o.isReadOnly()) 291 if (o.isAriaReadOnly())
280 state |= (1 << WebAccessibility::STATE_READONLY); 292 state |= (1 << WebAccessibility::STATE_READONLY);
281 293
294 if (o.isRequired())
295 state |= (1 << WebAccessibility::STATE_REQUIRED);
296
282 if (o.canSetSelectedAttribute()) 297 if (o.canSetSelectedAttribute())
283 state |= (1 << WebAccessibility::STATE_SELECTABLE); 298 state |= (1 << WebAccessibility::STATE_SELECTABLE);
284 299
285 if (o.isSelected()) 300 if (o.isSelected())
286 state |= (1 << WebAccessibility::STATE_SELECTED); 301 state |= (1 << WebAccessibility::STATE_SELECTED);
287 302
288 if (o.isVisited()) 303 if (o.isVisited())
289 state |= (1 << WebAccessibility::STATE_TRAVERSED); 304 state |= (1 << WebAccessibility::STATE_TRAVERSED);
290 305
291 if (!o.isEnabled()) 306 if (!o.isEnabled())
292 state |= (1 << WebAccessibility::STATE_UNAVAILABLE); 307 state |= (1 << WebAccessibility::STATE_UNAVAILABLE);
293 308
309 if (o.isVertical())
310 state |= (1 << WebAccessibility::STATE_VERTICAL);
311
312 if (o.isVisited())
313 state |= (1 << WebAccessibility::STATE_VISITED);
314
294 return state; 315 return state;
295 } 316 }
296 317
297 WebAccessibility::WebAccessibility() 318 WebAccessibility::WebAccessibility()
298 : id(-1), 319 : id(-1),
299 role(ROLE_NONE), 320 role(ROLE_NONE),
300 state(-1) { 321 state(-1) {
301 } 322 }
302 323
303 WebAccessibility::WebAccessibility(const WebKit::WebAccessibilityObject& src, 324 WebAccessibility::WebAccessibility(const WebKit::WebAccessibilityObject& src,
304 WebKit::WebAccessibilityCache* cache, 325 WebKit::WebAccessibilityCache* cache,
305 bool include_children) { 326 bool include_children) {
306 Init(src, cache, include_children); 327 Init(src, cache, include_children);
307 } 328 }
308 329
309 WebAccessibility::~WebAccessibility() { 330 WebAccessibility::~WebAccessibility() {
310 } 331 }
311 332
333 std::string WebAccessibility::DebugString(bool recursive) {
tony 2011/08/29 18:46:21 I think this is OK, but you might want to put Debu
dmazzoni 2011/08/29 19:38:35 Sure, done.
334 std::string result;
335 static int indent = 0;
336
337 for (int i = 0; i < indent; ++i)
338 result += " ";
339
340 result += "id=" + IntToString(id);
341
342 switch(role) {
343 case ROLE_ALERT: result += " ALERT"; break;
344 case ROLE_ALERT_DIALOG: result += " ALERT_DIALOG"; break;
345 case ROLE_ANNOTATION: result += " ANNOTATION"; break;
346 case ROLE_APPLICATION: result += " APPLICATION"; break;
347 case ROLE_ARTICLE: result += " ARTICLE"; break;
348 case ROLE_BROWSER: result += " BROWSER"; break;
349 case ROLE_BUSY_INDICATOR: result += " BUSY_INDICATOR"; break;
350 case ROLE_BUTTON: result += " BUTTON"; break;
351 case ROLE_CELL: result += " CELL"; break;
352 case ROLE_CHECKBOX: result += " CHECKBOX"; break;
353 case ROLE_COLOR_WELL: result += " COLOR_WELL"; break;
354 case ROLE_COLUMN: result += " COLUMN"; break;
355 case ROLE_COLUMN_HEADER: result += " COLUMN_HEADER"; break;
356 case ROLE_COMBO_BOX: result += " COMBO_BOX"; break;
357 case ROLE_DEFINITION_LIST_DEFINITION: result += " DL_DEFINITION"; break;
358 case ROLE_DEFINITION_LIST_TERM: result += " DL_TERM"; break;
359 case ROLE_DIALOG: result += " DIALOG"; break;
360 case ROLE_DIRECTORY: result += " DIRECTORY"; break;
361 case ROLE_DISCLOSURE_TRIANGLE: result += " DISCLOSURE_TRIANGLE"; break;
362 case ROLE_DOCUMENT: result += " DOCUMENT"; break;
363 case ROLE_DRAWER: result += " DRAWER"; break;
364 case ROLE_EDITABLE_TEXT: result += " EDITABLE_TEXT"; break;
365 case ROLE_GRID: result += " GRID"; break;
366 case ROLE_GROUP: result += " GROUP"; break;
367 case ROLE_GROW_AREA: result += " GROW_AREA"; break;
368 case ROLE_HEADING: result += " HEADING"; break;
369 case ROLE_HELP_TAG: result += " HELP_TAG"; break;
370 case ROLE_IGNORED: result += " IGNORED"; break;
371 case ROLE_IMAGE: result += " IMAGE"; break;
372 case ROLE_IMAGE_MAP: result += " IMAGE_MAP"; break;
373 case ROLE_IMAGE_MAP_LINK: result += " IMAGE_MAP_LINK"; break;
374 case ROLE_INCREMENTOR: result += " INCREMENTOR"; break;
375 case ROLE_LANDMARK_APPLICATION: result += " L_APPLICATION"; break;
376 case ROLE_LANDMARK_BANNER: result += " L_BANNER"; break;
377 case ROLE_LANDMARK_COMPLEMENTARY: result += " L_COMPLEMENTARY"; break;
378 case ROLE_LANDMARK_CONTENTINFO: result += " L_CONTENTINFO"; break;
379 case ROLE_LANDMARK_MAIN: result += " L_MAIN"; break;
380 case ROLE_LANDMARK_NAVIGATION: result += " L_NAVIGATION"; break;
381 case ROLE_LANDMARK_SEARCH: result += " L_SEARCH"; break;
382 case ROLE_LINK: result += " LINK"; break;
383 case ROLE_LIST: result += " LIST"; break;
384 case ROLE_LISTBOX: result += " LISTBOX"; break;
385 case ROLE_LISTBOX_OPTION: result += " LISTBOX_OPTION"; break;
386 case ROLE_LIST_ITEM: result += " LIST_ITEM"; break;
387 case ROLE_LIST_MARKER: result += " LIST_MARKER"; break;
388 case ROLE_LOG: result += " LOG"; break;
389 case ROLE_MARQUEE: result += " MARQUEE"; break;
390 case ROLE_MATH: result += " MATH"; break;
391 case ROLE_MATTE: result += " MATTE"; break;
392 case ROLE_MENU: result += " MENU"; break;
393 case ROLE_MENU_BAR: result += " MENU_BAR"; break;
394 case ROLE_MENU_BUTTON: result += " MENU_BUTTON"; break;
395 case ROLE_MENU_ITEM: result += " MENU_ITEM"; break;
396 case ROLE_MENU_LIST_OPTION: result += " MENU_LIST_OPTION"; break;
397 case ROLE_MENU_LIST_POPUP: result += " MENU_LIST_POPUP"; break;
398 case ROLE_NOTE: result += " NOTE"; break;
399 case ROLE_OUTLINE: result += " OUTLINE"; break;
400 case ROLE_POPUP_BUTTON: result += " POPUP_BUTTON"; break;
401 case ROLE_PROGRESS_INDICATOR: result += " PROGRESS_INDICATOR"; break;
402 case ROLE_RADIO_BUTTON: result += " RADIO_BUTTON"; break;
403 case ROLE_RADIO_GROUP: result += " RADIO_GROUP"; break;
404 case ROLE_REGION: result += " REGION"; break;
405 case ROLE_ROW: result += " ROW"; break;
406 case ROLE_ROW_HEADER: result += " ROW_HEADER"; break;
407 case ROLE_RULER: result += " RULER"; break;
408 case ROLE_RULER_MARKER: result += " RULER_MARKER"; break;
409 case ROLE_SCROLLAREA: result += " SCROLLAREA"; break;
410 case ROLE_SCROLLBAR: result += " SCROLLBAR"; break;
411 case ROLE_SHEET: result += " SHEET"; break;
412 case ROLE_SLIDER: result += " SLIDER"; break;
413 case ROLE_SLIDER_THUMB: result += " SLIDER_THUMB"; break;
414 case ROLE_SPLITTER: result += " SPLITTER"; break;
415 case ROLE_SPLIT_GROUP: result += " SPLIT_GROUP"; break;
416 case ROLE_STATIC_TEXT: result += " STATIC_TEXT"; break;
417 case ROLE_STATUS: result += " STATUS"; break;
418 case ROLE_SYSTEM_WIDE: result += " SYSTEM_WIDE"; break;
419 case ROLE_TAB: result += " TAB"; break;
420 case ROLE_TABLE: result += " TABLE"; break;
421 case ROLE_TABLE_HEADER_CONTAINER: result += " TABLE_HDR_CONTAINER"; break;
422 case ROLE_TAB_GROUP: result += " TAB_GROUP"; break;
423 case ROLE_TAB_LIST: result += " TAB_LIST"; break;
424 case ROLE_TAB_PANEL: result += " TAB_PANEL"; break;
425 case ROLE_TEXTAREA: result += " TEXTAREA"; break;
426 case ROLE_TEXT_FIELD: result += " TEXT_FIELD"; break;
427 case ROLE_TIMER: result += " TIMER"; break;
428 case ROLE_TOOLBAR: result += " TOOLBAR"; break;
429 case ROLE_TOOLTIP: result += " TOOLTIP"; break;
430 case ROLE_TREE: result += " TREE"; break;
431 case ROLE_TREE_GRID: result += " TREE_GRID"; break;
432 case ROLE_TREE_ITEM: result += " TREE_ITEM"; break;
433 case ROLE_UNKNOWN: result += " UNKNOWN"; break;
434 case ROLE_VALUE_INDICATOR: result += " VALUE_INDICATOR"; break;
435 case ROLE_WEBCORE_LINK: result += " WEBCORE_LINK"; break;
436 case ROLE_WEB_AREA: result += " WEB_AREA"; break;
437 case ROLE_WINDOW: result += " WINDOW"; break;
438 }
439
440 if (state & (1 << STATE_BUSY))
441 result += " BUSY";
442 if (state & (1 << STATE_CHECKED))
443 result += " CHECKED";
444 if (state & (1 << STATE_COLLAPSED))
445 result += " COLLAPSED";
446 if (state & (1 << STATE_EXPANDED))
447 result += " EXPANDED";
448 if (state & (1 << STATE_FOCUSABLE))
449 result += " FOCUSABLE";
450 if (state & (1 << STATE_FOCUSED))
451 result += " FOCUSED";
452 if (state & (1 << STATE_HASPOPUP))
453 result += " HASPOPUP";
454 if (state & (1 << STATE_HOTTRACKED))
455 result += " HOTTRACKED";
456 if (state & (1 << STATE_INDETERMINATE))
457 result += " INDETERMINATE";
458 if (state & (1 << STATE_INVISIBLE))
459 result += " INVISIBLE";
460 if (state & (1 << STATE_LINKED))
461 result += " LINKED";
462 if (state & (1 << STATE_MULTISELECTABLE))
463 result += " MULTISELECTABLE";
464 if (state & (1 << STATE_OFFSCREEN))
465 result += " OFFSCREEN";
466 if (state & (1 << STATE_PRESSED))
467 result += " PRESSED";
468 if (state & (1 << STATE_PROTECTED))
469 result += " PROTECTED";
470 if (state & (1 << STATE_READONLY))
471 result += " READONLY";
472 if (state & (1 << STATE_REQUIRED))
473 result += " REQUIRED";
474 if (state & (1 << STATE_SELECTABLE))
475 result += " SELECTABLE";
476 if (state & (1 << STATE_SELECTED))
477 result += " SELECTED";
478 if (state & (1 << STATE_TRAVERSED))
479 result += " TRAVERSED";
480 if (state & (1 << STATE_UNAVAILABLE))
481 result += " UNAVAILABLE";
482 if (state & (1 << STATE_VERTICAL))
483 result += " VERTICAL";
484 if (state & (1 << STATE_VISITED))
485 result += " VISITED";
486
487 std::string tmp = UTF16ToUTF8(name);
488 RemoveChars(tmp, "\n", &tmp);
489 if (!tmp.empty())
490 result += " name=" + tmp;
491
492 tmp = UTF16ToUTF8(value);
493 RemoveChars(tmp, "\n", &tmp);
494 if (!tmp.empty())
495 result += " value=" + tmp;
496
497 result += " (" + IntToString(location.x()) + ", " +
498 IntToString(location.y()) + ")-(" +
499 IntToString(location.width()) + ", " +
500 IntToString(location.height()) + ")";
501
502 for (std::map<IntAttribute, int32>::const_iterator iter =
503 int_attributes.begin();
504 iter != int_attributes.end();
505 ++iter) {
506 std::string value = IntToString(iter->second);
507 switch(iter->first) {
508 case ATTR_DOC_SCROLLX:
509 result += " scrollx=" + value;
510 break;
511 case ATTR_DOC_SCROLLY:
512 result += " scrolly=" + value;
513 break;
514 case ATTR_TEXT_SEL_START:
515 result += " sel_start=" + value;
516 break;
517 case ATTR_TEXT_SEL_END:
518 result += " sel_end=" + value;
519 break;
520 case ATTR_TABLE_ROW_COUNT:
521 result += " rows=" + value;
522 break;
523 case ATTR_TABLE_COLUMN_COUNT:
524 result += " cols=" + value;
525 break;
526 case ATTR_TABLE_CELL_COLUMN_INDEX:
527 result += " col=" + value;
528 break;
529 case ATTR_TABLE_CELL_ROW_INDEX:
530 result += " row=" + value;
531 break;
532 case ATTR_TABLE_CELL_COLUMN_SPAN:
533 result += " colspan=" + value;
534 break;
535 case ATTR_TABLE_CELL_ROW_SPAN:
536 result += " rowspan=" + value;
537 break;
538 }
539 }
540
541 for (std::map<StringAttribute, string16>::const_iterator iter =
542 string_attributes.begin();
543 iter != string_attributes.end();
544 ++iter) {
545 std::string value = UTF16ToUTF8(iter->second);
546 switch(iter->first) {
547 case ATTR_DOC_URL:
548 result += " doc_url=" + value;
549 break;
550 case ATTR_DOC_TITLE:
551 result += " doc_title=" + value;
552 break;
553 case ATTR_DOC_MIMETYPE:
554 result += " doc_mimetype=" + value;
555 break;
556 case ATTR_DOC_DOCTYPE:
557 result += " doc_doctype=" + value;
558 break;
559 case ATTR_ACCESS_KEY:
560 result += " access_key=" + value;
561 break;
562 case ATTR_ACTION:
563 result += " action=" + value;
564 break;
565 case ATTR_DESCRIPTION:
566 result += " description=" + value;
567 break;
568 case ATTR_DISPLAY:
569 result += " display=" + value;
570 break;
571 case ATTR_HELP:
572 result += " help=" + value;
573 break;
574 case ATTR_HTML_TAG:
575 result += " html_tag=" + value;
576 break;
577 case ATTR_LIVE_RELEVANT:
578 result += " relevant=" + value;
579 break;
580 case ATTR_LIVE_STATUS:
581 result += " live=" + value;
582 break;
583 case ATTR_CONTAINER_LIVE_RELEVANT:
584 result += " container_relevant=" + value;
585 break;
586 case ATTR_CONTAINER_LIVE_STATUS:
587 result += " container_live=" + value;
588 break;
589 case ATTR_ROLE:
590 result += " role=" + value;
591 break;
592 case ATTR_SHORTCUT:
593 result += " shortcut=" + value;
594 break;
595 case ATTR_URL:
596 result += " url=" + value;
597 break;
598 }
599 }
600
601 for (std::map<FloatAttribute, float>::const_iterator iter =
602 float_attributes.begin();
603 iter != float_attributes.end();
604 ++iter) {
605 std::string value = DoubleToString(iter->second);
606 switch(iter->first) {
607 case ATTR_DOC_LOADING_PROGRESS:
608 result += " doc_progress=" + value;
609 break;
610 case ATTR_VALUE_FOR_RANGE:
611 result += " value_for_range=" + value;
612 break;
613 case ATTR_MAX_VALUE_FOR_RANGE:
614 result += " max_value=" + value;
615 break;
616 case ATTR_MIN_VALUE_FOR_RANGE:
617 result += " min_value=" + value;
618 break;
619 }
620 }
621
622 for (std::map<BoolAttribute, bool>::const_iterator iter =
623 bool_attributes.begin();
624 iter != bool_attributes.end();
625 ++iter) {
626 std::string value = iter->second ? "true" : "false";
627 switch(iter->first) {
628 case ATTR_DOC_LOADED:
629 result += " doc_loaded=" + value;
630 break;
631 case ATTR_BUTTON_MIXED:
632 result += " mixed=" + value;
633 break;
634 case ATTR_LIVE_ATOMIC:
635 result += " atomic=" + value;
636 break;
637 case ATTR_LIVE_BUSY:
638 result += " busy=" + value;
639 break;
640 case ATTR_CONTAINER_LIVE_ATOMIC:
641 result += " container_atomic=" + value;
642 break;
643 case ATTR_CONTAINER_LIVE_BUSY:
644 result += " container_busy=" + value;
645 break;
646 }
647 }
648
649 if (!children.empty())
650 result += " children=" + IntToString(children.size());
651
652 if (!indirect_child_ids.empty())
653 result += " indirect_child_ids=" + IntVectorToString(indirect_child_ids);
654
655 if (!line_breaks.empty())
656 result += " line_breaks=" + IntVectorToString(line_breaks);
657
658 if (!cell_ids.empty())
659 result += " cell_ids=" + IntVectorToString(cell_ids);
660
661 if (recursive) {
662 result += "\n";
663 ++indent;
664 for (size_t i = 0; i < children.size(); ++i)
665 result += children[i].DebugString(true);
666 --indent;
667 }
668
669 return result;
670 }
671
312 void WebAccessibility::Init(const WebKit::WebAccessibilityObject& src, 672 void WebAccessibility::Init(const WebKit::WebAccessibilityObject& src,
313 WebKit::WebAccessibilityCache* cache, 673 WebKit::WebAccessibilityCache* cache,
314 bool include_children) { 674 bool include_children) {
315 name = src.title(); 675 name = src.title();
316 value = src.stringValue();
317 role = ConvertRole(src.roleValue()); 676 role = ConvertRole(src.roleValue());
318 state = ConvertState(src); 677 state = ConvertState(src);
319 location = src.boundingBoxRect(); 678 location = src.boundingBoxRect();
320 679
680 if (src.valueDescription().length())
681 value = src.valueDescription();
682 else
683 value = src.stringValue();
684
685 if (src.accessKey().length())
686 string_attributes[ATTR_ACCESS_KEY] = src.accessKey();
321 if (src.actionVerb().length()) 687 if (src.actionVerb().length())
322 string_attributes[ATTR_ACTION] = src.actionVerb(); 688 string_attributes[ATTR_ACTION] = src.actionVerb();
689 if (src.isButtonStateMixed())
690 bool_attributes[ATTR_BUTTON_MIXED] = true;
323 if (src.accessibilityDescription().length()) 691 if (src.accessibilityDescription().length())
324 string_attributes[ATTR_DESCRIPTION] = src.accessibilityDescription(); 692 string_attributes[ATTR_DESCRIPTION] = src.accessibilityDescription();
693 if (src.hasComputedStyle())
694 string_attributes[ATTR_DISPLAY] = src.computedStyleDisplay();
325 if (src.helpText().length()) 695 if (src.helpText().length())
326 string_attributes[ATTR_HELP] = src.helpText(); 696 string_attributes[ATTR_HELP] = src.helpText();
327 if (src.keyboardShortcut().length()) 697 if (src.keyboardShortcut().length())
328 string_attributes[ATTR_SHORTCUT] = src.keyboardShortcut(); 698 string_attributes[ATTR_SHORTCUT] = src.keyboardShortcut();
329 if (src.hasComputedStyle())
330 string_attributes[ATTR_DISPLAY] = src.computedStyleDisplay();
331 if (!src.url().isEmpty()) 699 if (!src.url().isEmpty())
332 string_attributes[ATTR_URL] = src.url().spec().utf16(); 700 string_attributes[ATTR_URL] = src.url().spec().utf16();
333 701
702 if (role == ROLE_TREE_ITEM)
703 int_attributes[ATTR_HIERARCHICAL_LEVEL] = src.hierarchicalLevel();
704
705 if (role == ROLE_SLIDER)
706 include_children = false;
707
334 WebKit::WebNode node = src.node(); 708 WebKit::WebNode node = src.node();
335 bool is_iframe = false; 709 bool is_iframe = false;
336 710
337 if (!node.isNull() && node.isElementNode()) { 711 if (!node.isNull() && node.isElementNode()) {
338 WebKit::WebElement element = node.to<WebKit::WebElement>(); 712 WebKit::WebElement element = node.to<WebKit::WebElement>();
339 is_iframe = (element.tagName() == ASCIIToUTF16("IFRAME")); 713 is_iframe = (element.tagName() == ASCIIToUTF16("IFRAME"));
340 714
341 // TODO(ctguil): The tagName in WebKit is lower cased but 715 // TODO(ctguil): The tagName in WebKit is lower cased but
342 // HTMLElement::nodeName calls localNameUpper. Consider adding 716 // HTMLElement::nodeName calls localNameUpper. Consider adding
343 // a WebElement method that returns the original lower cased tagName. 717 // a WebElement method that returns the original lower cased tagName.
344 string_attributes[ATTR_HTML_TAG] = 718 string_attributes[ATTR_HTML_TAG] =
345 StringToLowerASCII(string16(element.tagName())); 719 StringToLowerASCII(string16(element.tagName()));
346 for (unsigned i = 0; i < element.attributes().length(); i++) { 720 for (unsigned i = 0; i < element.attributes().length(); ++i) {
347 html_attributes.push_back( 721 string16 name = StringToLowerASCII(string16(
348 std::pair<string16, string16>( 722 element.attributes().attributeItem(i).localName()));
349 element.attributes().attributeItem(i).localName(), 723 string16 value = element.attributes().attributeItem(i).value();
350 element.attributes().attributeItem(i).value())); 724 html_attributes.push_back(std::pair<string16, string16>(name, value));
351 } 725 }
352 726
353 if (element.isFormControlElement()) { 727 if (element.isFormControlElement()) {
354 WebKit::WebFormControlElement form_element = 728 WebKit::WebFormControlElement form_element =
355 element.to<WebKit::WebFormControlElement>(); 729 element.to<WebKit::WebFormControlElement>();
356 if (form_element.formControlType() == ASCIIToUTF16("text") || 730 if (form_element.formControlType() == ASCIIToUTF16("text") ||
357 form_element.formControlType() == ASCIIToUTF16("textarea")) { 731 form_element.formControlType() == ASCIIToUTF16("textarea")) {
358 // Jaws gets confused by children of text fields, so we ignore them. 732 // Jaws gets confused by children of text fields, so we ignore them.
359 include_children = false; 733 include_children = false;
360 734
361 int_attributes[ATTR_TEXT_SEL_START] = src.selectionStart(); 735 int_attributes[ATTR_TEXT_SEL_START] = src.selectionStart();
362 int_attributes[ATTR_TEXT_SEL_END] = src.selectionEnd(); 736 int_attributes[ATTR_TEXT_SEL_END] = src.selectionEnd();
363 WebKit::WebVector<int> src_line_breaks; 737 WebKit::WebVector<int> src_line_breaks;
364 src.lineBreaks(src_line_breaks); 738 src.lineBreaks(src_line_breaks);
365 line_breaks.reserve(src_line_breaks.size()); 739 line_breaks.reserve(src_line_breaks.size());
366 for (size_t i = 0; i < src_line_breaks.size(); i++) 740 for (size_t i = 0; i < src_line_breaks.size(); ++i)
367 line_breaks.push_back(src_line_breaks[i]); 741 line_breaks.push_back(src_line_breaks[i]);
368 } 742 }
369 } 743 }
744
745 // ARIA role.
746 if (element.hasAttribute("role")) {
747 string_attributes[ATTR_ROLE] = element.getAttribute("role");
748 }
749
750 // Live region attributes
751 if (element.hasAttribute("aria-atomic")) {
752 bool_attributes[ATTR_LIVE_ATOMIC] =
753 LowerCaseEqualsASCII(element.getAttribute("aria-atomic"), "true");
754 }
755 if (element.hasAttribute("aria-busy")) {
756 bool_attributes[ATTR_LIVE_BUSY] =
757 LowerCaseEqualsASCII(element.getAttribute("aria-busy"), "true");
758 }
759 if (element.hasAttribute("aria-live")) {
760 string_attributes[ATTR_LIVE_STATUS] = element.getAttribute("aria-live");
761 }
762 if (element.hasAttribute("aria-relevant")) {
763 string_attributes[ATTR_LIVE_RELEVANT] =
764 element.getAttribute("aria-relevant");
765 }
766 }
767
768 // Walk up the parent chain to set live region attributes of containers
769
770 WebKit::WebAccessibilityObject container_accessible = src;
771 while (!container_accessible.isNull()) {
772 WebKit::WebNode container_node = container_accessible.node();
773 if (!container_node.isNull() && container_node.isElementNode()) {
774 WebKit::WebElement container_elem =
775 container_node.to<WebKit::WebElement>();
776 if (container_elem.hasAttribute("aria-atomic") &&
777 bool_attributes.find(ATTR_CONTAINER_LIVE_ATOMIC) ==
778 bool_attributes.end()) {
779 bool_attributes[ATTR_CONTAINER_LIVE_ATOMIC] =
780 LowerCaseEqualsASCII(container_elem.getAttribute("aria-atomic"),
781 "true");
782 }
783 if (container_elem.hasAttribute("aria-busy") &&
784 bool_attributes.find(ATTR_CONTAINER_LIVE_BUSY) ==
785 bool_attributes.end()) {
786 bool_attributes[ATTR_CONTAINER_LIVE_BUSY] =
787 LowerCaseEqualsASCII(container_elem.getAttribute("aria-busy"),
788 "true");
789 }
790 if (container_elem.hasAttribute("aria-live") &&
791 string_attributes.find(ATTR_CONTAINER_LIVE_STATUS) ==
792 string_attributes.end()) {
793 string_attributes[ATTR_CONTAINER_LIVE_STATUS] =
794 container_elem.getAttribute("aria-live");
795 }
796 if (container_elem.hasAttribute("aria-relevant") &&
797 string_attributes.find(ATTR_CONTAINER_LIVE_RELEVANT) ==
798 string_attributes.end()) {
799 string_attributes[ATTR_CONTAINER_LIVE_RELEVANT] =
800 container_elem.getAttribute("aria-relevant");
801 }
802 }
803 container_accessible = container_accessible.parentObject();
804 }
805
806 if (role == WebAccessibility::ROLE_PROGRESS_INDICATOR ||
807 role == WebAccessibility::ROLE_SCROLLBAR ||
808 role == WebAccessibility::ROLE_SLIDER) {
809 float_attributes[ATTR_VALUE_FOR_RANGE] = src.valueForRange();
810 float_attributes[ATTR_MAX_VALUE_FOR_RANGE] = src.minValueForRange();
811 float_attributes[ATTR_MIN_VALUE_FOR_RANGE] = src.maxValueForRange();
370 } 812 }
371 813
372 if (role == WebAccessibility::ROLE_DOCUMENT || 814 if (role == WebAccessibility::ROLE_DOCUMENT ||
373 role == WebAccessibility::ROLE_WEB_AREA) { 815 role == WebAccessibility::ROLE_WEB_AREA) {
374 const WebKit::WebDocument& document = src.document(); 816 const WebKit::WebDocument& document = src.document();
375 if (name.empty()) 817 if (name.empty())
376 name = document.title(); 818 name = document.title();
377 string_attributes[ATTR_DOC_TITLE] = document.title(); 819 string_attributes[ATTR_DOC_TITLE] = document.title();
378 string_attributes[ATTR_DOC_URL] = document.url().spec().utf16(); 820 string_attributes[ATTR_DOC_URL] = document.url().spec().utf16();
379 if (document.isXHTMLDocument()) 821 if (document.isXHTMLDocument())
380 string_attributes[ATTR_DOC_MIMETYPE] = WebKit::WebString("text/xhtml"); 822 string_attributes[ATTR_DOC_MIMETYPE] = WebKit::WebString("text/xhtml");
381 else 823 else
382 string_attributes[ATTR_DOC_MIMETYPE] = WebKit::WebString("text/html"); 824 string_attributes[ATTR_DOC_MIMETYPE] = WebKit::WebString("text/html");
825 bool_attributes[ATTR_DOC_LOADED] = src.isLoaded();
826 float_attributes[ATTR_DOC_LOADING_PROGRESS] =
827 src.estimatedLoadingProgress();
383 828
384 const WebKit::WebDocumentType& doctype = document.doctype(); 829 const WebKit::WebDocumentType& doctype = document.doctype();
385 if (!doctype.isNull()) 830 if (!doctype.isNull())
386 string_attributes[ATTR_DOC_DOCTYPE] = doctype.name(); 831 string_attributes[ATTR_DOC_DOCTYPE] = doctype.name();
387 832
388 const gfx::Size& scroll_offset = document.frame()->scrollOffset(); 833 const gfx::Size& scroll_offset = document.frame()->scrollOffset();
389 int_attributes[ATTR_DOC_SCROLLX] = scroll_offset.width(); 834 int_attributes[ATTR_DOC_SCROLLX] = scroll_offset.width();
390 int_attributes[ATTR_DOC_SCROLLY] = scroll_offset.height(); 835 int_attributes[ATTR_DOC_SCROLLY] = scroll_offset.height();
391 } 836 }
392 837
393 if (role == WebAccessibility::ROLE_TABLE) { 838 if (role == WebAccessibility::ROLE_TABLE) {
394 int column_count = src.columnCount(); 839 int column_count = src.columnCount();
395 int row_count = src.rowCount(); 840 int row_count = src.rowCount();
396 if (column_count > 0 && row_count > 0) { 841 if (column_count > 0 && row_count > 0) {
842 std::set<int> unique_cell_id_set;
397 int_attributes[ATTR_TABLE_COLUMN_COUNT] = column_count; 843 int_attributes[ATTR_TABLE_COLUMN_COUNT] = column_count;
398 int_attributes[ATTR_TABLE_ROW_COUNT] = row_count; 844 int_attributes[ATTR_TABLE_ROW_COUNT] = row_count;
399 for (int i = 0; i < column_count * row_count; i++) { 845 for (int i = 0; i < column_count * row_count; ++i) {
400 WebAccessibilityObject cell = src.cellForColumnAndRow( 846 WebAccessibilityObject cell = src.cellForColumnAndRow(
401 i % column_count, i / column_count); 847 i % column_count, i / column_count);
402 int cell_id = -1; 848 int cell_id = -1;
403 if (!cell.isNull()) 849 if (!cell.isNull()) {
404 cell_id = cache->addOrGetId(cell); 850 cell_id = cache->addOrGetId(cell);
851 if (unique_cell_id_set.find(cell_id) == unique_cell_id_set.end()) {
852 unique_cell_id_set.insert(cell_id);
853 unique_cell_ids.push_back(cell_id);
854 }
855 }
405 cell_ids.push_back(cell_id); 856 cell_ids.push_back(cell_id);
406 } 857 }
407 } 858 }
408 } 859 }
409 860
410 if (role == WebAccessibility::ROLE_CELL || 861 if (role == WebAccessibility::ROLE_CELL ||
411 role == WebAccessibility::ROLE_ROW_HEADER || 862 role == WebAccessibility::ROLE_ROW_HEADER ||
412 role == WebAccessibility::ROLE_COLUMN_HEADER) { 863 role == WebAccessibility::ROLE_COLUMN_HEADER) {
413 int_attributes[ATTR_TABLE_CELL_COLUMN_INDEX] = src.cellColumnIndex(); 864 int_attributes[ATTR_TABLE_CELL_COLUMN_INDEX] = src.cellColumnIndex();
414 int_attributes[ATTR_TABLE_CELL_COLUMN_SPAN] = src.cellColumnSpan(); 865 int_attributes[ATTR_TABLE_CELL_COLUMN_SPAN] = src.cellColumnSpan();
415 int_attributes[ATTR_TABLE_CELL_ROW_INDEX] = src.cellRowIndex(); 866 int_attributes[ATTR_TABLE_CELL_ROW_INDEX] = src.cellRowIndex();
416 int_attributes[ATTR_TABLE_CELL_ROW_SPAN] = src.cellRowSpan(); 867 int_attributes[ATTR_TABLE_CELL_ROW_SPAN] = src.cellRowSpan();
417 } 868 }
418 869
419 // Add the source object to the cache and store its id. 870 // Add the source object to the cache and store its id.
420 id = cache->addOrGetId(src); 871 id = cache->addOrGetId(src);
421 872
422 if (include_children) { 873 if (include_children) {
423 // Recursively create children. 874 // Recursively create children.
424 int child_count = src.childCount(); 875 int child_count = src.childCount();
425 std::set<int32> child_ids; 876 std::set<int32> child_ids;
426 for (int i = 0; i < child_count; i++) { 877 for (int i = 0; i < child_count; ++i) {
427 WebAccessibilityObject child = src.childAt(i); 878 WebAccessibilityObject child = src.childAt(i);
428 int32 child_id = cache->addOrGetId(child); 879 int32 child_id = cache->addOrGetId(child);
429 880
430 // The child may be invalid due to issues in webkit accessibility code. 881 // The child may be invalid due to issues in webkit accessibility code.
431 // Don't add children that are invalid thus preventing a crash. 882 // Don't add children that are invalid thus preventing a crash.
432 // https://bugs.webkit.org/show_bug.cgi?id=44149 883 // https://bugs.webkit.org/show_bug.cgi?id=44149
433 // TODO(ctguil): We may want to remove this check as webkit stabilizes. 884 // TODO(ctguil): We may want to remove this check as webkit stabilizes.
434 if (!child.isValid()) 885 if (!child.isValid())
435 continue; 886 continue;
436 887
(...skipping 24 matching lines...) Expand all
461 bool WebAccessibility::IsParentUnignoredOf( 912 bool WebAccessibility::IsParentUnignoredOf(
462 const WebKit::WebAccessibilityObject& ancestor, 913 const WebKit::WebAccessibilityObject& ancestor,
463 const WebKit::WebAccessibilityObject& child) { 914 const WebKit::WebAccessibilityObject& child) {
464 WebKit::WebAccessibilityObject parent = child.parentObject(); 915 WebKit::WebAccessibilityObject parent = child.parentObject();
465 while (!parent.isNull() && parent.accessibilityIsIgnored()) 916 while (!parent.isNull() && parent.accessibilityIsIgnored())
466 parent = parent.parentObject(); 917 parent = parent.parentObject();
467 return parent.equals(ancestor); 918 return parent.equals(ancestor);
468 } 919 }
469 920
470 } // namespace webkit_glue 921 } // namespace webkit_glue
OLDNEW
« no previous file with comments | « webkit/glue/webaccessibility.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698