Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1040)

Side by Side Diff: content/browser/accessibility/browser_accessibility_win.cc

Issue 1195223006: Reports the position of the caret and current selection in content editables. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebased with master. Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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>
11
10 #include "base/strings/string_number_conversions.h" 12 #include "base/strings/string_number_conversions.h"
11 #include "base/strings/string_split.h" 13 #include "base/strings/string_split.h"
12 #include "base/strings/string_util.h" 14 #include "base/strings/string_util.h"
13 #include "base/strings/utf_string_conversions.h" 15 #include "base/strings/utf_string_conversions.h"
14 #include "base/win/enum_variant.h" 16 #include "base/win/enum_variant.h"
15 #include "base/win/scoped_comptr.h" 17 #include "base/win/scoped_comptr.h"
16 #include "base/win/windows_version.h" 18 #include "base/win/windows_version.h"
17 #include "content/browser/accessibility/browser_accessibility_manager_win.h" 19 #include "content/browser/accessibility/browser_accessibility_manager_win.h"
18 #include "content/browser/accessibility/browser_accessibility_state_impl.h" 20 #include "content/browser/accessibility/browser_accessibility_state_impl.h"
19 #include "content/common/accessibility_messages.h" 21 #include "content/common/accessibility_messages.h"
(...skipping 1977 matching lines...) Expand 10 before | Expand all | Expand 10 after
1997 return S_OK; 1999 return S_OK;
1998 } 2000 }
1999 2001
2000 STDMETHODIMP BrowserAccessibilityWin::get_caretOffset(LONG* offset) { 2002 STDMETHODIMP BrowserAccessibilityWin::get_caretOffset(LONG* offset) {
2001 if (!instance_active()) 2003 if (!instance_active())
2002 return E_FAIL; 2004 return E_FAIL;
2003 2005
2004 if (!offset) 2006 if (!offset)
2005 return E_INVALIDARG; 2007 return E_INVALIDARG;
2006 2008
2007 // IA2 spec says that caret offset should be -1 if the object is not focused. 2009 int selection_start, selection_end;
2008 if (manager()->GetFocus(this) != this) { 2010 GetSelectionOffsets(&selection_start, &selection_end);
2009 *offset = -1; 2011 *offset = selection_start;
2012 if (selection_start < 0)
2010 return S_FALSE; 2013 return S_FALSE;
2011 }
2012
2013 *offset = 0;
2014 if (IsEditableText()) {
2015 int sel_start = 0;
2016 if (GetIntAttribute(ui::AX_ATTR_TEXT_SEL_START,
2017 &sel_start))
2018 *offset = sel_start;
2019 }
2020 2014
2021 return S_OK; 2015 return S_OK;
2022 } 2016 }
2023 2017
2024 STDMETHODIMP BrowserAccessibilityWin::get_characterExtents( 2018 STDMETHODIMP BrowserAccessibilityWin::get_characterExtents(
2025 LONG offset, 2019 LONG offset,
2026 enum IA2CoordinateType coordinate_type, 2020 enum IA2CoordinateType coordinate_type,
2027 LONG* out_x, 2021 LONG* out_x,
2028 LONG* out_y, 2022 LONG* out_y,
2029 LONG* out_width, 2023 LONG* out_width,
(...skipping 29 matching lines...) Expand all
2059 } 2053 }
2060 2054
2061 STDMETHODIMP BrowserAccessibilityWin::get_nSelections(LONG* n_selections) { 2055 STDMETHODIMP BrowserAccessibilityWin::get_nSelections(LONG* n_selections) {
2062 if (!instance_active()) 2056 if (!instance_active())
2063 return E_FAIL; 2057 return E_FAIL;
2064 2058
2065 if (!n_selections) 2059 if (!n_selections)
2066 return E_INVALIDARG; 2060 return E_INVALIDARG;
2067 2061
2068 *n_selections = 0; 2062 *n_selections = 0;
2069 if (IsEditableText()) { 2063 int selection_start, selection_end;
2070 int sel_start = 0; 2064 GetSelectionOffsets(&selection_start, &selection_end);
2071 int sel_end = 0; 2065 if (selection_start >= 0 && selection_end >= 0 &&
2072 if (GetIntAttribute(ui::AX_ATTR_TEXT_SEL_START, 2066 selection_start != selection_end)
2073 &sel_start) && 2067 *n_selections = 1;
2074 GetIntAttribute(ui::AX_ATTR_TEXT_SEL_END, &sel_end) &&
2075 sel_start != sel_end)
2076 *n_selections = 1;
2077 }
2078 2068
2079 return S_OK; 2069 return S_OK;
2080 } 2070 }
2081 2071
2082 STDMETHODIMP BrowserAccessibilityWin::get_selection(LONG selection_index, 2072 STDMETHODIMP BrowserAccessibilityWin::get_selection(LONG selection_index,
2083 LONG* start_offset, 2073 LONG* start_offset,
2084 LONG* end_offset) { 2074 LONG* end_offset) {
2085 if (!instance_active()) 2075 if (!instance_active())
2086 return E_FAIL; 2076 return E_FAIL;
2087 2077
2088 if (!start_offset || !end_offset || selection_index != 0) 2078 if (!start_offset || !end_offset || selection_index != 0)
2089 return E_INVALIDARG; 2079 return E_INVALIDARG;
2090 2080
2091 LONG n_selections = 0; 2081 LONG n_selections = 0;
2092 if (FAILED(get_nSelections(&n_selections)) || n_selections < 1) 2082 if (FAILED(get_nSelections(&n_selections)) || n_selections < 1)
2093 return E_INVALIDARG; 2083 return E_INVALIDARG;
2094 2084
2095 *start_offset = 0; 2085 *start_offset = 0;
2096 *end_offset = 0; 2086 *end_offset = 0;
2097 if (IsEditableText()) { 2087 int selection_start, selection_end;
2098 int sel_start = 0; 2088 GetSelectionOffsets(&selection_start, &selection_end);
2099 int sel_end = 0; 2089 if (selection_start >= 0 && selection_end >= 0) {
2100 if (GetIntAttribute( 2090 *start_offset = selection_start;
2101 ui::AX_ATTR_TEXT_SEL_START, &sel_start) && 2091 *end_offset = selection_end;
2102 GetIntAttribute(ui::AX_ATTR_TEXT_SEL_END, &sel_end)) {
2103 *start_offset = sel_start;
2104 *end_offset = sel_end;
2105 }
2106 } 2092 }
2107 2093
2108 return S_OK; 2094 return S_OK;
2109 } 2095 }
2110 2096
2111 STDMETHODIMP BrowserAccessibilityWin::get_text(LONG start_offset, 2097 STDMETHODIMP BrowserAccessibilityWin::get_text(LONG start_offset,
2112 LONG end_offset, 2098 LONG end_offset,
2113 BSTR* text) { 2099 BSTR* text) {
2114 if (!instance_active()) 2100 if (!instance_active())
2115 return E_FAIL; 2101 return E_FAIL;
(...skipping 1530 matching lines...) Expand 10 before | Expand all | Expand 10 after
3646 ui::AXIntAttribute attribute, 3632 ui::AXIntAttribute attribute,
3647 const char* ia2_attr) { 3633 const char* ia2_attr) {
3648 int value; 3634 int value;
3649 if (GetIntAttribute(attribute, &value)) { 3635 if (GetIntAttribute(attribute, &value)) {
3650 win_attributes_->ia2_attributes.push_back( 3636 win_attributes_->ia2_attributes.push_back(
3651 base::ASCIIToUTF16(ia2_attr) + L":" + 3637 base::ASCIIToUTF16(ia2_attr) + L":" +
3652 base::IntToString16(value)); 3638 base::IntToString16(value));
3653 } 3639 }
3654 } 3640 }
3655 3641
3642 int32 BrowserAccessibilityWin::GetHyperlinkIndexFromChild(
3643 const BrowserAccessibilityWin& child) const {
3644 auto iterator = std::find(
3645 hyperlinks().begin(), hyperlinks().end(), child.GetId());
3646 if (iterator == hyperlinks().end())
3647 return -1;
3648
3649 return static_cast<int32>(iterator - hyperlinks().begin());
3650 }
3651
3652 int32 BrowserAccessibilityWin::GetHypertextOffsetFromHyperlinkIndex(
3653 int32 hyperlink_index) const {
3654 auto& offsets_map = hyperlink_offset_to_index();
3655 for (auto& offset_index : offsets_map) {
3656 if (offset_index.second == hyperlink_index)
3657 return offset_index.first;
3658 }
3659
3660 return -1;
3661 }
3662
3663 int32 BrowserAccessibilityWin::GetHypertextOffsetFromChild(
3664 const BrowserAccessibilityWin& child) const {
3665 int32 hyperlink_index = GetHyperlinkIndexFromChild(child);
3666 if (hyperlink_index < 0)
3667 return -1;
3668
3669 return GetHypertextOffsetFromHyperlinkIndex(hyperlink_index);
3670 }
3671
3672 int32 BrowserAccessibilityWin::GetHypertextOffsetFromDescendant(
3673 const BrowserAccessibilityWin& descendant) const {
3674 auto parent_object = descendant.GetParent()->ToBrowserAccessibilityWin();
3675 auto current_object = const_cast<BrowserAccessibilityWin*>(&descendant);
3676 while (parent_object && parent_object != this) {
3677 current_object = parent_object;
3678 parent_object = current_object->GetParent()->ToBrowserAccessibilityWin();
3679 }
3680 if (!parent_object)
3681 return -1;
3682
3683 return parent_object->GetHypertextOffsetFromChild(*current_object);
3684 }
3685
3686 int BrowserAccessibilityWin::GetSelectionAnchor() const {
3687 BrowserAccessibility* root = manager()->GetRoot();
3688 int32 anchor_id;
3689 if (!root || !root->GetIntAttribute(ui::AX_ATTR_ANCHOR_OBJECT_ID, &anchor_id))
3690 return -1;
3691
3692 BrowserAccessibilityWin* anchor_object = manager()->GetFromID(
3693 anchor_id)->ToBrowserAccessibilityWin();
3694 if (!anchor_object)
3695 return -1;
3696
3697 if (anchor_object->IsDescendantOf(this))
3698 return GetHypertextOffsetFromDescendant(*anchor_object);
3699
3700 if (IsDescendantOf(anchor_object)) {
3701 int anchor_offset;
3702 if (!root->GetIntAttribute(ui::AX_ATTR_ANCHOR_OFFSET, &anchor_offset))
3703 return -1;
3704
3705 return anchor_offset;
3706 }
3707
3708 return -1;
3709 }
3710
3711 int BrowserAccessibilityWin::GetSelectionFocus() const {
3712 BrowserAccessibility* root = manager()->GetRoot();
3713 int32 focus_id;
3714 if (!root || !root->GetIntAttribute(ui::AX_ATTR_FOCUS_OBJECT_ID, &focus_id))
3715 return -1;
3716
3717 BrowserAccessibilityWin* focus_object = manager()->GetFromID(
3718 focus_id)->ToBrowserAccessibilityWin();
3719 if (!focus_object)
3720 return -1;
3721
3722 if (focus_object->IsDescendantOf(this))
3723 return GetHypertextOffsetFromDescendant(*focus_object);
3724
3725 if (IsDescendantOf(focus_object)) {
3726 int focus_offset;
3727 if (!root->GetIntAttribute(ui::AX_ATTR_FOCUS_OFFSET, &focus_offset))
3728 return -1;
3729
3730 return focus_offset;
3731 }
3732
3733 return -1;
3734 }
3735
3736 void BrowserAccessibilityWin::GetSelectionOffsets(
3737 int* selection_start, int* selection_end) const {
3738 DCHECK(selection_start && selection_end);
3739
3740 if (GetIntAttribute(ui::AX_ATTR_TEXT_SEL_START, selection_start) &&
3741 GetIntAttribute(ui::AX_ATTR_TEXT_SEL_END, selection_end)) {
3742 return;
3743 }
3744
3745 *selection_start = GetSelectionAnchor();
3746 *selection_end = GetSelectionFocus();
3747 if (*selection_start < 0 || *selection_end < 0)
3748 return;
3749
3750 if (*selection_end < *selection_start)
3751 std::swap(*selection_start, *selection_end);
3752
3753 // IA2 Spec says that the end of the selection should be after the last
3754 // embedded object character that is part of the selection.
3755 ++(*selection_end);
3756 }
3757
3656 base::string16 BrowserAccessibilityWin::GetNameRecursive() const { 3758 base::string16 BrowserAccessibilityWin::GetNameRecursive() const {
3657 if (!name().empty()) { 3759 if (!name().empty()) {
3658 return name(); 3760 return name();
3659 } 3761 }
3660 3762
3661 base::string16 result; 3763 base::string16 result;
3662 for (uint32 i = 0; i < PlatformChildCount(); ++i) { 3764 for (uint32 i = 0; i < PlatformChildCount(); ++i) {
3663 result += PlatformGetChild(i)->ToBrowserAccessibilityWin()-> 3765 result += PlatformGetChild(i)->ToBrowserAccessibilityWin()->
3664 GetNameRecursive(); 3766 GetNameRecursive();
3665 } 3767 }
(...skipping 711 matching lines...) Expand 10 before | Expand all | Expand 10 after
4377 ia2_role = ia_role; 4479 ia2_role = ia_role;
4378 4480
4379 win_attributes_->ia_role = ia_role; 4481 win_attributes_->ia_role = ia_role;
4380 win_attributes_->ia_state = ia_state; 4482 win_attributes_->ia_state = ia_state;
4381 win_attributes_->role_name = role_name; 4483 win_attributes_->role_name = role_name;
4382 win_attributes_->ia2_role = ia2_role; 4484 win_attributes_->ia2_role = ia2_role;
4383 win_attributes_->ia2_state = ia2_state; 4485 win_attributes_->ia2_state = ia2_state;
4384 } 4486 }
4385 4487
4386 } // namespace content 4488 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698