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