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 | 9 |
10 #include <algorithm> | 10 #include <algorithm> |
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
200 | 200 |
201 // static | 201 // static |
202 BrowserAccessibility* BrowserAccessibility::Create() { | 202 BrowserAccessibility* BrowserAccessibility::Create() { |
203 ui::win::CreateATLModuleIfNeeded(); | 203 ui::win::CreateATLModuleIfNeeded(); |
204 CComObject<BrowserAccessibilityWin>* instance; | 204 CComObject<BrowserAccessibilityWin>* instance; |
205 HRESULT hr = CComObject<BrowserAccessibilityWin>::CreateInstance(&instance); | 205 HRESULT hr = CComObject<BrowserAccessibilityWin>::CreateInstance(&instance); |
206 DCHECK(SUCCEEDED(hr)); | 206 DCHECK(SUCCEEDED(hr)); |
207 return instance->NewReference(); | 207 return instance->NewReference(); |
208 } | 208 } |
209 | 209 |
210 const BrowserAccessibilityWin* BrowserAccessibility::ToBrowserAccessibilityWin() | |
211 const { | |
212 return static_cast<const BrowserAccessibilityWin*>(this); | |
213 } | |
214 | |
215 BrowserAccessibilityWin* BrowserAccessibility::ToBrowserAccessibilityWin() { | 210 BrowserAccessibilityWin* BrowserAccessibility::ToBrowserAccessibilityWin() { |
216 return static_cast<BrowserAccessibilityWin*>(this); | 211 return static_cast<BrowserAccessibilityWin*>(this); |
217 } | 212 } |
218 | 213 |
219 BrowserAccessibilityWin::BrowserAccessibilityWin() | 214 BrowserAccessibilityWin::BrowserAccessibilityWin() |
220 : win_attributes_(new WinAttributes()), | 215 : win_attributes_(new WinAttributes()), |
221 previous_scroll_x_(0), | 216 previous_scroll_x_(0), |
222 previous_scroll_y_(0) { | 217 previous_scroll_y_(0) { |
223 // Start unique IDs at -1 and decrement each time, because get_accChild | 218 // Start unique IDs at -1 and decrement each time, because get_accChild |
224 // uses positive IDs to enumerate children, so we use negative IDs to | 219 // uses positive IDs to enumerate children, so we use negative IDs to |
(...skipping 1783 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2008 | 2003 |
2009 STDMETHODIMP BrowserAccessibilityWin::get_caretOffset(LONG* offset) { | 2004 STDMETHODIMP BrowserAccessibilityWin::get_caretOffset(LONG* offset) { |
2010 if (!instance_active()) | 2005 if (!instance_active()) |
2011 return E_FAIL; | 2006 return E_FAIL; |
2012 | 2007 |
2013 if (!offset) | 2008 if (!offset) |
2014 return E_INVALIDARG; | 2009 return E_INVALIDARG; |
2015 | 2010 |
2016 int selection_start, selection_end; | 2011 int selection_start, selection_end; |
2017 GetSelectionOffsets(&selection_start, &selection_end); | 2012 GetSelectionOffsets(&selection_start, &selection_end); |
2018 // The caret is always at the end of the selection, if a selection exists. | 2013 *offset = selection_start; |
2019 *offset = selection_end; | 2014 if (selection_start < 0) |
2020 if (*offset < 0) | |
2021 return S_FALSE; | 2015 return S_FALSE; |
2022 | 2016 |
2023 return S_OK; | 2017 return S_OK; |
2024 } | 2018 } |
2025 | 2019 |
2026 STDMETHODIMP BrowserAccessibilityWin::get_characterExtents( | 2020 STDMETHODIMP BrowserAccessibilityWin::get_characterExtents( |
2027 LONG offset, | 2021 LONG offset, |
2028 enum IA2CoordinateType coordinate_type, | 2022 enum IA2CoordinateType coordinate_type, |
2029 LONG* out_x, | 2023 LONG* out_x, |
2030 LONG* out_y, | 2024 LONG* out_y, |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2064 if (!instance_active()) | 2058 if (!instance_active()) |
2065 return E_FAIL; | 2059 return E_FAIL; |
2066 | 2060 |
2067 if (!n_selections) | 2061 if (!n_selections) |
2068 return E_INVALIDARG; | 2062 return E_INVALIDARG; |
2069 | 2063 |
2070 *n_selections = 0; | 2064 *n_selections = 0; |
2071 int selection_start, selection_end; | 2065 int selection_start, selection_end; |
2072 GetSelectionOffsets(&selection_start, &selection_end); | 2066 GetSelectionOffsets(&selection_start, &selection_end); |
2073 if (selection_start >= 0 && selection_end >= 0 && | 2067 if (selection_start >= 0 && selection_end >= 0 && |
2074 selection_start != selection_end) { | 2068 selection_start != selection_end) |
2075 *n_selections = 1; | 2069 *n_selections = 1; |
2076 } | |
2077 | 2070 |
2078 return S_OK; | 2071 return S_OK; |
2079 } | 2072 } |
2080 | 2073 |
2081 STDMETHODIMP BrowserAccessibilityWin::get_selection(LONG selection_index, | 2074 STDMETHODIMP BrowserAccessibilityWin::get_selection(LONG selection_index, |
2082 LONG* start_offset, | 2075 LONG* start_offset, |
2083 LONG* end_offset) { | 2076 LONG* end_offset) { |
2084 if (!instance_active()) | 2077 if (!instance_active()) |
2085 return E_FAIL; | 2078 return E_FAIL; |
2086 | 2079 |
2087 if (!start_offset || !end_offset || selection_index != 0) | 2080 if (!start_offset || !end_offset || selection_index != 0) |
2088 return E_INVALIDARG; | 2081 return E_INVALIDARG; |
2089 | 2082 |
2090 LONG n_selections = 0; | 2083 LONG n_selections = 0; |
2091 if (FAILED(get_nSelections(&n_selections)) || n_selections < 1) | 2084 if (FAILED(get_nSelections(&n_selections)) || n_selections < 1) |
2092 return E_INVALIDARG; | 2085 return E_INVALIDARG; |
2093 | 2086 |
2094 *start_offset = 0; | 2087 *start_offset = 0; |
2095 *end_offset = 0; | 2088 *end_offset = 0; |
2096 int selection_start, selection_end; | 2089 int selection_start, selection_end; |
2097 GetSelectionOffsets(&selection_start, &selection_end); | 2090 GetSelectionOffsets(&selection_start, &selection_end); |
2098 if (selection_start >= 0 && selection_end >= 0) { | 2091 if (selection_start >= 0 && selection_end >= 0) { |
2099 // We should ignore the direction of the selection when exposing start and | |
2100 // end offsets. According to the IA2 Spec the end offset is always increased | |
2101 // by one past the end of the selection. This wouldn't make sense if | |
2102 // end < start. | |
2103 if (selection_end < selection_start) | |
2104 std::swap(selection_start, selection_end); | |
2105 | |
2106 *start_offset = selection_start; | 2092 *start_offset = selection_start; |
2107 *end_offset = selection_end; | 2093 *end_offset = selection_end; |
2108 } | 2094 } |
2109 | 2095 |
2110 return S_OK; | 2096 return S_OK; |
2111 } | 2097 } |
2112 | 2098 |
2113 STDMETHODIMP BrowserAccessibilityWin::get_text(LONG start_offset, | 2099 STDMETHODIMP BrowserAccessibilityWin::get_text(LONG start_offset, |
2114 LONG end_offset, | 2100 LONG end_offset, |
2115 BSTR* text) { | 2101 BSTR* text) { |
(...skipping 1539 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3655 int value; | 3641 int value; |
3656 if (GetIntAttribute(attribute, &value)) { | 3642 if (GetIntAttribute(attribute, &value)) { |
3657 win_attributes_->ia2_attributes.push_back( | 3643 win_attributes_->ia2_attributes.push_back( |
3658 base::ASCIIToUTF16(ia2_attr) + L":" + | 3644 base::ASCIIToUTF16(ia2_attr) + L":" + |
3659 base::IntToString16(value)); | 3645 base::IntToString16(value)); |
3660 } | 3646 } |
3661 } | 3647 } |
3662 | 3648 |
3663 int32 BrowserAccessibilityWin::GetHyperlinkIndexFromChild( | 3649 int32 BrowserAccessibilityWin::GetHyperlinkIndexFromChild( |
3664 const BrowserAccessibilityWin& child) const { | 3650 const BrowserAccessibilityWin& child) const { |
3665 if (hyperlinks().empty()) | |
3666 return -1; | |
3667 | |
3668 auto iterator = std::find( | 3651 auto iterator = std::find( |
3669 hyperlinks().begin(), hyperlinks().end(), child.GetId()); | 3652 hyperlinks().begin(), hyperlinks().end(), child.GetId()); |
3670 if (iterator == hyperlinks().end()) | 3653 if (iterator == hyperlinks().end()) |
3671 return -1; | 3654 return -1; |
3672 | 3655 |
3673 return static_cast<int32>(iterator - hyperlinks().begin()); | 3656 return static_cast<int32>(iterator - hyperlinks().begin()); |
3674 } | 3657 } |
3675 | 3658 |
3676 int32 BrowserAccessibilityWin::GetHypertextOffsetFromHyperlinkIndex( | 3659 int32 BrowserAccessibilityWin::GetHypertextOffsetFromHyperlinkIndex( |
3677 int32 hyperlink_index) const { | 3660 int32 hyperlink_index) const { |
3678 for (auto& offset_index : hyperlink_offset_to_index()) { | 3661 auto& offsets_map = hyperlink_offset_to_index(); |
| 3662 for (auto& offset_index : offsets_map) { |
3679 if (offset_index.second == hyperlink_index) | 3663 if (offset_index.second == hyperlink_index) |
3680 return offset_index.first; | 3664 return offset_index.first; |
3681 } | 3665 } |
3682 | 3666 |
3683 return -1; | 3667 return -1; |
3684 } | 3668 } |
3685 | 3669 |
3686 int32 BrowserAccessibilityWin::GetHypertextOffsetFromChild( | 3670 int32 BrowserAccessibilityWin::GetHypertextOffsetFromChild( |
3687 const BrowserAccessibilityWin& child) const { | 3671 const BrowserAccessibilityWin& child) const { |
3688 int32 hyperlink_index = GetHyperlinkIndexFromChild(child); | 3672 int32 hyperlink_index = GetHyperlinkIndexFromChild(child); |
(...skipping 10 matching lines...) Expand all Loading... |
3699 while (parent_object && parent_object != this) { | 3683 while (parent_object && parent_object != this) { |
3700 current_object = parent_object; | 3684 current_object = parent_object; |
3701 parent_object = current_object->GetParent()->ToBrowserAccessibilityWin(); | 3685 parent_object = current_object->GetParent()->ToBrowserAccessibilityWin(); |
3702 } | 3686 } |
3703 if (!parent_object) | 3687 if (!parent_object) |
3704 return -1; | 3688 return -1; |
3705 | 3689 |
3706 return parent_object->GetHypertextOffsetFromChild(*current_object); | 3690 return parent_object->GetHypertextOffsetFromChild(*current_object); |
3707 } | 3691 } |
3708 | 3692 |
3709 int BrowserAccessibilityWin::GetHypertextOffsetFromEndpoint( | |
3710 const BrowserAccessibilityWin& endpoint_object, | |
3711 int endpoint_offset) const { | |
3712 // There are three cases: | |
3713 // 1. Either the selection endpoint is inside this object or is an ancestor of | |
3714 // of this object. endpoint_offset should be returned. | |
3715 // 2. The selection endpoint is a pure descendant of this object. The offset | |
3716 // of the embedded object character corresponding to the subtree in which | |
3717 // the endpoint is located should be returned. | |
3718 // 3. The selection endpoint is in a completely different part of the tree. | |
3719 // Either 0 or text_length should be returned depending on the direction that | |
3720 // one needs to travel to find the endpoint. | |
3721 | |
3722 // Case 1. | |
3723 // | |
3724 // IsDescendantOf includes the case when endpoint_object == this. | |
3725 if (IsDescendantOf(&endpoint_object) || | |
3726 // Handle the case when the endpoint is a direct text-only child. | |
3727 // The selection offset should still be valid on the parent. | |
3728 (endpoint_object.IsTextOnlyObject() && | |
3729 endpoint_object.GetParent() == this)) { | |
3730 return endpoint_offset; | |
3731 } | |
3732 | |
3733 const BrowserAccessibility* common_parent = this; | |
3734 while (common_parent && !endpoint_object.IsDescendantOf(common_parent)) { | |
3735 common_parent = common_parent->GetParent(); | |
3736 } | |
3737 if (!common_parent) | |
3738 return -1; | |
3739 | |
3740 auto common_parent_win = common_parent->ToBrowserAccessibilityWin(); | |
3741 // Text only objects must have a parent. | |
3742 DCHECK(!IsTextOnlyObject() || GetParent()); | |
3743 DCHECK(!endpoint_object.IsTextOnlyObject() || endpoint_object.GetParent()); | |
3744 // Text only objects that are direct descendants should behave as if they | |
3745 // are part of their parent when computing hyperlink offsets. | |
3746 const BrowserAccessibilityWin* nearest_non_text_ancestor = | |
3747 IsTextOnlyObject() ? GetParent()->ToBrowserAccessibilityWin() : this; | |
3748 const BrowserAccessibilityWin& nearest_non_text_endpoint = | |
3749 endpoint_object.IsTextOnlyObject() | |
3750 ? *(endpoint_object.GetParent()->ToBrowserAccessibilityWin()) | |
3751 : endpoint_object; | |
3752 | |
3753 // Case 2. | |
3754 // | |
3755 // We already checked in case 1 if our endpoint is inside this object. | |
3756 // We can safely assume that it is a descendant or in a completely different | |
3757 // part of the tree. | |
3758 if (common_parent_win == nearest_non_text_ancestor) { | |
3759 return nearest_non_text_ancestor->GetHypertextOffsetFromDescendant( | |
3760 nearest_non_text_endpoint); | |
3761 } | |
3762 | |
3763 // Case 3. | |
3764 // | |
3765 // We can safely assume that the endpoint is in another part of the tree or | |
3766 // at common parent, and that this object is a descendant of common parent. | |
3767 int current_offset = | |
3768 static_cast<int>(common_parent_win->GetHypertextOffsetFromDescendant( | |
3769 *nearest_non_text_ancestor)); | |
3770 DCHECK_GE(current_offset, 0); | |
3771 if (common_parent_win != &nearest_non_text_endpoint) { | |
3772 endpoint_offset = | |
3773 static_cast<int>(common_parent_win->GetHypertextOffsetFromDescendant( | |
3774 nearest_non_text_endpoint)); | |
3775 DCHECK_GE(endpoint_offset, 0); | |
3776 } | |
3777 | |
3778 if (endpoint_offset < current_offset) | |
3779 return 0; | |
3780 if (endpoint_offset > current_offset) | |
3781 return TextForIAccessibleText().length(); | |
3782 | |
3783 NOTREACHED(); | |
3784 return -1; | |
3785 } | |
3786 | |
3787 int BrowserAccessibilityWin::GetSelectionAnchor() const { | 3693 int BrowserAccessibilityWin::GetSelectionAnchor() const { |
3788 BrowserAccessibility* root = manager()->GetRoot(); | 3694 BrowserAccessibility* root = manager()->GetRoot(); |
3789 int32 anchor_id; | 3695 int32 anchor_id; |
3790 if (!root || !root->GetIntAttribute(ui::AX_ATTR_ANCHOR_OBJECT_ID, &anchor_id)) | 3696 if (!root || !root->GetIntAttribute(ui::AX_ATTR_ANCHOR_OBJECT_ID, &anchor_id)) |
3791 return -1; | 3697 return -1; |
3792 | 3698 |
3793 BrowserAccessibilityWin* anchor_object = manager()->GetFromID( | 3699 BrowserAccessibilityWin* anchor_object = manager()->GetFromID( |
3794 anchor_id)->ToBrowserAccessibilityWin(); | 3700 anchor_id)->ToBrowserAccessibilityWin(); |
3795 if (!anchor_object) | 3701 if (!anchor_object) |
3796 return -1; | 3702 return -1; |
3797 | 3703 |
3798 int anchor_offset; | 3704 // Includes the case when anchor_object == this. |
3799 if (!root->GetIntAttribute(ui::AX_ATTR_ANCHOR_OFFSET, &anchor_offset)) | 3705 if (IsDescendantOf(anchor_object) || |
3800 return -1; | 3706 // Text only objects that are direct descendants should behave as if they |
| 3707 // are part of this object when computing hypertext. |
| 3708 (anchor_object->GetParent() == this && |
| 3709 anchor_object->IsTextOnlyObject())) { |
| 3710 int anchor_offset; |
| 3711 if (!root->GetIntAttribute(ui::AX_ATTR_ANCHOR_OFFSET, &anchor_offset)) |
| 3712 return -1; |
3801 | 3713 |
3802 return GetHypertextOffsetFromEndpoint(*anchor_object, anchor_offset); | 3714 return anchor_offset; |
| 3715 } |
| 3716 |
| 3717 if (anchor_object->IsDescendantOf(this)) |
| 3718 return GetHypertextOffsetFromDescendant(*anchor_object); |
| 3719 |
| 3720 return -1; |
3803 } | 3721 } |
3804 | 3722 |
3805 int BrowserAccessibilityWin::GetSelectionFocus() const { | 3723 int BrowserAccessibilityWin::GetSelectionFocus() const { |
3806 BrowserAccessibility* root = manager()->GetRoot(); | 3724 BrowserAccessibility* root = manager()->GetRoot(); |
3807 int32 focus_id; | 3725 int32 focus_id; |
3808 if (!root || !root->GetIntAttribute(ui::AX_ATTR_FOCUS_OBJECT_ID, &focus_id)) | 3726 if (!root || !root->GetIntAttribute(ui::AX_ATTR_FOCUS_OBJECT_ID, &focus_id)) |
3809 return -1; | 3727 return -1; |
3810 | 3728 |
3811 BrowserAccessibilityWin* focus_object = manager()->GetFromID( | 3729 BrowserAccessibilityWin* focus_object = manager()->GetFromID( |
3812 focus_id)->ToBrowserAccessibilityWin(); | 3730 focus_id)->ToBrowserAccessibilityWin(); |
3813 if (!focus_object) | 3731 if (!focus_object) |
3814 return -1; | 3732 return -1; |
3815 | 3733 |
3816 int focus_offset; | 3734 // Includes the case when focus_object == this. |
3817 if (!root->GetIntAttribute(ui::AX_ATTR_FOCUS_OFFSET, &focus_offset)) | 3735 if (IsDescendantOf(focus_object) || |
3818 return -1; | 3736 // Text only objects that are direct descendants should behave as if they |
| 3737 // are part of this object when computing hypertext. |
| 3738 (focus_object->GetParent() == this && focus_object->IsTextOnlyObject())) { |
| 3739 int focus_offset; |
| 3740 if (!root->GetIntAttribute(ui::AX_ATTR_FOCUS_OFFSET, &focus_offset)) |
| 3741 return -1; |
3819 | 3742 |
3820 return GetHypertextOffsetFromEndpoint(*focus_object, focus_offset); | 3743 return focus_offset; |
| 3744 } |
| 3745 |
| 3746 if (focus_object->IsDescendantOf(this)) |
| 3747 return GetHypertextOffsetFromDescendant(*focus_object); |
| 3748 |
| 3749 return -1; |
3821 } | 3750 } |
3822 | 3751 |
3823 void BrowserAccessibilityWin::GetSelectionOffsets( | 3752 void BrowserAccessibilityWin::GetSelectionOffsets( |
3824 int* selection_start, int* selection_end) const { | 3753 int* selection_start, int* selection_end) const { |
3825 DCHECK(selection_start && selection_end); | 3754 DCHECK(selection_start && selection_end); |
3826 | 3755 |
3827 if (IsEditableText() && !HasState(ui::AX_STATE_RICHLY_EDITABLE) && | 3756 if (IsEditableText() && !HasState(ui::AX_STATE_RICHLY_EDITABLE) && |
3828 GetIntAttribute(ui::AX_ATTR_TEXT_SEL_START, selection_start) && | 3757 GetIntAttribute(ui::AX_ATTR_TEXT_SEL_START, selection_start) && |
3829 GetIntAttribute(ui::AX_ATTR_TEXT_SEL_END, selection_end)) { | 3758 GetIntAttribute(ui::AX_ATTR_TEXT_SEL_END, selection_end)) { |
3830 return; | 3759 return; |
3831 } | 3760 } |
3832 | 3761 |
3833 *selection_start = GetSelectionAnchor(); | 3762 *selection_start = GetSelectionAnchor(); |
3834 *selection_end = GetSelectionFocus(); | 3763 *selection_end = GetSelectionFocus(); |
3835 if (*selection_start < 0 || *selection_end < 0) | 3764 if (*selection_start < 0 || *selection_end < 0) |
3836 return; | 3765 return; |
3837 | 3766 |
3838 // If the selection is collapsed or if it only spans one character, return the | 3767 if (*selection_end < *selection_start) |
3839 // selection offsets only if the caret is active on this object or any of its | 3768 std::swap(*selection_start, *selection_end); |
3840 // children. | |
3841 // The focus object indicates the caret position. | |
3842 if (*selection_start == *selection_end) { | |
3843 BrowserAccessibility* root = manager()->GetRoot(); | |
3844 int32 focus_id; | |
3845 if (!root || !root->GetIntAttribute(ui::AX_ATTR_FOCUS_OBJECT_ID, &focus_id)) | |
3846 return; | |
3847 | 3769 |
3848 BrowserAccessibilityWin* focus_object = | 3770 // IA2 Spec says that the end of the selection should be after the last |
3849 manager()->GetFromID(focus_id)->ToBrowserAccessibilityWin(); | 3771 // embedded object character that is part of the selection, if there is one. |
3850 if (!focus_object) | 3772 if (hyperlink_offset_to_index().find(*selection_end) != |
3851 return; | 3773 hyperlink_offset_to_index().end()) { |
3852 | 3774 ++(*selection_end); |
3853 if (!focus_object->IsDescendantOf(this) && | |
3854 !(IsTextOnlyObject() && GetParent() == focus_object)) { | |
3855 *selection_start = -1; | |
3856 *selection_end = -1; | |
3857 return; | |
3858 } | |
3859 } | 3775 } |
3860 | |
3861 // The IA2 Spec says that if the largest of the two offsets falls on an | |
3862 // embedded object character and if there is a selection in that embedded | |
3863 // object, it should be incremented by one so that it points after the | |
3864 // embedded object character. | |
3865 // This is a signal to AT software that the embedded object is also part of | |
3866 // the selection. | |
3867 int* largest_offset = | |
3868 (*selection_start <= *selection_end) ? selection_end : selection_start; | |
3869 auto current_object = const_cast<BrowserAccessibilityWin*>(this); | |
3870 LONG hyperlink_index; | |
3871 HRESULT hr = | |
3872 current_object->get_hyperlinkIndex(*largest_offset, &hyperlink_index); | |
3873 if (hr != S_OK) | |
3874 return; | |
3875 | |
3876 DCHECK_GE(hyperlink_index, 0); | |
3877 base::win::ScopedComPtr<IAccessibleHyperlink> hyperlink; | |
3878 hr = current_object->get_hyperlink(hyperlink_index, hyperlink.Receive()); | |
3879 DCHECK(SUCCEEDED(hr)); | |
3880 base::win::ScopedComPtr<IAccessibleText> hyperlink_text; | |
3881 hr = hyperlink.QueryInterface(hyperlink_text.Receive()); | |
3882 DCHECK(SUCCEEDED(hr)); | |
3883 LONG n_selections = 0; | |
3884 hr = hyperlink_text->get_nSelections(&n_selections); | |
3885 DCHECK(SUCCEEDED(hr)); | |
3886 if (n_selections > 0) | |
3887 ++(*largest_offset); | |
3888 } | 3776 } |
3889 | 3777 |
3890 base::string16 BrowserAccessibilityWin::GetNameRecursive() const { | 3778 base::string16 BrowserAccessibilityWin::GetNameRecursive() const { |
3891 if (!name().empty()) { | 3779 if (!name().empty()) { |
3892 return name(); | 3780 return name(); |
3893 } | 3781 } |
3894 | 3782 |
3895 base::string16 result; | 3783 base::string16 result; |
3896 for (uint32 i = 0; i < PlatformChildCount(); ++i) { | 3784 for (uint32 i = 0; i < PlatformChildCount(); ++i) { |
3897 result += PlatformGetChild(i)->ToBrowserAccessibilityWin()-> | 3785 result += PlatformGetChild(i)->ToBrowserAccessibilityWin()-> |
3898 GetNameRecursive(); | 3786 GetNameRecursive(); |
3899 } | 3787 } |
3900 return result; | 3788 return result; |
3901 } | 3789 } |
3902 | 3790 |
3903 base::string16 BrowserAccessibilityWin::GetValueText() { | 3791 base::string16 BrowserAccessibilityWin::GetValueText() { |
3904 float fval; | 3792 float fval; |
3905 base::string16 value = this->value(); | 3793 base::string16 value = this->value(); |
3906 | 3794 |
3907 if (value.empty() && | 3795 if (value.empty() && |
3908 GetFloatAttribute(ui::AX_ATTR_VALUE_FOR_RANGE, &fval)) { | 3796 GetFloatAttribute(ui::AX_ATTR_VALUE_FOR_RANGE, &fval)) { |
3909 value = base::UTF8ToUTF16(base::DoubleToString(fval)); | 3797 value = base::UTF8ToUTF16(base::DoubleToString(fval)); |
3910 } | 3798 } |
3911 return value; | 3799 return value; |
3912 } | 3800 } |
3913 | 3801 |
3914 base::string16 BrowserAccessibilityWin::TextForIAccessibleText() const { | 3802 base::string16 BrowserAccessibilityWin::TextForIAccessibleText() { |
3915 switch (GetRole()) { | 3803 switch (GetRole()) { |
3916 case ui::AX_ROLE_TEXT_FIELD: | 3804 case ui::AX_ROLE_TEXT_FIELD: |
3917 case ui::AX_ROLE_MENU_LIST_OPTION: | 3805 case ui::AX_ROLE_MENU_LIST_OPTION: |
3918 return value(); | 3806 return value(); |
3919 default: | 3807 default: |
3920 return hypertext(); | 3808 return hypertext(); |
3921 } | 3809 } |
3922 } | 3810 } |
3923 | 3811 |
3924 bool BrowserAccessibilityWin::IsSameHypertextCharacter(size_t old_char_index, | 3812 bool BrowserAccessibilityWin::IsSameHypertextCharacter(size_t old_char_index, |
(...skipping 686 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4611 ia2_role = ia_role; | 4499 ia2_role = ia_role; |
4612 | 4500 |
4613 win_attributes_->ia_role = ia_role; | 4501 win_attributes_->ia_role = ia_role; |
4614 win_attributes_->ia_state = ia_state; | 4502 win_attributes_->ia_state = ia_state; |
4615 win_attributes_->role_name = role_name; | 4503 win_attributes_->role_name = role_name; |
4616 win_attributes_->ia2_role = ia2_role; | 4504 win_attributes_->ia2_role = ia2_role; |
4617 win_attributes_->ia2_state = ia2_state; | 4505 win_attributes_->ia2_state = ia2_state; |
4618 } | 4506 } |
4619 | 4507 |
4620 } // namespace content | 4508 } // namespace content |
OLD | NEW |