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 <UIAutomationClient.h> | 7 #include <UIAutomationClient.h> |
8 #include <UIAutomationCoreApi.h> | 8 #include <UIAutomationCoreApi.h> |
9 #include <algorithm> | |
dmazzoni
2015/07/16 19:50:23
Nit: don't group this with the Microsoft includes,
| |
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" |
17 #include "content/browser/accessibility/browser_accessibility_manager_win.h" | 18 #include "content/browser/accessibility/browser_accessibility_manager_win.h" |
18 #include "content/browser/accessibility/browser_accessibility_state_impl.h" | 19 #include "content/browser/accessibility/browser_accessibility_state_impl.h" |
(...skipping 1978 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1997 return S_OK; | 1998 return S_OK; |
1998 } | 1999 } |
1999 | 2000 |
2000 STDMETHODIMP BrowserAccessibilityWin::get_caretOffset(LONG* offset) { | 2001 STDMETHODIMP BrowserAccessibilityWin::get_caretOffset(LONG* offset) { |
2001 if (!instance_active()) | 2002 if (!instance_active()) |
2002 return E_FAIL; | 2003 return E_FAIL; |
2003 | 2004 |
2004 if (!offset) | 2005 if (!offset) |
2005 return E_INVALIDARG; | 2006 return E_INVALIDARG; |
2006 | 2007 |
2007 // IA2 spec says that caret offset should be -1 if the object is not focused. | 2008 int selection_start, selection_end; |
2008 if (manager()->GetFocus(this) != this) { | 2009 GetSelectionOffsets(&selection_start, &selection_end); |
dmazzoni
2015/07/16 19:50:23
Are you 100% sure that this change isn't going to
| |
2009 *offset = -1; | 2010 *offset = selection_start; |
2011 if (selection_start < 0) | |
2010 return S_FALSE; | 2012 return S_FALSE; |
2011 } | |
2012 | |
2013 *offset = 0; | |
2014 if (IsEditableText()) { | |
2015 int sel_start = 0; | |
2016 if (GetIntAttribute(ui::AX_ATTR_TEXT_SEL_START, | |
2017 &sel_start)) | |
2018 *offset = sel_start; | |
2019 } | |
2020 | 2013 |
2021 return S_OK; | 2014 return S_OK; |
2022 } | 2015 } |
2023 | 2016 |
2024 STDMETHODIMP BrowserAccessibilityWin::get_characterExtents( | 2017 STDMETHODIMP BrowserAccessibilityWin::get_characterExtents( |
2025 LONG offset, | 2018 LONG offset, |
2026 enum IA2CoordinateType coordinate_type, | 2019 enum IA2CoordinateType coordinate_type, |
2027 LONG* out_x, | 2020 LONG* out_x, |
2028 LONG* out_y, | 2021 LONG* out_y, |
2029 LONG* out_width, | 2022 LONG* out_width, |
(...skipping 29 matching lines...) Expand all Loading... | |
2059 } | 2052 } |
2060 | 2053 |
2061 STDMETHODIMP BrowserAccessibilityWin::get_nSelections(LONG* n_selections) { | 2054 STDMETHODIMP BrowserAccessibilityWin::get_nSelections(LONG* n_selections) { |
2062 if (!instance_active()) | 2055 if (!instance_active()) |
2063 return E_FAIL; | 2056 return E_FAIL; |
2064 | 2057 |
2065 if (!n_selections) | 2058 if (!n_selections) |
2066 return E_INVALIDARG; | 2059 return E_INVALIDARG; |
2067 | 2060 |
2068 *n_selections = 0; | 2061 *n_selections = 0; |
2069 if (IsEditableText()) { | 2062 int selection_start, selection_end; |
2070 int sel_start = 0; | 2063 GetSelectionOffsets(&selection_start, &selection_end); |
2071 int sel_end = 0; | 2064 if (selection_start >= 0 && selection_end >= 0 && |
2072 if (GetIntAttribute(ui::AX_ATTR_TEXT_SEL_START, | 2065 selection_start != selection_end) |
2073 &sel_start) && | 2066 *n_selections = 1; |
2074 GetIntAttribute(ui::AX_ATTR_TEXT_SEL_END, &sel_end) && | |
2075 sel_start != sel_end) | |
2076 *n_selections = 1; | |
2077 } | |
2078 | 2067 |
2079 return S_OK; | 2068 return S_OK; |
2080 } | 2069 } |
2081 | 2070 |
2082 STDMETHODIMP BrowserAccessibilityWin::get_selection(LONG selection_index, | 2071 STDMETHODIMP BrowserAccessibilityWin::get_selection(LONG selection_index, |
2083 LONG* start_offset, | 2072 LONG* start_offset, |
2084 LONG* end_offset) { | 2073 LONG* end_offset) { |
2085 if (!instance_active()) | 2074 if (!instance_active()) |
2086 return E_FAIL; | 2075 return E_FAIL; |
2087 | 2076 |
2088 if (!start_offset || !end_offset || selection_index != 0) | 2077 if (!start_offset || !end_offset || selection_index != 0) |
2089 return E_INVALIDARG; | 2078 return E_INVALIDARG; |
2090 | 2079 |
2091 LONG n_selections = 0; | 2080 LONG n_selections = 0; |
2092 if (FAILED(get_nSelections(&n_selections)) || n_selections < 1) | 2081 if (FAILED(get_nSelections(&n_selections)) || n_selections < 1) |
2093 return E_INVALIDARG; | 2082 return E_INVALIDARG; |
2094 | 2083 |
2095 *start_offset = 0; | 2084 *start_offset = 0; |
2096 *end_offset = 0; | 2085 *end_offset = 0; |
2097 if (IsEditableText()) { | 2086 int selection_start, selection_end; |
2098 int sel_start = 0; | 2087 GetSelectionOffsets(&selection_start, &selection_end); |
2099 int sel_end = 0; | 2088 if (selection_start >= 0 && selection_end >= 0) { |
2100 if (GetIntAttribute( | 2089 *start_offset = selection_start; |
2101 ui::AX_ATTR_TEXT_SEL_START, &sel_start) && | 2090 *end_offset = selection_end; |
2102 GetIntAttribute(ui::AX_ATTR_TEXT_SEL_END, &sel_end)) { | |
2103 *start_offset = sel_start; | |
2104 *end_offset = sel_end; | |
2105 } | |
2106 } | 2091 } |
2107 | 2092 |
2108 return S_OK; | 2093 return S_OK; |
2109 } | 2094 } |
2110 | 2095 |
2111 STDMETHODIMP BrowserAccessibilityWin::get_text(LONG start_offset, | 2096 STDMETHODIMP BrowserAccessibilityWin::get_text(LONG start_offset, |
2112 LONG end_offset, | 2097 LONG end_offset, |
2113 BSTR* text) { | 2098 BSTR* text) { |
2114 if (!instance_active()) | 2099 if (!instance_active()) |
2115 return E_FAIL; | 2100 return E_FAIL; |
(...skipping 1530 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3646 ui::AXIntAttribute attribute, | 3631 ui::AXIntAttribute attribute, |
3647 const char* ia2_attr) { | 3632 const char* ia2_attr) { |
3648 int value; | 3633 int value; |
3649 if (GetIntAttribute(attribute, &value)) { | 3634 if (GetIntAttribute(attribute, &value)) { |
3650 win_attributes_->ia2_attributes.push_back( | 3635 win_attributes_->ia2_attributes.push_back( |
3651 base::ASCIIToUTF16(ia2_attr) + L":" + | 3636 base::ASCIIToUTF16(ia2_attr) + L":" + |
3652 base::IntToString16(value)); | 3637 base::IntToString16(value)); |
3653 } | 3638 } |
3654 } | 3639 } |
3655 | 3640 |
3641 int32 BrowserAccessibilityWin::GetHyperlinkIndexFromChild( | |
3642 const BrowserAccessibilityWin& child) const { | |
3643 auto iterator = std::find( | |
3644 hyperlinks().begin(), hyperlinks().end(), child.GetId()); | |
3645 if (iterator == hyperlinks().end()) | |
3646 return -1; | |
3647 | |
3648 return static_cast<int32>(iterator - hyperlinks().begin()); | |
3649 } | |
3650 | |
3651 int32 BrowserAccessibilityWin::GetHypertextOffsetFromHyperlinkIndex( | |
3652 int32 hyperlink_index) const { | |
3653 auto& offsets_map = hyperlink_offset_to_index(); | |
3654 for (auto& offset_index : offsets_map) | |
dmazzoni
2015/07/16 19:50:23
Braces around the body of the for loop since there
| |
3655 if (offset_index.second == hyperlink_index) | |
3656 return offset_index.first; | |
3657 | |
3658 return -1; | |
3659 } | |
3660 | |
3661 int32 BrowserAccessibilityWin::GetHypertextOffsetFromChild( | |
3662 const BrowserAccessibilityWin& child) const { | |
3663 int32 hyperlink_index = GetHyperlinkIndexFromChild(child); | |
3664 if (hyperlink_index < 0) | |
3665 return -1; | |
3666 | |
3667 return GetHypertextOffsetFromHyperlinkIndex(hyperlink_index); | |
3668 } | |
3669 | |
3670 int32 BrowserAccessibilityWin::GetHypertextOffsetFromDescendant( | |
3671 const BrowserAccessibilityWin& descendant) const { | |
3672 auto parent_object = descendant.GetParent()->ToBrowserAccessibilityWin(); | |
3673 auto current_object = const_cast<BrowserAccessibilityWin*>(&descendant); | |
3674 while (parent_object && parent_object != this) { | |
3675 current_object = parent_object; | |
3676 parent_object = current_object->GetParent()->ToBrowserAccessibilityWin(); | |
3677 } | |
3678 if (!parent_object) | |
3679 return -1; | |
3680 | |
3681 return parent_object->GetHypertextOffsetFromChild(*current_object); | |
3682 } | |
3683 | |
3684 int BrowserAccessibilityWin::GetSelectionAnchor() const { | |
3685 BrowserAccessibility* root = manager()->GetRoot(); | |
3686 int32 anchor_id; | |
3687 if (!root || !root->GetIntAttribute(ui::AX_ATTR_ANCHOR_OBJECT_ID, &anchor_id)) | |
3688 return -1; | |
3689 | |
3690 BrowserAccessibilityWin* anchor_object = manager()->GetFromID( | |
3691 anchor_id)->ToBrowserAccessibilityWin(); | |
3692 if (!anchor_object) | |
3693 return -1; | |
3694 | |
3695 if (anchor_object->IsDescendantOf(this)) | |
3696 return GetHypertextOffsetFromDescendant(*anchor_object); | |
3697 | |
3698 if (IsDescendantOf(anchor_object)) { | |
3699 int anchor_offset; | |
3700 if (!root->GetIntAttribute(ui::AX_ATTR_ANCHOR_OFFSET, &anchor_offset)) | |
3701 return -1; | |
3702 | |
3703 return anchor_offset; | |
3704 } | |
3705 | |
3706 return -1; | |
3707 } | |
3708 | |
3709 int BrowserAccessibilityWin::GetSelectionFocus() const { | |
3710 BrowserAccessibility* root = manager()->GetRoot(); | |
3711 int32 focus_id; | |
3712 if (!root || !root->GetIntAttribute(ui::AX_ATTR_FOCUS_OBJECT_ID, &focus_id)) | |
3713 return -1; | |
3714 | |
3715 BrowserAccessibilityWin* focus_object = manager()->GetFromID( | |
3716 focus_id)->ToBrowserAccessibilityWin(); | |
3717 if (!focus_object) | |
3718 return -1; | |
3719 | |
3720 if (focus_object->IsDescendantOf(this)) | |
3721 return GetHypertextOffsetFromDescendant(*focus_object); | |
3722 | |
3723 if (IsDescendantOf(focus_object)) { | |
3724 int focus_offset; | |
3725 if (!root->GetIntAttribute(ui::AX_ATTR_FOCUS_OFFSET, &focus_offset)) | |
3726 return -1; | |
3727 | |
3728 return focus_offset; | |
3729 } | |
3730 | |
3731 return -1; | |
3732 } | |
3733 | |
3734 void BrowserAccessibilityWin::GetSelectionOffsets( | |
3735 int* selection_start, int* selection_end) const { | |
3736 if (!selection_start || !selection_end) | |
3737 return; | |
3738 | |
3739 if (GetIntAttribute(ui::AX_ATTR_TEXT_SEL_START, selection_start) && | |
3740 GetIntAttribute(ui::AX_ATTR_TEXT_SEL_END, selection_end)) { | |
3741 return; | |
3742 } | |
3743 | |
3744 *selection_start = GetSelectionAnchor(); | |
3745 *selection_end = GetSelectionFocus(); | |
3746 if (*selection_start < 0 || *selection_end < 0) | |
3747 return; | |
3748 | |
3749 if (*selection_end < *selection_start) | |
3750 std::swap(*selection_start, *selection_end); | |
dmazzoni
2015/07/16 19:50:23
Are you sure this is correct? I think IA2 might su
| |
3751 | |
3752 // IA2 Spec says that the end of the selection should be after the last | |
3753 // embedded object character that is part of the selection. | |
3754 ++(*selection_end); | |
3755 } | |
3756 | |
3656 base::string16 BrowserAccessibilityWin::GetNameRecursive() const { | 3757 base::string16 BrowserAccessibilityWin::GetNameRecursive() const { |
3657 if (!name().empty()) { | 3758 if (!name().empty()) { |
3658 return name(); | 3759 return name(); |
3659 } | 3760 } |
3660 | 3761 |
3661 base::string16 result; | 3762 base::string16 result; |
3662 for (uint32 i = 0; i < PlatformChildCount(); ++i) { | 3763 for (uint32 i = 0; i < PlatformChildCount(); ++i) { |
3663 result += PlatformGetChild(i)->ToBrowserAccessibilityWin()-> | 3764 result += PlatformGetChild(i)->ToBrowserAccessibilityWin()-> |
3664 GetNameRecursive(); | 3765 GetNameRecursive(); |
3665 } | 3766 } |
(...skipping 711 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4377 ia2_role = ia_role; | 4478 ia2_role = ia_role; |
4378 | 4479 |
4379 win_attributes_->ia_role = ia_role; | 4480 win_attributes_->ia_role = ia_role; |
4380 win_attributes_->ia_state = ia_state; | 4481 win_attributes_->ia_state = ia_state; |
4381 win_attributes_->role_name = role_name; | 4482 win_attributes_->role_name = role_name; |
4382 win_attributes_->ia2_role = ia2_role; | 4483 win_attributes_->ia2_role = ia2_role; |
4383 win_attributes_->ia2_state = ia2_state; | 4484 win_attributes_->ia2_state = ia2_state; |
4384 } | 4485 } |
4385 | 4486 |
4386 } // namespace content | 4487 } // namespace content |
OLD | NEW |