| OLD | NEW |
| 1 // Copyright (c) 2017 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2017 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_com_win.h" | 5 #include "content/browser/accessibility/browser_accessibility_com_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 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 213 content::AccessibilityMode::kHTML; | 213 content::AccessibilityMode::kHTML; |
| 214 | 214 |
| 215 const WCHAR* const IA2_RELATION_DETAILS = L"details"; | 215 const WCHAR* const IA2_RELATION_DETAILS = L"details"; |
| 216 const WCHAR* const IA2_RELATION_DETAILS_FOR = L"detailsFor"; | 216 const WCHAR* const IA2_RELATION_DETAILS_FOR = L"detailsFor"; |
| 217 const WCHAR* const IA2_RELATION_ERROR_MESSAGE = L"errorMessage"; | 217 const WCHAR* const IA2_RELATION_ERROR_MESSAGE = L"errorMessage"; |
| 218 | 218 |
| 219 } // namespace | 219 } // namespace |
| 220 | 220 |
| 221 namespace content { | 221 namespace content { |
| 222 | 222 |
| 223 using AXPlatformPositionInstance = AXPlatformPosition::AXPositionInstance; | 223 using AXPlatformPositionInstance = AXPlatformPosition::ConcreteInstance; |
| 224 using AXAbstractPositionInstance = AXPlatformPosition::AXPositionInstance; |
| 224 using AXPlatformRange = ui::AXRange<AXPlatformPositionInstance::element_type>; | 225 using AXPlatformRange = ui::AXRange<AXPlatformPositionInstance::element_type>; |
| 225 | 226 |
| 226 // These nonstandard GUIDs are taken directly from the Mozilla sources | 227 // These nonstandard GUIDs are taken directly from the Mozilla sources |
| 227 // (accessible/src/msaa/nsAccessNodeWrap.cpp); some documentation is here: | 228 // (accessible/src/msaa/nsAccessNodeWrap.cpp); some documentation is here: |
| 228 // http://developer.mozilla.org/en/Accessibility/AT-APIs/ImplementationFeatures/
MSAA | 229 // http://developer.mozilla.org/en/Accessibility/AT-APIs/ImplementationFeatures/
MSAA |
| 229 const GUID GUID_ISimpleDOM = {0x0c539790, | 230 const GUID GUID_ISimpleDOM = {0x0c539790, |
| 230 0x12e4, | 231 0x12e4, |
| 231 0x11cf, | 232 0x11cf, |
| 232 {0xb6, 0x61, 0x00, 0xaa, 0x00, 0x4c, 0xd6, 0xd8}}; | 233 {0xb6, 0x61, 0x00, 0xaa, 0x00, 0x4c, 0xd6, 0xd8}}; |
| 233 const GUID GUID_IAccessibleContentDocument = { | 234 const GUID GUID_IAccessibleContentDocument = { |
| (...skipping 3347 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3581 else | 3582 else |
| 3582 start_offset += 1; | 3583 start_offset += 1; |
| 3583 } | 3584 } |
| 3584 | 3585 |
| 3585 win_attributes_->offset_to_text_attributes.swap(attributes_map); | 3586 win_attributes_->offset_to_text_attributes.swap(attributes_map); |
| 3586 } | 3587 } |
| 3587 | 3588 |
| 3588 // |offset| could either be a text character or a child index in case of | 3589 // |offset| could either be a text character or a child index in case of |
| 3589 // non-text objects. | 3590 // non-text objects. |
| 3590 // TODO(nektar): Remove this function once selection bugs are fixed in Blink. | 3591 // TODO(nektar): Remove this function once selection bugs are fixed in Blink. |
| 3591 AXPlatformPosition::AXPositionInstance | 3592 AXPlatformPosition::ConcreteInstance |
| 3592 BrowserAccessibilityComWin::CreatePositionForSelectionAt(int offset) const { | 3593 BrowserAccessibilityComWin::CreatePositionForSelectionAt(int offset) const { |
| 3593 if (!owner()->IsNativeTextControl() && !owner()->IsTextOnlyObject()) { | 3594 if (!owner()->IsNativeTextControl() && !owner()->IsTextOnlyObject()) { |
| 3594 auto* manager = Manager(); | 3595 auto* manager = Manager(); |
| 3595 DCHECK(manager); | 3596 DCHECK(manager); |
| 3596 const BrowserAccessibilityComWin* child = this; | 3597 const BrowserAccessibilityComWin* child = this; |
| 3597 // TODO(nektar): Make parents of text-only objects not include the text of | 3598 // TODO(nektar): Make parents of text-only objects not include the text of |
| 3598 // children in their hypertext. | 3599 // children in their hypertext. |
| 3599 for (size_t i = 0; i < owner()->InternalChildCount(); ++i) { | 3600 for (size_t i = 0; i < owner()->InternalChildCount(); ++i) { |
| 3600 int new_offset = offset; | 3601 int new_offset = offset; |
| 3601 child = ToBrowserAccessibilityComWin(owner()->InternalGetChild(i)); | 3602 child = ToBrowserAccessibilityComWin(owner()->InternalGetChild(i)); |
| 3602 DCHECK(child); | 3603 DCHECK(child); |
| 3603 if (child->owner()->IsTextOnlyObject()) { | 3604 if (child->owner()->IsTextOnlyObject()) { |
| 3604 new_offset -= child->owner()->GetText().length(); | 3605 new_offset -= child->owner()->GetText().length(); |
| 3605 } else { | 3606 } else { |
| 3606 new_offset -= 1; | 3607 new_offset -= 1; |
| 3607 } | 3608 } |
| 3608 if (new_offset <= 0) | 3609 if (new_offset <= 0) |
| 3609 break; | 3610 break; |
| 3610 offset = new_offset; | 3611 offset = new_offset; |
| 3611 } | 3612 } |
| 3612 AXPlatformPositionInstance position = | 3613 AXPlatformPositionInstance position = AXPlatformPosition::FromBase( |
| 3613 AXPlatformPosition::CreateTextPosition(manager->ax_tree_id(), | 3614 AXPlatformPosition::CreateConcreteTextPosition( |
| 3614 child->owner()->GetId(), offset, | 3615 manager->ax_tree_id(), child->owner()->GetId(), offset, |
| 3615 ui::AX_TEXT_AFFINITY_DOWNSTREAM) | 3616 ui::AX_TEXT_AFFINITY_DOWNSTREAM) |
| 3616 ->AsLeafTextPosition(); | 3617 ->AsLeafTextPosition()); |
| 3617 if (position->GetAnchor() && | 3618 if (position->GetAnchor() && |
| 3618 position->GetAnchor()->GetRole() == ui::AX_ROLE_INLINE_TEXT_BOX) { | 3619 position->GetAnchor()->GetRole() == ui::AX_ROLE_INLINE_TEXT_BOX) { |
| 3619 return position->CreateParentPosition(); | 3620 return AXPlatformPosition::FromBase(position->CreateParentPosition()); |
| 3620 } | 3621 } |
| 3621 return position; | 3622 return position; |
| 3622 } | 3623 } |
| 3623 return owner()->CreatePositionAt(offset); | 3624 return owner()->CreatePositionAt(offset); |
| 3624 } | 3625 } |
| 3625 | 3626 |
| 3626 // | 3627 // |
| 3627 // Private methods. | 3628 // Private methods. |
| 3628 // | 3629 // |
| 3629 | 3630 |
| (...skipping 631 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4261 } | 4262 } |
| 4262 | 4263 |
| 4263 void BrowserAccessibilityComWin::SetIA2HypertextSelection(LONG start_offset, | 4264 void BrowserAccessibilityComWin::SetIA2HypertextSelection(LONG start_offset, |
| 4264 LONG end_offset) { | 4265 LONG end_offset) { |
| 4265 HandleSpecialTextOffset(&start_offset); | 4266 HandleSpecialTextOffset(&start_offset); |
| 4266 HandleSpecialTextOffset(&end_offset); | 4267 HandleSpecialTextOffset(&end_offset); |
| 4267 AXPlatformPositionInstance start_position = | 4268 AXPlatformPositionInstance start_position = |
| 4268 CreatePositionForSelectionAt(static_cast<int>(start_offset)); | 4269 CreatePositionForSelectionAt(static_cast<int>(start_offset)); |
| 4269 AXPlatformPositionInstance end_position = | 4270 AXPlatformPositionInstance end_position = |
| 4270 CreatePositionForSelectionAt(static_cast<int>(end_offset)); | 4271 CreatePositionForSelectionAt(static_cast<int>(end_offset)); |
| 4271 Manager()->SetSelection(AXPlatformRange(start_position->AsTextPosition(), | 4272 Manager()->SetSelection(ui::AXAbstractRange(start_position->AsTextPosition(), |
| 4272 end_position->AsTextPosition())); | 4273 end_position->AsTextPosition())); |
| 4273 } | 4274 } |
| 4274 | 4275 |
| 4275 void BrowserAccessibilityComWin::StringAttributeToIA2( | 4276 void BrowserAccessibilityComWin::StringAttributeToIA2( |
| 4276 ui::AXStringAttribute attribute, | 4277 ui::AXStringAttribute attribute, |
| 4277 const char* ia2_attr) { | 4278 const char* ia2_attr) { |
| 4278 base::string16 value; | 4279 base::string16 value; |
| 4279 if (owner()->GetString16Attribute(attribute, &value)) { | 4280 if (owner()->GetString16Attribute(attribute, &value)) { |
| 4280 SanitizeStringAttributeForIA2(value, &value); | 4281 SanitizeStringAttributeForIA2(value, &value); |
| 4281 win_attributes_->ia2_attributes.push_back(base::ASCIIToUTF16(ia2_attr) + | 4282 win_attributes_->ia2_attributes.push_back(base::ASCIIToUTF16(ia2_attr) + |
| 4282 L":" + value); | 4283 L":" + value); |
| (...skipping 389 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4672 // affinity, otherwise default to downstream affinity. | 4673 // affinity, otherwise default to downstream affinity. |
| 4673 ui::AXTextAffinity affinity = | 4674 ui::AXTextAffinity affinity = |
| 4674 start_offset == IA2_TEXT_OFFSET_CARET | 4675 start_offset == IA2_TEXT_OFFSET_CARET |
| 4675 ? Manager()->GetTreeData().sel_focus_affinity | 4676 ? Manager()->GetTreeData().sel_focus_affinity |
| 4676 : ui::AX_TEXT_AFFINITY_DOWNSTREAM; | 4677 : ui::AX_TEXT_AFFINITY_DOWNSTREAM; |
| 4677 | 4678 |
| 4678 HandleSpecialTextOffset(&start_offset); | 4679 HandleSpecialTextOffset(&start_offset); |
| 4679 if (ia2_boundary == IA2_TEXT_BOUNDARY_WORD) { | 4680 if (ia2_boundary == IA2_TEXT_BOUNDARY_WORD) { |
| 4680 switch (direction) { | 4681 switch (direction) { |
| 4681 case ui::FORWARDS_DIRECTION: { | 4682 case ui::FORWARDS_DIRECTION: { |
| 4682 AXPlatformPositionInstance position = | 4683 AXAbstractPositionInstance position = |
| 4683 owner()->CreatePositionAt(static_cast<int>(start_offset), affinity); | 4684 owner()->CreatePositionAt(static_cast<int>(start_offset), affinity); |
| 4684 AXPlatformPositionInstance next_word = | 4685 AXAbstractPositionInstance next_word = |
| 4685 position->CreateNextWordStartPosition(); | 4686 position->CreateNextWordStartPosition(); |
| 4686 if (next_word->anchor_id() != owner()->GetId()) | 4687 if (next_word->anchor_id() != owner()->GetId()) |
| 4687 next_word = position->CreatePositionAtEndOfAnchor(); | 4688 next_word = position->CreatePositionAtEndOfAnchor(); |
| 4688 return next_word->text_offset(); | 4689 return next_word->text_offset(); |
| 4689 } | 4690 } |
| 4690 case ui::BACKWARDS_DIRECTION: { | 4691 case ui::BACKWARDS_DIRECTION: { |
| 4691 AXPlatformPositionInstance position = | 4692 AXAbstractPositionInstance position = |
| 4692 owner()->CreatePositionAt(static_cast<int>(start_offset), affinity); | 4693 owner()->CreatePositionAt(static_cast<int>(start_offset), affinity); |
| 4693 AXPlatformPositionInstance previous_word; | 4694 AXAbstractPositionInstance previous_word; |
| 4694 if (!position->AtStartOfWord()) { | 4695 if (!position->AtStartOfWord()) { |
| 4695 previous_word = position->CreatePreviousWordStartPosition(); | 4696 previous_word = position->CreatePreviousWordStartPosition(); |
| 4696 if (previous_word->anchor_id() != owner()->GetId()) | 4697 if (previous_word->anchor_id() != owner()->GetId()) |
| 4697 previous_word = position->CreatePositionAtStartOfAnchor(); | 4698 previous_word = position->CreatePositionAtStartOfAnchor(); |
| 4698 } else { | 4699 } else { |
| 4699 previous_word = std::move(position); | 4700 previous_word = std::move(position); |
| 4700 } | 4701 } |
| 4701 return previous_word->text_offset(); | 4702 return previous_word->text_offset(); |
| 4702 } | 4703 } |
| 4703 } | 4704 } |
| 4704 } | 4705 } |
| 4705 | 4706 |
| 4706 if (ia2_boundary == IA2_TEXT_BOUNDARY_LINE) { | 4707 if (ia2_boundary == IA2_TEXT_BOUNDARY_LINE) { |
| 4707 switch (direction) { | 4708 switch (direction) { |
| 4708 case ui::FORWARDS_DIRECTION: { | 4709 case ui::FORWARDS_DIRECTION: { |
| 4709 AXPlatformPositionInstance position = | 4710 AXAbstractPositionInstance position = |
| 4710 owner()->CreatePositionAt(static_cast<int>(start_offset), affinity); | 4711 owner()->CreatePositionAt(static_cast<int>(start_offset), affinity); |
| 4711 AXPlatformPositionInstance next_line = | 4712 AXAbstractPositionInstance next_line = |
| 4712 position->CreateNextLineStartPosition(); | 4713 position->CreateNextLineStartPosition(); |
| 4713 if (next_line->anchor_id() != owner()->GetId()) | 4714 if (next_line->anchor_id() != owner()->GetId()) |
| 4714 next_line = position->CreatePositionAtEndOfAnchor(); | 4715 next_line = position->CreatePositionAtEndOfAnchor(); |
| 4715 return next_line->text_offset(); | 4716 return next_line->text_offset(); |
| 4716 } | 4717 } |
| 4717 case ui::BACKWARDS_DIRECTION: { | 4718 case ui::BACKWARDS_DIRECTION: { |
| 4718 AXPlatformPositionInstance position = | 4719 AXAbstractPositionInstance position = |
| 4719 owner()->CreatePositionAt(static_cast<int>(start_offset), affinity); | 4720 owner()->CreatePositionAt(static_cast<int>(start_offset), affinity); |
| 4720 AXPlatformPositionInstance previous_line; | 4721 AXAbstractPositionInstance previous_line; |
| 4721 if (!position->AtStartOfLine()) { | 4722 if (!position->AtStartOfLine()) { |
| 4722 previous_line = position->CreatePreviousLineStartPosition(); | 4723 previous_line = position->CreatePreviousLineStartPosition(); |
| 4723 if (previous_line->anchor_id() != owner()->GetId()) | 4724 if (previous_line->anchor_id() != owner()->GetId()) |
| 4724 previous_line = position->CreatePositionAtStartOfAnchor(); | 4725 previous_line = position->CreatePositionAtStartOfAnchor(); |
| 4725 } else { | 4726 } else { |
| 4726 previous_line = std::move(position); | 4727 previous_line = std::move(position); |
| 4727 } | 4728 } |
| 4728 return previous_line->text_offset(); | 4729 return previous_line->text_offset(); |
| 4729 } | 4730 } |
| 4730 } | 4731 } |
| (...skipping 852 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5583 | 5584 |
| 5584 BrowserAccessibilityComWin* ToBrowserAccessibilityComWin( | 5585 BrowserAccessibilityComWin* ToBrowserAccessibilityComWin( |
| 5585 BrowserAccessibility* obj) { | 5586 BrowserAccessibility* obj) { |
| 5586 if (!obj || !obj->IsNative()) | 5587 if (!obj || !obj->IsNative()) |
| 5587 return nullptr; | 5588 return nullptr; |
| 5588 auto* result = static_cast<BrowserAccessibilityWin*>(obj)->GetCOM(); | 5589 auto* result = static_cast<BrowserAccessibilityWin*>(obj)->GetCOM(); |
| 5589 return result; | 5590 return result; |
| 5590 } | 5591 } |
| 5591 | 5592 |
| 5592 } // namespace content | 5593 } // namespace content |
| OLD | NEW |