| 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 702 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 713 DCHECK(*attributes); | 713 DCHECK(*attributes); |
| 714 return S_OK; | 714 return S_OK; |
| 715 } | 715 } |
| 716 | 716 |
| 717 STDMETHODIMP BrowserAccessibilityComWin::get_states(AccessibleStates* states) { | 717 STDMETHODIMP BrowserAccessibilityComWin::get_states(AccessibleStates* states) { |
| 718 WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_STATES); | 718 WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_STATES); |
| 719 if (!owner()) | 719 if (!owner()) |
| 720 return E_FAIL; | 720 return E_FAIL; |
| 721 AddAccessibilityModeFlags(kScreenReaderAndHTMLAccessibilityModes); | 721 AddAccessibilityModeFlags(kScreenReaderAndHTMLAccessibilityModes); |
| 722 | 722 |
| 723 if (!states) | 723 return AXPlatformNodeWin::get_states(states); |
| 724 return E_INVALIDARG; | |
| 725 | |
| 726 *states = ia2_state(); | |
| 727 | |
| 728 return S_OK; | |
| 729 } | 724 } |
| 730 | 725 |
| 731 STDMETHODIMP BrowserAccessibilityComWin::get_uniqueID(LONG* unique_id) { | 726 STDMETHODIMP BrowserAccessibilityComWin::get_uniqueID(LONG* unique_id) { |
| 732 WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_UNIQUE_ID); | 727 WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_UNIQUE_ID); |
| 733 if (!owner()) | 728 if (!owner()) |
| 734 return E_FAIL; | 729 return E_FAIL; |
| 735 | 730 |
| 736 if (!unique_id) | 731 if (!unique_id) |
| 737 return E_INVALIDARG; | 732 return E_INVALIDARG; |
| 738 | 733 |
| (...skipping 2993 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3732 AddRelation(IA2_RELATION_MEMBER_OF, member_of_id); | 3727 AddRelation(IA2_RELATION_MEMBER_OF, member_of_id); |
| 3733 | 3728 |
| 3734 int error_message_id; | 3729 int error_message_id; |
| 3735 if (owner()->GetIntAttribute(ui::AX_ATTR_ERRORMESSAGE_ID, &error_message_id)) | 3730 if (owner()->GetIntAttribute(ui::AX_ATTR_ERRORMESSAGE_ID, &error_message_id)) |
| 3736 AddRelation(IA2_RELATION_ERROR_MESSAGE, error_message_id); | 3731 AddRelation(IA2_RELATION_ERROR_MESSAGE, error_message_id); |
| 3737 | 3732 |
| 3738 UpdateRequiredAttributes(); | 3733 UpdateRequiredAttributes(); |
| 3739 // If this is a web area for a presentational iframe, give it a role of | 3734 // If this is a web area for a presentational iframe, give it a role of |
| 3740 // something other than DOCUMENT so that the fact that it's a separate doc | 3735 // something other than DOCUMENT so that the fact that it's a separate doc |
| 3741 // is not exposed to AT. | 3736 // is not exposed to AT. |
| 3737 // TODO(dougt): When we move IA2 Role handling to AXPlatformNodeWin, we can |
| 3738 // remove this ia2_role special case. |
| 3742 if (owner()->IsWebAreaForPresentationalIframe()) { | 3739 if (owner()->IsWebAreaForPresentationalIframe()) { |
| 3743 win_attributes_->ia2_role = ROLE_SYSTEM_GROUPING; | 3740 win_attributes_->ia2_role = ROLE_SYSTEM_GROUPING; |
| 3744 } | 3741 } |
| 3745 } | 3742 } |
| 3746 | 3743 |
| 3747 void BrowserAccessibilityComWin::UpdateStep2ComputeHypertext() { | 3744 void BrowserAccessibilityComWin::UpdateStep2ComputeHypertext() { |
| 3748 if (owner()->IsSimpleTextControl()) { | 3745 if (owner()->IsSimpleTextControl()) { |
| 3749 win_attributes_->hypertext = value(); | 3746 win_attributes_->hypertext = value(); |
| 3750 return; | 3747 return; |
| 3751 } | 3748 } |
| (...skipping 1161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4913 } | 4910 } |
| 4914 | 4911 |
| 4915 void BrowserAccessibilityComWin::FireNativeEvent(LONG win_event_type) const { | 4912 void BrowserAccessibilityComWin::FireNativeEvent(LONG win_event_type) const { |
| 4916 (new BrowserAccessibilityEventWin(BrowserAccessibilityEvent::FromTreeChange, | 4913 (new BrowserAccessibilityEventWin(BrowserAccessibilityEvent::FromTreeChange, |
| 4917 ui::AX_EVENT_NONE, win_event_type, owner())) | 4914 ui::AX_EVENT_NONE, win_event_type, owner())) |
| 4918 ->Fire(); | 4915 ->Fire(); |
| 4919 } | 4916 } |
| 4920 | 4917 |
| 4921 void BrowserAccessibilityComWin::InitRoleAndState() { | 4918 void BrowserAccessibilityComWin::InitRoleAndState() { |
| 4922 int32_t ia2_role = 0; | 4919 int32_t ia2_role = 0; |
| 4923 int32_t ia2_state = IA2_STATE_OPAQUE; | |
| 4924 | |
| 4925 const auto checked_state = static_cast<ui::AXCheckedState>( | |
| 4926 owner()->GetIntAttribute(ui::AX_ATTR_CHECKED_STATE)); | |
| 4927 if (checked_state) { | |
| 4928 ia2_state |= IA2_STATE_CHECKABLE; | |
| 4929 } | |
| 4930 | |
| 4931 if (owner()->HasIntAttribute(ui::AX_ATTR_INVALID_STATE) && | |
| 4932 owner()->GetIntAttribute(ui::AX_ATTR_INVALID_STATE) != | |
| 4933 ui::AX_INVALID_STATE_FALSE) | |
| 4934 ia2_state |= IA2_STATE_INVALID_ENTRY; | |
| 4935 if (owner()->HasState(ui::AX_STATE_REQUIRED)) | |
| 4936 ia2_state |= IA2_STATE_REQUIRED; | |
| 4937 if (owner()->HasState(ui::AX_STATE_VERTICAL)) | |
| 4938 ia2_state |= IA2_STATE_VERTICAL; | |
| 4939 if (owner()->HasState(ui::AX_STATE_HORIZONTAL)) | |
| 4940 ia2_state |= IA2_STATE_HORIZONTAL; | |
| 4941 | |
| 4942 const bool is_editable = owner()->HasState(ui::AX_STATE_EDITABLE); | |
| 4943 if (is_editable) | |
| 4944 ia2_state |= IA2_STATE_EDITABLE; | |
| 4945 | |
| 4946 if (owner()->IsRichTextControl() || owner()->IsEditField()) { | |
| 4947 // Support multi/single line states if root editable or appropriate role. | |
| 4948 // We support the edit box roles even if the area is not actually editable, | |
| 4949 // because it is technically feasible for JS to implement the edit box | |
| 4950 // by controlling selection. | |
| 4951 if (owner()->HasState(ui::AX_STATE_MULTILINE)) { | |
| 4952 ia2_state |= IA2_STATE_MULTI_LINE; | |
| 4953 } else { | |
| 4954 ia2_state |= IA2_STATE_SINGLE_LINE; | |
| 4955 } | |
| 4956 } | |
| 4957 | |
| 4958 if (!owner()->GetStringAttribute(ui::AX_ATTR_AUTO_COMPLETE).empty()) | |
| 4959 ia2_state |= IA2_STATE_SUPPORTS_AUTOCOMPLETION; | |
| 4960 | |
| 4961 if (owner()->GetBoolAttribute(ui::AX_ATTR_MODAL)) | |
| 4962 ia2_state |= IA2_STATE_MODAL; | |
| 4963 | 4920 |
| 4964 base::string16 html_tag = owner()->GetString16Attribute(ui::AX_ATTR_HTML_TAG); | 4921 base::string16 html_tag = owner()->GetString16Attribute(ui::AX_ATTR_HTML_TAG); |
| 4965 switch (owner()->GetRole()) { | 4922 switch (owner()->GetRole()) { |
| 4966 case ui::AX_ROLE_BANNER: | 4923 case ui::AX_ROLE_BANNER: |
| 4967 ia2_role = IA2_ROLE_HEADER; | 4924 ia2_role = IA2_ROLE_HEADER; |
| 4968 break; | 4925 break; |
| 4969 case ui::AX_ROLE_BLOCKQUOTE: | 4926 case ui::AX_ROLE_BLOCKQUOTE: |
| 4970 ia2_role = IA2_ROLE_SECTION; | 4927 ia2_role = IA2_ROLE_SECTION; |
| 4971 break; | 4928 break; |
| 4972 case ui::AX_ROLE_CANVAS: | 4929 case ui::AX_ROLE_CANVAS: |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5031 break; | 4988 break; |
| 5032 case ui::AX_ROLE_MARK: | 4989 case ui::AX_ROLE_MARK: |
| 5033 ia2_role = IA2_ROLE_TEXT_FRAME; | 4990 ia2_role = IA2_ROLE_TEXT_FRAME; |
| 5034 break; | 4991 break; |
| 5035 case ui::AX_ROLE_MENU_ITEM_CHECK_BOX: | 4992 case ui::AX_ROLE_MENU_ITEM_CHECK_BOX: |
| 5036 ia2_role = IA2_ROLE_CHECK_MENU_ITEM; | 4993 ia2_role = IA2_ROLE_CHECK_MENU_ITEM; |
| 5037 break; | 4994 break; |
| 5038 case ui::AX_ROLE_MENU_ITEM_RADIO: | 4995 case ui::AX_ROLE_MENU_ITEM_RADIO: |
| 5039 ia2_role = IA2_ROLE_RADIO_MENU_ITEM; | 4996 ia2_role = IA2_ROLE_RADIO_MENU_ITEM; |
| 5040 break; | 4997 break; |
| 5041 case ui::AX_ROLE_MENU_LIST_POPUP: | |
| 5042 ia2_state &= ~(IA2_STATE_EDITABLE); | |
| 5043 break; | |
| 5044 case ui::AX_ROLE_MENU_LIST_OPTION: | |
| 5045 ia2_state &= ~(IA2_STATE_EDITABLE); | |
| 5046 break; | |
| 5047 case ui::AX_ROLE_NAVIGATION: | 4998 case ui::AX_ROLE_NAVIGATION: |
| 5048 ia2_role = IA2_ROLE_SECTION; | 4999 ia2_role = IA2_ROLE_SECTION; |
| 5049 break; | 5000 break; |
| 5050 case ui::AX_ROLE_NOTE: | 5001 case ui::AX_ROLE_NOTE: |
| 5051 ia2_role = IA2_ROLE_NOTE; | 5002 ia2_role = IA2_ROLE_NOTE; |
| 5052 break; | 5003 break; |
| 5053 case ui::AX_ROLE_PARAGRAPH: | 5004 case ui::AX_ROLE_PARAGRAPH: |
| 5054 ia2_role = IA2_ROLE_PARAGRAPH; | 5005 ia2_role = IA2_ROLE_PARAGRAPH; |
| 5055 break; | 5006 break; |
| 5056 case ui::AX_ROLE_PRE: | 5007 case ui::AX_ROLE_PRE: |
| 5057 ia2_role = IA2_ROLE_PARAGRAPH; | 5008 ia2_role = IA2_ROLE_PARAGRAPH; |
| 5058 break; | 5009 break; |
| 5059 case ui::AX_ROLE_REGION: | 5010 case ui::AX_ROLE_REGION: |
| 5060 if (html_tag == L"section") { | 5011 if (html_tag == L"section") { |
| 5061 ia2_role = IA2_ROLE_SECTION; | 5012 ia2_role = IA2_ROLE_SECTION; |
| 5062 } | 5013 } |
| 5063 break; | 5014 break; |
| 5064 case ui::AX_ROLE_RUBY: | 5015 case ui::AX_ROLE_RUBY: |
| 5065 ia2_role = IA2_ROLE_TEXT_FRAME; | 5016 ia2_role = IA2_ROLE_TEXT_FRAME; |
| 5066 break; | 5017 break; |
| 5067 case ui::AX_ROLE_RULER: | 5018 case ui::AX_ROLE_RULER: |
| 5068 ia2_role = IA2_ROLE_RULER; | 5019 ia2_role = IA2_ROLE_RULER; |
| 5069 break; | 5020 break; |
| 5070 case ui::AX_ROLE_SCROLL_AREA: | 5021 case ui::AX_ROLE_SCROLL_AREA: |
| 5071 ia2_role = IA2_ROLE_SCROLL_PANE; | 5022 ia2_role = IA2_ROLE_SCROLL_PANE; |
| 5072 ia2_state &= ~(IA2_STATE_EDITABLE); | |
| 5073 break; | 5023 break; |
| 5074 case ui::AX_ROLE_SEARCH: | 5024 case ui::AX_ROLE_SEARCH: |
| 5075 ia2_role = IA2_ROLE_SECTION; | 5025 ia2_role = IA2_ROLE_SECTION; |
| 5076 break; | 5026 break; |
| 5077 case ui::AX_ROLE_SWITCH: | 5027 case ui::AX_ROLE_SWITCH: |
| 5078 ia2_role = IA2_ROLE_TOGGLE_BUTTON; | 5028 ia2_role = IA2_ROLE_TOGGLE_BUTTON; |
| 5079 break; | 5029 break; |
| 5080 case ui::AX_ROLE_TABLE_HEADER_CONTAINER: | 5030 case ui::AX_ROLE_TABLE_HEADER_CONTAINER: |
| 5081 ia2_role = IA2_ROLE_SECTION; | 5031 ia2_role = IA2_ROLE_SECTION; |
| 5082 break; | 5032 break; |
| 5083 case ui::AX_ROLE_TOGGLE_BUTTON: | 5033 case ui::AX_ROLE_TOGGLE_BUTTON: |
| 5084 ia2_role = IA2_ROLE_TOGGLE_BUTTON; | 5034 ia2_role = IA2_ROLE_TOGGLE_BUTTON; |
| 5085 break; | 5035 break; |
| 5086 case ui::AX_ROLE_TEXT_FIELD: | |
| 5087 case ui::AX_ROLE_SEARCH_BOX: | |
| 5088 ia2_state |= IA2_STATE_SELECTABLE_TEXT; | |
| 5089 break; | |
| 5090 case ui::AX_ROLE_ABBR: | 5036 case ui::AX_ROLE_ABBR: |
| 5091 case ui::AX_ROLE_TIME: | 5037 case ui::AX_ROLE_TIME: |
| 5092 ia2_role = IA2_ROLE_TEXT_FRAME; | 5038 ia2_role = IA2_ROLE_TEXT_FRAME; |
| 5093 break; | 5039 break; |
| 5094 default: | 5040 default: |
| 5095 break; | 5041 break; |
| 5096 } | 5042 } |
| 5097 | 5043 |
| 5098 win_attributes_->ia_role = MSAARole(); | 5044 win_attributes_->ia_role = MSAARole(); |
| 5099 win_attributes_->ia_state = MSAAState(); | 5045 win_attributes_->ia_state = MSAAState(); |
| 5100 win_attributes_->role_name = base::UTF8ToUTF16(StringOverrideForMSAARole()); | 5046 win_attributes_->role_name = base::UTF8ToUTF16(StringOverrideForMSAARole()); |
| 5101 | 5047 |
| 5102 // If we didn't explicitly set the IAccessible2 role, make it the same | 5048 // If we didn't explicitly set the IAccessible2 role, make it the same |
| 5103 // as the MSAA role. | 5049 // as the MSAA role. |
| 5104 if (!ia2_role) | 5050 if (!ia2_role) |
| 5105 ia2_role = win_attributes_->ia_role; | 5051 ia2_role = win_attributes_->ia_role; |
| 5106 | 5052 |
| 5107 win_attributes_->ia2_role = ia2_role; | 5053 win_attributes_->ia2_role = ia2_role; |
| 5108 win_attributes_->ia2_state = ia2_state; | 5054 win_attributes_->ia2_state = IA2State(); |
| 5109 } | 5055 } |
| 5110 | 5056 |
| 5111 BrowserAccessibilityComWin* ToBrowserAccessibilityComWin( | 5057 BrowserAccessibilityComWin* ToBrowserAccessibilityComWin( |
| 5112 BrowserAccessibility* obj) { | 5058 BrowserAccessibility* obj) { |
| 5113 if (!obj || !obj->IsNative()) | 5059 if (!obj || !obj->IsNative()) |
| 5114 return nullptr; | 5060 return nullptr; |
| 5115 auto* result = static_cast<BrowserAccessibilityWin*>(obj)->GetCOM(); | 5061 auto* result = static_cast<BrowserAccessibilityWin*>(obj)->GetCOM(); |
| 5116 return result; | 5062 return result; |
| 5117 } | 5063 } |
| 5118 | 5064 |
| 5119 } // namespace content | 5065 } // namespace content |
| OLD | NEW |