OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |