| 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 3373 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3607 else | 3608 else |
| 3608 start_offset += 1; | 3609 start_offset += 1; |
| 3609 } | 3610 } |
| 3610 | 3611 |
| 3611 win_attributes_->offset_to_text_attributes.swap(attributes_map); | 3612 win_attributes_->offset_to_text_attributes.swap(attributes_map); |
| 3612 } | 3613 } |
| 3613 | 3614 |
| 3614 // |offset| could either be a text character or a child index in case of | 3615 // |offset| could either be a text character or a child index in case of |
| 3615 // non-text objects. | 3616 // non-text objects. |
| 3616 // TODO(nektar): Remove this function once selection bugs are fixed in Blink. | 3617 // TODO(nektar): Remove this function once selection bugs are fixed in Blink. |
| 3617 AXPlatformPosition::AXPositionInstance | 3618 AXPlatformPosition::ConcreteInstance |
| 3618 BrowserAccessibilityComWin::CreatePositionForSelectionAt(int offset) const { | 3619 BrowserAccessibilityComWin::CreatePositionForSelectionAt(int offset) const { |
| 3619 if (!owner()->IsNativeTextControl() && !owner()->IsTextOnlyObject()) { | 3620 if (!owner()->IsNativeTextControl() && !owner()->IsTextOnlyObject()) { |
| 3620 auto* manager = Manager(); | 3621 auto* manager = Manager(); |
| 3621 DCHECK(manager); | 3622 DCHECK(manager); |
| 3622 const BrowserAccessibilityComWin* child = this; | 3623 const BrowserAccessibilityComWin* child = this; |
| 3623 // TODO(nektar): Make parents of text-only objects not include the text of | 3624 // TODO(nektar): Make parents of text-only objects not include the text of |
| 3624 // children in their hypertext. | 3625 // children in their hypertext. |
| 3625 for (size_t i = 0; i < owner()->InternalChildCount(); ++i) { | 3626 for (size_t i = 0; i < owner()->InternalChildCount(); ++i) { |
| 3626 int new_offset = offset; | 3627 int new_offset = offset; |
| 3627 child = ToBrowserAccessibilityComWin(owner()->InternalGetChild(i)); | 3628 child = ToBrowserAccessibilityComWin(owner()->InternalGetChild(i)); |
| 3628 DCHECK(child); | 3629 DCHECK(child); |
| 3629 if (child->owner()->IsTextOnlyObject()) { | 3630 if (child->owner()->IsTextOnlyObject()) { |
| 3630 new_offset -= child->owner()->GetText().length(); | 3631 new_offset -= child->owner()->GetText().length(); |
| 3631 } else { | 3632 } else { |
| 3632 new_offset -= 1; | 3633 new_offset -= 1; |
| 3633 } | 3634 } |
| 3634 if (new_offset <= 0) | 3635 if (new_offset <= 0) |
| 3635 break; | 3636 break; |
| 3636 offset = new_offset; | 3637 offset = new_offset; |
| 3637 } | 3638 } |
| 3638 AXPlatformPositionInstance position = | 3639 AXPlatformPositionInstance position = AXPlatformPosition::FromBase( |
| 3639 AXPlatformPosition::CreateTextPosition(manager->ax_tree_id(), | 3640 AXPlatformPosition::CreateConcreteTextPosition( |
| 3640 child->owner()->GetId(), offset, | 3641 manager->ax_tree_id(), child->owner()->GetId(), offset, |
| 3641 ui::AX_TEXT_AFFINITY_DOWNSTREAM) | 3642 ui::AX_TEXT_AFFINITY_DOWNSTREAM) |
| 3642 ->AsLeafTextPosition(); | 3643 ->AsLeafTextPosition()); |
| 3643 if (position->GetAnchor() && | 3644 if (position->GetAnchor() && |
| 3644 position->GetAnchor()->GetRole() == ui::AX_ROLE_INLINE_TEXT_BOX) { | 3645 position->GetAnchor()->GetRole() == ui::AX_ROLE_INLINE_TEXT_BOX) { |
| 3645 return position->CreateParentPosition(); | 3646 return AXPlatformPosition::FromBase(position->CreateParentPosition()); |
| 3646 } | 3647 } |
| 3647 return position; | 3648 return position; |
| 3648 } | 3649 } |
| 3649 return owner()->CreatePositionAt(offset); | 3650 return owner()->CreatePositionAt(offset); |
| 3650 } | 3651 } |
| 3651 | 3652 |
| 3652 // | 3653 // |
| 3653 // Private methods. | 3654 // Private methods. |
| 3654 // | 3655 // |
| 3655 | 3656 |
| (...skipping 625 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4281 } | 4282 } |
| 4282 | 4283 |
| 4283 void BrowserAccessibilityComWin::SetIA2HypertextSelection(LONG start_offset, | 4284 void BrowserAccessibilityComWin::SetIA2HypertextSelection(LONG start_offset, |
| 4284 LONG end_offset) { | 4285 LONG end_offset) { |
| 4285 HandleSpecialTextOffset(&start_offset); | 4286 HandleSpecialTextOffset(&start_offset); |
| 4286 HandleSpecialTextOffset(&end_offset); | 4287 HandleSpecialTextOffset(&end_offset); |
| 4287 AXPlatformPositionInstance start_position = | 4288 AXPlatformPositionInstance start_position = |
| 4288 CreatePositionForSelectionAt(static_cast<int>(start_offset)); | 4289 CreatePositionForSelectionAt(static_cast<int>(start_offset)); |
| 4289 AXPlatformPositionInstance end_position = | 4290 AXPlatformPositionInstance end_position = |
| 4290 CreatePositionForSelectionAt(static_cast<int>(end_offset)); | 4291 CreatePositionForSelectionAt(static_cast<int>(end_offset)); |
| 4291 Manager()->SetSelection(AXPlatformRange(start_position->AsTextPosition(), | 4292 Manager()->SetSelection(ui::AXAbstractRange(start_position->AsTextPosition(), |
| 4292 end_position->AsTextPosition())); | 4293 end_position->AsTextPosition())); |
| 4293 } | 4294 } |
| 4294 | 4295 |
| 4295 void BrowserAccessibilityComWin::StringAttributeToIA2( | 4296 void BrowserAccessibilityComWin::StringAttributeToIA2( |
| 4296 ui::AXStringAttribute attribute, | 4297 ui::AXStringAttribute attribute, |
| 4297 const char* ia2_attr) { | 4298 const char* ia2_attr) { |
| 4298 base::string16 value; | 4299 base::string16 value; |
| 4299 if (owner()->GetString16Attribute(attribute, &value)) { | 4300 if (owner()->GetString16Attribute(attribute, &value)) { |
| 4300 SanitizeStringAttributeForIA2(value, &value); | 4301 SanitizeStringAttributeForIA2(value, &value); |
| 4301 win_attributes_->ia2_attributes.push_back(base::ASCIIToUTF16(ia2_attr) + | 4302 win_attributes_->ia2_attributes.push_back(base::ASCIIToUTF16(ia2_attr) + |
| 4302 L":" + value); | 4303 L":" + value); |
| (...skipping 389 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4692 // affinity, otherwise default to downstream affinity. | 4693 // affinity, otherwise default to downstream affinity. |
| 4693 ui::AXTextAffinity affinity = | 4694 ui::AXTextAffinity affinity = |
| 4694 start_offset == IA2_TEXT_OFFSET_CARET | 4695 start_offset == IA2_TEXT_OFFSET_CARET |
| 4695 ? Manager()->GetTreeData().sel_focus_affinity | 4696 ? Manager()->GetTreeData().sel_focus_affinity |
| 4696 : ui::AX_TEXT_AFFINITY_DOWNSTREAM; | 4697 : ui::AX_TEXT_AFFINITY_DOWNSTREAM; |
| 4697 | 4698 |
| 4698 HandleSpecialTextOffset(&start_offset); | 4699 HandleSpecialTextOffset(&start_offset); |
| 4699 if (ia2_boundary == IA2_TEXT_BOUNDARY_WORD) { | 4700 if (ia2_boundary == IA2_TEXT_BOUNDARY_WORD) { |
| 4700 switch (direction) { | 4701 switch (direction) { |
| 4701 case ui::FORWARDS_DIRECTION: { | 4702 case ui::FORWARDS_DIRECTION: { |
| 4702 AXPlatformPositionInstance position = | 4703 AXAbstractPositionInstance position = |
| 4703 owner()->CreatePositionAt(static_cast<int>(start_offset), affinity); | 4704 owner()->CreatePositionAt(static_cast<int>(start_offset), affinity); |
| 4704 AXPlatformPositionInstance next_word = | 4705 AXAbstractPositionInstance next_word = |
| 4705 position->CreateNextWordStartPosition(); | 4706 position->CreateNextWordStartPosition(); |
| 4706 if (next_word->anchor_id() != owner()->GetId()) | 4707 if (next_word->anchor_id() != owner()->GetId()) |
| 4707 next_word = position->CreatePositionAtEndOfAnchor(); | 4708 next_word = position->CreatePositionAtEndOfAnchor(); |
| 4708 return next_word->text_offset(); | 4709 return next_word->text_offset(); |
| 4709 } | 4710 } |
| 4710 case ui::BACKWARDS_DIRECTION: { | 4711 case ui::BACKWARDS_DIRECTION: { |
| 4711 AXPlatformPositionInstance position = | 4712 AXAbstractPositionInstance position = |
| 4712 owner()->CreatePositionAt(static_cast<int>(start_offset), affinity); | 4713 owner()->CreatePositionAt(static_cast<int>(start_offset), affinity); |
| 4713 AXPlatformPositionInstance previous_word; | 4714 AXAbstractPositionInstance previous_word; |
| 4714 if (!position->AtStartOfWord()) { | 4715 if (!position->AtStartOfWord()) { |
| 4715 previous_word = position->CreatePreviousWordStartPosition(); | 4716 previous_word = position->CreatePreviousWordStartPosition(); |
| 4716 if (previous_word->anchor_id() != owner()->GetId()) | 4717 if (previous_word->anchor_id() != owner()->GetId()) |
| 4717 previous_word = position->CreatePositionAtStartOfAnchor(); | 4718 previous_word = position->CreatePositionAtStartOfAnchor(); |
| 4718 } else { | 4719 } else { |
| 4719 previous_word = std::move(position); | 4720 previous_word = std::move(position); |
| 4720 } | 4721 } |
| 4721 return previous_word->text_offset(); | 4722 return previous_word->text_offset(); |
| 4722 } | 4723 } |
| 4723 } | 4724 } |
| 4724 } | 4725 } |
| 4725 | 4726 |
| 4726 if (ia2_boundary == IA2_TEXT_BOUNDARY_LINE) { | 4727 if (ia2_boundary == IA2_TEXT_BOUNDARY_LINE) { |
| 4727 switch (direction) { | 4728 switch (direction) { |
| 4728 case ui::FORWARDS_DIRECTION: { | 4729 case ui::FORWARDS_DIRECTION: { |
| 4729 AXPlatformPositionInstance position = | 4730 AXAbstractPositionInstance position = |
| 4730 owner()->CreatePositionAt(static_cast<int>(start_offset), affinity); | 4731 owner()->CreatePositionAt(static_cast<int>(start_offset), affinity); |
| 4731 AXPlatformPositionInstance next_line = | 4732 AXAbstractPositionInstance next_line = |
| 4732 position->CreateNextLineStartPosition(); | 4733 position->CreateNextLineStartPosition(); |
| 4733 if (next_line->anchor_id() != owner()->GetId()) | 4734 if (next_line->anchor_id() != owner()->GetId()) |
| 4734 next_line = position->CreatePositionAtEndOfAnchor(); | 4735 next_line = position->CreatePositionAtEndOfAnchor(); |
| 4735 return next_line->text_offset(); | 4736 return next_line->text_offset(); |
| 4736 } | 4737 } |
| 4737 case ui::BACKWARDS_DIRECTION: { | 4738 case ui::BACKWARDS_DIRECTION: { |
| 4738 AXPlatformPositionInstance position = | 4739 AXAbstractPositionInstance position = |
| 4739 owner()->CreatePositionAt(static_cast<int>(start_offset), affinity); | 4740 owner()->CreatePositionAt(static_cast<int>(start_offset), affinity); |
| 4740 AXPlatformPositionInstance previous_line; | 4741 AXAbstractPositionInstance previous_line; |
| 4741 if (!position->AtStartOfLine()) { | 4742 if (!position->AtStartOfLine()) { |
| 4742 previous_line = position->CreatePreviousLineStartPosition(); | 4743 previous_line = position->CreatePreviousLineStartPosition(); |
| 4743 if (previous_line->anchor_id() != owner()->GetId()) | 4744 if (previous_line->anchor_id() != owner()->GetId()) |
| 4744 previous_line = position->CreatePositionAtStartOfAnchor(); | 4745 previous_line = position->CreatePositionAtStartOfAnchor(); |
| 4745 } else { | 4746 } else { |
| 4746 previous_line = std::move(position); | 4747 previous_line = std::move(position); |
| 4747 } | 4748 } |
| 4748 return previous_line->text_offset(); | 4749 return previous_line->text_offset(); |
| 4749 } | 4750 } |
| 4750 } | 4751 } |
| (...skipping 845 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5596 | 5597 |
| 5597 BrowserAccessibilityComWin* ToBrowserAccessibilityComWin( | 5598 BrowserAccessibilityComWin* ToBrowserAccessibilityComWin( |
| 5598 BrowserAccessibility* obj) { | 5599 BrowserAccessibility* obj) { |
| 5599 if (!obj || !obj->IsNative()) | 5600 if (!obj || !obj->IsNative()) |
| 5600 return nullptr; | 5601 return nullptr; |
| 5601 auto* result = static_cast<BrowserAccessibilityWin*>(obj)->GetCOM(); | 5602 auto* result = static_cast<BrowserAccessibilityWin*>(obj)->GetCOM(); |
| 5602 return result; | 5603 return result; |
| 5603 } | 5604 } |
| 5604 | 5605 |
| 5605 } // namespace content | 5606 } // namespace content |
| OLD | NEW |