OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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 "chrome/browser/browser_accessibility_win.h" | 5 #include "chrome/browser/browser_accessibility_win.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 #include "base/string_util.h" | |
9 #include "base/utf_string_conversions.h" | |
10 #include "chrome/browser/browser_accessibility_manager_win.h" | 8 #include "chrome/browser/browser_accessibility_manager_win.h" |
11 #include "net/base/escape.h" | |
12 | 9 |
13 using webkit_glue::WebAccessibility; | 10 using webkit_glue::WebAccessibility; |
14 | 11 |
15 BrowserAccessibility::BrowserAccessibility() | 12 BrowserAccessibility::BrowserAccessibility() |
16 : manager_(NULL), | 13 : manager_(NULL), |
17 parent_(NULL), | 14 parent_(NULL), |
18 child_id_(-1), | 15 child_id_(-1), |
19 index_in_parent_(-1), | 16 index_in_parent_(-1), |
20 renderer_id_(-1), | 17 renderer_id_(-1), |
21 instance_active_(false) { | 18 instance_active_(false) { |
(...skipping 13 matching lines...) Expand all Loading... |
35 | 32 |
36 manager_ = manager; | 33 manager_ = manager; |
37 parent_ = parent; | 34 parent_ = parent; |
38 child_id_ = child_id; | 35 child_id_ = child_id; |
39 index_in_parent_ = index_in_parent; | 36 index_in_parent_ = index_in_parent; |
40 | 37 |
41 renderer_id_ = src.id; | 38 renderer_id_ = src.id; |
42 name_ = src.name; | 39 name_ = src.name; |
43 value_ = src.value; | 40 value_ = src.value; |
44 attributes_ = src.attributes; | 41 attributes_ = src.attributes; |
45 html_attributes_ = src.html_attributes; | |
46 location_ = src.location; | 42 location_ = src.location; |
47 InitRoleAndState(src.role, src.state); | 43 InitRoleAndState(src.role, src.state); |
48 | 44 |
49 // If this object doesn't have a name but it does have a description, | 45 // If this object doesn't have a name but it does have a description, |
50 // use the description as its name - because some screen readers only | 46 // use the description as its name - because some screen readers only |
51 // announce the name. | 47 // announce the name. |
52 if (name_.empty() && HasAttribute(WebAccessibility::ATTR_DESCRIPTION)) { | 48 if (name_.empty() && HasAttribute(WebAccessibility::ATTR_DESCRIPTION)) { |
53 GetAttribute(WebAccessibility::ATTR_DESCRIPTION, &name_); | 49 GetAttribute(WebAccessibility::ATTR_DESCRIPTION, &name_); |
54 } | 50 } |
55 | 51 |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
102 | 98 |
103 BrowserAccessibility* BrowserAccessibility::GetPreviousSibling() { | 99 BrowserAccessibility* BrowserAccessibility::GetPreviousSibling() { |
104 if (parent_ && index_in_parent_ > 0) | 100 if (parent_ && index_in_parent_ > 0) |
105 return parent_->children_[index_in_parent_ - 1]; | 101 return parent_->children_[index_in_parent_ - 1]; |
106 | 102 |
107 return NULL; | 103 return NULL; |
108 } | 104 } |
109 | 105 |
110 BrowserAccessibility* BrowserAccessibility::GetNextSibling() { | 106 BrowserAccessibility* BrowserAccessibility::GetNextSibling() { |
111 if (parent_ && | 107 if (parent_ && |
112 index_in_parent_ >= 0 && | |
113 index_in_parent_ < static_cast<int>(parent_->children_.size() - 1)) { | 108 index_in_parent_ < static_cast<int>(parent_->children_.size() - 1)) { |
114 return parent_->children_[index_in_parent_ + 1]; | 109 return parent_->children_[index_in_parent_ + 1]; |
115 } | 110 } |
116 | 111 |
117 return NULL; | 112 return NULL; |
118 } | 113 } |
119 | 114 |
120 void BrowserAccessibility::ReplaceChild( | 115 void BrowserAccessibility::ReplaceChild( |
121 const BrowserAccessibility* old_acc, BrowserAccessibility* new_acc) { | 116 const BrowserAccessibility* old_acc, BrowserAccessibility* new_acc) { |
122 DCHECK_EQ(children_[old_acc->index_in_parent_], old_acc); | 117 DCHECK_EQ(children_[old_acc->index_in_parent_], old_acc); |
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
269 if (!instance_active_) | 264 if (!instance_active_) |
270 return E_FAIL; | 265 return E_FAIL; |
271 | 266 |
272 if (!def_action) | 267 if (!def_action) |
273 return E_INVALIDARG; | 268 return E_INVALIDARG; |
274 | 269 |
275 BrowserAccessibility* target = GetTargetFromChildID(var_id); | 270 BrowserAccessibility* target = GetTargetFromChildID(var_id); |
276 if (!target) | 271 if (!target) |
277 return E_INVALIDARG; | 272 return E_INVALIDARG; |
278 | 273 |
279 return target->GetAttributeAsBstr( | 274 string16 action; |
280 WebAccessibility::ATTR_SHORTCUT, def_action); | 275 if (!target->GetAttribute(WebAccessibility::ATTR_SHORTCUT, &action)) |
| 276 return S_FALSE; |
| 277 |
| 278 if (action.empty()) |
| 279 return S_FALSE; |
| 280 |
| 281 *def_action = SysAllocString(action.c_str()); |
| 282 |
| 283 DCHECK(*def_action); |
| 284 return S_OK; |
281 } | 285 } |
282 | 286 |
283 STDMETHODIMP BrowserAccessibility::get_accDescription(VARIANT var_id, | 287 STDMETHODIMP BrowserAccessibility::get_accDescription(VARIANT var_id, |
284 BSTR* desc) { | 288 BSTR* desc) { |
285 if (!instance_active_) | 289 if (!instance_active_) |
286 return E_FAIL; | 290 return E_FAIL; |
287 | 291 |
288 if (!desc) | 292 if (!desc) |
289 return E_INVALIDARG; | 293 return E_INVALIDARG; |
290 | 294 |
291 BrowserAccessibility* target = GetTargetFromChildID(var_id); | 295 BrowserAccessibility* target = GetTargetFromChildID(var_id); |
292 if (!target) | 296 if (!target) |
293 return E_INVALIDARG; | 297 return E_INVALIDARG; |
294 | 298 |
295 return target->GetAttributeAsBstr(WebAccessibility::ATTR_DESCRIPTION, desc); | 299 string16 description; |
| 300 if (!target->GetAttribute(WebAccessibility::ATTR_DESCRIPTION, &description)) |
| 301 return S_FALSE; |
| 302 |
| 303 if (description.empty()) |
| 304 return S_FALSE; |
| 305 |
| 306 *desc = SysAllocString(description.c_str()); |
| 307 |
| 308 DCHECK(*desc); |
| 309 return S_OK; |
296 } | 310 } |
297 | 311 |
298 STDMETHODIMP BrowserAccessibility::get_accFocus(VARIANT* focus_child) { | 312 STDMETHODIMP BrowserAccessibility::get_accFocus(VARIANT* focus_child) { |
299 if (!instance_active_) | 313 if (!instance_active_) |
300 return E_FAIL; | 314 return E_FAIL; |
301 | 315 |
302 if (!focus_child) | 316 if (!focus_child) |
303 return E_INVALIDARG; | 317 return E_INVALIDARG; |
304 | 318 |
305 BrowserAccessibility* focus = manager_->GetFocus(this); | 319 BrowserAccessibility* focus = manager_->GetFocus(this); |
(...skipping 14 matching lines...) Expand all Loading... |
320 if (!instance_active_) | 334 if (!instance_active_) |
321 return E_FAIL; | 335 return E_FAIL; |
322 | 336 |
323 if (!help) | 337 if (!help) |
324 return E_INVALIDARG; | 338 return E_INVALIDARG; |
325 | 339 |
326 BrowserAccessibility* target = GetTargetFromChildID(var_id); | 340 BrowserAccessibility* target = GetTargetFromChildID(var_id); |
327 if (!target) | 341 if (!target) |
328 return E_INVALIDARG; | 342 return E_INVALIDARG; |
329 | 343 |
330 return target->GetAttributeAsBstr(WebAccessibility::ATTR_HELP, help); | 344 string16 help_str; |
| 345 if (!target->GetAttribute(WebAccessibility::ATTR_HELP, &help_str)) |
| 346 return S_FALSE; |
| 347 |
| 348 if (help_str.empty()) |
| 349 return S_FALSE; |
| 350 |
| 351 *help = SysAllocString(help_str.c_str()); |
| 352 |
| 353 DCHECK(*help); |
| 354 return S_OK; |
331 } | 355 } |
332 | 356 |
333 STDMETHODIMP BrowserAccessibility::get_accKeyboardShortcut(VARIANT var_id, | 357 STDMETHODIMP BrowserAccessibility::get_accKeyboardShortcut(VARIANT var_id, |
334 BSTR* acc_key) { | 358 BSTR* acc_key) { |
335 if (!instance_active_) | 359 if (!instance_active_) |
336 return E_FAIL; | 360 return E_FAIL; |
337 | 361 |
338 if (!acc_key) | 362 if (!acc_key) |
339 return E_INVALIDARG; | 363 return E_INVALIDARG; |
340 | 364 |
341 BrowserAccessibility* target = GetTargetFromChildID(var_id); | 365 BrowserAccessibility* target = GetTargetFromChildID(var_id); |
342 if (!target) | 366 if (!target) |
343 return E_INVALIDARG; | 367 return E_INVALIDARG; |
344 | 368 |
345 return target->GetAttributeAsBstr(WebAccessibility::ATTR_SHORTCUT, acc_key); | 369 string16 shortcut; |
| 370 if (!target->GetAttribute(WebAccessibility::ATTR_SHORTCUT, &shortcut)) |
| 371 return S_FALSE; |
| 372 |
| 373 if (shortcut.empty()) |
| 374 return S_FALSE; |
| 375 |
| 376 *acc_key = SysAllocString(shortcut.c_str()); |
| 377 |
| 378 DCHECK(*acc_key); |
| 379 return S_OK; |
346 } | 380 } |
347 | 381 |
348 STDMETHODIMP BrowserAccessibility::get_accName(VARIANT var_id, BSTR* name) { | 382 STDMETHODIMP BrowserAccessibility::get_accName(VARIANT var_id, BSTR* name) { |
349 if (!instance_active_) | 383 if (!instance_active_) |
350 return E_FAIL; | 384 return E_FAIL; |
351 | 385 |
352 if (!name) | 386 if (!name) |
353 return E_INVALIDARG; | 387 return E_INVALIDARG; |
354 | 388 |
355 BrowserAccessibility* target = GetTargetFromChildID(var_id); | 389 BrowserAccessibility* target = GetTargetFromChildID(var_id); |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
483 return S_OK; | 517 return S_OK; |
484 } | 518 } |
485 | 519 |
486 STDMETHODIMP BrowserAccessibility::get_attributes(BSTR* attributes) { | 520 STDMETHODIMP BrowserAccessibility::get_attributes(BSTR* attributes) { |
487 if (!instance_active_) | 521 if (!instance_active_) |
488 return E_FAIL; | 522 return E_FAIL; |
489 | 523 |
490 if (!attributes) | 524 if (!attributes) |
491 return E_INVALIDARG; | 525 return E_INVALIDARG; |
492 | 526 |
493 // Follow Firefox's convention, which is to return a set of key-value pairs | 527 return S_FALSE; |
494 // separated by semicolons, with a colon between the key and the value. | |
495 string16 str; | |
496 for (unsigned int i = 0; i < html_attributes_.size(); i++) { | |
497 if (i != 0) | |
498 str += L';'; | |
499 str += Escape(html_attributes_[i].first); | |
500 str += L':'; | |
501 str += Escape(html_attributes_[i].second); | |
502 } | |
503 | |
504 if (str.empty()) | |
505 return S_FALSE; | |
506 | |
507 *attributes = SysAllocString(str.c_str()); | |
508 DCHECK(*attributes); | |
509 return S_OK; | |
510 } | 528 } |
511 | 529 |
512 STDMETHODIMP BrowserAccessibility::get_states(AccessibleStates* states) { | 530 STDMETHODIMP BrowserAccessibility::get_states(AccessibleStates* states) { |
513 if (!instance_active_) | 531 if (!instance_active_) |
514 return E_FAIL; | 532 return E_FAIL; |
515 | 533 |
516 if (!states) | 534 if (!states) |
517 return E_INVALIDARG; | 535 return E_INVALIDARG; |
518 | 536 |
519 *states = ia2_state_; | 537 *states = ia2_state_; |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
558 // IAccessibleImage methods. | 576 // IAccessibleImage methods. |
559 // | 577 // |
560 | 578 |
561 STDMETHODIMP BrowserAccessibility::get_description(BSTR* desc) { | 579 STDMETHODIMP BrowserAccessibility::get_description(BSTR* desc) { |
562 if (!instance_active_) | 580 if (!instance_active_) |
563 return E_FAIL; | 581 return E_FAIL; |
564 | 582 |
565 if (!desc) | 583 if (!desc) |
566 return E_INVALIDARG; | 584 return E_INVALIDARG; |
567 | 585 |
568 return GetAttributeAsBstr(WebAccessibility::ATTR_DESCRIPTION, desc); | 586 string16 description; |
| 587 if (!GetAttribute(WebAccessibility::ATTR_DESCRIPTION, &description)) |
| 588 return S_FALSE; |
| 589 |
| 590 if (description.empty()) |
| 591 return S_FALSE; |
| 592 |
| 593 *desc = SysAllocString(description.c_str()); |
| 594 |
| 595 DCHECK(*desc); |
| 596 return S_OK; |
569 } | 597 } |
570 | 598 |
571 STDMETHODIMP BrowserAccessibility::get_imagePosition( | 599 STDMETHODIMP BrowserAccessibility::get_imagePosition( |
572 enum IA2CoordinateType coordinate_type, long* x, long* y) { | 600 enum IA2CoordinateType coordinate_type, long* x, long* y) { |
573 if (!instance_active_) | 601 if (!instance_active_) |
574 return E_FAIL; | 602 return E_FAIL; |
575 | 603 |
576 if (!x || !y) | 604 if (!x || !y) |
577 return E_INVALIDARG; | 605 return E_INVALIDARG; |
578 | 606 |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
630 | 658 |
631 if (!text) | 659 if (!text) |
632 return E_INVALIDARG; | 660 return E_INVALIDARG; |
633 | 661 |
634 long len = name_.length(); | 662 long len = name_.length(); |
635 if (start_offset < 0) | 663 if (start_offset < 0) |
636 start_offset = 0; | 664 start_offset = 0; |
637 if (end_offset > len) | 665 if (end_offset > len) |
638 end_offset = len; | 666 end_offset = len; |
639 | 667 |
640 string16 substr = name_.substr(start_offset, end_offset - start_offset); | 668 *text = SysAllocString( |
641 if (substr.empty()) | 669 name_.substr(start_offset, end_offset - start_offset).c_str()); |
642 return S_FALSE; | |
643 | |
644 *text = SysAllocString(substr.c_str()); | |
645 DCHECK(*text); | |
646 return S_OK; | 670 return S_OK; |
647 } | 671 } |
648 | 672 |
649 STDMETHODIMP BrowserAccessibility::get_caretOffset(long* offset) { | 673 STDMETHODIMP BrowserAccessibility::get_caretOffset(long* offset) { |
650 if (!instance_active_) | |
651 return E_FAIL; | |
652 | |
653 if (!offset) | |
654 return E_INVALIDARG; | |
655 | |
656 *offset = 0; | 674 *offset = 0; |
657 return S_OK; | 675 return S_OK; |
658 } | 676 } |
659 | 677 |
660 // | 678 // |
661 // ISimpleDOMDocument methods. | |
662 // | |
663 | |
664 STDMETHODIMP BrowserAccessibility::get_URL(BSTR* url) { | |
665 if (!instance_active_) | |
666 return E_FAIL; | |
667 | |
668 if (!url) | |
669 return E_INVALIDARG; | |
670 | |
671 return GetAttributeAsBstr(WebAccessibility::ATTR_DOC_URL, url); | |
672 } | |
673 | |
674 STDMETHODIMP BrowserAccessibility::get_title(BSTR* title) { | |
675 if (!instance_active_) | |
676 return E_FAIL; | |
677 | |
678 if (!title) | |
679 return E_INVALIDARG; | |
680 | |
681 return GetAttributeAsBstr(WebAccessibility::ATTR_DOC_TITLE, title); | |
682 } | |
683 | |
684 STDMETHODIMP BrowserAccessibility::get_mimeType(BSTR* mime_type) { | |
685 if (!instance_active_) | |
686 return E_FAIL; | |
687 | |
688 if (!mime_type) | |
689 return E_INVALIDARG; | |
690 | |
691 return GetAttributeAsBstr(WebAccessibility::ATTR_DOC_MIMETYPE, mime_type); | |
692 } | |
693 | |
694 STDMETHODIMP BrowserAccessibility::get_docType(BSTR* doc_type) { | |
695 if (!instance_active_) | |
696 return E_FAIL; | |
697 | |
698 if (!doc_type) | |
699 return E_INVALIDARG; | |
700 | |
701 return GetAttributeAsBstr(WebAccessibility::ATTR_DOC_DOCTYPE, doc_type); | |
702 } | |
703 | |
704 // | |
705 // ISimpleDOMNode methods. | |
706 // | |
707 | |
708 STDMETHODIMP BrowserAccessibility::get_nodeInfo( | |
709 BSTR* node_name, | |
710 short* name_space_id, | |
711 BSTR* node_value, | |
712 unsigned int* num_children, | |
713 unsigned int* unique_id, | |
714 unsigned short* node_type) { | |
715 if (!instance_active_) | |
716 return E_FAIL; | |
717 | |
718 if (!node_name || !name_space_id || !node_value || !num_children || | |
719 !unique_id || !node_type) { | |
720 return E_INVALIDARG; | |
721 } | |
722 | |
723 string16 tag; | |
724 if (GetAttribute(WebAccessibility::ATTR_HTML_TAG, &tag)) | |
725 *node_name = SysAllocString(tag.c_str()); | |
726 else | |
727 *node_name = NULL; | |
728 | |
729 *name_space_id = 0; | |
730 *node_value = SysAllocString(value_.c_str()); | |
731 *num_children = children_.size(); | |
732 *unique_id = child_id_; | |
733 | |
734 if (role_ == ROLE_SYSTEM_DOCUMENT) { | |
735 *node_type = NODETYPE_DOCUMENT; | |
736 } else if (role_ == ROLE_SYSTEM_TEXT && | |
737 ((ia2_state_ & IA2_STATE_EDITABLE) == 0)) { | |
738 *node_type = NODETYPE_TEXT; | |
739 } else { | |
740 *node_type = NODETYPE_ELEMENT; | |
741 } | |
742 | |
743 return S_OK; | |
744 } | |
745 | |
746 STDMETHODIMP BrowserAccessibility::get_attributes( | |
747 unsigned short max_attribs, | |
748 BSTR* attrib_names, | |
749 short* name_space_id, | |
750 BSTR* attrib_values, | |
751 unsigned short* num_attribs) { | |
752 if (!instance_active_) | |
753 return E_FAIL; | |
754 | |
755 if (!attrib_names || !name_space_id || !attrib_values || !num_attribs) | |
756 return E_INVALIDARG; | |
757 | |
758 *num_attribs = max_attribs; | |
759 if (*num_attribs > html_attributes_.size()) | |
760 *num_attribs = html_attributes_.size(); | |
761 | |
762 for (unsigned short i = 0; i < *num_attribs; ++i) { | |
763 attrib_names[i] = SysAllocString(html_attributes_[i].first.c_str()); | |
764 name_space_id[i] = 0; | |
765 attrib_values[i] = SysAllocString(html_attributes_[i].second.c_str()); | |
766 } | |
767 return S_OK; | |
768 } | |
769 | |
770 STDMETHODIMP BrowserAccessibility::get_attributesForNames( | |
771 unsigned short num_attribs, | |
772 BSTR* attrib_names, | |
773 short* name_space_id, | |
774 BSTR* attrib_values) { | |
775 if (!instance_active_) | |
776 return E_FAIL; | |
777 | |
778 if (!attrib_names || !name_space_id || !attrib_values) | |
779 return E_INVALIDARG; | |
780 | |
781 for (unsigned short i = 0; i < num_attribs; ++i) { | |
782 name_space_id[i] = 0; | |
783 bool found = false; | |
784 string16 name = (LPCWSTR)attrib_names[i]; | |
785 for (unsigned int j = 0; j < html_attributes_.size(); ++j) { | |
786 if (html_attributes_[j].first == name) { | |
787 attrib_values[i] = SysAllocString(html_attributes_[j].second.c_str()); | |
788 found = true; | |
789 break; | |
790 } | |
791 } | |
792 if (!found) { | |
793 attrib_values[i] = NULL; | |
794 } | |
795 } | |
796 return S_OK; | |
797 } | |
798 | |
799 STDMETHODIMP BrowserAccessibility::get_computedStyle( | |
800 unsigned short max_style_properties, | |
801 boolean use_alternate_view, | |
802 BSTR *style_properties, | |
803 BSTR *style_values, | |
804 unsigned short *num_style_properties) { | |
805 if (!instance_active_) | |
806 return E_FAIL; | |
807 | |
808 if (!style_properties || !style_values) | |
809 return E_INVALIDARG; | |
810 | |
811 // We only cache a single style property for now: DISPLAY | |
812 | |
813 if (max_style_properties == 0 || | |
814 !HasAttribute(WebAccessibility::ATTR_DISPLAY)) { | |
815 *num_style_properties = 0; | |
816 return S_OK; | |
817 } | |
818 | |
819 string16 display; | |
820 GetAttribute(WebAccessibility::ATTR_DISPLAY, &display); | |
821 *num_style_properties = 1; | |
822 style_properties[0] = SysAllocString(L"display"); | |
823 style_values[0] = SysAllocString(display.c_str()); | |
824 | |
825 return S_OK; | |
826 } | |
827 | |
828 STDMETHODIMP BrowserAccessibility::get_computedStyleForProperties( | |
829 unsigned short num_style_properties, | |
830 boolean use_alternate_view, | |
831 BSTR* style_properties, | |
832 BSTR* style_values) { | |
833 if (!instance_active_) | |
834 return E_FAIL; | |
835 | |
836 if (!style_properties || !style_values) | |
837 return E_INVALIDARG; | |
838 | |
839 // We only cache a single style property for now: DISPLAY | |
840 | |
841 for (unsigned short i = 0; i < num_style_properties; i++) { | |
842 string16 name = (LPCWSTR)style_properties[i]; | |
843 StringToLowerASCII(&name); | |
844 if (name == L"display") { | |
845 string16 display; | |
846 GetAttribute(WebAccessibility::ATTR_DISPLAY, &display); | |
847 style_values[i] = SysAllocString(display.c_str()); | |
848 } else { | |
849 style_values[i] = NULL; | |
850 } | |
851 } | |
852 | |
853 return S_OK; | |
854 } | |
855 | |
856 STDMETHODIMP BrowserAccessibility::scrollTo(boolean placeTopLeft) { | |
857 return E_NOTIMPL; | |
858 } | |
859 | |
860 STDMETHODIMP BrowserAccessibility::get_parentNode(ISimpleDOMNode** node) { | |
861 if (!instance_active_) | |
862 return E_FAIL; | |
863 | |
864 if (!node) | |
865 return E_INVALIDARG; | |
866 | |
867 *node = parent_->NewReference(); | |
868 return S_OK; | |
869 } | |
870 | |
871 STDMETHODIMP BrowserAccessibility::get_firstChild(ISimpleDOMNode** node) { | |
872 if (!instance_active_) | |
873 return E_FAIL; | |
874 | |
875 if (!node) | |
876 return E_INVALIDARG; | |
877 | |
878 if (children_.size()) { | |
879 *node = children_[0]->NewReference(); | |
880 return S_OK; | |
881 } else { | |
882 *node = NULL; | |
883 return S_FALSE; | |
884 } | |
885 } | |
886 | |
887 STDMETHODIMP BrowserAccessibility::get_lastChild(ISimpleDOMNode** node) { | |
888 if (!instance_active_) | |
889 return E_FAIL; | |
890 | |
891 if (!node) | |
892 return E_INVALIDARG; | |
893 | |
894 if (children_.size()) { | |
895 *node = children_[children_.size() - 1]->NewReference(); | |
896 return S_OK; | |
897 } else { | |
898 *node = NULL; | |
899 return S_FALSE; | |
900 } | |
901 } | |
902 | |
903 STDMETHODIMP BrowserAccessibility::get_previousSibling( | |
904 ISimpleDOMNode** node) { | |
905 if (!instance_active_) | |
906 return E_FAIL; | |
907 | |
908 if (!node) | |
909 return E_INVALIDARG; | |
910 | |
911 if (parent_ && index_in_parent_ > 0) { | |
912 *node = parent_->children_[index_in_parent_ - 1]->NewReference(); | |
913 return S_OK; | |
914 } else { | |
915 *node = NULL; | |
916 return S_FALSE; | |
917 } | |
918 } | |
919 | |
920 STDMETHODIMP BrowserAccessibility::get_nextSibling(ISimpleDOMNode** node) { | |
921 if (!instance_active_) | |
922 return E_FAIL; | |
923 | |
924 if (!node) | |
925 return E_INVALIDARG; | |
926 | |
927 if (parent_ && | |
928 index_in_parent_ >= 0 && | |
929 index_in_parent_ < static_cast<int>(parent_->children_.size()) - 1) { | |
930 *node = parent_->children_[index_in_parent_ + 1]->NewReference(); | |
931 return S_OK; | |
932 } else { | |
933 *node = NULL; | |
934 return S_FALSE; | |
935 } | |
936 } | |
937 | |
938 STDMETHODIMP BrowserAccessibility::get_childAt( | |
939 unsigned int child_index, | |
940 ISimpleDOMNode** node) { | |
941 if (!instance_active_) | |
942 return E_FAIL; | |
943 | |
944 if (!node) | |
945 return E_INVALIDARG; | |
946 | |
947 if (child_index < children_.size()) { | |
948 *node = children_[child_index]->NewReference(); | |
949 return S_OK; | |
950 } else { | |
951 *node = NULL; | |
952 return S_FALSE; | |
953 } | |
954 } | |
955 | |
956 // | |
957 // ISimpleDOMText methods. | |
958 // | |
959 | |
960 STDMETHODIMP BrowserAccessibility::get_domText(BSTR* dom_text) { | |
961 if (!instance_active_) | |
962 return E_FAIL; | |
963 | |
964 if (!dom_text) | |
965 return E_INVALIDARG; | |
966 | |
967 if (name_.empty()) | |
968 return S_FALSE; | |
969 | |
970 *dom_text = SysAllocString(name_.c_str()); | |
971 DCHECK(*dom_text); | |
972 return S_OK; | |
973 } | |
974 | |
975 // | |
976 // IServiceProvider methods. | 679 // IServiceProvider methods. |
977 // | 680 // |
978 | 681 |
979 STDMETHODIMP BrowserAccessibility::QueryService( | 682 STDMETHODIMP BrowserAccessibility::QueryService( |
980 REFGUID guidService, REFIID riid, void** object) { | 683 REFGUID guidService, REFIID riid, void** object) { |
981 if (!instance_active_) | 684 if (!instance_active_) |
982 return E_FAIL; | 685 return E_FAIL; |
983 | 686 |
984 if (guidService == IID_IAccessible || | 687 if (guidService == IID_IAccessible || guidService == IID_IAccessible2) |
985 guidService == IID_IAccessible2 || | |
986 guidService == IID_IAccessibleImage || | |
987 guidService == IID_IAccessibleText || | |
988 guidService == IID_ISimpleDOMDocument || | |
989 guidService == IID_ISimpleDOMNode || | |
990 guidService == IID_ISimpleDOMText) { | |
991 return QueryInterface(riid, object); | 688 return QueryInterface(riid, object); |
992 } | |
993 | 689 |
994 *object = NULL; | 690 *object = NULL; |
995 return E_FAIL; | 691 return E_FAIL; |
996 } | 692 } |
997 | 693 |
998 // | 694 // |
999 // CComObjectRootEx methods. | 695 // CComObjectRootEx methods. |
1000 // | 696 // |
1001 | 697 |
1002 HRESULT WINAPI BrowserAccessibility::InternalQueryInterface( | 698 HRESULT WINAPI BrowserAccessibility::InternalQueryInterface( |
1003 void* this_ptr, | 699 void* this_ptr, |
1004 const _ATL_INTMAP_ENTRY* entries, | 700 const _ATL_INTMAP_ENTRY* entries, |
1005 REFIID iid, | 701 REFIID iid, |
1006 void** object) { | 702 void** object) { |
1007 if (iid == IID_IAccessibleText) { | 703 if (iid == IID_IAccessibleText) { |
1008 if (role_ != ROLE_SYSTEM_LINK) { | 704 if (role_ != ROLE_SYSTEM_LINK) { |
1009 *object = NULL; | 705 *object = NULL; |
1010 return E_NOINTERFACE; | 706 return E_NOINTERFACE; |
1011 } | 707 } |
1012 } else if (iid == IID_IAccessibleImage) { | 708 } else if (iid == IID_IAccessibleImage) { |
1013 if (role_ != ROLE_SYSTEM_GRAPHIC) { | 709 if (role_ != ROLE_SYSTEM_GRAPHIC) { |
1014 *object = NULL; | 710 *object = NULL; |
1015 return E_NOINTERFACE; | 711 return E_NOINTERFACE; |
1016 } | 712 } |
1017 } else if (iid == IID_ISimpleDOMDocument) { | |
1018 if (role_ != ROLE_SYSTEM_DOCUMENT) { | |
1019 *object = NULL; | |
1020 return E_NOINTERFACE; | |
1021 } | |
1022 } | 713 } |
1023 | 714 |
1024 return CComObjectRootBase::InternalQueryInterface( | 715 return CComObjectRootBase::InternalQueryInterface( |
1025 this_ptr, entries, iid, object); | 716 this_ptr, entries, iid, object); |
1026 } | 717 } |
1027 | 718 |
1028 // | 719 // |
1029 // Private methods. | 720 // Private methods. |
1030 // | 721 // |
1031 | 722 |
(...skipping 20 matching lines...) Expand all Loading... |
1052 WebAccessibility::Attribute attribute, string16* value) { | 743 WebAccessibility::Attribute attribute, string16* value) { |
1053 std::map<int32, string16>::iterator iter = attributes_.find(attribute); | 744 std::map<int32, string16>::iterator iter = attributes_.find(attribute); |
1054 if (iter != attributes_.end()) { | 745 if (iter != attributes_.end()) { |
1055 *value = iter->second; | 746 *value = iter->second; |
1056 return true; | 747 return true; |
1057 } | 748 } |
1058 | 749 |
1059 return false; | 750 return false; |
1060 } | 751 } |
1061 | 752 |
1062 HRESULT BrowserAccessibility::GetAttributeAsBstr( | |
1063 WebAccessibility::Attribute attribute, BSTR* value_bstr) { | |
1064 string16 str; | |
1065 | |
1066 if (!GetAttribute(attribute, &str)) | |
1067 return S_FALSE; | |
1068 | |
1069 if (str.empty()) | |
1070 return S_FALSE; | |
1071 | |
1072 *value_bstr = SysAllocString(str.c_str()); | |
1073 DCHECK(*value_bstr); | |
1074 | |
1075 return S_OK; | |
1076 } | |
1077 | |
1078 string16 BrowserAccessibility::Escape(string16 str) { | |
1079 return UTF8ToUTF16(EscapeNonASCII(UTF16ToUTF8(str))); | |
1080 } | |
1081 | |
1082 void BrowserAccessibility::InitRoleAndState(LONG web_role, | 753 void BrowserAccessibility::InitRoleAndState(LONG web_role, |
1083 LONG web_state) { | 754 LONG web_state) { |
1084 state_ = 0; | 755 state_ = 0; |
1085 ia2_state_ = IA2_STATE_OPAQUE; | 756 ia2_state_ = IA2_STATE_OPAQUE; |
1086 GetAttribute(WebAccessibility::ATTR_HTML_TAG, &role_name_); | |
1087 | 757 |
1088 if ((web_state >> WebAccessibility::STATE_CHECKED) & 1) | 758 if ((web_state >> WebAccessibility::STATE_CHECKED) & 1) |
1089 state_ |= STATE_SYSTEM_CHECKED; | 759 state_ |= STATE_SYSTEM_CHECKED; |
1090 if ((web_state >> WebAccessibility::STATE_FOCUSABLE) & 1) | 760 if ((web_state >> WebAccessibility::STATE_FOCUSABLE) & 1) |
1091 state_ |= STATE_SYSTEM_FOCUSABLE; | 761 state_ |= STATE_SYSTEM_FOCUSABLE; |
1092 if ((web_state >> WebAccessibility::STATE_HOTTRACKED) & 1) | 762 if ((web_state >> WebAccessibility::STATE_HOTTRACKED) & 1) |
1093 state_ |= STATE_SYSTEM_HOTTRACKED; | 763 state_ |= STATE_SYSTEM_HOTTRACKED; |
1094 if ((web_state >> WebAccessibility::STATE_INDETERMINATE) & 1) | 764 if ((web_state >> WebAccessibility::STATE_INDETERMINATE) & 1) |
1095 state_ |= STATE_SYSTEM_INDETERMINATE; | 765 state_ |= STATE_SYSTEM_INDETERMINATE; |
1096 if ((web_state >> WebAccessibility::STATE_LINKED) & 1) | 766 if ((web_state >> WebAccessibility::STATE_LINKED) & 1) |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1140 case WebAccessibility::ROLE_COLUMN: | 810 case WebAccessibility::ROLE_COLUMN: |
1141 role_ = ROLE_SYSTEM_COLUMN; | 811 role_ = ROLE_SYSTEM_COLUMN; |
1142 break; | 812 break; |
1143 case WebAccessibility::ROLE_COLUMN_HEADER: | 813 case WebAccessibility::ROLE_COLUMN_HEADER: |
1144 role_ = ROLE_SYSTEM_COLUMNHEADER; | 814 role_ = ROLE_SYSTEM_COLUMNHEADER; |
1145 break; | 815 break; |
1146 case WebAccessibility::ROLE_COMBO_BOX: | 816 case WebAccessibility::ROLE_COMBO_BOX: |
1147 role_ = ROLE_SYSTEM_COMBOBOX; | 817 role_ = ROLE_SYSTEM_COMBOBOX; |
1148 break; | 818 break; |
1149 case WebAccessibility::ROLE_DEFINITION_LIST_DEFINITION: | 819 case WebAccessibility::ROLE_DEFINITION_LIST_DEFINITION: |
| 820 role_name_ = L"dd"; |
1150 ia2_role_ = IA2_ROLE_PARAGRAPH; | 821 ia2_role_ = IA2_ROLE_PARAGRAPH; |
1151 break; | 822 break; |
1152 case WebAccessibility::ROLE_DEFINITION_LIST_TERM: | 823 case WebAccessibility::ROLE_DEFINITION_LIST_TERM: |
1153 role_ = ROLE_SYSTEM_LISTITEM; | 824 role_ = ROLE_SYSTEM_LISTITEM; |
1154 break; | 825 break; |
1155 case WebAccessibility::ROLE_DIALOG: | 826 case WebAccessibility::ROLE_DIALOG: |
1156 role_ = ROLE_SYSTEM_DIALOG; | 827 role_ = ROLE_SYSTEM_DIALOG; |
1157 break; | 828 break; |
1158 case WebAccessibility::ROLE_DOCUMENT: | 829 case WebAccessibility::ROLE_DOCUMENT: |
1159 case WebAccessibility::ROLE_WEB_AREA: | 830 case WebAccessibility::ROLE_WEB_AREA: |
1160 role_ = ROLE_SYSTEM_DOCUMENT; | 831 role_ = ROLE_SYSTEM_DOCUMENT; |
1161 state_ |= STATE_SYSTEM_READONLY; | 832 state_ |= STATE_SYSTEM_READONLY; |
1162 state_ |= STATE_SYSTEM_FOCUSABLE; | 833 state_ |= STATE_SYSTEM_FOCUSABLE; |
1163 break; | 834 break; |
1164 case WebAccessibility::ROLE_EDITABLE_TEXT: | 835 case WebAccessibility::ROLE_EDITABLE_TEXT: |
1165 role_ = ROLE_SYSTEM_TEXT; | 836 role_ = ROLE_SYSTEM_TEXT; |
1166 ia2_state_ |= IA2_STATE_SINGLE_LINE; | 837 ia2_state_ |= IA2_STATE_SINGLE_LINE; |
1167 ia2_state_ |= IA2_STATE_EDITABLE; | 838 ia2_state_ |= IA2_STATE_EDITABLE; |
1168 break; | 839 break; |
1169 case WebAccessibility::ROLE_GRID: | 840 case WebAccessibility::ROLE_GRID: |
1170 role_ = ROLE_SYSTEM_TABLE; | 841 role_ = ROLE_SYSTEM_TABLE; |
1171 break; | 842 break; |
1172 case WebAccessibility::ROLE_GROUP: | 843 case WebAccessibility::ROLE_GROUP: |
| 844 role_name_ = L"div"; |
1173 ia2_role_ = IA2_ROLE_SECTION; | 845 ia2_role_ = IA2_ROLE_SECTION; |
1174 break; | 846 break; |
1175 case WebAccessibility::ROLE_HEADING: | 847 case WebAccessibility::ROLE_HEADING: |
| 848 // TODO(dmazzoni): support all heading levels |
| 849 role_name_ = L"h1"; |
1176 ia2_role_ = IA2_ROLE_HEADING; | 850 ia2_role_ = IA2_ROLE_HEADING; |
1177 break; | 851 break; |
1178 case WebAccessibility::ROLE_IMAGE: | 852 case WebAccessibility::ROLE_IMAGE: |
1179 role_ = ROLE_SYSTEM_GRAPHIC; | 853 role_ = ROLE_SYSTEM_GRAPHIC; |
1180 break; | 854 break; |
1181 case WebAccessibility::ROLE_IMAGE_MAP: | 855 case WebAccessibility::ROLE_IMAGE_MAP: |
| 856 role_name_ = L"map"; |
1182 ia2_role_ = IA2_ROLE_IMAGE_MAP; | 857 ia2_role_ = IA2_ROLE_IMAGE_MAP; |
1183 break; | 858 break; |
1184 case WebAccessibility::ROLE_IMAGE_MAP_LINK: | 859 case WebAccessibility::ROLE_IMAGE_MAP_LINK: |
1185 role_ = ROLE_SYSTEM_LINK; | 860 role_ = ROLE_SYSTEM_LINK; |
1186 state_ |= STATE_SYSTEM_LINKED; | 861 state_ |= STATE_SYSTEM_LINKED; |
1187 break; | 862 break; |
1188 case WebAccessibility::ROLE_LANDMARK_APPLICATION: | 863 case WebAccessibility::ROLE_LANDMARK_APPLICATION: |
1189 case WebAccessibility::ROLE_LANDMARK_BANNER: | 864 case WebAccessibility::ROLE_LANDMARK_BANNER: |
1190 case WebAccessibility::ROLE_LANDMARK_COMPLEMENTARY: | 865 case WebAccessibility::ROLE_LANDMARK_COMPLEMENTARY: |
1191 case WebAccessibility::ROLE_LANDMARK_CONTENTINFO: | 866 case WebAccessibility::ROLE_LANDMARK_CONTENTINFO: |
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1351 } | 1026 } |
1352 | 1027 |
1353 // The role should always be set. | 1028 // The role should always be set. |
1354 DCHECK(!role_name_.empty() || role_); | 1029 DCHECK(!role_name_.empty() || role_); |
1355 | 1030 |
1356 // If we didn't explicitly set the IAccessible2 role, make it the same | 1031 // If we didn't explicitly set the IAccessible2 role, make it the same |
1357 // as the MSAA role. | 1032 // as the MSAA role. |
1358 if (!ia2_role_) | 1033 if (!ia2_role_) |
1359 ia2_role_ = role_; | 1034 ia2_role_ = role_; |
1360 } | 1035 } |
OLD | NEW |