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

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

Issue 1195223006: Reports the position of the caret and current selection in content editables. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 6 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
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "content/browser/accessibility/browser_accessibility_win.h" 5 #include "content/browser/accessibility/browser_accessibility_win.h"
6 6
7 #include <algorithm>
7 #include <UIAutomationClient.h> 8 #include <UIAutomationClient.h>
8 #include <UIAutomationCoreApi.h> 9 #include <UIAutomationCoreApi.h>
9 10
10 #include "base/strings/string_number_conversions.h" 11 #include "base/strings/string_number_conversions.h"
11 #include "base/strings/string_split.h" 12 #include "base/strings/string_split.h"
12 #include "base/strings/string_util.h" 13 #include "base/strings/string_util.h"
13 #include "base/strings/utf_string_conversions.h" 14 #include "base/strings/utf_string_conversions.h"
14 #include "base/win/enum_variant.h" 15 #include "base/win/enum_variant.h"
15 #include "base/win/scoped_comptr.h" 16 #include "base/win/scoped_comptr.h"
16 #include "base/win/windows_version.h" 17 #include "base/win/windows_version.h"
(...skipping 1977 matching lines...) Expand 10 before | Expand all | Expand 10 after
1994 return S_OK; 1995 return S_OK;
1995 } 1996 }
1996 1997
1997 STDMETHODIMP BrowserAccessibilityWin::get_caretOffset(LONG* offset) { 1998 STDMETHODIMP BrowserAccessibilityWin::get_caretOffset(LONG* offset) {
1998 if (!instance_active()) 1999 if (!instance_active())
1999 return E_FAIL; 2000 return E_FAIL;
2000 2001
2001 if (!offset) 2002 if (!offset)
2002 return E_INVALIDARG; 2003 return E_INVALIDARG;
2003 2004
2004 // IA2 spec says that caret offset should be -1 if the object is not focused. 2005 // IA2 spec says that caret offset should be -1 if the caret is not active
2005 if (manager()->GetFocus(this) != this) { 2006 // on this object.
2007 if (!manager()->GetFocus(this)) {
2006 *offset = -1; 2008 *offset = -1;
2007 return S_FALSE; 2009 return S_FALSE;
2008 } 2010 }
2011
2012 int selection_start = GetSelectionStart();
dmazzoni 2015/06/22 19:23:21 nit: indentation
2009 2013
2010 *offset = 0; 2014 *offset = selection_start;
2011 if (IsEditableText()) { 2015 if (selection_start < 0)
2012 int sel_start = 0; 2016 return S_FALSE;
2013 if (GetIntAttribute(ui::AX_ATTR_TEXT_SEL_START,
2014 &sel_start))
2015 *offset = sel_start;
2016 }
2017 2017
2018 return S_OK; 2018 return S_OK;
2019 } 2019 }
2020 2020
2021 STDMETHODIMP BrowserAccessibilityWin::get_characterExtents( 2021 STDMETHODIMP BrowserAccessibilityWin::get_characterExtents(
2022 LONG offset, 2022 LONG offset,
2023 enum IA2CoordinateType coordinate_type, 2023 enum IA2CoordinateType coordinate_type,
2024 LONG* out_x, 2024 LONG* out_x,
2025 LONG* out_y, 2025 LONG* out_y,
2026 LONG* out_width, 2026 LONG* out_width,
(...skipping 29 matching lines...) Expand all
2056 } 2056 }
2057 2057
2058 STDMETHODIMP BrowserAccessibilityWin::get_nSelections(LONG* n_selections) { 2058 STDMETHODIMP BrowserAccessibilityWin::get_nSelections(LONG* n_selections) {
2059 if (!instance_active()) 2059 if (!instance_active())
2060 return E_FAIL; 2060 return E_FAIL;
2061 2061
2062 if (!n_selections) 2062 if (!n_selections)
2063 return E_INVALIDARG; 2063 return E_INVALIDARG;
2064 2064
2065 *n_selections = 0; 2065 *n_selections = 0;
2066 if (IsEditableText()) { 2066 int selection_start = GetSelectionStart();
2067 int sel_start = 0; 2067 int selection_end = GetSelectionEnd();
2068 int sel_end = 0; 2068 if (selection_start >= 0 && selection_end >= 0 &&
2069 if (GetIntAttribute(ui::AX_ATTR_TEXT_SEL_START, 2069 selection_start != selection_end)
2070 &sel_start) && 2070 *n_selections = 1;
2071 GetIntAttribute(ui::AX_ATTR_TEXT_SEL_END, &sel_end) &&
2072 sel_start != sel_end)
2073 *n_selections = 1;
2074 }
2075 2071
2076 return S_OK; 2072 return S_OK;
2077 } 2073 }
2078 2074
2079 STDMETHODIMP BrowserAccessibilityWin::get_selection(LONG selection_index, 2075 STDMETHODIMP BrowserAccessibilityWin::get_selection(LONG selection_index,
2080 LONG* start_offset, 2076 LONG* start_offset,
2081 LONG* end_offset) { 2077 LONG* end_offset) {
2082 if (!instance_active()) 2078 if (!instance_active())
2083 return E_FAIL; 2079 return E_FAIL;
2084 2080
2085 if (!start_offset || !end_offset || selection_index != 0) 2081 if (!start_offset || !end_offset || selection_index != 0)
2086 return E_INVALIDARG; 2082 return E_INVALIDARG;
2087 2083
2088 LONG n_selections = 0; 2084 LONG n_selections = 0;
2089 if (FAILED(get_nSelections(&n_selections)) || n_selections < 1) 2085 if (FAILED(get_nSelections(&n_selections)) || n_selections < 1)
2090 return E_INVALIDARG; 2086 return E_INVALIDARG;
2091 2087
2092 *start_offset = 0; 2088 *start_offset = 0;
2093 *end_offset = 0; 2089 *end_offset = 0;
2094 if (IsEditableText()) { 2090 int selection_start = GetSelectionStart();
2095 int sel_start = 0; 2091 int selection_end = GetSelectionEnd();
2096 int sel_end = 0; 2092 if (selection_start >= 0 && selection_end >= 0)
2097 if (GetIntAttribute( 2093 *start_offset = sel_start;
2098 ui::AX_ATTR_TEXT_SEL_START, &sel_start) && 2094 *end_offset = sel_end;
2099 GetIntAttribute(ui::AX_ATTR_TEXT_SEL_END, &sel_end)) {
2100 *start_offset = sel_start;
2101 *end_offset = sel_end;
2102 }
2103 } 2095 }
2104 2096
2105 return S_OK; 2097 return S_OK;
2106 } 2098 }
2107 2099
2108 STDMETHODIMP BrowserAccessibilityWin::get_text(LONG start_offset, 2100 STDMETHODIMP BrowserAccessibilityWin::get_text(LONG start_offset,
2109 LONG end_offset, 2101 LONG end_offset,
2110 BSTR* text) { 2102 BSTR* text) {
2111 if (!instance_active()) 2103 if (!instance_active())
2112 return E_FAIL; 2104 return E_FAIL;
(...skipping 1530 matching lines...) Expand 10 before | Expand all | Expand 10 after
3643 ui::AXIntAttribute attribute, 3635 ui::AXIntAttribute attribute,
3644 const char* ia2_attr) { 3636 const char* ia2_attr) {
3645 int value; 3637 int value;
3646 if (GetIntAttribute(attribute, &value)) { 3638 if (GetIntAttribute(attribute, &value)) {
3647 win_attributes_->ia2_attributes.push_back( 3639 win_attributes_->ia2_attributes.push_back(
3648 base::ASCIIToUTF16(ia2_attr) + L":" + 3640 base::ASCIIToUTF16(ia2_attr) + L":" +
3649 base::IntToString16(value)); 3641 base::IntToString16(value));
3650 } 3642 }
3651 } 3643 }
3652 3644
3645 int32 BrowserAccessibilityWin::GetHyperlinkIndexFromChild(
3646 const BrowserAccessibilityWin& child) const {
3647 auto& iterator = std::find(
3648 hyperlinks().begin(), hyperlinks().end(), child.GetId());
3649 if (iterator == hyperlinks().end())
3650 return -1;
3651
3652 return static_cast<int32>(iterator - hyperlinks().begin());
3653 }
3654
3655 int32 BrowserAccessibilityWin::GetHypertextOffsetFromHyperlinkIndex(
3656 int32 hyperlink_index) const {
3657 auto& offsets_map = hyperlink_offset_to_index();
3658 for (size_t i = 0; i < hyperlink_offset_to_index().size(); ++i)
3659 if (offsets_map[i].second == hyperlink_index)
3660 return offsets_map[i].first;
3661
3662 return -1;
3663 }
3664
3665 int32 BrowserAccessibilityWin::GetSelectionStart() const {
3666 int32 selection_start;
3667 if (!GetIntAttribute(ui::AX_ATTR_TEXT_SEL_START, &selection_start))
dmazzoni 2015/06/22 19:23:21 Did you mean this to be negated?
3668 return selection_start;
3669
3670 BrowserAccessibility* root = manager()->GetRoot();
3671 int32 focus_id;
3672 if (!root || !GetIntAttribute(ui::AX_ATTR_OBJ_SEL_START, &focus_id))
dmazzoni 2015/06/22 19:23:21 Did you mean to call GetIntAttribute on root?
3673 return -1;
3674
3675 BrowserAccessibilityWin* focus_object = manager()->GetFromID(
3676 focus_id)->ToBrowserAccessibilityWin();
3677 if (!focus_object)
3678 return -1;
3679
3680 if (focus_object == this) {
3681 int focus_offset;
3682 if (!GetIntAttribute(ui::AX_ATTR_SEL_TEXT_START, &focus_offset))
3683 return -1;
3684
3685 return focus_offset;
3686 }
3687
3688 auto focus_parent = focus_object->GetParent();
dmazzoni 2015/06/22 19:23:21 Stick this part of the code in a helper function t
3689 while (parent_object && parent_object != this) {
3690 focus_object = parent_object;
3691 parent_object = focus_object->GetParent();
3692 }
3693 if (!parent_object)
3694 return -1;
3695
3696 int32 hyperlink_index = parent_object->GetHyperlinkIndexFromChild(
3697 focus_object);
3698 if (hyperlink_index < 0)
3699 return -1;
3700
3701 hypertext_offset = parent_object->GetHypertextOffsetFromHyperlinkIndex(
3702 hyperlink_index);
3703 if (hypertext_offset < 0)
3704 return -1;
3705
3706 return hypertext_offset;
3707 }
3708
3709 int32 BrowserAccessibilityWin::GetSelectionEnd() const {
3710 int selection_end;
3711 if (!GetIntAttribute(ui::AX_ATTR_TEXT_SEL_END, &selection_end))
3712 return selection_end;
3713
3714 BrowserAccessibility* root = manager()->GetRoot();
3715 int32 anchor_id;
3716 if (!root || !GetIntAttribute(ui::AX_ATTR_OBJ_SEL_END, &anchor_id))
3717 return -1;
3718
3719 BrowserAccessibilityWin* anchor_object = manager()->GetFromID(
3720 anchor_id)->ToBrowserAccessibilityWin();
3721 if (!anchor_object)
3722 return -1;
3723
3724 if (anchor_object == this) {
3725 int anchor_offset;
3726 if (!GetIntAttribute(ui::AX_ATTR_SEL_TEXT_END, &anchor_offset))
3727 return -1;
3728
3729 return anchor_offset;
3730 }
3731
3732 auto anchor_parent = anchor_object->GetParent();
3733 while (parent_object && parent_object != this) {
3734 anchor_object = parent_object;
3735 parent_object = anchor_object->GetParent();
3736 }
3737 if (!parent_object)
3738 return -1;
3739
3740 int32 hyperlink_index = parent_object->GetHyperlinkIndexFromChild(
3741 anchor_object);
3742 if (hyperlink_index < 0)
3743 return -1;
3744
3745 int32 hypertext_offset = parent_object->GetHypertextOffsetFromHyperlinkIndex(
3746 hyperlink_index);
3747 if (hypertext_offset < 0)
3748 return -1;
3749
3750 return hypertext_offset;
3751 }
3752
3653 base::string16 BrowserAccessibilityWin::GetNameRecursive() const { 3753 base::string16 BrowserAccessibilityWin::GetNameRecursive() const {
3654 if (!name().empty()) { 3754 if (!name().empty()) {
3655 return name(); 3755 return name();
3656 } 3756 }
3657 3757
3658 base::string16 result; 3758 base::string16 result;
3659 for (uint32 i = 0; i < PlatformChildCount(); ++i) { 3759 for (uint32 i = 0; i < PlatformChildCount(); ++i) {
3660 result += PlatformGetChild(i)->ToBrowserAccessibilityWin()-> 3760 result += PlatformGetChild(i)->ToBrowserAccessibilityWin()->
3661 GetNameRecursive(); 3761 GetNameRecursive();
3662 } 3762 }
(...skipping 711 matching lines...) Expand 10 before | Expand all | Expand 10 after
4374 ia2_role = ia_role; 4474 ia2_role = ia_role;
4375 4475
4376 win_attributes_->ia_role = ia_role; 4476 win_attributes_->ia_role = ia_role;
4377 win_attributes_->ia_state = ia_state; 4477 win_attributes_->ia_state = ia_state;
4378 win_attributes_->role_name = role_name; 4478 win_attributes_->role_name = role_name;
4379 win_attributes_->ia2_role = ia2_role; 4479 win_attributes_->ia2_role = ia2_role;
4380 win_attributes_->ia2_state = ia2_state; 4480 win_attributes_->ia2_state = ia2_state;
4381 } 4481 }
4382 4482
4383 } // namespace content 4483 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698