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

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

Issue 3550017: Implement additional IAccessibleText methods to return the nearest... (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/accessibility/browser_accessibility_win.h" 5 #include "chrome/browser/accessibility/browser_accessibility_win.h"
6 6
7 #include "base/string_number_conversions.h" 7 #include "base/string_number_conversions.h"
8 #include "base/string_util.h" 8 #include "base/string_util.h"
9 #include "base/utf_string_conversions.h" 9 #include "base/utf_string_conversions.h"
10 #include "chrome/browser/accessibility/browser_accessibility_manager_win.h" 10 #include "chrome/browser/accessibility/browser_accessibility_manager_win.h"
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
47 47
48 BrowserAccessibilityWin* target = GetTargetFromChildID(var_id); 48 BrowserAccessibilityWin* target = GetTargetFromChildID(var_id);
49 if (!target) 49 if (!target)
50 return E_INVALIDARG; 50 return E_INVALIDARG;
51 51
52 manager_->DoDefaultAction(*target); 52 manager_->DoDefaultAction(*target);
53 return S_OK; 53 return S_OK;
54 } 54 }
55 55
56 STDMETHODIMP BrowserAccessibilityWin::accHitTest(LONG x_left, LONG y_top, 56 STDMETHODIMP BrowserAccessibilityWin::accHitTest(LONG x_left, LONG y_top,
57 VARIANT* child) { 57 VARIANT* child) {
58 if (!instance_active_) 58 if (!instance_active_)
59 return E_FAIL; 59 return E_FAIL;
60 60
61 if (!child) 61 if (!child)
62 return E_INVALIDARG; 62 return E_INVALIDARG;
63 63
64 return E_NOTIMPL; 64 return E_NOTIMPL;
65 } 65 }
66 66
67 STDMETHODIMP BrowserAccessibilityWin::accLocation(LONG* x_left, LONG* y_top, 67 STDMETHODIMP BrowserAccessibilityWin::accLocation(LONG* x_left, LONG* y_top,
68 LONG* width, LONG* height, 68 LONG* width, LONG* height,
69 VARIANT var_id) { 69 VARIANT var_id) {
70 if (!instance_active_) 70 if (!instance_active_)
71 return E_FAIL; 71 return E_FAIL;
72 72
73 if (!x_left || !y_top || !width || !height) 73 if (!x_left || !y_top || !width || !height)
74 return E_INVALIDARG; 74 return E_INVALIDARG;
75 75
76 BrowserAccessibilityWin* target = GetTargetFromChildID(var_id); 76 BrowserAccessibilityWin* target = GetTargetFromChildID(var_id);
77 if (!target) 77 if (!target)
78 return E_INVALIDARG; 78 return E_INVALIDARG;
79 79
(...skipping 447 matching lines...) Expand 10 before | Expand all | Expand 10 after
527 527
528 if (role_ == WebAccessibility::ROLE_TEXT_FIELD) { 528 if (role_ == WebAccessibility::ROLE_TEXT_FIELD) {
529 *n_characters = value_.length(); 529 *n_characters = value_.length();
530 } else { 530 } else {
531 *n_characters = name_.length(); 531 *n_characters = name_.length();
532 } 532 }
533 533
534 return S_OK; 534 return S_OK;
535 } 535 }
536 536
537 STDMETHODIMP BrowserAccessibilityWin::get_text(
538 LONG start_offset, LONG end_offset, BSTR* text) {
539 if (!instance_active_)
540 return E_FAIL;
541
542 if (!text)
543 return E_INVALIDARG;
544
545 string16 text_str;
546 if (role_ == WebAccessibility::ROLE_TEXT_FIELD) {
547 text_str = value_;
548 } else {
549 text_str = name_;
550 }
551
552 // The spec allows the arguments to be reversed.
553 if (start_offset > end_offset) {
554 LONG tmp = start_offset;
555 start_offset = end_offset;
556 end_offset = tmp;
557 }
558
559 // The spec does not allow the start or end offsets to be out or range;
560 // we must return an error if so.
561 LONG len = text_str.length();
562 if (start_offset < 0)
563 return E_INVALIDARG;
564 if (end_offset > len)
565 return E_INVALIDARG;
566
567 string16 substr = text_str.substr(start_offset, end_offset - start_offset);
568 if (substr.empty())
569 return S_FALSE;
570
571 *text = SysAllocString(substr.c_str());
572 DCHECK(*text);
573 return S_OK;
574 }
575
576 STDMETHODIMP BrowserAccessibilityWin::get_caretOffset(LONG* offset) { 537 STDMETHODIMP BrowserAccessibilityWin::get_caretOffset(LONG* offset) {
577 if (!instance_active_) 538 if (!instance_active_)
578 return E_FAIL; 539 return E_FAIL;
579 540
580 if (!offset) 541 if (!offset)
581 return E_INVALIDARG; 542 return E_INVALIDARG;
582 543
583 if (role_ == WebAccessibility::ROLE_TEXT_FIELD) { 544 if (role_ == WebAccessibility::ROLE_TEXT_FIELD) {
584 int sel_start = 0; 545 int sel_start = 0;
585 if (GetAttributeAsInt(WebAccessibility::ATTR_TEXT_SEL_START, &sel_start)) { 546 if (GetAttributeAsInt(WebAccessibility::ATTR_TEXT_SEL_START, &sel_start)) {
586 *offset = sel_start; 547 *offset = sel_start;
587 } else { 548 } else {
588 *offset = 0; 549 *offset = 0;
589 } 550 }
590 } else { 551 } else {
591 *offset = 0; 552 *offset = 0;
592 } 553 }
593 554
594 return S_OK; 555 return S_OK;
595 } 556 }
596 557
597 STDMETHODIMP BrowserAccessibilityWin::get_nSelections(LONG* n_selections) { 558 STDMETHODIMP BrowserAccessibilityWin::get_nSelections(LONG* n_selections) {
598 if (!instance_active_) 559 if (!instance_active_)
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
639 *end_offset = 0; 600 *end_offset = 0;
640 } 601 }
641 } else { 602 } else {
642 *start_offset = 0; 603 *start_offset = 0;
643 *end_offset = 0; 604 *end_offset = 0;
644 } 605 }
645 606
646 return S_OK; 607 return S_OK;
647 } 608 }
648 609
610 STDMETHODIMP BrowserAccessibilityWin::get_text(
611 LONG start_offset, LONG end_offset, BSTR* text) {
612 if (!instance_active_)
613 return E_FAIL;
614
615 if (!text)
616 return E_INVALIDARG;
617
618 const string16& text_str = TextForIAccessibleText();
619
620 // The spec allows the arguments to be reversed.
621 if (start_offset > end_offset) {
622 LONG tmp = start_offset;
623 start_offset = end_offset;
624 end_offset = tmp;
625 }
626
627 // The spec does not allow the start or end offsets to be out or range;
628 // we must return an error if so.
629 LONG len = text_str.length();
630 if (start_offset < 0)
631 return E_INVALIDARG;
632 if (end_offset > len)
633 return E_INVALIDARG;
634
635 string16 substr = text_str.substr(start_offset, end_offset - start_offset);
636 if (substr.empty())
637 return S_FALSE;
638
639 *text = SysAllocString(substr.c_str());
640 DCHECK(*text);
641 return S_OK;
642 }
643
644 STDMETHODIMP BrowserAccessibilityWin::get_textAtOffset(
645 LONG offset,
646 enum IA2TextBoundaryType boundary_type,
647 LONG* start_offset, LONG* end_offset,
648 BSTR* text) {
649 if (!instance_active_)
650 return E_FAIL;
651
652 if (!start_offset || !end_offset || !text)
653 return E_INVALIDARG;
654
655 // The IAccessible2 spec says we don't have to implement the "sentence"
656 // boundary type, we can just let the screenreader handle it.
657 if (boundary_type == IA2_TEXT_BOUNDARY_SENTENCE) {
658 *start_offset = 0;
659 *end_offset = 0;
660 *text = NULL;
661 return S_FALSE;
662 }
663
664 const string16& text_str = TextForIAccessibleText();
665
666 *start_offset = FindBoundary(text_str, boundary_type, offset, -1);
667 *end_offset = FindBoundary(text_str, boundary_type, offset, 1);
668 return get_text(*start_offset, *end_offset, text);
669 }
670
671 STDMETHODIMP BrowserAccessibilityWin::get_textBeforeOffset(
672 LONG offset,
673 enum IA2TextBoundaryType boundary_type,
674 LONG* start_offset, LONG* end_offset,
675 BSTR* text) {
676 if (!instance_active_)
677 return E_FAIL;
678
679 if (!start_offset || !end_offset || !text)
680 return E_INVALIDARG;
681
682 // The IAccessible2 spec says we don't have to implement the "sentence"
683 // boundary type, we can just let the screenreader handle it.
684 if (boundary_type == IA2_TEXT_BOUNDARY_SENTENCE) {
685 *start_offset = 0;
686 *end_offset = 0;
687 *text = NULL;
688 return S_FALSE;
689 }
690
691 const string16& text_str = TextForIAccessibleText();
692
693 *start_offset = FindBoundary(text_str, boundary_type, offset, -1);
694 *end_offset = offset;
695 return get_text(*start_offset, *end_offset, text);
696 }
697
698 STDMETHODIMP BrowserAccessibilityWin::get_textAfterOffset(
699 LONG offset,
700 enum IA2TextBoundaryType boundary_type,
701 LONG* start_offset, LONG* end_offset,
702 BSTR* text) {
703 if (!instance_active_)
704 return E_FAIL;
705
706 if (!start_offset || !end_offset || !text)
707 return E_INVALIDARG;
708
709 // The IAccessible2 spec says we don't have to implement the "sentence"
710 // boundary type, we can just let the screenreader handle it.
711 if (boundary_type == IA2_TEXT_BOUNDARY_SENTENCE) {
712 *start_offset = 0;
713 *end_offset = 0;
714 *text = NULL;
715 return S_FALSE;
716 }
717
718 const string16& text_str = TextForIAccessibleText();
719
720 *start_offset = offset;
721 *end_offset = FindBoundary(text_str, boundary_type, offset, 1);
722 return get_text(*start_offset, *end_offset, text);
723 }
724
649 // 725 //
650 // ISimpleDOMDocument methods. 726 // ISimpleDOMDocument methods.
651 // 727 //
652 728
653 STDMETHODIMP BrowserAccessibilityWin::get_URL(BSTR* url) { 729 STDMETHODIMP BrowserAccessibilityWin::get_URL(BSTR* url) {
654 if (!instance_active_) 730 if (!instance_active_)
655 return E_FAIL; 731 return E_FAIL;
656 732
657 if (!url) 733 if (!url)
658 return E_INVALIDARG; 734 return E_INVALIDARG;
(...skipping 463 matching lines...) Expand 10 before | Expand all | Expand 10 after
1122 if (!base::StringToInt(value_str, value_int)) 1198 if (!base::StringToInt(value_str, value_int))
1123 return false; 1199 return false;
1124 1200
1125 return true; 1201 return true;
1126 } 1202 }
1127 1203
1128 string16 BrowserAccessibilityWin::Escape(string16 str) { 1204 string16 BrowserAccessibilityWin::Escape(string16 str) {
1129 return EscapeQueryParamValueUTF8(str, false); 1205 return EscapeQueryParamValueUTF8(str, false);
1130 } 1206 }
1131 1207
1208 const string16& BrowserAccessibilityWin::TextForIAccessibleText() {
1209 if (role_ == WebAccessibility::ROLE_TEXT_FIELD) {
1210 return value_;
1211 } else {
1212 return name_;
1213 }
1214 }
1215
1216 LONG BrowserAccessibilityWin::FindBoundary(
1217 const string16& text,
1218 IA2TextBoundaryType boundary,
1219 LONG start_offset,
1220 LONG direction) {
1221 LONG text_size = static_cast<LONG>(text.size());
1222 DCHECK(start_offset >= 0 && start_offset <= text_size);
1223 DCHECK(direction == 1 || direction == -1);
1224
1225 if (boundary == IA2_TEXT_BOUNDARY_CHAR) {
1226 if (direction == 1 && start_offset < text_size)
1227 return start_offset + 1;
1228 else
1229 return start_offset;
1230 }
1231
1232 LONG result = start_offset;
1233 for (;;) {
1234 LONG pos;
1235 if (direction == 1) {
1236 if (result >= text_size)
1237 return text_size;
1238 pos = result;
1239 } else {
1240 if (result <= 0)
1241 return 0;
1242 pos = result - 1;
1243 }
1244
1245 switch (boundary) {
1246 case IA2_TEXT_BOUNDARY_WORD:
1247 if (IsWhitespace(text[pos]))
1248 return result;
1249 break;
1250 case IA2_TEXT_BOUNDARY_LINE:
1251 case IA2_TEXT_BOUNDARY_PARAGRAPH:
1252 if (text[pos] == '\n')
1253 return result;
1254 case IA2_TEXT_BOUNDARY_SENTENCE:
1255 // Note that we don't actually have to implement sentence support;
1256 // currently IAccessibleText functions return S_FALSE so that
1257 // screenreaders will handle it on their own.
1258 if ((text[pos] == '.' || text[pos] == '!' || text[pos] == '?') &&
1259 (pos == text_size - 1 || IsWhitespace(text[pos + 1]))) {
1260 return result;
1261 }
1262 case IA2_TEXT_BOUNDARY_ALL:
1263 default:
1264 break;
1265 }
1266
1267 if (direction > 0) {
1268 result++;
1269 } else if (direction < 0) {
1270 result--;
1271 } else {
1272 NOTREACHED();
1273 return result;
1274 }
1275 }
1276 }
1277
1132 void BrowserAccessibilityWin::InitRoleAndState() { 1278 void BrowserAccessibilityWin::InitRoleAndState() {
1133 ia_state_ = 0; 1279 ia_state_ = 0;
1134 ia2_state_ = IA2_STATE_OPAQUE; 1280 ia2_state_ = IA2_STATE_OPAQUE;
1135 1281
1136 if ((state_ >> WebAccessibility::STATE_CHECKED) & 1) 1282 if ((state_ >> WebAccessibility::STATE_CHECKED) & 1)
1137 ia_state_ |= STATE_SYSTEM_CHECKED; 1283 ia_state_ |= STATE_SYSTEM_CHECKED;
1138 if ((state_ >> WebAccessibility::STATE_COLLAPSED) & 1) 1284 if ((state_ >> WebAccessibility::STATE_COLLAPSED) & 1)
1139 ia_state_|= STATE_SYSTEM_COLLAPSED; 1285 ia_state_|= STATE_SYSTEM_COLLAPSED;
1140 if ((state_ >> WebAccessibility::STATE_EXPANDED) & 1) 1286 if ((state_ >> WebAccessibility::STATE_EXPANDED) & 1)
1141 ia_state_|= STATE_SYSTEM_EXPANDED; 1287 ia_state_|= STATE_SYSTEM_EXPANDED;
(...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after
1420 } 1566 }
1421 1567
1422 // The role should always be set. 1568 // The role should always be set.
1423 DCHECK(!role_name_.empty() || ia_role_); 1569 DCHECK(!role_name_.empty() || ia_role_);
1424 1570
1425 // If we didn't explicitly set the IAccessible2 role, make it the same 1571 // If we didn't explicitly set the IAccessible2 role, make it the same
1426 // as the MSAA role. 1572 // as the MSAA role.
1427 if (!ia2_role_) 1573 if (!ia2_role_)
1428 ia2_role_ = ia_role_; 1574 ia2_role_ = ia_role_;
1429 } 1575 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698