OLD | NEW |
1 // Copyright (c) 2017 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2017 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_com_win.h" | 5 #include "content/browser/accessibility/browser_accessibility_com_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 748 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
759 return E_INVALIDARG; | 759 return E_INVALIDARG; |
760 | 760 |
761 state->vt = VT_I4; | 761 state->vt = VT_I4; |
762 state->lVal = target->ia_state(); | 762 state->lVal = target->ia_state(); |
763 if (manager->GetFocus() == owner()) | 763 if (manager->GetFocus() == owner()) |
764 state->lVal |= STATE_SYSTEM_FOCUSED; | 764 state->lVal |= STATE_SYSTEM_FOCUSED; |
765 | 765 |
766 return S_OK; | 766 return S_OK; |
767 } | 767 } |
768 | 768 |
| 769 bool BrowserAccessibilityComWin::IsRangeValueSupported() { |
| 770 switch (ia_role()) { |
| 771 case ROLE_SYSTEM_PROGRESSBAR: |
| 772 case ROLE_SYSTEM_SLIDER: |
| 773 case ROLE_SYSTEM_SPINBUTTON: |
| 774 case ROLE_SYSTEM_SCROLLBAR: |
| 775 return true; |
| 776 case ROLE_SYSTEM_SEPARATOR: |
| 777 return owner()->HasState(ui::AX_STATE_FOCUSABLE); |
| 778 default: |
| 779 return false; |
| 780 } |
| 781 } |
| 782 |
769 STDMETHODIMP BrowserAccessibilityComWin::get_accValue(VARIANT var_id, | 783 STDMETHODIMP BrowserAccessibilityComWin::get_accValue(VARIANT var_id, |
770 BSTR* value) { | 784 BSTR* value) { |
771 WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_ACC_VALUE); | 785 WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_ACC_VALUE); |
772 if (!owner()) | 786 if (!owner()) |
773 return E_FAIL; | 787 return E_FAIL; |
774 | 788 |
775 if (!value) | 789 if (!value) |
776 return E_INVALIDARG; | 790 return E_INVALIDARG; |
777 | 791 |
778 BrowserAccessibilityComWin* target = GetTargetFromChildID(var_id); | 792 BrowserAccessibilityComWin* target = GetTargetFromChildID(var_id); |
779 if (!target) | 793 if (!target) |
780 return E_INVALIDARG; | 794 return E_INVALIDARG; |
781 | 795 |
782 if (target->ia_role() == ROLE_SYSTEM_PROGRESSBAR || | 796 if (target->IsRangeValueSupported()) { |
783 target->ia_role() == ROLE_SYSTEM_SCROLLBAR || | 797 base::string16 value_text = target->GetRangeValueText(); |
784 target->ia_role() == ROLE_SYSTEM_SLIDER) { | |
785 base::string16 value_text = target->GetValueText(); | |
786 *value = SysAllocString(value_text.c_str()); | 798 *value = SysAllocString(value_text.c_str()); |
787 DCHECK(*value); | 799 DCHECK(*value); |
788 return S_OK; | 800 return S_OK; |
789 } | 801 } |
790 | 802 |
791 // Expose color well value. | 803 // Expose color well value. |
792 if (target->ia2_role() == IA2_ROLE_COLOR_CHOOSER) { | 804 if (target->ia2_role() == IA2_ROLE_COLOR_CHOOSER) { |
793 unsigned int color = static_cast<unsigned int>( | 805 unsigned int color = static_cast<unsigned int>( |
794 target->owner()->GetIntAttribute(ui::AX_ATTR_COLOR_VALUE)); | 806 target->owner()->GetIntAttribute(ui::AX_ATTR_COLOR_VALUE)); |
795 unsigned int red = SkColorGetR(color); | 807 unsigned int red = SkColorGetR(color); |
(...skipping 2768 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3564 PATTERNID id, | 3576 PATTERNID id, |
3565 IUnknown** provider) { | 3577 IUnknown** provider) { |
3566 WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_PATTERN_PROVIDER); | 3578 WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_PATTERN_PROVIDER); |
3567 DVLOG(1) << "In Function: " << __func__ << " for pattern id: " << id; | 3579 DVLOG(1) << "In Function: " << __func__ << " for pattern id: " << id; |
3568 if (!owner()) | 3580 if (!owner()) |
3569 return E_FAIL; | 3581 return E_FAIL; |
3570 | 3582 |
3571 if (id == UIA_ValuePatternId || id == UIA_TextPatternId) { | 3583 if (id == UIA_ValuePatternId || id == UIA_TextPatternId) { |
3572 if (owner()->HasState(ui::AX_STATE_EDITABLE)) { | 3584 if (owner()->HasState(ui::AX_STATE_EDITABLE)) { |
3573 DVLOG(1) << "Returning UIA text provider"; | 3585 DVLOG(1) << "Returning UIA text provider"; |
3574 base::win::UIATextProvider::CreateTextProvider(GetValueText(), true, | 3586 base::win::UIATextProvider::CreateTextProvider(GetRangeValueText(), true, |
3575 provider); | 3587 provider); |
3576 return S_OK; | 3588 return S_OK; |
3577 } | 3589 } |
3578 } | 3590 } |
3579 return E_NOTIMPL; | 3591 return E_NOTIMPL; |
3580 } | 3592 } |
3581 | 3593 |
3582 STDMETHODIMP BrowserAccessibilityComWin::GetPropertyValue(PROPERTYID id, | 3594 STDMETHODIMP BrowserAccessibilityComWin::GetPropertyValue(PROPERTYID id, |
3583 VARIANT* ret) { | 3595 VARIANT* ret) { |
3584 WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_PROPERTY_VALUE); | 3596 WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_PROPERTY_VALUE); |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3633 if (ia_role != ROLE_SYSTEM_TABLE) { | 3645 if (ia_role != ROLE_SYSTEM_TABLE) { |
3634 *object = NULL; | 3646 *object = NULL; |
3635 return E_NOINTERFACE; | 3647 return E_NOINTERFACE; |
3636 } | 3648 } |
3637 } else if (iid == IID_IAccessibleTableCell) { | 3649 } else if (iid == IID_IAccessibleTableCell) { |
3638 if (!accessibility->owner()->IsCellOrTableHeaderRole()) { | 3650 if (!accessibility->owner()->IsCellOrTableHeaderRole()) { |
3639 *object = NULL; | 3651 *object = NULL; |
3640 return E_NOINTERFACE; | 3652 return E_NOINTERFACE; |
3641 } | 3653 } |
3642 } else if (iid == IID_IAccessibleValue) { | 3654 } else if (iid == IID_IAccessibleValue) { |
3643 if (ia_role != ROLE_SYSTEM_PROGRESSBAR && | 3655 if (!accessibility->IsRangeValueSupported()) { |
3644 ia_role != ROLE_SYSTEM_SCROLLBAR && ia_role != ROLE_SYSTEM_SLIDER) { | |
3645 *object = NULL; | 3656 *object = NULL; |
3646 return E_NOINTERFACE; | 3657 return E_NOINTERFACE; |
3647 } | 3658 } |
3648 } else if (iid == IID_ISimpleDOMDocument) { | 3659 } else if (iid == IID_ISimpleDOMDocument) { |
3649 if (ia_role != ROLE_SYSTEM_DOCUMENT) { | 3660 if (ia_role != ROLE_SYSTEM_DOCUMENT) { |
3650 *object = NULL; | 3661 *object = NULL; |
3651 return E_NOINTERFACE; | 3662 return E_NOINTERFACE; |
3652 } | 3663 } |
3653 } else if (iid == IID_IAccessibleHyperlink) { | 3664 } else if (iid == IID_IAccessibleHyperlink) { |
3654 auto* ax_object = | 3665 auto* ax_object = |
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3908 break; | 3919 break; |
3909 } | 3920 } |
3910 } | 3921 } |
3911 | 3922 |
3912 win_attributes_->name = owner()->GetString16Attribute(ui::AX_ATTR_NAME); | 3923 win_attributes_->name = owner()->GetString16Attribute(ui::AX_ATTR_NAME); |
3913 win_attributes_->description = | 3924 win_attributes_->description = |
3914 owner()->GetString16Attribute(ui::AX_ATTR_DESCRIPTION); | 3925 owner()->GetString16Attribute(ui::AX_ATTR_DESCRIPTION); |
3915 StringAttributeToIA2(ui::AX_ATTR_PLACEHOLDER, "placeholder"); | 3926 StringAttributeToIA2(ui::AX_ATTR_PLACEHOLDER, "placeholder"); |
3916 | 3927 |
3917 base::string16 value = owner()->GetValue(); | 3928 base::string16 value = owner()->GetValue(); |
3918 // On Windows, the value of a document should be its url. | 3929 |
3919 if (owner()->GetRole() == ui::AX_ROLE_ROOT_WEB_AREA || | 3930 // Expose slider value. |
3920 owner()->GetRole() == ui::AX_ROLE_WEB_AREA) { | 3931 if (IsRangeValueSupported()) { |
3921 value = base::UTF8ToUTF16(Manager()->GetTreeData().url); | 3932 value = GetRangeValueText(); |
| 3933 SanitizeStringAttributeForIA2(value, &value); |
| 3934 win_attributes_->ia2_attributes.push_back(L"valuetext:" + value); |
| 3935 } else { |
| 3936 // On Windows, the value of a document should be its url. |
| 3937 if (owner()->GetRole() == ui::AX_ROLE_ROOT_WEB_AREA || |
| 3938 owner()->GetRole() == ui::AX_ROLE_WEB_AREA) { |
| 3939 value = base::UTF8ToUTF16(Manager()->GetTreeData().url); |
| 3940 } |
| 3941 // If this doesn't have a value and is linked then set its value to the url |
| 3942 // attribute. This allows screen readers to read an empty link's |
| 3943 // destination. |
| 3944 if (value.empty() && (ia_state() & STATE_SYSTEM_LINKED)) |
| 3945 value = owner()->GetString16Attribute(ui::AX_ATTR_URL); |
3922 } | 3946 } |
3923 // If this doesn't have a value and is linked then set its value to the url | 3947 |
3924 // attribute. This allows screen readers to read an empty link's destination. | |
3925 if (value.empty() && (ia_state() & STATE_SYSTEM_LINKED)) | |
3926 value = owner()->GetString16Attribute(ui::AX_ATTR_URL); | |
3927 win_attributes_->value = value; | 3948 win_attributes_->value = value; |
3928 | 3949 |
3929 ClearOwnRelations(); | 3950 ClearOwnRelations(); |
3930 AddBidirectionalRelations(IA2_RELATION_CONTROLLER_FOR, | 3951 AddBidirectionalRelations(IA2_RELATION_CONTROLLER_FOR, |
3931 IA2_RELATION_CONTROLLED_BY, | 3952 IA2_RELATION_CONTROLLED_BY, |
3932 ui::AX_ATTR_CONTROLS_IDS); | 3953 ui::AX_ATTR_CONTROLS_IDS); |
3933 AddBidirectionalRelations(IA2_RELATION_DESCRIBED_BY, | 3954 AddBidirectionalRelations(IA2_RELATION_DESCRIBED_BY, |
3934 IA2_RELATION_DESCRIPTION_FOR, | 3955 IA2_RELATION_DESCRIPTION_FOR, |
3935 ui::AX_ATTR_DESCRIBEDBY_IDS); | 3956 ui::AX_ATTR_DESCRIBEDBY_IDS); |
3936 AddBidirectionalRelations(IA2_RELATION_FLOWS_TO, IA2_RELATION_FLOWS_FROM, | 3957 AddBidirectionalRelations(IA2_RELATION_FLOWS_TO, IA2_RELATION_FLOWS_FROM, |
3937 ui::AX_ATTR_FLOWTO_IDS); | 3958 ui::AX_ATTR_FLOWTO_IDS); |
3938 AddBidirectionalRelations(IA2_RELATION_LABELLED_BY, IA2_RELATION_LABEL_FOR, | 3959 AddBidirectionalRelations(IA2_RELATION_LABELLED_BY, IA2_RELATION_LABEL_FOR, |
3939 ui::AX_ATTR_LABELLEDBY_IDS); | 3960 ui::AX_ATTR_LABELLEDBY_IDS); |
3940 AddBidirectionalRelations(IA2_RELATION_DETAILS, IA2_RELATION_DETAILS_FOR, | 3961 AddBidirectionalRelations(IA2_RELATION_DETAILS, IA2_RELATION_DETAILS_FOR, |
3941 ui::AX_ATTR_DETAILS_IDS); | 3962 ui::AX_ATTR_DETAILS_IDS); |
3942 | 3963 |
3943 int member_of_id; | 3964 int member_of_id; |
3944 if (owner()->GetIntAttribute(ui::AX_ATTR_MEMBER_OF_ID, &member_of_id)) | 3965 if (owner()->GetIntAttribute(ui::AX_ATTR_MEMBER_OF_ID, &member_of_id)) |
3945 AddRelation(IA2_RELATION_MEMBER_OF, member_of_id); | 3966 AddRelation(IA2_RELATION_MEMBER_OF, member_of_id); |
3946 | 3967 |
3947 int error_message_id; | 3968 int error_message_id; |
3948 if (owner()->GetIntAttribute(ui::AX_ATTR_ERRORMESSAGE_ID, &error_message_id)) | 3969 if (owner()->GetIntAttribute(ui::AX_ATTR_ERRORMESSAGE_ID, &error_message_id)) |
3949 AddRelation(IA2_RELATION_ERROR_MESSAGE, error_message_id); | 3970 AddRelation(IA2_RELATION_ERROR_MESSAGE, error_message_id); |
3950 | 3971 |
3951 // Expose slider value. | |
3952 if (ia_role() == ROLE_SYSTEM_PROGRESSBAR || | |
3953 ia_role() == ROLE_SYSTEM_SCROLLBAR || ia_role() == ROLE_SYSTEM_SLIDER) { | |
3954 base::string16 value_text = GetValueText(); | |
3955 SanitizeStringAttributeForIA2(value_text, &value_text); | |
3956 win_attributes_->ia2_attributes.push_back(L"valuetext:" + value_text); | |
3957 } | |
3958 | |
3959 UpdateRequiredAttributes(); | 3972 UpdateRequiredAttributes(); |
3960 // If this is a web area for a presentational iframe, give it a role of | 3973 // If this is a web area for a presentational iframe, give it a role of |
3961 // something other than DOCUMENT so that the fact that it's a separate doc | 3974 // something other than DOCUMENT so that the fact that it's a separate doc |
3962 // is not exposed to AT. | 3975 // is not exposed to AT. |
3963 if (owner()->IsWebAreaForPresentationalIframe()) { | 3976 if (owner()->IsWebAreaForPresentationalIframe()) { |
3964 win_attributes_->ia_role = ROLE_SYSTEM_GROUPING; | 3977 win_attributes_->ia_role = ROLE_SYSTEM_GROUPING; |
3965 win_attributes_->ia2_role = ROLE_SYSTEM_GROUPING; | 3978 win_attributes_->ia2_role = ROLE_SYSTEM_GROUPING; |
3966 } | 3979 } |
3967 } | 3980 } |
3968 | 3981 |
(...skipping 707 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4676 if (!hyperlink) | 4689 if (!hyperlink) |
4677 return; | 4690 return; |
4678 | 4691 |
4679 LONG n_selections = 0; | 4692 LONG n_selections = 0; |
4680 HRESULT hr = hyperlink->get_nSelections(&n_selections); | 4693 HRESULT hr = hyperlink->get_nSelections(&n_selections); |
4681 DCHECK(SUCCEEDED(hr)); | 4694 DCHECK(SUCCEEDED(hr)); |
4682 if (n_selections > 0) | 4695 if (n_selections > 0) |
4683 ++(*largest_offset); | 4696 ++(*largest_offset); |
4684 } | 4697 } |
4685 | 4698 |
4686 base::string16 BrowserAccessibilityComWin::GetValueText() { | 4699 base::string16 BrowserAccessibilityComWin::GetRangeValueText() { |
4687 float fval; | 4700 float fval; |
4688 base::string16 result = value(); | 4701 base::string16 result = owner()->GetValue(); |
4689 | 4702 |
4690 if (result.empty() && GetFloatAttribute(ui::AX_ATTR_VALUE_FOR_RANGE, &fval)) { | 4703 if (result.empty() && GetFloatAttribute(ui::AX_ATTR_VALUE_FOR_RANGE, &fval)) { |
4691 result = base::UTF8ToUTF16(base::DoubleToString(fval)); | 4704 result = base::UTF8ToUTF16(base::DoubleToString(fval)); |
4692 } | 4705 } |
4693 return result; | 4706 return result; |
4694 } | 4707 } |
4695 | 4708 |
4696 bool BrowserAccessibilityComWin::IsSameHypertextCharacter( | 4709 bool BrowserAccessibilityComWin::IsSameHypertextCharacter( |
4697 size_t old_char_index, | 4710 size_t old_char_index, |
4698 size_t new_char_index) { | 4711 size_t new_char_index) { |
(...skipping 1018 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5717 | 5730 |
5718 BrowserAccessibilityComWin* ToBrowserAccessibilityComWin( | 5731 BrowserAccessibilityComWin* ToBrowserAccessibilityComWin( |
5719 BrowserAccessibility* obj) { | 5732 BrowserAccessibility* obj) { |
5720 if (!obj || !obj->IsNative()) | 5733 if (!obj || !obj->IsNative()) |
5721 return nullptr; | 5734 return nullptr; |
5722 auto* result = static_cast<BrowserAccessibilityWin*>(obj)->GetCOM(); | 5735 auto* result = static_cast<BrowserAccessibilityWin*>(obj)->GetCOM(); |
5723 return result; | 5736 return result; |
5724 } | 5737 } |
5725 | 5738 |
5726 } // namespace content | 5739 } // namespace content |
OLD | NEW |