| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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_win.h" | 5 #include "content/browser/accessibility/browser_accessibility_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 713 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 724 return S_OK; | 724 return S_OK; |
| 725 } | 725 } |
| 726 | 726 |
| 727 STDMETHODIMP BrowserAccessibilityWin::get_uniqueID(LONG* unique_id) { | 727 STDMETHODIMP BrowserAccessibilityWin::get_uniqueID(LONG* unique_id) { |
| 728 if (!instance_active()) | 728 if (!instance_active()) |
| 729 return E_FAIL; | 729 return E_FAIL; |
| 730 | 730 |
| 731 if (!unique_id) | 731 if (!unique_id) |
| 732 return E_INVALIDARG; | 732 return E_INVALIDARG; |
| 733 | 733 |
| 734 *unique_id = -unique_id_; | 734 *unique_id = -this->unique_id(); |
| 735 return S_OK; | 735 return S_OK; |
| 736 } | 736 } |
| 737 | 737 |
| 738 STDMETHODIMP BrowserAccessibilityWin::get_windowHandle(HWND* window_handle) { | 738 STDMETHODIMP BrowserAccessibilityWin::get_windowHandle(HWND* window_handle) { |
| 739 if (!instance_active()) | 739 if (!instance_active()) |
| 740 return E_FAIL; | 740 return E_FAIL; |
| 741 | 741 |
| 742 if (!window_handle) | 742 if (!window_handle) |
| 743 return E_INVALIDARG; | 743 return E_INVALIDARG; |
| 744 | 744 |
| (...skipping 1659 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2404 if (!instance_active()) | 2404 if (!instance_active()) |
| 2405 return E_FAIL; | 2405 return E_FAIL; |
| 2406 | 2406 |
| 2407 if (!hyperlink || | 2407 if (!hyperlink || |
| 2408 index < 0 || | 2408 index < 0 || |
| 2409 index >= static_cast<long>(hyperlinks().size())) { | 2409 index >= static_cast<long>(hyperlinks().size())) { |
| 2410 return E_INVALIDARG; | 2410 return E_INVALIDARG; |
| 2411 } | 2411 } |
| 2412 | 2412 |
| 2413 int32_t id = hyperlinks()[index]; | 2413 int32_t id = hyperlinks()[index]; |
| 2414 BrowserAccessibilityWin* link = GetFromID(id); | 2414 BrowserAccessibilityWin* link = |
| 2415 ToBrowserAccessibilityWin(GetFromUniqueID(id)); |
| 2415 if (!link) | 2416 if (!link) |
| 2416 return E_FAIL; | 2417 return E_FAIL; |
| 2417 | 2418 |
| 2418 *hyperlink = static_cast<IAccessibleHyperlink*>(link->NewReference()); | 2419 *hyperlink = static_cast<IAccessibleHyperlink*>(link->NewReference()); |
| 2419 return S_OK; | 2420 return S_OK; |
| 2420 } | 2421 } |
| 2421 | 2422 |
| 2422 STDMETHODIMP BrowserAccessibilityWin::get_hyperlinkIndex( | 2423 STDMETHODIMP BrowserAccessibilityWin::get_hyperlinkIndex( |
| 2423 long char_index, | 2424 long char_index, |
| 2424 long* hyperlink_index) { | 2425 long* hyperlink_index) { |
| (...skipping 345 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2770 | 2771 |
| 2771 base::string16 tag; | 2772 base::string16 tag; |
| 2772 if (GetString16Attribute(ui::AX_ATTR_HTML_TAG, &tag)) | 2773 if (GetString16Attribute(ui::AX_ATTR_HTML_TAG, &tag)) |
| 2773 *node_name = SysAllocString(tag.c_str()); | 2774 *node_name = SysAllocString(tag.c_str()); |
| 2774 else | 2775 else |
| 2775 *node_name = NULL; | 2776 *node_name = NULL; |
| 2776 | 2777 |
| 2777 *name_space_id = 0; | 2778 *name_space_id = 0; |
| 2778 *node_value = SysAllocString(value().c_str()); | 2779 *node_value = SysAllocString(value().c_str()); |
| 2779 *num_children = PlatformChildCount(); | 2780 *num_children = PlatformChildCount(); |
| 2780 *unique_id = -unique_id_; | 2781 *unique_id = -this->unique_id(); |
| 2781 | 2782 |
| 2782 if (GetRole() == ui::AX_ROLE_ROOT_WEB_AREA || | 2783 if (GetRole() == ui::AX_ROLE_ROOT_WEB_AREA || |
| 2783 GetRole() == ui::AX_ROLE_WEB_AREA) { | 2784 GetRole() == ui::AX_ROLE_WEB_AREA) { |
| 2784 *node_type = NODETYPE_DOCUMENT; | 2785 *node_type = NODETYPE_DOCUMENT; |
| 2785 } else if (IsTextOnlyObject()) { | 2786 } else if (IsTextOnlyObject()) { |
| 2786 *node_type = NODETYPE_TEXT; | 2787 *node_type = NODETYPE_TEXT; |
| 2787 } else { | 2788 } else { |
| 2788 *node_type = NODETYPE_ELEMENT; | 2789 *node_type = NODETYPE_ELEMENT; |
| 2789 } | 2790 } |
| 2790 | 2791 |
| (...skipping 711 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3502 case ui::AX_SORT_DIRECTION_OTHER: | 3503 case ui::AX_SORT_DIRECTION_OTHER: |
| 3503 win_attributes_->ia2_attributes.push_back(L"sort:other"); | 3504 win_attributes_->ia2_attributes.push_back(L"sort:other"); |
| 3504 break; | 3505 break; |
| 3505 } | 3506 } |
| 3506 } | 3507 } |
| 3507 | 3508 |
| 3508 win_attributes_->name = GetString16Attribute(ui::AX_ATTR_NAME); | 3509 win_attributes_->name = GetString16Attribute(ui::AX_ATTR_NAME); |
| 3509 win_attributes_->description = GetString16Attribute(ui::AX_ATTR_DESCRIPTION); | 3510 win_attributes_->description = GetString16Attribute(ui::AX_ATTR_DESCRIPTION); |
| 3510 | 3511 |
| 3511 base::string16 value = GetValue(); | 3512 base::string16 value = GetValue(); |
| 3512 | |
| 3513 // On Windows, the value of a document should be its url. | 3513 // On Windows, the value of a document should be its url. |
| 3514 if (GetRole() == ui::AX_ROLE_ROOT_WEB_AREA || | 3514 if (GetRole() == ui::AX_ROLE_ROOT_WEB_AREA || |
| 3515 GetRole() == ui::AX_ROLE_WEB_AREA) { | 3515 GetRole() == ui::AX_ROLE_WEB_AREA) { |
| 3516 value = base::UTF8ToUTF16(manager()->GetTreeData().url); | 3516 value = base::UTF8ToUTF16(manager()->GetTreeData().url); |
| 3517 } | 3517 } |
| 3518 | |
| 3519 // If this doesn't have a value and is linked then set its value to the url | 3518 // If this doesn't have a value and is linked then set its value to the url |
| 3520 // attribute. This allows screen readers to read an empty link's destination. | 3519 // attribute. This allows screen readers to read an empty link's destination. |
| 3521 if (value.empty() && (ia_state() & STATE_SYSTEM_LINKED)) | 3520 if (value.empty() && (ia_state() & STATE_SYSTEM_LINKED)) |
| 3522 value = GetString16Attribute(ui::AX_ATTR_URL); | 3521 value = GetString16Attribute(ui::AX_ATTR_URL); |
| 3523 | |
| 3524 win_attributes_->value = value; | 3522 win_attributes_->value = value; |
| 3525 | 3523 |
| 3526 // Clear any old relationships between this node and other nodes. | 3524 // Clear any old relationships between this node and other nodes. |
| 3527 for (size_t i = 0; i < relations_.size(); ++i) | 3525 for (size_t i = 0; i < relations_.size(); ++i) |
| 3528 relations_[i]->Release(); | 3526 relations_[i]->Release(); |
| 3529 relations_.clear(); | 3527 relations_.clear(); |
| 3530 | 3528 |
| 3531 // Handle title UI element. | 3529 // Handle title UI element. |
| 3532 AddRelations(ui::AX_ATTR_CONTROLS_IDS, IA2_RELATION_CONTROLLER_FOR); | 3530 AddRelations(ui::AX_ATTR_CONTROLS_IDS, IA2_RELATION_CONTROLLER_FOR); |
| 3533 AddRelations(ui::AX_ATTR_DESCRIBEDBY_IDS, IA2_RELATION_DESCRIBED_BY); | 3531 AddRelations(ui::AX_ATTR_DESCRIBEDBY_IDS, IA2_RELATION_DESCRIBED_BY); |
| 3534 AddRelations(ui::AX_ATTR_FLOWTO_IDS, IA2_RELATION_FLOWS_TO); | 3532 AddRelations(ui::AX_ATTR_FLOWTO_IDS, IA2_RELATION_FLOWS_TO); |
| 3535 AddRelations(ui::AX_ATTR_LABELLEDBY_IDS, IA2_RELATION_LABELLED_BY); | 3533 AddRelations(ui::AX_ATTR_LABELLEDBY_IDS, IA2_RELATION_LABELLED_BY); |
| 3536 | 3534 |
| 3537 UpdateRequiredAttributes(); | 3535 UpdateRequiredAttributes(); |
| 3538 // If this is a web area for a presentational iframe, give it a role of | 3536 // If this is a web area for a presentational iframe, give it a role of |
| 3539 // something other than DOCUMENT so that the fact that it's a separate doc | 3537 // something other than DOCUMENT so that the fact that it's a separate doc |
| 3540 // is not exposed to AT. | 3538 // is not exposed to AT. |
| 3541 if (IsWebAreaForPresentationalIframe()) { | 3539 if (IsWebAreaForPresentationalIframe()) { |
| 3542 win_attributes_->ia_role = ROLE_SYSTEM_GROUPING; | 3540 win_attributes_->ia_role = ROLE_SYSTEM_GROUPING; |
| 3543 win_attributes_->ia2_role = ROLE_SYSTEM_GROUPING; | 3541 win_attributes_->ia2_role = ROLE_SYSTEM_GROUPING; |
| 3544 } | 3542 } |
| 3545 } | 3543 } |
| 3546 | 3544 |
| 3547 void BrowserAccessibilityWin::UpdateStep2ComputeHypertext() { | 3545 void BrowserAccessibilityWin::UpdateStep2ComputeHypertext() { |
| 3548 if (PlatformIsLeaf()) { | 3546 if (!PlatformChildCount()) { |
| 3549 if (IsSimpleTextControl()) | 3547 if (IsSimpleTextControl()) { |
| 3550 win_attributes_->hypertext = value(); | 3548 win_attributes_->hypertext = value(); |
| 3551 else { | 3549 } else if (IsRichTextControl()) { |
| 3550 // We don't want to expose any associated label in IA2 Hypertext. |
| 3551 return; |
| 3552 } else { |
| 3552 win_attributes_->hypertext = name(); | 3553 win_attributes_->hypertext = name(); |
| 3553 } | 3554 } |
| 3554 | 3555 |
| 3555 return; | 3556 return; |
| 3556 } | 3557 } |
| 3557 | 3558 |
| 3558 // Construct the hypertext for this node, which contains the concatenation | 3559 // Construct the hypertext for this node, which contains the concatenation |
| 3559 // of all of the static text and widespace of this node's children and an | 3560 // of all of the static text and widespace of this node's children and an |
| 3560 // embedded object character for all the other children. Build up a map from | 3561 // embedded object character for all the other children. Build up a map from |
| 3561 // the character index of each embedded object character to the id of the | 3562 // the character index of each embedded object character to the id of the |
| 3562 // child object it points to. | 3563 // child object it points to. |
| 3563 for (unsigned int i = 0; i < PlatformChildCount(); ++i) { | 3564 for (unsigned int i = 0; i < PlatformChildCount(); ++i) { |
| 3564 const auto child = ToBrowserAccessibilityWin(PlatformGetChild(i)); | 3565 const auto child = ToBrowserAccessibilityWin(PlatformGetChild(i)); |
| 3565 DCHECK(child); | 3566 DCHECK(child); |
| 3566 // Similar to Firefox, we don't expose text-only objects in IA2 hypertext. | 3567 // Similar to Firefox, we don't expose text-only objects in IA2 hypertext. |
| 3567 if (child->IsTextOnlyObject()) { | 3568 if (child->IsTextOnlyObject()) { |
| 3568 win_attributes_->hypertext += child->name(); | 3569 win_attributes_->hypertext += child->name(); |
| 3569 } else { | 3570 } else { |
| 3570 int32_t char_offset = static_cast<int32_t>(GetText().size()); | 3571 int32_t char_offset = static_cast<int32_t>(GetText().size()); |
| 3571 int32_t child_id = child->GetId(); | 3572 int32_t child_unique_id = child->unique_id(); |
| 3572 int32_t index = hyperlinks().size(); | 3573 int32_t index = hyperlinks().size(); |
| 3573 win_attributes_->hyperlink_offset_to_index[char_offset] = index; | 3574 win_attributes_->hyperlink_offset_to_index[char_offset] = index; |
| 3574 win_attributes_->hyperlinks.push_back(child_id); | 3575 win_attributes_->hyperlinks.push_back(child_unique_id); |
| 3575 win_attributes_->hypertext += kEmbeddedCharacter; | 3576 win_attributes_->hypertext += kEmbeddedCharacter; |
| 3576 } | 3577 } |
| 3577 } | 3578 } |
| 3578 } | 3579 } |
| 3579 | 3580 |
| 3580 void BrowserAccessibilityWin::UpdateStep3FireEvents(bool is_subtree_creation) { | 3581 void BrowserAccessibilityWin::UpdateStep3FireEvents(bool is_subtree_creation) { |
| 3581 // Fire an event when an alert first appears. | 3582 // Fire an event when an alert first appears. |
| 3582 if (ia_role() == ROLE_SYSTEM_ALERT && | 3583 if (ia_role() == ROLE_SYSTEM_ALERT && |
| 3583 old_win_attributes_->ia_role != ROLE_SYSTEM_ALERT) { | 3584 old_win_attributes_->ia_role != ROLE_SYSTEM_ALERT) { |
| 3584 BrowserAccessibilityEvent::Create( | 3585 BrowserAccessibilityEvent::Create( |
| (...skipping 440 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4025 BrowserAccessibilityWin::GetHyperlinkFromHypertextOffset(int offset) const { | 4026 BrowserAccessibilityWin::GetHyperlinkFromHypertextOffset(int offset) const { |
| 4026 std::map<int32_t, int32_t>::iterator iterator = | 4027 std::map<int32_t, int32_t>::iterator iterator = |
| 4027 hyperlink_offset_to_index().find(offset); | 4028 hyperlink_offset_to_index().find(offset); |
| 4028 if (iterator == hyperlink_offset_to_index().end()) | 4029 if (iterator == hyperlink_offset_to_index().end()) |
| 4029 return nullptr; | 4030 return nullptr; |
| 4030 | 4031 |
| 4031 int32_t index = iterator->second; | 4032 int32_t index = iterator->second; |
| 4032 DCHECK_GE(index, 0); | 4033 DCHECK_GE(index, 0); |
| 4033 DCHECK_LT(index, static_cast<int32_t>(hyperlinks().size())); | 4034 DCHECK_LT(index, static_cast<int32_t>(hyperlinks().size())); |
| 4034 int32_t id = hyperlinks()[index]; | 4035 int32_t id = hyperlinks()[index]; |
| 4035 BrowserAccessibilityWin* hyperlink = GetFromID(id); | 4036 BrowserAccessibilityWin* hyperlink = |
| 4037 ToBrowserAccessibilityWin(GetFromUniqueID(id)); |
| 4036 if (!hyperlink) | 4038 if (!hyperlink) |
| 4037 return nullptr; | 4039 return nullptr; |
| 4038 return hyperlink; | 4040 return hyperlink; |
| 4039 } | 4041 } |
| 4040 | 4042 |
| 4041 int32_t BrowserAccessibilityWin::GetHyperlinkIndexFromChild( | 4043 int32_t BrowserAccessibilityWin::GetHyperlinkIndexFromChild( |
| 4042 const BrowserAccessibilityWin& child) const { | 4044 const BrowserAccessibilityWin& child) const { |
| 4043 if (hyperlinks().empty()) | 4045 if (hyperlinks().empty()) |
| 4044 return -1; | 4046 return -1; |
| 4045 | 4047 |
| 4046 auto iterator = std::find( | 4048 auto iterator = |
| 4047 hyperlinks().begin(), hyperlinks().end(), child.GetId()); | 4049 std::find(hyperlinks().begin(), hyperlinks().end(), child.unique_id()); |
| 4048 if (iterator == hyperlinks().end()) | 4050 if (iterator == hyperlinks().end()) |
| 4049 return -1; | 4051 return -1; |
| 4050 | 4052 |
| 4051 return static_cast<int32_t>(iterator - hyperlinks().begin()); | 4053 return static_cast<int32_t>(iterator - hyperlinks().begin()); |
| 4052 } | 4054 } |
| 4053 | 4055 |
| 4054 int32_t BrowserAccessibilityWin::GetHypertextOffsetFromHyperlinkIndex( | 4056 int32_t BrowserAccessibilityWin::GetHypertextOffsetFromHyperlinkIndex( |
| 4055 int32_t hyperlink_index) const { | 4057 int32_t hyperlink_index) const { |
| 4056 for (auto& offset_index : hyperlink_offset_to_index()) { | 4058 for (auto& offset_index : hyperlink_offset_to_index()) { |
| 4057 if (offset_index.second == hyperlink_index) | 4059 if (offset_index.second == hyperlink_index) |
| (...skipping 1028 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5086 return static_cast<BrowserAccessibilityWin*>(obj); | 5088 return static_cast<BrowserAccessibilityWin*>(obj); |
| 5087 } | 5089 } |
| 5088 | 5090 |
| 5089 const BrowserAccessibilityWin* | 5091 const BrowserAccessibilityWin* |
| 5090 ToBrowserAccessibilityWin(const BrowserAccessibility* obj) { | 5092 ToBrowserAccessibilityWin(const BrowserAccessibility* obj) { |
| 5091 DCHECK(!obj || obj->IsNative()); | 5093 DCHECK(!obj || obj->IsNative()); |
| 5092 return static_cast<const BrowserAccessibilityWin*>(obj); | 5094 return static_cast<const BrowserAccessibilityWin*>(obj); |
| 5093 } | 5095 } |
| 5094 | 5096 |
| 5095 } // namespace content | 5097 } // namespace content |
| OLD | NEW |