| 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 |