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 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
215 return instance->NewReference(); | 215 return instance->NewReference(); |
216 } | 216 } |
217 | 217 |
218 BrowserAccessibilityWin::BrowserAccessibilityWin() | 218 BrowserAccessibilityWin::BrowserAccessibilityWin() |
219 : win_attributes_(new WinAttributes()), | 219 : win_attributes_(new WinAttributes()), |
220 previous_scroll_x_(0), | 220 previous_scroll_x_(0), |
221 previous_scroll_y_(0) { | 221 previous_scroll_y_(0) { |
222 } | 222 } |
223 | 223 |
224 BrowserAccessibilityWin::~BrowserAccessibilityWin() { | 224 BrowserAccessibilityWin::~BrowserAccessibilityWin() { |
225 for (size_t i = 0; i < relations_.size(); ++i) | 225 for (BrowserAccessibilityRelation* relation : relations_) |
226 relations_[i]->Release(); | 226 relation->Release(); |
227 } | 227 } |
228 | 228 |
229 // | 229 // |
230 // IAccessible methods. | 230 // IAccessible methods. |
231 // | 231 // |
232 // Conventions: | 232 // Conventions: |
233 // * Always test for instance_active() first and return E_FAIL if it's false. | 233 // * Always test for instance_active() first and return E_FAIL if it's false. |
234 // * Always check for invalid arguments first, even if they're unused. | 234 // * Always check for invalid arguments first, even if they're unused. |
235 // * Return S_FALSE if the only output is a string argument and it's empty. | 235 // * Return S_FALSE if the only output is a string argument and it's empty. |
236 // | 236 // |
(...skipping 4210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4447 if (role == ui::AX_ROLE_MENU_LIST_OPTION && | 4447 if (role == ui::AX_ROLE_MENU_LIST_OPTION && |
4448 parent_role == ui::AX_ROLE_MENU_LIST_POPUP) { | 4448 parent_role == ui::AX_ROLE_MENU_LIST_POPUP) { |
4449 return true; | 4449 return true; |
4450 } | 4450 } |
4451 | 4451 |
4452 return false; | 4452 return false; |
4453 } | 4453 } |
4454 | 4454 |
4455 void BrowserAccessibilityWin::AddRelation(const base::string16& relation_type, | 4455 void BrowserAccessibilityWin::AddRelation(const base::string16& relation_type, |
4456 int target_id) { | 4456 int target_id) { |
| 4457 // Reflexive relations don't need to be exposed through IA2. |
| 4458 if (target_id == GetId()) |
| 4459 return; |
| 4460 |
4457 CComObject<BrowserAccessibilityRelation>* relation; | 4461 CComObject<BrowserAccessibilityRelation>* relation; |
4458 HRESULT hr = | 4462 HRESULT hr = |
4459 CComObject<BrowserAccessibilityRelation>::CreateInstance(&relation); | 4463 CComObject<BrowserAccessibilityRelation>::CreateInstance(&relation); |
4460 DCHECK(SUCCEEDED(hr)); | 4464 DCHECK(SUCCEEDED(hr)); |
4461 relation->AddRef(); | 4465 relation->AddRef(); |
4462 relation->Initialize(this, relation_type); | 4466 relation->Initialize(this, relation_type); |
4463 relation->AddTarget(target_id); | 4467 relation->AddTarget(target_id); |
4464 relations_.push_back(relation); | 4468 relations_.push_back(relation); |
4465 } | 4469 } |
4466 | 4470 |
4467 void BrowserAccessibilityWin::AddBidirectionalRelations( | 4471 void BrowserAccessibilityWin::AddBidirectionalRelations( |
4468 const base::string16& relation_type, | 4472 const base::string16& relation_type, |
4469 const base::string16& reverse_relation_type, | 4473 const base::string16& reverse_relation_type, |
4470 ui::AXIntListAttribute attribute) { | 4474 ui::AXIntListAttribute attribute) { |
4471 if (!HasIntListAttribute(attribute)) | 4475 if (!HasIntListAttribute(attribute)) |
4472 return; | 4476 return; |
4473 | 4477 |
| 4478 const std::vector<int32_t>& target_ids = GetIntListAttribute(attribute); |
| 4479 // Reflexive relations don't need to be exposed through IA2. |
| 4480 std::vector<int32_t> filtered_target_ids; |
| 4481 int32_t current_id = GetId(); |
| 4482 std::copy_if(target_ids.begin(), target_ids.end(), |
| 4483 std::back_inserter(filtered_target_ids), |
| 4484 [current_id](int32_t id) { return id != current_id; }); |
| 4485 if (filtered_target_ids.empty()) |
| 4486 return; |
| 4487 |
4474 CComObject<BrowserAccessibilityRelation>* relation; | 4488 CComObject<BrowserAccessibilityRelation>* relation; |
4475 HRESULT hr = | 4489 HRESULT hr = |
4476 CComObject<BrowserAccessibilityRelation>::CreateInstance(&relation); | 4490 CComObject<BrowserAccessibilityRelation>::CreateInstance(&relation); |
4477 DCHECK(SUCCEEDED(hr)); | 4491 DCHECK(SUCCEEDED(hr)); |
4478 relation->AddRef(); | 4492 relation->AddRef(); |
4479 relation->Initialize(this, relation_type); | 4493 relation->Initialize(this, relation_type); |
4480 | 4494 |
4481 for (int target_id : GetIntListAttribute(attribute)) { | 4495 for (int target_id : filtered_target_ids) { |
4482 BrowserAccessibilityWin* target = | 4496 BrowserAccessibilityWin* target = |
4483 GetFromID(static_cast<int32_t>(target_id)); | 4497 GetFromID(static_cast<int32_t>(target_id)); |
4484 if (!target || !target->instance_active()) | 4498 if (!target || !target->instance_active()) |
4485 continue; | 4499 continue; |
4486 relation->AddTarget(target_id); | 4500 relation->AddTarget(target_id); |
4487 target->AddRelation(reverse_relation_type, GetId()); | 4501 target->AddRelation(reverse_relation_type, GetId()); |
4488 } | 4502 } |
4489 | 4503 |
4490 relations_.push_back(relation); | 4504 relations_.push_back(relation); |
4491 } | 4505 } |
(...skipping 28 matching lines...) Expand all Loading... |
4520 const base::string16& reverse_relation_type) { | 4534 const base::string16& reverse_relation_type) { |
4521 for (auto iter = relations_.begin(); iter != relations_.end();) { | 4535 for (auto iter = relations_.begin(); iter != relations_.end();) { |
4522 BrowserAccessibilityRelation* relation = *iter; | 4536 BrowserAccessibilityRelation* relation = *iter; |
4523 DCHECK(relation); | 4537 DCHECK(relation); |
4524 if (relation->get_type() == relation_type) { | 4538 if (relation->get_type() == relation_type) { |
4525 for (int target_id : relation->get_target_ids()) { | 4539 for (int target_id : relation->get_target_ids()) { |
4526 BrowserAccessibilityWin* target = | 4540 BrowserAccessibilityWin* target = |
4527 GetFromID(static_cast<int32_t>(target_id)); | 4541 GetFromID(static_cast<int32_t>(target_id)); |
4528 if (!target || !target->instance_active()) | 4542 if (!target || !target->instance_active()) |
4529 continue; | 4543 continue; |
| 4544 DCHECK_NE(target, this); |
4530 target->RemoveTargetFromRelation(reverse_relation_type, GetId()); | 4545 target->RemoveTargetFromRelation(reverse_relation_type, GetId()); |
4531 } | 4546 } |
| 4547 iter = relations_.erase(iter); |
4532 relation->Release(); | 4548 relation->Release(); |
4533 iter = relations_.erase(iter); | |
4534 } else { | 4549 } else { |
4535 ++iter; | 4550 ++iter; |
4536 } | 4551 } |
4537 } | 4552 } |
4538 } | 4553 } |
4539 | 4554 |
4540 void BrowserAccessibilityWin::RemoveTargetFromRelation( | 4555 void BrowserAccessibilityWin::RemoveTargetFromRelation( |
4541 const base::string16& relation_type, | 4556 const base::string16& relation_type, |
4542 int target_id) { | 4557 int target_id) { |
4543 for (auto iter = relations_.begin(); iter != relations_.end();) { | 4558 for (auto iter = relations_.begin(); iter != relations_.end();) { |
4544 BrowserAccessibilityRelation* relation = *iter; | 4559 BrowserAccessibilityRelation* relation = *iter; |
4545 DCHECK(relation); | 4560 DCHECK(relation); |
4546 if (relation->get_type() == relation_type) { | 4561 if (relation->get_type() == relation_type) { |
4547 // If |target_id| is not present, |RemoveTarget| will do nothing. | 4562 // If |target_id| is not present, |RemoveTarget| will do nothing. |
4548 relation->RemoveTarget(target_id); | 4563 relation->RemoveTarget(target_id); |
4549 } | 4564 } |
4550 if (relation->get_target_ids().empty()) { | 4565 if (relation->get_target_ids().empty()) { |
| 4566 iter = relations_.erase(iter); |
4551 relation->Release(); | 4567 relation->Release(); |
4552 iter = relations_.erase(iter); | |
4553 } else { | 4568 } else { |
4554 ++iter; | 4569 ++iter; |
4555 } | 4570 } |
4556 } | 4571 } |
4557 } | 4572 } |
4558 | 4573 |
4559 void BrowserAccessibilityWin::UpdateRequiredAttributes() { | 4574 void BrowserAccessibilityWin::UpdateRequiredAttributes() { |
4560 // Expose slider value. | 4575 // Expose slider value. |
4561 if (ia_role() == ROLE_SYSTEM_PROGRESSBAR || | 4576 if (ia_role() == ROLE_SYSTEM_PROGRESSBAR || |
4562 ia_role() == ROLE_SYSTEM_SCROLLBAR || | 4577 ia_role() == ROLE_SYSTEM_SCROLLBAR || |
(...skipping 626 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5189 return static_cast<BrowserAccessibilityWin*>(obj); | 5204 return static_cast<BrowserAccessibilityWin*>(obj); |
5190 } | 5205 } |
5191 | 5206 |
5192 const BrowserAccessibilityWin* | 5207 const BrowserAccessibilityWin* |
5193 ToBrowserAccessibilityWin(const BrowserAccessibility* obj) { | 5208 ToBrowserAccessibilityWin(const BrowserAccessibility* obj) { |
5194 DCHECK(!obj || obj->IsNative()); | 5209 DCHECK(!obj || obj->IsNative()); |
5195 return static_cast<const BrowserAccessibilityWin*>(obj); | 5210 return static_cast<const BrowserAccessibilityWin*>(obj); |
5196 } | 5211 } |
5197 | 5212 |
5198 } // namespace content | 5213 } // namespace content |
OLD | NEW |