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