| 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 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 59 BEGIN_COM_MAP(BrowserAccessibilityRelation) | 59 BEGIN_COM_MAP(BrowserAccessibilityRelation) |
| 60 COM_INTERFACE_ENTRY(IAccessibleRelation) | 60 COM_INTERFACE_ENTRY(IAccessibleRelation) |
| 61 END_COM_MAP() | 61 END_COM_MAP() |
| 62 | 62 |
| 63 CONTENT_EXPORT BrowserAccessibilityRelation() {} | 63 CONTENT_EXPORT BrowserAccessibilityRelation() {} |
| 64 CONTENT_EXPORT virtual ~BrowserAccessibilityRelation() {} | 64 CONTENT_EXPORT virtual ~BrowserAccessibilityRelation() {} |
| 65 | 65 |
| 66 CONTENT_EXPORT void Initialize(BrowserAccessibilityWin* owner, | 66 CONTENT_EXPORT void Initialize(BrowserAccessibilityWin* owner, |
| 67 const base::string16& type); | 67 const base::string16& type); |
| 68 CONTENT_EXPORT void AddTarget(int target_id); | 68 CONTENT_EXPORT void AddTarget(int target_id); |
| 69 CONTENT_EXPORT void RemoveTarget(int target_id); |
| 70 |
| 71 // Accessors. |
| 72 const base::string16& get_type() const { return type_; } |
| 73 const std::vector<int>& get_target_ids() const { return target_ids_; } |
| 69 | 74 |
| 70 // IAccessibleRelation methods. | 75 // IAccessibleRelation methods. |
| 71 CONTENT_EXPORT STDMETHODIMP get_relationType(BSTR* relation_type) override; | 76 CONTENT_EXPORT STDMETHODIMP get_relationType(BSTR* relation_type) override; |
| 72 CONTENT_EXPORT STDMETHODIMP get_nTargets(long* n_targets) override; | 77 CONTENT_EXPORT STDMETHODIMP get_nTargets(long* n_targets) override; |
| 73 CONTENT_EXPORT STDMETHODIMP | 78 CONTENT_EXPORT STDMETHODIMP |
| 74 get_target(long target_index, IUnknown** target) override; | 79 get_target(long target_index, IUnknown** target) override; |
| 75 CONTENT_EXPORT STDMETHODIMP | 80 CONTENT_EXPORT STDMETHODIMP |
| 76 get_targets(long max_targets, IUnknown** targets, long* n_targets) override; | 81 get_targets(long max_targets, IUnknown** targets, long* n_targets) override; |
| 77 | 82 |
| 78 // IAccessibleRelation methods not implemented. | 83 // IAccessibleRelation methods not implemented. |
| (...skipping 11 matching lines...) Expand all Loading... |
| 90 void BrowserAccessibilityRelation::Initialize(BrowserAccessibilityWin* owner, | 95 void BrowserAccessibilityRelation::Initialize(BrowserAccessibilityWin* owner, |
| 91 const base::string16& type) { | 96 const base::string16& type) { |
| 92 owner_ = owner; | 97 owner_ = owner; |
| 93 type_ = type; | 98 type_ = type; |
| 94 } | 99 } |
| 95 | 100 |
| 96 void BrowserAccessibilityRelation::AddTarget(int target_id) { | 101 void BrowserAccessibilityRelation::AddTarget(int target_id) { |
| 97 target_ids_.push_back(target_id); | 102 target_ids_.push_back(target_id); |
| 98 } | 103 } |
| 99 | 104 |
| 105 void BrowserAccessibilityRelation::RemoveTarget(int target_id) { |
| 106 target_ids_.erase( |
| 107 std::remove(target_ids_.begin(), target_ids_.end(), target_id), |
| 108 target_ids_.end()); |
| 109 } |
| 110 |
| 100 STDMETHODIMP BrowserAccessibilityRelation::get_relationType( | 111 STDMETHODIMP BrowserAccessibilityRelation::get_relationType( |
| 101 BSTR* relation_type) { | 112 BSTR* relation_type) { |
| 102 if (!relation_type) | 113 if (!relation_type) |
| 103 return E_INVALIDARG; | 114 return E_INVALIDARG; |
| 104 | 115 |
| 105 if (!owner_->instance_active()) | 116 if (!owner_->instance_active()) |
| 106 return E_FAIL; | 117 return E_FAIL; |
| 107 | 118 |
| 108 *relation_type = SysAllocString(type_.c_str()); | 119 *relation_type = SysAllocString(type_.c_str()); |
| 109 DCHECK(*relation_type); | 120 DCHECK(*relation_type); |
| (...skipping 3404 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3514 if (GetRole() == ui::AX_ROLE_ROOT_WEB_AREA || | 3525 if (GetRole() == ui::AX_ROLE_ROOT_WEB_AREA || |
| 3515 GetRole() == ui::AX_ROLE_WEB_AREA) { | 3526 GetRole() == ui::AX_ROLE_WEB_AREA) { |
| 3516 value = base::UTF8ToUTF16(manager()->GetTreeData().url); | 3527 value = base::UTF8ToUTF16(manager()->GetTreeData().url); |
| 3517 } | 3528 } |
| 3518 // If this doesn't have a value and is linked then set its value to the url | 3529 // If this doesn't have a value and is linked then set its value to the url |
| 3519 // attribute. This allows screen readers to read an empty link's destination. | 3530 // attribute. This allows screen readers to read an empty link's destination. |
| 3520 if (value.empty() && (ia_state() & STATE_SYSTEM_LINKED)) | 3531 if (value.empty() && (ia_state() & STATE_SYSTEM_LINKED)) |
| 3521 value = GetString16Attribute(ui::AX_ATTR_URL); | 3532 value = GetString16Attribute(ui::AX_ATTR_URL); |
| 3522 win_attributes_->value = value; | 3533 win_attributes_->value = value; |
| 3523 | 3534 |
| 3524 // Clear any old relationships between this node and other nodes. | 3535 ClearOwnRelations(); |
| 3525 for (size_t i = 0; i < relations_.size(); ++i) | 3536 AddBidirectionalRelations(IA2_RELATION_CONTROLLER_FOR, |
| 3526 relations_[i]->Release(); | 3537 IA2_RELATION_CONTROLLED_BY, |
| 3527 relations_.clear(); | 3538 ui::AX_ATTR_CONTROLS_IDS); |
| 3539 AddBidirectionalRelations(IA2_RELATION_DESCRIBED_BY, |
| 3540 IA2_RELATION_DESCRIPTION_FOR, |
| 3541 ui::AX_ATTR_DESCRIBEDBY_IDS); |
| 3542 AddBidirectionalRelations(IA2_RELATION_FLOWS_TO, IA2_RELATION_FLOWS_FROM, |
| 3543 ui::AX_ATTR_FLOWTO_IDS); |
| 3544 AddBidirectionalRelations(IA2_RELATION_LABELLED_BY, IA2_RELATION_LABEL_FOR, |
| 3545 ui::AX_ATTR_LABELLEDBY_IDS); |
| 3528 | 3546 |
| 3529 // Handle title UI element. | 3547 int member_of_id; |
| 3530 AddRelations(ui::AX_ATTR_CONTROLS_IDS, IA2_RELATION_CONTROLLER_FOR); | 3548 if (GetIntAttribute(ui::AX_ATTR_MEMBER_OF_ID, &member_of_id)) |
| 3531 AddRelations(ui::AX_ATTR_DESCRIBEDBY_IDS, IA2_RELATION_DESCRIBED_BY); | 3549 AddRelation(IA2_RELATION_MEMBER_OF, member_of_id); |
| 3532 AddRelations(ui::AX_ATTR_FLOWTO_IDS, IA2_RELATION_FLOWS_TO); | |
| 3533 AddRelations(ui::AX_ATTR_LABELLEDBY_IDS, IA2_RELATION_LABELLED_BY); | |
| 3534 | 3550 |
| 3535 UpdateRequiredAttributes(); | 3551 UpdateRequiredAttributes(); |
| 3536 // If this is a web area for a presentational iframe, give it a role of | 3552 // If this is a web area for a presentational iframe, give it a role of |
| 3537 // something other than DOCUMENT so that the fact that it's a separate doc | 3553 // something other than DOCUMENT so that the fact that it's a separate doc |
| 3538 // is not exposed to AT. | 3554 // is not exposed to AT. |
| 3539 if (IsWebAreaForPresentationalIframe()) { | 3555 if (IsWebAreaForPresentationalIframe()) { |
| 3540 win_attributes_->ia_role = ROLE_SYSTEM_GROUPING; | 3556 win_attributes_->ia_role = ROLE_SYSTEM_GROUPING; |
| 3541 win_attributes_->ia2_role = ROLE_SYSTEM_GROUPING; | 3557 win_attributes_->ia2_role = ROLE_SYSTEM_GROUPING; |
| 3542 } | 3558 } |
| 3543 } | 3559 } |
| (...skipping 885 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4429 } | 4445 } |
| 4430 | 4446 |
| 4431 if (role == ui::AX_ROLE_MENU_LIST_OPTION && | 4447 if (role == ui::AX_ROLE_MENU_LIST_OPTION && |
| 4432 parent_role == ui::AX_ROLE_MENU_LIST_POPUP) { | 4448 parent_role == ui::AX_ROLE_MENU_LIST_POPUP) { |
| 4433 return true; | 4449 return true; |
| 4434 } | 4450 } |
| 4435 | 4451 |
| 4436 return false; | 4452 return false; |
| 4437 } | 4453 } |
| 4438 | 4454 |
| 4439 void BrowserAccessibilityWin::AddRelations( | 4455 void BrowserAccessibilityWin::AddRelation(const base::string16& relation_type, |
| 4440 ui::AXIntListAttribute src_attr, | 4456 int target_id) { |
| 4441 const base::string16& iaccessiblerelation_type) { | 4457 CComObject<BrowserAccessibilityRelation>* relation; |
| 4442 if (!HasIntListAttribute(src_attr)) | 4458 HRESULT hr = |
| 4459 CComObject<BrowserAccessibilityRelation>::CreateInstance(&relation); |
| 4460 DCHECK(SUCCEEDED(hr)); |
| 4461 relation->AddRef(); |
| 4462 relation->Initialize(this, relation_type); |
| 4463 relation->AddTarget(target_id); |
| 4464 relations_.push_back(relation); |
| 4465 } |
| 4466 |
| 4467 void BrowserAccessibilityWin::AddBidirectionalRelations( |
| 4468 const base::string16& relation_type, |
| 4469 const base::string16& reverse_relation_type, |
| 4470 ui::AXIntListAttribute attribute) { |
| 4471 if (!HasIntListAttribute(attribute)) |
| 4443 return; | 4472 return; |
| 4444 | 4473 |
| 4445 const std::vector<int32_t>& ids = GetIntListAttribute(src_attr); | 4474 CComObject<BrowserAccessibilityRelation>* relation; |
| 4446 for (size_t i = 0; i < ids.size(); ++i) { | 4475 HRESULT hr = |
| 4447 CComObject<BrowserAccessibilityRelation>* relation; | 4476 CComObject<BrowserAccessibilityRelation>::CreateInstance(&relation); |
| 4448 HRESULT hr = | 4477 DCHECK(SUCCEEDED(hr)); |
| 4449 CComObject<BrowserAccessibilityRelation>::CreateInstance(&relation); | 4478 relation->AddRef(); |
| 4450 DCHECK(SUCCEEDED(hr)); | 4479 relation->Initialize(this, relation_type); |
| 4451 relation->AddRef(); | 4480 |
| 4452 relation->Initialize(this, iaccessiblerelation_type); | 4481 for (int target_id : GetIntListAttribute(attribute)) { |
| 4453 relation->AddTarget(ids[i]); | 4482 BrowserAccessibilityWin* target = |
| 4454 relations_.push_back(relation); | 4483 GetFromID(static_cast<int32_t>(target_id)); |
| 4484 if (!target || !target->instance_active()) |
| 4485 continue; |
| 4486 relation->AddTarget(target_id); |
| 4487 target->AddRelation(reverse_relation_type, GetId()); |
| 4488 } |
| 4489 |
| 4490 relations_.push_back(relation); |
| 4491 } |
| 4492 |
| 4493 // Clears all the forward relations from this object to any other object and the |
| 4494 // associated reverse relations on the other objects, but leaves any reverse |
| 4495 // relations on this object alone. |
| 4496 void BrowserAccessibilityWin::ClearOwnRelations() { |
| 4497 RemoveBidirectionalRelationsOfType(IA2_RELATION_CONTROLLER_FOR, |
| 4498 IA2_RELATION_CONTROLLED_BY); |
| 4499 RemoveBidirectionalRelationsOfType(IA2_RELATION_DESCRIBED_BY, |
| 4500 IA2_RELATION_DESCRIPTION_FOR); |
| 4501 RemoveBidirectionalRelationsOfType(IA2_RELATION_FLOWS_TO, |
| 4502 IA2_RELATION_FLOWS_FROM); |
| 4503 RemoveBidirectionalRelationsOfType(IA2_RELATION_LABELLED_BY, |
| 4504 IA2_RELATION_LABEL_FOR); |
| 4505 |
| 4506 relations_.erase( |
| 4507 std::remove_if(relations_.begin(), relations_.end(), |
| 4508 [](BrowserAccessibilityRelation* relation) { |
| 4509 if (relation->get_type() == IA2_RELATION_MEMBER_OF) { |
| 4510 relation->Release(); |
| 4511 return true; |
| 4512 } |
| 4513 return false; |
| 4514 }), |
| 4515 relations_.end()); |
| 4516 } |
| 4517 |
| 4518 void BrowserAccessibilityWin::RemoveBidirectionalRelationsOfType( |
| 4519 const base::string16& relation_type, |
| 4520 const base::string16& reverse_relation_type) { |
| 4521 for (auto iter = relations_.begin(); iter != relations_.end();) { |
| 4522 BrowserAccessibilityRelation* relation = *iter; |
| 4523 DCHECK(relation); |
| 4524 if (relation->get_type() == relation_type) { |
| 4525 for (int target_id : relation->get_target_ids()) { |
| 4526 BrowserAccessibilityWin* target = |
| 4527 GetFromID(static_cast<int32_t>(target_id)); |
| 4528 if (!target || !target->instance_active()) |
| 4529 continue; |
| 4530 target->RemoveTargetFromRelation(reverse_relation_type, GetId()); |
| 4531 } |
| 4532 relation->Release(); |
| 4533 iter = relations_.erase(iter); |
| 4534 } else { |
| 4535 ++iter; |
| 4536 } |
| 4455 } | 4537 } |
| 4456 } | 4538 } |
| 4457 | 4539 |
| 4540 void BrowserAccessibilityWin::RemoveTargetFromRelation( |
| 4541 const base::string16& relation_type, |
| 4542 int target_id) { |
| 4543 for (auto iter = relations_.begin(); iter != relations_.end();) { |
| 4544 BrowserAccessibilityRelation* relation = *iter; |
| 4545 DCHECK(relation); |
| 4546 if (relation->get_type() == relation_type) { |
| 4547 // If |target_id| is not present, |RemoveTarget| will do nothing. |
| 4548 relation->RemoveTarget(target_id); |
| 4549 } |
| 4550 if (relation->get_target_ids().empty()) { |
| 4551 relation->Release(); |
| 4552 iter = relations_.erase(iter); |
| 4553 } else { |
| 4554 ++iter; |
| 4555 } |
| 4556 } |
| 4557 } |
| 4558 |
| 4458 void BrowserAccessibilityWin::UpdateRequiredAttributes() { | 4559 void BrowserAccessibilityWin::UpdateRequiredAttributes() { |
| 4459 // Expose slider value. | 4560 // Expose slider value. |
| 4460 if (ia_role() == ROLE_SYSTEM_PROGRESSBAR || | 4561 if (ia_role() == ROLE_SYSTEM_PROGRESSBAR || |
| 4461 ia_role() == ROLE_SYSTEM_SCROLLBAR || | 4562 ia_role() == ROLE_SYSTEM_SCROLLBAR || |
| 4462 ia_role() == ROLE_SYSTEM_SLIDER) { | 4563 ia_role() == ROLE_SYSTEM_SLIDER) { |
| 4463 base::string16 value_text = GetValueText(); | 4564 base::string16 value_text = GetValueText(); |
| 4464 SanitizeStringAttributeForIA2(value_text, &value_text); | 4565 SanitizeStringAttributeForIA2(value_text, &value_text); |
| 4465 win_attributes_->ia2_attributes.push_back(L"valuetext:" + value_text); | 4566 win_attributes_->ia2_attributes.push_back(L"valuetext:" + value_text); |
| 4466 } | 4567 } |
| 4467 | 4568 |
| (...skipping 620 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5088 return static_cast<BrowserAccessibilityWin*>(obj); | 5189 return static_cast<BrowserAccessibilityWin*>(obj); |
| 5089 } | 5190 } |
| 5090 | 5191 |
| 5091 const BrowserAccessibilityWin* | 5192 const BrowserAccessibilityWin* |
| 5092 ToBrowserAccessibilityWin(const BrowserAccessibility* obj) { | 5193 ToBrowserAccessibilityWin(const BrowserAccessibility* obj) { |
| 5093 DCHECK(!obj || obj->IsNative()); | 5194 DCHECK(!obj || obj->IsNative()); |
| 5094 return static_cast<const BrowserAccessibilityWin*>(obj); | 5195 return static_cast<const BrowserAccessibilityWin*>(obj); |
| 5095 } | 5196 } |
| 5096 | 5197 |
| 5097 } // namespace content | 5198 } // namespace content |
| OLD | NEW |