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(); |