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

Unified 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: Created 5 years, 6 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 side-by-side diff with in-line comments
Download patch
Index: content/browser/accessibility/browser_accessibility_win.cc
diff --git a/content/browser/accessibility/browser_accessibility_win.cc b/content/browser/accessibility/browser_accessibility_win.cc
index 285f99d9c9f9031f0a3aaea0224a02807ab67cc8..9c7d955f0f09c8319857d1467abe1648eb61867f 100644
--- a/content/browser/accessibility/browser_accessibility_win.cc
+++ b/content/browser/accessibility/browser_accessibility_win.cc
@@ -4,6 +4,7 @@
#include "content/browser/accessibility/browser_accessibility_win.h"
+#include <algorithm>
#include <UIAutomationClient.h>
#include <UIAutomationCoreApi.h>
@@ -2001,19 +2002,18 @@ STDMETHODIMP BrowserAccessibilityWin::get_caretOffset(LONG* offset) {
if (!offset)
return E_INVALIDARG;
- // IA2 spec says that caret offset should be -1 if the object is not focused.
- if (manager()->GetFocus(this) != this) {
+ // IA2 spec says that caret offset should be -1 if the caret is not active
+ // on this object.
+ if (!manager()->GetFocus(this)) {
*offset = -1;
return S_FALSE;
}
+
+ int selection_start = GetSelectionStart();
dmazzoni 2015/06/22 19:23:21 nit: indentation
- *offset = 0;
- if (IsEditableText()) {
- int sel_start = 0;
- if (GetIntAttribute(ui::AX_ATTR_TEXT_SEL_START,
- &sel_start))
- *offset = sel_start;
- }
+ *offset = selection_start;
+ if (selection_start < 0)
+ return S_FALSE;
return S_OK;
}
@@ -2063,15 +2063,11 @@ STDMETHODIMP BrowserAccessibilityWin::get_nSelections(LONG* n_selections) {
return E_INVALIDARG;
*n_selections = 0;
- if (IsEditableText()) {
- int sel_start = 0;
- int sel_end = 0;
- if (GetIntAttribute(ui::AX_ATTR_TEXT_SEL_START,
- &sel_start) &&
- GetIntAttribute(ui::AX_ATTR_TEXT_SEL_END, &sel_end) &&
- sel_start != sel_end)
- *n_selections = 1;
- }
+ int selection_start = GetSelectionStart();
+ int selection_end = GetSelectionEnd();
+ if (selection_start >= 0 && selection_end >= 0 &&
+ selection_start != selection_end)
+ *n_selections = 1;
return S_OK;
}
@@ -2091,15 +2087,11 @@ STDMETHODIMP BrowserAccessibilityWin::get_selection(LONG selection_index,
*start_offset = 0;
*end_offset = 0;
- if (IsEditableText()) {
- int sel_start = 0;
- int sel_end = 0;
- if (GetIntAttribute(
- ui::AX_ATTR_TEXT_SEL_START, &sel_start) &&
- GetIntAttribute(ui::AX_ATTR_TEXT_SEL_END, &sel_end)) {
- *start_offset = sel_start;
- *end_offset = sel_end;
- }
+ int selection_start = GetSelectionStart();
+ int selection_end = GetSelectionEnd();
+ if (selection_start >= 0 && selection_end >= 0)
+ *start_offset = sel_start;
+ *end_offset = sel_end;
}
return S_OK;
@@ -3650,6 +3642,114 @@ void BrowserAccessibilityWin::IntAttributeToIA2(
}
}
+int32 BrowserAccessibilityWin::GetHyperlinkIndexFromChild(
+ const BrowserAccessibilityWin& child) const {
+ auto& iterator = std::find(
+ hyperlinks().begin(), hyperlinks().end(), child.GetId());
+ if (iterator == hyperlinks().end())
+ return -1;
+
+ return static_cast<int32>(iterator - hyperlinks().begin());
+}
+
+int32 BrowserAccessibilityWin::GetHypertextOffsetFromHyperlinkIndex(
+ int32 hyperlink_index) const {
+ auto& offsets_map = hyperlink_offset_to_index();
+ for (size_t i = 0; i < hyperlink_offset_to_index().size(); ++i)
+ if (offsets_map[i].second == hyperlink_index)
+ return offsets_map[i].first;
+
+ return -1;
+}
+
+int32 BrowserAccessibilityWin::GetSelectionStart() const {
+ int32 selection_start;
+ if (!GetIntAttribute(ui::AX_ATTR_TEXT_SEL_START, &selection_start))
dmazzoni 2015/06/22 19:23:21 Did you mean this to be negated?
+ return selection_start;
+
+ BrowserAccessibility* root = manager()->GetRoot();
+ int32 focus_id;
+ if (!root || !GetIntAttribute(ui::AX_ATTR_OBJ_SEL_START, &focus_id))
dmazzoni 2015/06/22 19:23:21 Did you mean to call GetIntAttribute on root?
+ return -1;
+
+ BrowserAccessibilityWin* focus_object = manager()->GetFromID(
+ focus_id)->ToBrowserAccessibilityWin();
+ if (!focus_object)
+ return -1;
+
+ if (focus_object == this) {
+ int focus_offset;
+ if (!GetIntAttribute(ui::AX_ATTR_SEL_TEXT_START, &focus_offset))
+ return -1;
+
+ return focus_offset;
+ }
+
+ auto focus_parent = focus_object->GetParent();
dmazzoni 2015/06/22 19:23:21 Stick this part of the code in a helper function t
+ while (parent_object && parent_object != this) {
+ focus_object = parent_object;
+ parent_object = focus_object->GetParent();
+ }
+ if (!parent_object)
+ return -1;
+
+ int32 hyperlink_index = parent_object->GetHyperlinkIndexFromChild(
+ focus_object);
+ if (hyperlink_index < 0)
+ return -1;
+
+ hypertext_offset = parent_object->GetHypertextOffsetFromHyperlinkIndex(
+ hyperlink_index);
+ if (hypertext_offset < 0)
+ return -1;
+
+ return hypertext_offset;
+}
+
+int32 BrowserAccessibilityWin::GetSelectionEnd() const {
+ int selection_end;
+ if (!GetIntAttribute(ui::AX_ATTR_TEXT_SEL_END, &selection_end))
+ return selection_end;
+
+ BrowserAccessibility* root = manager()->GetRoot();
+ int32 anchor_id;
+ if (!root || !GetIntAttribute(ui::AX_ATTR_OBJ_SEL_END, &anchor_id))
+ return -1;
+
+ BrowserAccessibilityWin* anchor_object = manager()->GetFromID(
+ anchor_id)->ToBrowserAccessibilityWin();
+ if (!anchor_object)
+ return -1;
+
+ if (anchor_object == this) {
+ int anchor_offset;
+ if (!GetIntAttribute(ui::AX_ATTR_SEL_TEXT_END, &anchor_offset))
+ return -1;
+
+ return anchor_offset;
+ }
+
+ auto anchor_parent = anchor_object->GetParent();
+ while (parent_object && parent_object != this) {
+ anchor_object = parent_object;
+ parent_object = anchor_object->GetParent();
+ }
+ if (!parent_object)
+ return -1;
+
+ int32 hyperlink_index = parent_object->GetHyperlinkIndexFromChild(
+ anchor_object);
+ if (hyperlink_index < 0)
+ return -1;
+
+ int32 hypertext_offset = parent_object->GetHypertextOffsetFromHyperlinkIndex(
+ hyperlink_index);
+ if (hypertext_offset < 0)
+ return -1;
+
+ return hypertext_offset;
+}
+
base::string16 BrowserAccessibilityWin::GetNameRecursive() const {
if (!name().empty()) {
return name();

Powered by Google App Engine
This is Rietveld 408576698