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

Side by Side Diff: chrome/browser/browser_accessibility_win.cc

Issue 3389037: Make the selection start and end attributes of an html input control... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 10 years, 2 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
OLDNEW
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_number_conversions.h"
8 #include "base/string_util.h" 9 #include "base/string_util.h"
9 #include "base/utf_string_conversions.h" 10 #include "base/utf_string_conversions.h"
10 #include "chrome/browser/browser_accessibility_manager_win.h" 11 #include "chrome/browser/browser_accessibility_manager_win.h"
11 #include "net/base/escape.h" 12 #include "net/base/escape.h"
12 13
13 using webkit_glue::WebAccessibility; 14 using webkit_glue::WebAccessibility;
14 15
15 BrowserAccessibility::BrowserAccessibility() 16 BrowserAccessibility::BrowserAccessibility()
16 : manager_(NULL), 17 : manager_(NULL),
17 parent_(NULL), 18 parent_(NULL),
18 child_id_(-1), 19 child_id_(-1),
19 index_in_parent_(-1), 20 index_in_parent_(-1),
20 renderer_id_(-1), 21 renderer_id_(-1),
21 instance_active_(false) { 22 instance_active_(false) {
22 } 23 }
23 24
24 BrowserAccessibility::~BrowserAccessibility() { 25 BrowserAccessibility::~BrowserAccessibility() {
25 InactivateTree(); 26 InactivateTree();
26 } 27 }
27 28
28 void BrowserAccessibility::Initialize( 29 void BrowserAccessibility::Initialize(
29 BrowserAccessibilityManager* manager, 30 BrowserAccessibilityManager* manager,
30 BrowserAccessibility* parent, 31 BrowserAccessibility* parent,
31 LONG child_id, 32 LONG child_id,
32 LONG index_in_parent, 33 LONG index_in_parent,
33 const webkit_glue::WebAccessibility& src) { 34 const webkit_glue::WebAccessibility& src) {
34 DCHECK_EQ(children_.size(), 0U);
35
36 manager_ = manager; 35 manager_ = manager;
37 parent_ = parent; 36 parent_ = parent;
38 child_id_ = child_id; 37 child_id_ = child_id;
39 index_in_parent_ = index_in_parent; 38 index_in_parent_ = index_in_parent;
40 39
41 renderer_id_ = src.id; 40 renderer_id_ = src.id;
42 name_ = src.name; 41 name_ = src.name;
43 value_ = src.value; 42 value_ = src.value;
44 attributes_ = src.attributes; 43 attributes_ = src.attributes;
45 html_attributes_ = src.html_attributes; 44 html_attributes_ = src.html_attributes;
46 location_ = src.location; 45 location_ = src.location;
46 src_role_ = src.role;
47 InitRoleAndState(src.role, src.state); 47 InitRoleAndState(src.role, src.state);
48 48
49 // Expose headings levels to NVDA with the "level" object attribute. 49 // Expose headings levels to NVDA with the "level" object attribute.
50 if (src.role == WebAccessibility::ROLE_HEADING && role_name_.size() == 2 && 50 if (src.role == WebAccessibility::ROLE_HEADING && role_name_.size() == 2 &&
51 IsAsciiDigit(role_name_[1])) { 51 IsAsciiDigit(role_name_[1])) {
52 html_attributes_.push_back(std::make_pair(L"level", role_name_.substr(1))); 52 html_attributes_.push_back(std::make_pair(L"level", role_name_.substr(1)));
53 } 53 }
54 54
55 // If this object doesn't have a name but it does have a description, 55 // If this object doesn't have a name but it does have a description,
56 // use the description as its name - because some screen readers only 56 // use the description as its name - because some screen readers only
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
99 } 99 }
100 100
101 BrowserAccessibility* BrowserAccessibility::GetParent() { 101 BrowserAccessibility* BrowserAccessibility::GetParent() {
102 return parent_; 102 return parent_;
103 } 103 }
104 104
105 uint32 BrowserAccessibility::GetChildCount() { 105 uint32 BrowserAccessibility::GetChildCount() {
106 return children_.size(); 106 return children_.size();
107 } 107 }
108 108
109 BrowserAccessibility* BrowserAccessibility::GetChild(uint32 child_index) {
110 DCHECK(child_index >= 0 && child_index < children_.size());
111 return children_[child_index];
112 }
113
109 BrowserAccessibility* BrowserAccessibility::GetPreviousSibling() { 114 BrowserAccessibility* BrowserAccessibility::GetPreviousSibling() {
110 if (parent_ && index_in_parent_ > 0) 115 if (parent_ && index_in_parent_ > 0)
111 return parent_->children_[index_in_parent_ - 1]; 116 return parent_->children_[index_in_parent_ - 1];
112 117
113 return NULL; 118 return NULL;
114 } 119 }
115 120
116 BrowserAccessibility* BrowserAccessibility::GetNextSibling() { 121 BrowserAccessibility* BrowserAccessibility::GetNextSibling() {
117 if (parent_ && 122 if (parent_ &&
118 index_in_parent_ >= 0 && 123 index_in_parent_ >= 0 &&
(...skipping 449 matching lines...) Expand 10 before | Expand all | Expand 10 after
568 if (!instance_active_) 573 if (!instance_active_)
569 return E_FAIL; 574 return E_FAIL;
570 575
571 if (!desc) 576 if (!desc)
572 return E_INVALIDARG; 577 return E_INVALIDARG;
573 578
574 return GetAttributeAsBstr(WebAccessibility::ATTR_DESCRIPTION, desc); 579 return GetAttributeAsBstr(WebAccessibility::ATTR_DESCRIPTION, desc);
575 } 580 }
576 581
577 STDMETHODIMP BrowserAccessibility::get_imagePosition( 582 STDMETHODIMP BrowserAccessibility::get_imagePosition(
578 enum IA2CoordinateType coordinate_type, long* x, long* y) { 583 enum IA2CoordinateType coordinate_type, LONG* x, LONG* y) {
579 if (!instance_active_) 584 if (!instance_active_)
580 return E_FAIL; 585 return E_FAIL;
581 586
582 if (!x || !y) 587 if (!x || !y)
583 return E_INVALIDARG; 588 return E_INVALIDARG;
584 589
585 if (coordinate_type == IA2_COORDTYPE_SCREEN_RELATIVE) { 590 if (coordinate_type == IA2_COORDTYPE_SCREEN_RELATIVE) {
586 HWND parent_hwnd = manager_->GetParentHWND(); 591 HWND parent_hwnd = manager_->GetParentHWND();
587 POINT top_left = {0, 0}; 592 POINT top_left = {0, 0};
588 ::ClientToScreen(parent_hwnd, &top_left); 593 ::ClientToScreen(parent_hwnd, &top_left);
589 *x = location_.x + top_left.x; 594 *x = location_.x + top_left.x;
590 *y = location_.y + top_left.y; 595 *y = location_.y + top_left.y;
591 } else if (coordinate_type == IA2_COORDTYPE_PARENT_RELATIVE) { 596 } else if (coordinate_type == IA2_COORDTYPE_PARENT_RELATIVE) {
592 *x = location_.x; 597 *x = location_.x;
593 *y = location_.y; 598 *y = location_.y;
594 if (parent_) { 599 if (parent_) {
595 *x -= parent_->location_.x; 600 *x -= parent_->location_.x;
596 *y -= parent_->location_.y; 601 *y -= parent_->location_.y;
597 } 602 }
598 } else { 603 } else {
599 return E_INVALIDARG; 604 return E_INVALIDARG;
600 } 605 }
601 606
602 return S_OK; 607 return S_OK;
603 } 608 }
604 609
605 STDMETHODIMP BrowserAccessibility::get_imageSize(long* height, long* width) { 610 STDMETHODIMP BrowserAccessibility::get_imageSize(LONG* height, LONG* width) {
606 if (!instance_active_) 611 if (!instance_active_)
607 return E_FAIL; 612 return E_FAIL;
608 613
609 if (!height || !width) 614 if (!height || !width)
610 return E_INVALIDARG; 615 return E_INVALIDARG;
611 616
612 *height = location_.height; 617 *height = location_.height;
613 *width = location_.width; 618 *width = location_.width;
614 return S_OK; 619 return S_OK;
615 } 620 }
616 621
617 // 622 //
618 // IAccessibleText methods. 623 // IAccessibleText methods.
619 // 624 //
620 625
621 STDMETHODIMP BrowserAccessibility::get_nCharacters(long* n_characters) { 626 STDMETHODIMP BrowserAccessibility::get_nCharacters(LONG* n_characters) {
622 if (!instance_active_) 627 if (!instance_active_)
623 return E_FAIL; 628 return E_FAIL;
624 629
625 if (!n_characters) 630 if (!n_characters)
626 return E_INVALIDARG; 631 return E_INVALIDARG;
627 632
628 *n_characters = name_.length(); 633 if (src_role_ == WebAccessibility::ROLE_TEXT_FIELD) {
634 *n_characters = value_.length();
635 } else {
636 *n_characters = name_.length();
637 }
638
629 return S_OK; 639 return S_OK;
630 } 640 }
631 641
632 STDMETHODIMP BrowserAccessibility::get_text( 642 STDMETHODIMP BrowserAccessibility::get_text(
633 long start_offset, long end_offset, BSTR* text) { 643 LONG start_offset, LONG end_offset, BSTR* text) {
634 if (!instance_active_) 644 if (!instance_active_)
635 return E_FAIL; 645 return E_FAIL;
636 646
637 if (!text) 647 if (!text)
638 return E_INVALIDARG; 648 return E_INVALIDARG;
639 649
640 long len = name_.length(); 650 string16 text_str;
Chris Guillory 2010/10/01 18:06:43 Can we use a reference here.
651 if (src_role_ == WebAccessibility::ROLE_TEXT_FIELD) {
652 text_str = value_;
653 } else {
654 text_str = name_;
655 }
656
657 // The spec allows the arguments to be reversed.
658 if (start_offset > end_offset) {
659 LONG tmp = start_offset;
660 start_offset = end_offset;
661 end_offset = tmp;
662 }
663
664 // The spec does not allow the start or end offsets to be out or range;
665 // we must return an error if so.
666 LONG len = text_str.length();
641 if (start_offset < 0) 667 if (start_offset < 0)
642 start_offset = 0; 668 return E_INVALIDARG;
643 if (end_offset > len) 669 if (end_offset > len)
644 end_offset = len; 670 return E_INVALIDARG;
645 671
646 string16 substr = name_.substr(start_offset, end_offset - start_offset); 672 string16 substr = text_str.substr(start_offset, end_offset - start_offset);
647 if (substr.empty()) 673 if (substr.empty())
648 return S_FALSE; 674 return S_FALSE;
649 675
650 *text = SysAllocString(substr.c_str()); 676 *text = SysAllocString(substr.c_str());
651 DCHECK(*text); 677 DCHECK(*text);
652 return S_OK; 678 return S_OK;
653 } 679 }
654 680
655 STDMETHODIMP BrowserAccessibility::get_caretOffset(long* offset) { 681 STDMETHODIMP BrowserAccessibility::get_caretOffset(LONG* offset) {
656 if (!instance_active_) 682 if (!instance_active_)
657 return E_FAIL; 683 return E_FAIL;
658 684
659 if (!offset) 685 if (!offset)
660 return E_INVALIDARG; 686 return E_INVALIDARG;
661 687
662 *offset = 0; 688 if (src_role_ == WebAccessibility::ROLE_TEXT_FIELD) {
689 int sel_start = 0;
690 if (GetAttributeAsInt(WebAccessibility::ATTR_TEXT_SEL_START, &sel_start)) {
691 *offset = sel_start;
692 } else {
693 *offset = 0;
694 }
695 } else {
696 *offset = 0;
697 }
698
699 return S_OK;
700 }
701
702 STDMETHODIMP BrowserAccessibility::get_nSelections(LONG* n_selections) {
703 if (!instance_active_)
704 return E_FAIL;
705
706 if (!n_selections)
707 return E_INVALIDARG;
708
709 if (src_role_ == WebAccessibility::ROLE_TEXT_FIELD) {
710 int sel_start = 0;
711 int sel_end = 0;
712 if (GetAttributeAsInt(WebAccessibility::ATTR_TEXT_SEL_START, &sel_start) &&
713 GetAttributeAsInt(WebAccessibility::ATTR_TEXT_SEL_END, &sel_end) &&
714 sel_start != sel_end) {
715 *n_selections = 1;
716 } else {
717 *n_selections = 0;
718 }
719 } else {
720 *n_selections = 0;
721 }
722
723 return S_OK;
724 }
725
726 STDMETHODIMP BrowserAccessibility::get_selection(LONG selection_index,
727 LONG* start_offset,
728 LONG* end_offset) {
729 if (!instance_active_)
730 return E_FAIL;
731
732 if (!start_offset || !end_offset || selection_index != 0)
733 return E_INVALIDARG;
734
735 if (src_role_ == WebAccessibility::ROLE_TEXT_FIELD) {
736 int sel_start = 0;
737 int sel_end = 0;
738 if (GetAttributeAsInt(WebAccessibility::ATTR_TEXT_SEL_START, &sel_start) &&
739 GetAttributeAsInt(WebAccessibility::ATTR_TEXT_SEL_END, &sel_end)) {
740 *start_offset = sel_start;
741 *end_offset = sel_end;
742 } else {
743 *start_offset = 0;
744 *end_offset = 0;
745 }
746 } else {
747 *start_offset = 0;
748 *end_offset = 0;
749 }
750
663 return S_OK; 751 return S_OK;
664 } 752 }
665 753
666 // 754 //
667 // ISimpleDOMDocument methods. 755 // ISimpleDOMDocument methods.
668 // 756 //
669 757
670 STDMETHODIMP BrowserAccessibility::get_URL(BSTR* url) { 758 STDMETHODIMP BrowserAccessibility::get_URL(BSTR* url) {
671 if (!instance_active_) 759 if (!instance_active_)
672 return E_FAIL; 760 return E_FAIL;
(...skipping 331 matching lines...) Expand 10 before | Expand all | Expand 10 after
1004 // 1092 //
1005 // CComObjectRootEx methods. 1093 // CComObjectRootEx methods.
1006 // 1094 //
1007 1095
1008 HRESULT WINAPI BrowserAccessibility::InternalQueryInterface( 1096 HRESULT WINAPI BrowserAccessibility::InternalQueryInterface(
1009 void* this_ptr, 1097 void* this_ptr,
1010 const _ATL_INTMAP_ENTRY* entries, 1098 const _ATL_INTMAP_ENTRY* entries,
1011 REFIID iid, 1099 REFIID iid,
1012 void** object) { 1100 void** object) {
1013 if (iid == IID_IAccessibleText) { 1101 if (iid == IID_IAccessibleText) {
1014 if (role_ != ROLE_SYSTEM_LINK) { 1102 if (role_ != ROLE_SYSTEM_LINK && role_ != ROLE_SYSTEM_TEXT) {
1015 *object = NULL; 1103 *object = NULL;
1016 return E_NOINTERFACE; 1104 return E_NOINTERFACE;
1017 } 1105 }
1018 } else if (iid == IID_IAccessibleImage) { 1106 } else if (iid == IID_IAccessibleImage) {
1019 if (role_ != ROLE_SYSTEM_GRAPHIC) { 1107 if (role_ != ROLE_SYSTEM_GRAPHIC) {
1020 *object = NULL; 1108 *object = NULL;
1021 return E_NOINTERFACE; 1109 return E_NOINTERFACE;
1022 } 1110 }
1023 } else if (iid == IID_ISimpleDOMDocument) { 1111 } else if (iid == IID_ISimpleDOMDocument) {
1024 if (role_ != ROLE_SYSTEM_DOCUMENT) { 1112 if (role_ != ROLE_SYSTEM_DOCUMENT) {
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
1074 1162
1075 if (str.empty()) 1163 if (str.empty())
1076 return S_FALSE; 1164 return S_FALSE;
1077 1165
1078 *value_bstr = SysAllocString(str.c_str()); 1166 *value_bstr = SysAllocString(str.c_str());
1079 DCHECK(*value_bstr); 1167 DCHECK(*value_bstr);
1080 1168
1081 return S_OK; 1169 return S_OK;
1082 } 1170 }
1083 1171
1084 string16 BrowserAccessibility::Escape(string16 str) { 1172 bool BrowserAccessibility::GetAttributeAsInt(
1085 return UTF8ToUTF16(EscapeNonASCII(UTF16ToUTF8(str))); 1173 WebAccessibility::Attribute attribute, int* value_int) {
1174 string16 value_str;
1175
1176 if (!GetAttribute(attribute, &value_str))
1177 return false;
1178
1179 if (!base::StringToInt(value_str, value_int))
1180 return false;
1181
1182 return true;
1086 } 1183 }
1087 1184
1088 void BrowserAccessibility::InitRoleAndState(LONG web_role, 1185 string16 BrowserAccessibility::Escape(string16 str) {
1089 LONG web_state) { 1186 return EscapeQueryParamValueUTF8(str, false);
1187 }
1188
1189 void BrowserAccessibility::InitRoleAndState(LONG web_role, LONG web_state) {
1090 state_ = 0; 1190 state_ = 0;
1091 ia2_state_ = IA2_STATE_OPAQUE; 1191 ia2_state_ = IA2_STATE_OPAQUE;
1092 1192
1093 if ((web_state >> WebAccessibility::STATE_CHECKED) & 1) 1193 if ((web_state >> WebAccessibility::STATE_CHECKED) & 1)
1094 state_ |= STATE_SYSTEM_CHECKED; 1194 state_ |= STATE_SYSTEM_CHECKED;
1095 if ((web_state >> WebAccessibility::STATE_COLLAPSED) & 1) 1195 if ((web_state >> WebAccessibility::STATE_COLLAPSED) & 1)
1096 state_ |= STATE_SYSTEM_COLLAPSED; 1196 state_ |= STATE_SYSTEM_COLLAPSED;
1097 if ((web_state >> WebAccessibility::STATE_EXPANDED) & 1) 1197 if ((web_state >> WebAccessibility::STATE_EXPANDED) & 1)
1098 state_ |= STATE_SYSTEM_EXPANDED; 1198 state_ |= STATE_SYSTEM_EXPANDED;
1099 if ((web_state >> WebAccessibility::STATE_FOCUSABLE) & 1) 1199 if ((web_state >> WebAccessibility::STATE_FOCUSABLE) & 1)
(...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after
1377 } 1477 }
1378 1478
1379 // The role should always be set. 1479 // The role should always be set.
1380 DCHECK(!role_name_.empty() || role_); 1480 DCHECK(!role_name_.empty() || role_);
1381 1481
1382 // If we didn't explicitly set the IAccessible2 role, make it the same 1482 // If we didn't explicitly set the IAccessible2 role, make it the same
1383 // as the MSAA role. 1483 // as the MSAA role.
1384 if (!ia2_role_) 1484 if (!ia2_role_)
1385 ia2_role_ = role_; 1485 ia2_role_ = role_;
1386 } 1486 }
OLDNEW
« no previous file with comments | « chrome/browser/browser_accessibility_win.h ('k') | chrome/browser/renderer_host/test/renderer_accessibility_browsertest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698