Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(226)

Side by Side Diff: content/browser/accessibility/browser_accessibility_win.cc

Issue 2040523002: Improves computation of IAccessible2 Hypertext. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fixed expectations on Windows for hopefully the last time. Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698