Chromium Code Reviews| 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 |