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" |
8 #include "chrome/browser/browser_accessibility_manager_win.h" | 10 #include "chrome/browser/browser_accessibility_manager_win.h" |
| 11 #include "net/base/escape.h" |
9 | 12 |
10 using webkit_glue::WebAccessibility; | 13 using webkit_glue::WebAccessibility; |
11 | 14 |
12 BrowserAccessibility::BrowserAccessibility() | 15 BrowserAccessibility::BrowserAccessibility() |
13 : manager_(NULL), | 16 : manager_(NULL), |
14 parent_(NULL), | 17 parent_(NULL), |
15 child_id_(-1), | 18 child_id_(-1), |
16 index_in_parent_(-1), | 19 index_in_parent_(-1), |
17 renderer_id_(-1), | 20 renderer_id_(-1), |
18 instance_active_(false) { | 21 instance_active_(false) { |
(...skipping 13 matching lines...) Expand all Loading... |
32 | 35 |
33 manager_ = manager; | 36 manager_ = manager; |
34 parent_ = parent; | 37 parent_ = parent; |
35 child_id_ = child_id; | 38 child_id_ = child_id; |
36 index_in_parent_ = index_in_parent; | 39 index_in_parent_ = index_in_parent; |
37 | 40 |
38 renderer_id_ = src.id; | 41 renderer_id_ = src.id; |
39 name_ = src.name; | 42 name_ = src.name; |
40 value_ = src.value; | 43 value_ = src.value; |
41 attributes_ = src.attributes; | 44 attributes_ = src.attributes; |
| 45 html_attributes_ = src.html_attributes; |
42 location_ = src.location; | 46 location_ = src.location; |
43 InitRoleAndState(src.role, src.state); | 47 InitRoleAndState(src.role, src.state); |
44 | 48 |
45 // If this object doesn't have a name but it does have a description, | 49 // If this object doesn't have a name but it does have a description, |
46 // use the description as its name - because some screen readers only | 50 // use the description as its name - because some screen readers only |
47 // announce the name. | 51 // announce the name. |
48 if (name_.empty() && HasAttribute(WebAccessibility::ATTR_DESCRIPTION)) { | 52 if (name_.empty() && HasAttribute(WebAccessibility::ATTR_DESCRIPTION)) { |
49 GetAttribute(WebAccessibility::ATTR_DESCRIPTION, &name_); | 53 GetAttribute(WebAccessibility::ATTR_DESCRIPTION, &name_); |
50 } | 54 } |
51 | 55 |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
98 | 102 |
99 BrowserAccessibility* BrowserAccessibility::GetPreviousSibling() { | 103 BrowserAccessibility* BrowserAccessibility::GetPreviousSibling() { |
100 if (parent_ && index_in_parent_ > 0) | 104 if (parent_ && index_in_parent_ > 0) |
101 return parent_->children_[index_in_parent_ - 1]; | 105 return parent_->children_[index_in_parent_ - 1]; |
102 | 106 |
103 return NULL; | 107 return NULL; |
104 } | 108 } |
105 | 109 |
106 BrowserAccessibility* BrowserAccessibility::GetNextSibling() { | 110 BrowserAccessibility* BrowserAccessibility::GetNextSibling() { |
107 if (parent_ && | 111 if (parent_ && |
| 112 index_in_parent_ >= 0 && |
108 index_in_parent_ < static_cast<int>(parent_->children_.size() - 1)) { | 113 index_in_parent_ < static_cast<int>(parent_->children_.size() - 1)) { |
109 return parent_->children_[index_in_parent_ + 1]; | 114 return parent_->children_[index_in_parent_ + 1]; |
110 } | 115 } |
111 | 116 |
112 return NULL; | 117 return NULL; |
113 } | 118 } |
114 | 119 |
115 void BrowserAccessibility::ReplaceChild( | 120 void BrowserAccessibility::ReplaceChild( |
116 const BrowserAccessibility* old_acc, BrowserAccessibility* new_acc) { | 121 const BrowserAccessibility* old_acc, BrowserAccessibility* new_acc) { |
117 DCHECK_EQ(children_[old_acc->index_in_parent_], old_acc); | 122 DCHECK_EQ(children_[old_acc->index_in_parent_], old_acc); |
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
264 if (!instance_active_) | 269 if (!instance_active_) |
265 return E_FAIL; | 270 return E_FAIL; |
266 | 271 |
267 if (!def_action) | 272 if (!def_action) |
268 return E_INVALIDARG; | 273 return E_INVALIDARG; |
269 | 274 |
270 BrowserAccessibility* target = GetTargetFromChildID(var_id); | 275 BrowserAccessibility* target = GetTargetFromChildID(var_id); |
271 if (!target) | 276 if (!target) |
272 return E_INVALIDARG; | 277 return E_INVALIDARG; |
273 | 278 |
274 string16 action; | 279 return target->GetAttributeAsBstr( |
275 if (!target->GetAttribute(WebAccessibility::ATTR_SHORTCUT, &action)) | 280 WebAccessibility::ATTR_SHORTCUT, def_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; | |
285 } | 281 } |
286 | 282 |
287 STDMETHODIMP BrowserAccessibility::get_accDescription(VARIANT var_id, | 283 STDMETHODIMP BrowserAccessibility::get_accDescription(VARIANT var_id, |
288 BSTR* desc) { | 284 BSTR* desc) { |
289 if (!instance_active_) | 285 if (!instance_active_) |
290 return E_FAIL; | 286 return E_FAIL; |
291 | 287 |
292 if (!desc) | 288 if (!desc) |
293 return E_INVALIDARG; | 289 return E_INVALIDARG; |
294 | 290 |
295 BrowserAccessibility* target = GetTargetFromChildID(var_id); | 291 BrowserAccessibility* target = GetTargetFromChildID(var_id); |
296 if (!target) | 292 if (!target) |
297 return E_INVALIDARG; | 293 return E_INVALIDARG; |
298 | 294 |
299 string16 description; | 295 return target->GetAttributeAsBstr(WebAccessibility::ATTR_DESCRIPTION, desc); |
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; | |
310 } | 296 } |
311 | 297 |
312 STDMETHODIMP BrowserAccessibility::get_accFocus(VARIANT* focus_child) { | 298 STDMETHODIMP BrowserAccessibility::get_accFocus(VARIANT* focus_child) { |
313 if (!instance_active_) | 299 if (!instance_active_) |
314 return E_FAIL; | 300 return E_FAIL; |
315 | 301 |
316 if (!focus_child) | 302 if (!focus_child) |
317 return E_INVALIDARG; | 303 return E_INVALIDARG; |
318 | 304 |
319 BrowserAccessibility* focus = manager_->GetFocus(this); | 305 BrowserAccessibility* focus = manager_->GetFocus(this); |
(...skipping 14 matching lines...) Expand all Loading... |
334 if (!instance_active_) | 320 if (!instance_active_) |
335 return E_FAIL; | 321 return E_FAIL; |
336 | 322 |
337 if (!help) | 323 if (!help) |
338 return E_INVALIDARG; | 324 return E_INVALIDARG; |
339 | 325 |
340 BrowserAccessibility* target = GetTargetFromChildID(var_id); | 326 BrowserAccessibility* target = GetTargetFromChildID(var_id); |
341 if (!target) | 327 if (!target) |
342 return E_INVALIDARG; | 328 return E_INVALIDARG; |
343 | 329 |
344 string16 help_str; | 330 return target->GetAttributeAsBstr(WebAccessibility::ATTR_HELP, help); |
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; | |
355 } | 331 } |
356 | 332 |
357 STDMETHODIMP BrowserAccessibility::get_accKeyboardShortcut(VARIANT var_id, | 333 STDMETHODIMP BrowserAccessibility::get_accKeyboardShortcut(VARIANT var_id, |
358 BSTR* acc_key) { | 334 BSTR* acc_key) { |
359 if (!instance_active_) | 335 if (!instance_active_) |
360 return E_FAIL; | 336 return E_FAIL; |
361 | 337 |
362 if (!acc_key) | 338 if (!acc_key) |
363 return E_INVALIDARG; | 339 return E_INVALIDARG; |
364 | 340 |
365 BrowserAccessibility* target = GetTargetFromChildID(var_id); | 341 BrowserAccessibility* target = GetTargetFromChildID(var_id); |
366 if (!target) | 342 if (!target) |
367 return E_INVALIDARG; | 343 return E_INVALIDARG; |
368 | 344 |
369 string16 shortcut; | 345 return target->GetAttributeAsBstr(WebAccessibility::ATTR_SHORTCUT, acc_key); |
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; | |
380 } | 346 } |
381 | 347 |
382 STDMETHODIMP BrowserAccessibility::get_accName(VARIANT var_id, BSTR* name) { | 348 STDMETHODIMP BrowserAccessibility::get_accName(VARIANT var_id, BSTR* name) { |
383 if (!instance_active_) | 349 if (!instance_active_) |
384 return E_FAIL; | 350 return E_FAIL; |
385 | 351 |
386 if (!name) | 352 if (!name) |
387 return E_INVALIDARG; | 353 return E_INVALIDARG; |
388 | 354 |
389 BrowserAccessibility* target = GetTargetFromChildID(var_id); | 355 BrowserAccessibility* target = GetTargetFromChildID(var_id); |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
517 return S_OK; | 483 return S_OK; |
518 } | 484 } |
519 | 485 |
520 STDMETHODIMP BrowserAccessibility::get_attributes(BSTR* attributes) { | 486 STDMETHODIMP BrowserAccessibility::get_attributes(BSTR* attributes) { |
521 if (!instance_active_) | 487 if (!instance_active_) |
522 return E_FAIL; | 488 return E_FAIL; |
523 | 489 |
524 if (!attributes) | 490 if (!attributes) |
525 return E_INVALIDARG; | 491 return E_INVALIDARG; |
526 | 492 |
527 return S_FALSE; | 493 // Follow Firefox's convention, which is to return a set of key-value pairs |
| 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; |
528 } | 510 } |
529 | 511 |
530 STDMETHODIMP BrowserAccessibility::get_states(AccessibleStates* states) { | 512 STDMETHODIMP BrowserAccessibility::get_states(AccessibleStates* states) { |
531 if (!instance_active_) | 513 if (!instance_active_) |
532 return E_FAIL; | 514 return E_FAIL; |
533 | 515 |
534 if (!states) | 516 if (!states) |
535 return E_INVALIDARG; | 517 return E_INVALIDARG; |
536 | 518 |
537 *states = ia2_state_; | 519 *states = ia2_state_; |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
576 // IAccessibleImage methods. | 558 // IAccessibleImage methods. |
577 // | 559 // |
578 | 560 |
579 STDMETHODIMP BrowserAccessibility::get_description(BSTR* desc) { | 561 STDMETHODIMP BrowserAccessibility::get_description(BSTR* desc) { |
580 if (!instance_active_) | 562 if (!instance_active_) |
581 return E_FAIL; | 563 return E_FAIL; |
582 | 564 |
583 if (!desc) | 565 if (!desc) |
584 return E_INVALIDARG; | 566 return E_INVALIDARG; |
585 | 567 |
586 string16 description; | 568 return GetAttributeAsBstr(WebAccessibility::ATTR_DESCRIPTION, desc); |
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; | |
597 } | 569 } |
598 | 570 |
599 STDMETHODIMP BrowserAccessibility::get_imagePosition( | 571 STDMETHODIMP BrowserAccessibility::get_imagePosition( |
600 enum IA2CoordinateType coordinate_type, long* x, long* y) { | 572 enum IA2CoordinateType coordinate_type, long* x, long* y) { |
601 if (!instance_active_) | 573 if (!instance_active_) |
602 return E_FAIL; | 574 return E_FAIL; |
603 | 575 |
604 if (!x || !y) | 576 if (!x || !y) |
605 return E_INVALIDARG; | 577 return E_INVALIDARG; |
606 | 578 |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
658 | 630 |
659 if (!text) | 631 if (!text) |
660 return E_INVALIDARG; | 632 return E_INVALIDARG; |
661 | 633 |
662 long len = name_.length(); | 634 long len = name_.length(); |
663 if (start_offset < 0) | 635 if (start_offset < 0) |
664 start_offset = 0; | 636 start_offset = 0; |
665 if (end_offset > len) | 637 if (end_offset > len) |
666 end_offset = len; | 638 end_offset = len; |
667 | 639 |
668 *text = SysAllocString( | 640 string16 substr = name_.substr(start_offset, end_offset - start_offset); |
669 name_.substr(start_offset, end_offset - start_offset).c_str()); | 641 if (substr.empty()) |
| 642 return S_FALSE; |
| 643 |
| 644 *text = SysAllocString(substr.c_str()); |
| 645 DCHECK(*text); |
670 return S_OK; | 646 return S_OK; |
671 } | 647 } |
672 | 648 |
673 STDMETHODIMP BrowserAccessibility::get_caretOffset(long* offset) { | 649 STDMETHODIMP BrowserAccessibility::get_caretOffset(long* offset) { |
| 650 if (!instance_active_) |
| 651 return E_FAIL; |
| 652 |
| 653 if (!offset) |
| 654 return E_INVALIDARG; |
| 655 |
674 *offset = 0; | 656 *offset = 0; |
675 return S_OK; | 657 return S_OK; |
676 } | 658 } |
677 | 659 |
678 // | 660 // |
| 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 // |
679 // IServiceProvider methods. | 976 // IServiceProvider methods. |
680 // | 977 // |
681 | 978 |
682 STDMETHODIMP BrowserAccessibility::QueryService( | 979 STDMETHODIMP BrowserAccessibility::QueryService( |
683 REFGUID guidService, REFIID riid, void** object) { | 980 REFGUID guidService, REFIID riid, void** object) { |
684 if (!instance_active_) | 981 if (!instance_active_) |
685 return E_FAIL; | 982 return E_FAIL; |
686 | 983 |
687 if (guidService == IID_IAccessible || guidService == IID_IAccessible2) | 984 if (guidService == IID_IAccessible || |
| 985 guidService == IID_IAccessible2 || |
| 986 guidService == IID_IAccessibleImage || |
| 987 guidService == IID_IAccessibleText || |
| 988 guidService == IID_ISimpleDOMDocument || |
| 989 guidService == IID_ISimpleDOMNode || |
| 990 guidService == IID_ISimpleDOMText) { |
688 return QueryInterface(riid, object); | 991 return QueryInterface(riid, object); |
| 992 } |
689 | 993 |
690 *object = NULL; | 994 *object = NULL; |
691 return E_FAIL; | 995 return E_FAIL; |
692 } | 996 } |
693 | 997 |
694 // | 998 // |
695 // CComObjectRootEx methods. | 999 // CComObjectRootEx methods. |
696 // | 1000 // |
697 | 1001 |
698 HRESULT WINAPI BrowserAccessibility::InternalQueryInterface( | 1002 HRESULT WINAPI BrowserAccessibility::InternalQueryInterface( |
699 void* this_ptr, | 1003 void* this_ptr, |
700 const _ATL_INTMAP_ENTRY* entries, | 1004 const _ATL_INTMAP_ENTRY* entries, |
701 REFIID iid, | 1005 REFIID iid, |
702 void** object) { | 1006 void** object) { |
703 if (iid == IID_IAccessibleText) { | 1007 if (iid == IID_IAccessibleText) { |
704 if (role_ != ROLE_SYSTEM_LINK) { | 1008 if (role_ != ROLE_SYSTEM_LINK) { |
705 *object = NULL; | 1009 *object = NULL; |
706 return E_NOINTERFACE; | 1010 return E_NOINTERFACE; |
707 } | 1011 } |
708 } else if (iid == IID_IAccessibleImage) { | 1012 } else if (iid == IID_IAccessibleImage) { |
709 if (role_ != ROLE_SYSTEM_GRAPHIC) { | 1013 if (role_ != ROLE_SYSTEM_GRAPHIC) { |
710 *object = NULL; | 1014 *object = NULL; |
711 return E_NOINTERFACE; | 1015 return E_NOINTERFACE; |
712 } | 1016 } |
| 1017 } else if (iid == IID_ISimpleDOMDocument) { |
| 1018 if (role_ != ROLE_SYSTEM_DOCUMENT) { |
| 1019 *object = NULL; |
| 1020 return E_NOINTERFACE; |
| 1021 } |
713 } | 1022 } |
714 | 1023 |
715 return CComObjectRootBase::InternalQueryInterface( | 1024 return CComObjectRootBase::InternalQueryInterface( |
716 this_ptr, entries, iid, object); | 1025 this_ptr, entries, iid, object); |
717 } | 1026 } |
718 | 1027 |
719 // | 1028 // |
720 // Private methods. | 1029 // Private methods. |
721 // | 1030 // |
722 | 1031 |
(...skipping 20 matching lines...) Expand all Loading... |
743 WebAccessibility::Attribute attribute, string16* value) { | 1052 WebAccessibility::Attribute attribute, string16* value) { |
744 std::map<int32, string16>::iterator iter = attributes_.find(attribute); | 1053 std::map<int32, string16>::iterator iter = attributes_.find(attribute); |
745 if (iter != attributes_.end()) { | 1054 if (iter != attributes_.end()) { |
746 *value = iter->second; | 1055 *value = iter->second; |
747 return true; | 1056 return true; |
748 } | 1057 } |
749 | 1058 |
750 return false; | 1059 return false; |
751 } | 1060 } |
752 | 1061 |
| 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 |
753 void BrowserAccessibility::InitRoleAndState(LONG web_role, | 1082 void BrowserAccessibility::InitRoleAndState(LONG web_role, |
754 LONG web_state) { | 1083 LONG web_state) { |
755 state_ = 0; | 1084 state_ = 0; |
756 ia2_state_ = IA2_STATE_OPAQUE; | 1085 ia2_state_ = IA2_STATE_OPAQUE; |
| 1086 GetAttribute(WebAccessibility::ATTR_HTML_TAG, &role_name_); |
757 | 1087 |
758 if ((web_state >> WebAccessibility::STATE_CHECKED) & 1) | 1088 if ((web_state >> WebAccessibility::STATE_CHECKED) & 1) |
759 state_ |= STATE_SYSTEM_CHECKED; | 1089 state_ |= STATE_SYSTEM_CHECKED; |
760 if ((web_state >> WebAccessibility::STATE_FOCUSABLE) & 1) | 1090 if ((web_state >> WebAccessibility::STATE_FOCUSABLE) & 1) |
761 state_ |= STATE_SYSTEM_FOCUSABLE; | 1091 state_ |= STATE_SYSTEM_FOCUSABLE; |
762 if ((web_state >> WebAccessibility::STATE_HOTTRACKED) & 1) | 1092 if ((web_state >> WebAccessibility::STATE_HOTTRACKED) & 1) |
763 state_ |= STATE_SYSTEM_HOTTRACKED; | 1093 state_ |= STATE_SYSTEM_HOTTRACKED; |
764 if ((web_state >> WebAccessibility::STATE_INDETERMINATE) & 1) | 1094 if ((web_state >> WebAccessibility::STATE_INDETERMINATE) & 1) |
765 state_ |= STATE_SYSTEM_INDETERMINATE; | 1095 state_ |= STATE_SYSTEM_INDETERMINATE; |
766 if ((web_state >> WebAccessibility::STATE_LINKED) & 1) | 1096 if ((web_state >> WebAccessibility::STATE_LINKED) & 1) |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
810 case WebAccessibility::ROLE_COLUMN: | 1140 case WebAccessibility::ROLE_COLUMN: |
811 role_ = ROLE_SYSTEM_COLUMN; | 1141 role_ = ROLE_SYSTEM_COLUMN; |
812 break; | 1142 break; |
813 case WebAccessibility::ROLE_COLUMN_HEADER: | 1143 case WebAccessibility::ROLE_COLUMN_HEADER: |
814 role_ = ROLE_SYSTEM_COLUMNHEADER; | 1144 role_ = ROLE_SYSTEM_COLUMNHEADER; |
815 break; | 1145 break; |
816 case WebAccessibility::ROLE_COMBO_BOX: | 1146 case WebAccessibility::ROLE_COMBO_BOX: |
817 role_ = ROLE_SYSTEM_COMBOBOX; | 1147 role_ = ROLE_SYSTEM_COMBOBOX; |
818 break; | 1148 break; |
819 case WebAccessibility::ROLE_DEFINITION_LIST_DEFINITION: | 1149 case WebAccessibility::ROLE_DEFINITION_LIST_DEFINITION: |
820 role_name_ = L"dd"; | |
821 ia2_role_ = IA2_ROLE_PARAGRAPH; | 1150 ia2_role_ = IA2_ROLE_PARAGRAPH; |
822 break; | 1151 break; |
823 case WebAccessibility::ROLE_DEFINITION_LIST_TERM: | 1152 case WebAccessibility::ROLE_DEFINITION_LIST_TERM: |
824 role_ = ROLE_SYSTEM_LISTITEM; | 1153 role_ = ROLE_SYSTEM_LISTITEM; |
825 break; | 1154 break; |
826 case WebAccessibility::ROLE_DIALOG: | 1155 case WebAccessibility::ROLE_DIALOG: |
827 role_ = ROLE_SYSTEM_DIALOG; | 1156 role_ = ROLE_SYSTEM_DIALOG; |
828 break; | 1157 break; |
829 case WebAccessibility::ROLE_DOCUMENT: | 1158 case WebAccessibility::ROLE_DOCUMENT: |
830 case WebAccessibility::ROLE_WEB_AREA: | 1159 case WebAccessibility::ROLE_WEB_AREA: |
831 role_ = ROLE_SYSTEM_DOCUMENT; | 1160 role_ = ROLE_SYSTEM_DOCUMENT; |
832 state_ |= STATE_SYSTEM_READONLY; | 1161 state_ |= STATE_SYSTEM_READONLY; |
833 state_ |= STATE_SYSTEM_FOCUSABLE; | 1162 state_ |= STATE_SYSTEM_FOCUSABLE; |
834 break; | 1163 break; |
835 case WebAccessibility::ROLE_EDITABLE_TEXT: | 1164 case WebAccessibility::ROLE_EDITABLE_TEXT: |
836 role_ = ROLE_SYSTEM_TEXT; | 1165 role_ = ROLE_SYSTEM_TEXT; |
837 ia2_state_ |= IA2_STATE_SINGLE_LINE; | 1166 ia2_state_ |= IA2_STATE_SINGLE_LINE; |
838 ia2_state_ |= IA2_STATE_EDITABLE; | 1167 ia2_state_ |= IA2_STATE_EDITABLE; |
839 break; | 1168 break; |
840 case WebAccessibility::ROLE_GRID: | 1169 case WebAccessibility::ROLE_GRID: |
841 role_ = ROLE_SYSTEM_TABLE; | 1170 role_ = ROLE_SYSTEM_TABLE; |
842 break; | 1171 break; |
843 case WebAccessibility::ROLE_GROUP: | 1172 case WebAccessibility::ROLE_GROUP: |
844 role_name_ = L"div"; | |
845 ia2_role_ = IA2_ROLE_SECTION; | 1173 ia2_role_ = IA2_ROLE_SECTION; |
846 break; | 1174 break; |
847 case WebAccessibility::ROLE_HEADING: | 1175 case WebAccessibility::ROLE_HEADING: |
848 // TODO(dmazzoni): support all heading levels | |
849 role_name_ = L"h1"; | |
850 ia2_role_ = IA2_ROLE_HEADING; | 1176 ia2_role_ = IA2_ROLE_HEADING; |
851 break; | 1177 break; |
852 case WebAccessibility::ROLE_IMAGE: | 1178 case WebAccessibility::ROLE_IMAGE: |
853 role_ = ROLE_SYSTEM_GRAPHIC; | 1179 role_ = ROLE_SYSTEM_GRAPHIC; |
854 break; | 1180 break; |
855 case WebAccessibility::ROLE_IMAGE_MAP: | 1181 case WebAccessibility::ROLE_IMAGE_MAP: |
856 role_name_ = L"map"; | |
857 ia2_role_ = IA2_ROLE_IMAGE_MAP; | 1182 ia2_role_ = IA2_ROLE_IMAGE_MAP; |
858 break; | 1183 break; |
859 case WebAccessibility::ROLE_IMAGE_MAP_LINK: | 1184 case WebAccessibility::ROLE_IMAGE_MAP_LINK: |
860 role_ = ROLE_SYSTEM_LINK; | 1185 role_ = ROLE_SYSTEM_LINK; |
861 state_ |= STATE_SYSTEM_LINKED; | 1186 state_ |= STATE_SYSTEM_LINKED; |
862 break; | 1187 break; |
863 case WebAccessibility::ROLE_LANDMARK_APPLICATION: | 1188 case WebAccessibility::ROLE_LANDMARK_APPLICATION: |
864 case WebAccessibility::ROLE_LANDMARK_BANNER: | 1189 case WebAccessibility::ROLE_LANDMARK_BANNER: |
865 case WebAccessibility::ROLE_LANDMARK_COMPLEMENTARY: | 1190 case WebAccessibility::ROLE_LANDMARK_COMPLEMENTARY: |
866 case WebAccessibility::ROLE_LANDMARK_CONTENTINFO: | 1191 case WebAccessibility::ROLE_LANDMARK_CONTENTINFO: |
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1026 } | 1351 } |
1027 | 1352 |
1028 // The role should always be set. | 1353 // The role should always be set. |
1029 DCHECK(!role_name_.empty() || role_); | 1354 DCHECK(!role_name_.empty() || role_); |
1030 | 1355 |
1031 // If we didn't explicitly set the IAccessible2 role, make it the same | 1356 // If we didn't explicitly set the IAccessible2 role, make it the same |
1032 // as the MSAA role. | 1357 // as the MSAA role. |
1033 if (!ia2_role_) | 1358 if (!ia2_role_) |
1034 ia2_role_ = role_; | 1359 ia2_role_ = role_; |
1035 } | 1360 } |
OLD | NEW |