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 2914 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2925 if (owner()->GetString16Attribute(ui::AX_ATTR_HTML_TAG, &tag)) | 2925 if (owner()->GetString16Attribute(ui::AX_ATTR_HTML_TAG, &tag)) |
| 2926 *node_name = SysAllocString(tag.c_str()); | 2926 *node_name = SysAllocString(tag.c_str()); |
| 2927 else | 2927 else |
| 2928 *node_name = nullptr; | 2928 *node_name = nullptr; |
| 2929 | 2929 |
| 2930 *name_space_id = 0; | 2930 *name_space_id = 0; |
| 2931 *node_value = SysAllocString(value().c_str()); | 2931 *node_value = SysAllocString(value().c_str()); |
| 2932 *num_children = owner()->PlatformChildCount(); | 2932 *num_children = owner()->PlatformChildCount(); |
| 2933 *unique_id = -owner()->unique_id(); | 2933 *unique_id = -owner()->unique_id(); |
| 2934 | 2934 |
| 2935 if (owner()->GetRole() == ui::AX_ROLE_ROOT_WEB_AREA || | 2935 if (IsDocument()) { |
| 2936 owner()->GetRole() == ui::AX_ROLE_WEB_AREA) { | |
| 2937 *node_type = NODETYPE_DOCUMENT; | 2936 *node_type = NODETYPE_DOCUMENT; |
| 2938 } else if (owner()->IsTextOnlyObject()) { | 2937 } else if (owner()->IsTextOnlyObject()) { |
| 2939 *node_type = NODETYPE_TEXT; | 2938 *node_type = NODETYPE_TEXT; |
| 2940 } else { | 2939 } else { |
| 2941 *node_type = NODETYPE_ELEMENT; | 2940 *node_type = NODETYPE_ELEMENT; |
| 2942 } | 2941 } |
| 2943 | 2942 |
| 2944 return S_OK; | 2943 return S_OK; |
| 2945 } | 2944 } |
| 2946 | 2945 |
| (...skipping 823 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3770 | 3769 |
| 3771 base::string16 value = owner()->GetValue(); | 3770 base::string16 value = owner()->GetValue(); |
| 3772 | 3771 |
| 3773 // Expose slider value. | 3772 // Expose slider value. |
| 3774 if (IsRangeValueSupported()) { | 3773 if (IsRangeValueSupported()) { |
| 3775 value = GetRangeValueText(); | 3774 value = GetRangeValueText(); |
| 3776 SanitizeStringAttributeForIA2(value, &value); | 3775 SanitizeStringAttributeForIA2(value, &value); |
| 3777 win_attributes_->ia2_attributes.push_back(L"valuetext:" + value); | 3776 win_attributes_->ia2_attributes.push_back(L"valuetext:" + value); |
| 3778 } else { | 3777 } else { |
| 3779 // On Windows, the value of a document should be its url. | 3778 // On Windows, the value of a document should be its url. |
| 3780 if (owner()->GetRole() == ui::AX_ROLE_ROOT_WEB_AREA || | 3779 if (IsDocument()) { |
| 3781 owner()->GetRole() == ui::AX_ROLE_WEB_AREA) { | |
| 3782 value = base::UTF8ToUTF16(Manager()->GetTreeData().url); | 3780 value = base::UTF8ToUTF16(Manager()->GetTreeData().url); |
| 3783 } | 3781 } |
| 3784 // If this doesn't have a value and is linked then set its value to the url | 3782 // If this doesn't have a value and is linked then set its value to the url |
| 3785 // attribute. This allows screen readers to read an empty link's | 3783 // attribute. This allows screen readers to read an empty link's |
| 3786 // destination. | 3784 // destination. |
| 3787 if (value.empty() && (ia_state() & STATE_SYSTEM_LINKED)) | 3785 if (value.empty() && (ia_state() & STATE_SYSTEM_LINKED)) |
| 3788 value = owner()->GetString16Attribute(ui::AX_ATTR_URL); | 3786 value = owner()->GetString16Attribute(ui::AX_ATTR_URL); |
| 3789 } | 3787 } |
| 3790 | 3788 |
| 3791 win_attributes_->value = value; | 3789 win_attributes_->value = value; |
| (...skipping 503 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4295 | 4293 |
| 4296 void BrowserAccessibilityComWin::IntAttributeToIA2(ui::AXIntAttribute attribute, | 4294 void BrowserAccessibilityComWin::IntAttributeToIA2(ui::AXIntAttribute attribute, |
| 4297 const char* ia2_attr) { | 4295 const char* ia2_attr) { |
| 4298 int value; | 4296 int value; |
| 4299 if (owner()->GetIntAttribute(attribute, &value)) { | 4297 if (owner()->GetIntAttribute(attribute, &value)) { |
| 4300 win_attributes_->ia2_attributes.push_back( | 4298 win_attributes_->ia2_attributes.push_back( |
| 4301 base::ASCIIToUTF16(ia2_attr) + L":" + base::IntToString16(value)); | 4299 base::ASCIIToUTF16(ia2_attr) + L":" + base::IntToString16(value)); |
| 4302 } | 4300 } |
| 4303 } | 4301 } |
| 4304 | 4302 |
| 4303 bool BrowserAccessibilityComWin::IsDocument() const { | |
| 4304 return owner()->GetRole() == ui::AX_ROLE_ROOT_WEB_AREA || | |
| 4305 owner()->GetRole() == ui::AX_ROLE_WEB_AREA; | |
| 4306 } | |
| 4307 | |
| 4308 bool BrowserAccessibilityComWin::IsRootEditable() const { | |
| 4309 if (!owner()->HasState(ui::AX_STATE_EDITABLE)) | |
| 4310 return false; | |
| 4311 | |
| 4312 if (IsDocument()) | |
| 4313 return true; | |
| 4314 | |
| 4315 BrowserAccessibility* parent = owner()->PlatformGetParent(); | |
|
dougt
2017/06/23 18:27:18
I am confused by this.
GetParent() is just retur
aleventhal
2017/06/28 14:20:57
It does what I want, but maybe it needs a differen
| |
| 4316 return !parent || !parent->HasState(ui::AX_STATE_EDITABLE); | |
| 4317 } | |
| 4318 | |
| 4319 bool BrowserAccessibilityComWin::IsEditBoxRole() const { | |
| 4320 const int32_t role = owner()->GetRole(); | |
| 4321 return role == ui::AX_ROLE_TEXT_FIELD || role == ui::AX_ROLE_SEARCH_BOX; | |
| 4322 } | |
| 4323 | |
| 4305 bool BrowserAccessibilityComWin::IsHyperlink() const { | 4324 bool BrowserAccessibilityComWin::IsHyperlink() const { |
| 4306 int32_t hyperlink_index = -1; | 4325 int32_t hyperlink_index = -1; |
| 4307 auto* parent = owner()->PlatformGetParent(); | 4326 auto* parent = owner()->PlatformGetParent(); |
| 4308 if (parent) { | 4327 if (parent) { |
| 4309 hyperlink_index = | 4328 hyperlink_index = |
| 4310 ToBrowserAccessibilityComWin(parent)->GetHyperlinkIndexFromChild(*this); | 4329 ToBrowserAccessibilityComWin(parent)->GetHyperlinkIndexFromChild(*this); |
| 4311 } | 4330 } |
| 4312 | 4331 |
| 4313 if (hyperlink_index >= 0) | 4332 if (hyperlink_index >= 0) |
| 4314 return true; | 4333 return true; |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4356 return -1; | 4375 return -1; |
| 4357 } | 4376 } |
| 4358 | 4377 |
| 4359 int32_t BrowserAccessibilityComWin::GetHypertextOffsetFromChild( | 4378 int32_t BrowserAccessibilityComWin::GetHypertextOffsetFromChild( |
| 4360 BrowserAccessibilityComWin& child) { | 4379 BrowserAccessibilityComWin& child) { |
| 4361 DCHECK(child.owner()->PlatformGetParent() == owner()); | 4380 DCHECK(child.owner()->PlatformGetParent() == owner()); |
| 4362 | 4381 |
| 4363 // Handle the case when we are dealing with a direct text-only child. | 4382 // Handle the case when we are dealing with a direct text-only child. |
| 4364 // (Note that this object might be a platform leaf, e.g. an ARIA searchbox, | 4383 // (Note that this object might be a platform leaf, e.g. an ARIA searchbox, |
| 4365 // and so |owner()->InternalChild...| functions need to be used. Also, | 4384 // and so |owner()->InternalChild...| functions need to be used. Also, |
| 4366 // direct text-only children should not be present at tree roots and so no | 4385 // direct text-only children should not be present at tree s and so no |
|
dougt
2017/06/23 18:27:18
I don't think you want this change.
aleventhal
2017/06/28 14:20:57
Done.
| |
| 4367 // cross-tree traversal is necessary.) | 4386 // cross-tree traversal is necessary.) |
| 4368 if (child.owner()->IsTextOnlyObject()) { | 4387 if (child.owner()->IsTextOnlyObject()) { |
| 4369 int32_t hypertextOffset = 0; | 4388 int32_t hypertextOffset = 0; |
| 4370 int32_t index_in_parent = child.GetIndexInParent(); | 4389 int32_t index_in_parent = child.GetIndexInParent(); |
| 4371 DCHECK_GE(index_in_parent, 0); | 4390 DCHECK_GE(index_in_parent, 0); |
| 4372 DCHECK_LT(index_in_parent, | 4391 DCHECK_LT(index_in_parent, |
| 4373 static_cast<int32_t>(owner()->InternalChildCount())); | 4392 static_cast<int32_t>(owner()->InternalChildCount())); |
| 4374 for (uint32_t i = 0; i < static_cast<uint32_t>(index_in_parent); ++i) { | 4393 for (uint32_t i = 0; i < static_cast<uint32_t>(index_in_parent); ++i) { |
| 4375 const BrowserAccessibilityComWin* sibling = | 4394 const BrowserAccessibilityComWin* sibling = |
| 4376 ToBrowserAccessibilityComWin(owner()->InternalGetChild(i)); | 4395 ToBrowserAccessibilityComWin(owner()->InternalGetChild(i)); |
| (...skipping 694 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5071 // Expose whether or not the mouse is over an element, but suppress | 5090 // Expose whether or not the mouse is over an element, but suppress |
| 5072 // this for tests because it can make the test results flaky depending | 5091 // this for tests because it can make the test results flaky depending |
| 5073 // on the position of the mouse. | 5092 // on the position of the mouse. |
| 5074 BrowserAccessibilityStateImpl* accessibility_state = | 5093 BrowserAccessibilityStateImpl* accessibility_state = |
| 5075 BrowserAccessibilityStateImpl::GetInstance(); | 5094 BrowserAccessibilityStateImpl::GetInstance(); |
| 5076 if (!accessibility_state->disable_hot_tracking_for_testing()) { | 5095 if (!accessibility_state->disable_hot_tracking_for_testing()) { |
| 5077 if (owner()->HasState(ui::AX_STATE_HOVERED)) | 5096 if (owner()->HasState(ui::AX_STATE_HOVERED)) |
| 5078 ia_state |= STATE_SYSTEM_HOTTRACKED; | 5097 ia_state |= STATE_SYSTEM_HOTTRACKED; |
| 5079 } | 5098 } |
| 5080 | 5099 |
| 5081 if (owner()->HasState(ui::AX_STATE_EDITABLE)) | 5100 const bool is_editable = owner()->HasState(ui::AX_STATE_EDITABLE); |
| 5101 if (is_editable) { | |
| 5082 ia2_state |= IA2_STATE_EDITABLE; | 5102 ia2_state |= IA2_STATE_EDITABLE; |
| 5103 } | |
|
dougt
2017/06/23 18:27:17
Since this is a one liner, you don't need the curl
aleventhal
2017/06/28 14:20:57
Done.
| |
| 5104 | |
| 5105 if (is_editable ? IsRootEditable() : IsEditBoxRole()) { | |
| 5106 // Support multi/single line states if root edtiable or appropriate role. | |
| 5107 // We support the edit box roles even if the area is not actually editable, | |
| 5108 // because it is technically feasible for JS to implement the edit box | |
| 5109 // by controlling selection. | |
| 5110 if (owner()->HasState(ui::AX_STATE_MULTILINE)) { | |
| 5111 ia2_state |= IA2_STATE_MULTI_LINE; | |
| 5112 } else { | |
| 5113 ia2_state |= IA2_STATE_SINGLE_LINE; | |
| 5114 } | |
| 5115 } | |
| 5083 | 5116 |
| 5084 if (!owner()->GetStringAttribute(ui::AX_ATTR_AUTO_COMPLETE).empty()) | 5117 if (!owner()->GetStringAttribute(ui::AX_ATTR_AUTO_COMPLETE).empty()) |
| 5085 ia2_state |= IA2_STATE_SUPPORTS_AUTOCOMPLETION; | 5118 ia2_state |= IA2_STATE_SUPPORTS_AUTOCOMPLETION; |
| 5086 | 5119 |
| 5087 if (owner()->GetBoolAttribute(ui::AX_ATTR_MODAL)) | 5120 if (owner()->GetBoolAttribute(ui::AX_ATTR_MODAL)) |
| 5088 ia2_state |= IA2_STATE_MODAL; | 5121 ia2_state |= IA2_STATE_MODAL; |
| 5089 | 5122 |
| 5090 base::string16 html_tag = owner()->GetString16Attribute(ui::AX_ATTR_HTML_TAG); | 5123 base::string16 html_tag = owner()->GetString16Attribute(ui::AX_ATTR_HTML_TAG); |
| 5091 switch (owner()->GetRole()) { | 5124 switch (owner()->GetRole()) { |
| 5092 case ui::AX_ROLE_ALERT: | 5125 case ui::AX_ROLE_ALERT: |
| (...skipping 377 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5470 ia_role = ROLE_SYSTEM_LISTITEM; | 5503 ia_role = ROLE_SYSTEM_LISTITEM; |
| 5471 ia_state |= STATE_SYSTEM_READONLY; | 5504 ia_state |= STATE_SYSTEM_READONLY; |
| 5472 break; | 5505 break; |
| 5473 case ui::AX_ROLE_TOGGLE_BUTTON: | 5506 case ui::AX_ROLE_TOGGLE_BUTTON: |
| 5474 ia_role = ROLE_SYSTEM_PUSHBUTTON; | 5507 ia_role = ROLE_SYSTEM_PUSHBUTTON; |
| 5475 ia2_role = IA2_ROLE_TOGGLE_BUTTON; | 5508 ia2_role = IA2_ROLE_TOGGLE_BUTTON; |
| 5476 break; | 5509 break; |
| 5477 case ui::AX_ROLE_TEXT_FIELD: | 5510 case ui::AX_ROLE_TEXT_FIELD: |
| 5478 case ui::AX_ROLE_SEARCH_BOX: | 5511 case ui::AX_ROLE_SEARCH_BOX: |
| 5479 ia_role = ROLE_SYSTEM_TEXT; | 5512 ia_role = ROLE_SYSTEM_TEXT; |
| 5480 if (owner()->HasState(ui::AX_STATE_MULTILINE)) { | |
| 5481 ia2_state |= IA2_STATE_MULTI_LINE; | |
| 5482 } else { | |
| 5483 ia2_state |= IA2_STATE_SINGLE_LINE; | |
| 5484 } | |
| 5485 if (owner()->HasState(ui::AX_STATE_READ_ONLY)) | 5513 if (owner()->HasState(ui::AX_STATE_READ_ONLY)) |
| 5486 ia_state |= STATE_SYSTEM_READONLY; | 5514 ia_state |= STATE_SYSTEM_READONLY; |
| 5487 ia2_state |= IA2_STATE_SELECTABLE_TEXT; | 5515 ia2_state |= IA2_STATE_SELECTABLE_TEXT; |
| 5488 break; | 5516 break; |
| 5489 case ui::AX_ROLE_ABBR: | 5517 case ui::AX_ROLE_ABBR: |
| 5490 case ui::AX_ROLE_TIME: | 5518 case ui::AX_ROLE_TIME: |
| 5491 role_name = html_tag; | 5519 role_name = html_tag; |
| 5492 ia_role = ROLE_SYSTEM_TEXT; | 5520 ia_role = ROLE_SYSTEM_TEXT; |
| 5493 ia2_role = IA2_ROLE_TEXT_FRAME; | 5521 ia2_role = IA2_ROLE_TEXT_FRAME; |
| 5494 break; | 5522 break; |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5583 | 5611 |
| 5584 BrowserAccessibilityComWin* ToBrowserAccessibilityComWin( | 5612 BrowserAccessibilityComWin* ToBrowserAccessibilityComWin( |
| 5585 BrowserAccessibility* obj) { | 5613 BrowserAccessibility* obj) { |
| 5586 if (!obj || !obj->IsNative()) | 5614 if (!obj || !obj->IsNative()) |
| 5587 return nullptr; | 5615 return nullptr; |
| 5588 auto* result = static_cast<BrowserAccessibilityWin*>(obj)->GetCOM(); | 5616 auto* result = static_cast<BrowserAccessibilityWin*>(obj)->GetCOM(); |
| 5589 return result; | 5617 return result; |
| 5590 } | 5618 } |
| 5591 | 5619 |
| 5592 } // namespace content | 5620 } // namespace content |
| OLD | NEW |