Chromium Code Reviews| 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 262d480156f03ce79a789b289ef29c00a2de3cff..0419c23867c713a6ba6c12ba946bbb6a2c007819 100644 |
| --- a/content/browser/accessibility/browser_accessibility_win.cc |
| +++ b/content/browser/accessibility/browser_accessibility_win.cc |
| @@ -429,7 +429,7 @@ HRESULT BrowserAccessibilityWin::accDoDefaultAction(VARIANT var_id) { |
| if (!target->HasIntAttribute(ui::AX_ATTR_ACTION)) |
| return DISP_E_MEMBERNOTFOUND; |
| - manager()->DoDefaultAction(*target); |
| + manager_->DoDefaultAction(*target); |
| return S_OK; |
| } |
| @@ -450,7 +450,7 @@ STDMETHODIMP BrowserAccessibilityWin::accHitTest(LONG x_left, |
| return S_FALSE; |
| } |
| - BrowserAccessibility* result = manager()->CachingAsyncHitTest(point); |
| + BrowserAccessibility* result = manager_->CachingAsyncHitTest(point); |
| if (result == this) { |
| // Point is within this object. |
| child->vt = VT_I4; |
| @@ -616,8 +616,8 @@ STDMETHODIMP BrowserAccessibilityWin::get_accFocus(VARIANT* focus_child) { |
| if (!focus_child) |
| return E_INVALIDARG; |
| - BrowserAccessibilityWin* focus = static_cast<BrowserAccessibilityWin*>( |
| - manager()->GetFocus()); |
| + BrowserAccessibilityWin* focus = |
| + static_cast<BrowserAccessibilityWin*>(manager_->GetFocus()); |
| if (focus == this) { |
| focus_child->vt = VT_I4; |
| focus_child->lVal = CHILDID_SELF; |
| @@ -702,7 +702,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_accParent(IDispatch** disp_parent) { |
| // This happens if we're the root of the tree; |
| // return the IAccessible for the window. |
| parent_obj = |
| - manager()->ToBrowserAccessibilityManagerWin()->GetParentIAccessible(); |
| + manager_->ToBrowserAccessibilityManagerWin()->GetParentIAccessible(); |
| // |parent| can only be NULL if the manager was created before the parent |
| // IAccessible was known and it wasn't subsequently set before a client |
| // requested it. This has been fixed. |parent| may also be NULL during |
| @@ -757,7 +757,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_accState(VARIANT var_id, |
| state->vt = VT_I4; |
| state->lVal = target->ia_state(); |
| - if (manager()->GetFocus() == this) |
| + if (manager_->GetFocus() == this) |
| state->lVal |= STATE_SYSTEM_FOCUSED; |
| return S_OK; |
| @@ -869,7 +869,7 @@ STDMETHODIMP BrowserAccessibilityWin::accSelect( |
| return E_FAIL; |
| if (flags_sel & SELFLAG_TAKEFOCUS) { |
| - manager()->SetFocus(*this); |
| + manager_->SetFocus(*this); |
| return S_OK; |
| } |
| @@ -958,7 +958,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_windowHandle(HWND* window_handle) { |
| return E_INVALIDARG; |
| *window_handle = |
| - manager()->ToBrowserAccessibilityManagerWin()->GetParentHWND(); |
| + manager_->ToBrowserAccessibilityManagerWin()->GetParentHWND(); |
| if (!*window_handle) |
| return E_FAIL; |
| @@ -1044,31 +1044,31 @@ STDMETHODIMP BrowserAccessibilityWin::scrollTo(IA2ScrollType scroll_type) { |
| gfx::Rect r = GetFrameBoundsRect(); |
| switch(scroll_type) { |
| case IA2_SCROLL_TYPE_TOP_LEFT: |
| - manager()->ScrollToMakeVisible(*this, gfx::Rect(r.x(), r.y(), 0, 0)); |
| + manager_->ScrollToMakeVisible(*this, gfx::Rect(r.x(), r.y(), 0, 0)); |
| break; |
| case IA2_SCROLL_TYPE_BOTTOM_RIGHT: |
| - manager()->ScrollToMakeVisible( |
| - *this, gfx::Rect(r.right(), r.bottom(), 0, 0)); |
| + manager_->ScrollToMakeVisible(*this, |
| + gfx::Rect(r.right(), r.bottom(), 0, 0)); |
| break; |
| case IA2_SCROLL_TYPE_TOP_EDGE: |
| - manager()->ScrollToMakeVisible( |
| - *this, gfx::Rect(r.x(), r.y(), r.width(), 0)); |
| + manager_->ScrollToMakeVisible(*this, |
| + gfx::Rect(r.x(), r.y(), r.width(), 0)); |
| break; |
| case IA2_SCROLL_TYPE_BOTTOM_EDGE: |
| - manager()->ScrollToMakeVisible( |
| - *this, gfx::Rect(r.x(), r.bottom(), r.width(), 0)); |
| - break; |
| + manager_->ScrollToMakeVisible(*this, |
| + gfx::Rect(r.x(), r.bottom(), r.width(), 0)); |
| + break; |
| case IA2_SCROLL_TYPE_LEFT_EDGE: |
| - manager()->ScrollToMakeVisible( |
| - *this, gfx::Rect(r.x(), r.y(), 0, r.height())); |
| + manager_->ScrollToMakeVisible(*this, |
| + gfx::Rect(r.x(), r.y(), 0, r.height())); |
| break; |
| case IA2_SCROLL_TYPE_RIGHT_EDGE: |
| - manager()->ScrollToMakeVisible( |
| - *this, gfx::Rect(r.right(), r.y(), 0, r.height())); |
| + manager_->ScrollToMakeVisible(*this, |
| + gfx::Rect(r.right(), r.y(), 0, r.height())); |
| break; |
| case IA2_SCROLL_TYPE_ANYWHERE: |
| default: |
| - manager()->ScrollToMakeVisible(*this, r); |
| + manager_->ScrollToMakeVisible(*this, r); |
| break; |
| } |
| @@ -1086,7 +1086,7 @@ STDMETHODIMP BrowserAccessibilityWin::scrollToPoint( |
| gfx::Point scroll_to(x, y); |
| if (coordinate_type == IA2_COORDTYPE_SCREEN_RELATIVE) { |
| - scroll_to -= manager()->GetViewBounds().OffsetFromOrigin(); |
| + scroll_to -= manager_->GetViewBounds().OffsetFromOrigin(); |
| } else if (coordinate_type == IA2_COORDTYPE_PARENT_RELATIVE) { |
| if (GetParent()) |
| scroll_to += GetParent()->GetFrameBoundsRect().OffsetFromOrigin(); |
| @@ -1094,7 +1094,7 @@ STDMETHODIMP BrowserAccessibilityWin::scrollToPoint( |
| return E_INVALIDARG; |
| } |
| - manager()->ScrollToPoint(*this, scroll_to); |
| + manager_->ScrollToPoint(*this, scroll_to); |
| return S_OK; |
| } |
| @@ -2056,7 +2056,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_columnHeaderCells( |
| int index = 0; |
| for (int i = 0; i < rows; ++i) { |
| int cell_id = cell_ids[i * columns + column]; |
| - BrowserAccessibility* cell = manager()->GetFromID(cell_id); |
| + BrowserAccessibility* cell = manager_->GetFromID(cell_id); |
| if (cell && cell->GetRole() == ui::AX_ROLE_COLUMN_HEADER) { |
| (*cell_accessibles)[index] = static_cast<IAccessible*>( |
| ToBrowserAccessibilityWin(cell)->NewReference()); |
| @@ -2149,7 +2149,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_rowHeaderCells( |
| for (int i = 0; i < columns; ++i) { |
| int cell_id = cell_ids[row * columns + i]; |
| - BrowserAccessibility* cell = manager()->GetFromID(cell_id); |
| + BrowserAccessibility* cell = manager_->GetFromID(cell_id); |
| if (cell && cell->GetRole() == ui::AX_ROLE_ROW_HEADER) |
| (*n_row_header_cells)++; |
| } |
| @@ -2159,7 +2159,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_rowHeaderCells( |
| int index = 0; |
| for (int i = 0; i < columns; ++i) { |
| int cell_id = cell_ids[row * columns + i]; |
| - BrowserAccessibility* cell = manager()->GetFromID(cell_id); |
| + BrowserAccessibility* cell = manager_->GetFromID(cell_id); |
| if (cell && cell->GetRole() == ui::AX_ROLE_ROW_HEADER) { |
| (*cell_accessibles)[index] = static_cast<IAccessible*>( |
| ToBrowserAccessibilityWin(cell)->NewReference()); |
| @@ -2327,8 +2327,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_characterExtents( |
| return E_INVALIDARG; |
| const base::string16& text_str = GetText(); |
| - HandleSpecialTextOffset(text_str, &offset); |
| - |
| + HandleSpecialTextOffset(&offset); |
| if (offset < 0 || offset > static_cast<LONG>(text_str.size())) |
| return E_INVALIDARG; |
| @@ -2417,8 +2416,8 @@ STDMETHODIMP BrowserAccessibilityWin::get_text(LONG start_offset, |
| return E_INVALIDARG; |
| const base::string16& text_str = GetText(); |
| - HandleSpecialTextOffset(text_str, &start_offset); |
| - HandleSpecialTextOffset(text_str, &end_offset); |
| + HandleSpecialTextOffset(&start_offset); |
| + HandleSpecialTextOffset(&end_offset); |
| // The spec allows the arguments to be reversed. |
| if (start_offset > end_offset) { |
| @@ -2462,7 +2461,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_textAtOffset( |
| return E_INVALIDARG; |
| const base::string16& text_str = GetText(); |
| - HandleSpecialTextOffset(text_str, &offset); |
| + HandleSpecialTextOffset(&offset); |
| if (offset < 0) |
| return E_INVALIDARG; |
| @@ -2673,11 +2672,8 @@ STDMETHODIMP BrowserAccessibilityWin::addSelection(LONG start_offset, |
| if (!instance_active()) |
| return E_FAIL; |
| - const base::string16& text_str = GetText(); |
| - HandleSpecialTextOffset(text_str, &start_offset); |
| - HandleSpecialTextOffset(text_str, &end_offset); |
| - |
| - manager()->SetTextSelection(*this, start_offset, end_offset); |
| + // We only support one selection. |
| + SetIA2HypertextSelection(start_offset, end_offset); |
| return S_OK; |
| } |
| @@ -2690,7 +2686,14 @@ STDMETHODIMP BrowserAccessibilityWin::removeSelection(LONG selection_index) { |
| if (selection_index != 0) |
| return E_INVALIDARG; |
| - manager()->SetTextSelection(*this, 0, 0); |
| + // Simply collapse the selection to the position of the caret if a caret is |
| + // visible, otherwise set the selection to 0. |
| + LONG caret_offset = 0; |
| + int selection_start, selection_end; |
| + GetSelectionOffsets(&selection_start, &selection_end); |
| + if (HasCaret() && selection_end >= 0) |
| + caret_offset = selection_end; |
| + SetIA2HypertextSelection(caret_offset, caret_offset); |
| return S_OK; |
| } |
| @@ -2699,10 +2702,7 @@ STDMETHODIMP BrowserAccessibilityWin::setCaretOffset(LONG offset) { |
| AddAccessibilityModeFlags(ACCESSIBILITY_MODE_FLAG_SCREEN_READER); |
| if (!instance_active()) |
| return E_FAIL; |
| - |
| - const base::string16& text_str = GetText(); |
| - HandleSpecialTextOffset(text_str, &offset); |
| - manager()->SetTextSelection(*this, offset, offset); |
| + SetIA2HypertextSelection(offset, offset); |
| return S_OK; |
| } |
| @@ -2713,15 +2713,9 @@ STDMETHODIMP BrowserAccessibilityWin::setSelection(LONG selection_index, |
| AddAccessibilityModeFlags(ACCESSIBILITY_MODE_FLAG_SCREEN_READER); |
| if (!instance_active()) |
| return E_FAIL; |
| - |
| if (selection_index != 0) |
| return E_INVALIDARG; |
| - |
| - const base::string16& text_str = GetText(); |
| - HandleSpecialTextOffset(text_str, &start_offset); |
| - HandleSpecialTextOffset(text_str, &end_offset); |
| - |
| - manager()->SetTextSelection(*this, start_offset, end_offset); |
| + SetIA2HypertextSelection(start_offset, end_offset); |
| return S_OK; |
| } |
| @@ -2739,8 +2733,8 @@ STDMETHODIMP BrowserAccessibilityWin::get_attributes(LONG offset, |
| if (!instance_active()) |
| return E_FAIL; |
| - const base::string16& text = GetText(); |
| - HandleSpecialTextOffset(text, &offset); |
| + const base::string16 text = GetText(); |
| + HandleSpecialTextOffset(&offset); |
| if (offset < 0 || offset > static_cast<LONG>(text.size())) |
| return E_INVALIDARG; |
| @@ -2958,7 +2952,7 @@ STDMETHODIMP BrowserAccessibilityWin::doAction(long action_index) { |
| if (!HasIntAttribute(ui::AX_ATTR_ACTION) || action_index != 0) |
| return E_INVALIDARG; |
| - manager()->DoDefaultAction(*this); |
| + manager_->DoDefaultAction(*this); |
| return S_OK; |
| } |
| @@ -3120,10 +3114,10 @@ STDMETHODIMP BrowserAccessibilityWin::get_URL(BSTR* url) { |
| if (!url) |
| return E_INVALIDARG; |
| - if (this != manager()->GetRoot()) |
| + if (this != manager_->GetRoot()) |
| return E_FAIL; |
| - std::string str = manager()->GetTreeData().url; |
| + std::string str = manager_->GetTreeData().url; |
| if (str.empty()) |
| return S_FALSE; |
| @@ -3141,7 +3135,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_title(BSTR* title) { |
| if (!title) |
| return E_INVALIDARG; |
| - std::string str = manager()->GetTreeData().title; |
| + std::string str = manager_->GetTreeData().title; |
| if (str.empty()) |
| return S_FALSE; |
| @@ -3159,7 +3153,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_mimeType(BSTR* mime_type) { |
| if (!mime_type) |
| return E_INVALIDARG; |
| - std::string str = manager()->GetTreeData().mimetype; |
| + std::string str = manager_->GetTreeData().mimetype; |
| if (str.empty()) |
| return S_FALSE; |
| @@ -3177,7 +3171,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_docType(BSTR* doc_type) { |
| if (!doc_type) |
| return E_INVALIDARG; |
| - std::string str = manager()->GetTreeData().doctype; |
| + std::string str = manager_->GetTreeData().doctype; |
| if (str.empty()) |
| return S_FALSE; |
| @@ -3592,8 +3586,8 @@ STDMETHODIMP BrowserAccessibilityWin::scrollToSubstring( |
| return E_INVALIDARG; |
| } |
| - manager()->ScrollToMakeVisible(*this, GetPageBoundsForRange( |
| - start_index, end_index - start_index)); |
| + manager_->ScrollToMakeVisible( |
| + *this, GetPageBoundsForRange(start_index, end_index - start_index)); |
| return S_OK; |
| } |
| @@ -4012,7 +4006,7 @@ void BrowserAccessibilityWin::UpdateStep1ComputeWinAttributes() { |
| // On Windows, the value of a document should be its url. |
| if (GetRole() == ui::AX_ROLE_ROOT_WEB_AREA || |
| GetRole() == ui::AX_ROLE_WEB_AREA) { |
| - value = base::UTF8ToUTF16(manager()->GetTreeData().url); |
| + value = base::UTF8ToUTF16(manager_->GetTreeData().url); |
| } |
| // If this doesn't have a value and is linked then set its value to the url |
| // attribute. This allows screen readers to read an empty link's destination. |
| @@ -4195,6 +4189,18 @@ void BrowserAccessibilityWin::OnLocationChanged() { |
| FireNativeEvent(EVENT_OBJECT_LOCATIONCHANGE); |
| } |
| +// |offset| could either be a text character or a child index in case of |
| +// non-text objects. |
| +BrowserAccessibilityWin::AXPlatformPositionInstance |
|
dmazzoni
2017/02/14 20:17:58
can you make this shorter with the "using" keyword
|
| +BrowserAccessibilityWin::CreatePositionAt(int offset) const { |
| + if (!IsTextOnlyObject()) { |
| + DCHECK(manager_); |
| + return AXPlatformPosition::CreateTreePosition(manager_->ax_tree_id(), |
| + GetId(), offset); |
| + } |
| + return BrowserAccessibility::CreatePositionAt(offset); |
| +} |
| + |
| std::vector<base::string16> BrowserAccessibilityWin::ComputeTextAttributes() |
| const { |
| std::vector<base::string16> attributes; |
| @@ -4472,6 +4478,18 @@ void BrowserAccessibilityWin::SanitizeStringAttributeForIA2( |
| base::ReplaceChars(*output, L";", L"\\;", output); |
| } |
| +void BrowserAccessibilityWin::SetIA2HypertextSelection(LONG start_offset, |
| + LONG end_offset) { |
| + HandleSpecialTextOffset(&start_offset); |
| + HandleSpecialTextOffset(&end_offset); |
| + AXPlatformPositionInstance start_position = |
| + CreatePositionAt(static_cast<int>(start_offset)); |
| + AXPlatformPositionInstance end_position = |
| + CreatePositionAt(static_cast<int>(end_offset)); |
| + manager_->SetSelection(AXPlatformRange(start_position->AsLeafTextPosition(), |
| + end_position->AsLeafTextPosition())); |
| +} |
| + |
| void BrowserAccessibilityWin::StringAttributeToIA2( |
| ui::AXStringAttribute attribute, |
| const char* ia2_attr) { |
| @@ -4678,22 +4696,22 @@ int BrowserAccessibilityWin::GetHypertextOffsetFromEndpoint( |
| } |
| int BrowserAccessibilityWin::GetSelectionAnchor() const { |
| - int32_t anchor_id = manager()->GetTreeData().sel_anchor_object_id; |
| + int32_t anchor_id = manager_->GetTreeData().sel_anchor_object_id; |
| const BrowserAccessibilityWin* anchor_object = GetFromID(anchor_id); |
| if (!anchor_object) |
| return -1; |
| - int anchor_offset = manager()->GetTreeData().sel_anchor_offset; |
| + int anchor_offset = manager_->GetTreeData().sel_anchor_offset; |
| return GetHypertextOffsetFromEndpoint(*anchor_object, anchor_offset); |
| } |
| int BrowserAccessibilityWin::GetSelectionFocus() const { |
| - int32_t focus_id = manager()->GetTreeData().sel_focus_object_id; |
| + int32_t focus_id = manager_->GetTreeData().sel_focus_object_id; |
| const BrowserAccessibilityWin* focus_object = GetFromID(focus_id); |
| if (!focus_object) |
| return -1; |
| - int focus_offset = manager()->GetTreeData().sel_focus_offset; |
| + int focus_offset = manager_->GetTreeData().sel_focus_offset; |
| return GetHypertextOffsetFromEndpoint(*focus_object, focus_offset); |
| } |
| @@ -4830,13 +4848,15 @@ void BrowserAccessibilityWin::ComputeHypertextRemovedAndInserted( |
| *new_len = new_text.size() - common_prefix - common_suffix; |
| } |
| -void BrowserAccessibilityWin::HandleSpecialTextOffset( |
| - const base::string16& text, |
| - LONG* offset) { |
| - if (*offset == IA2_TEXT_OFFSET_LENGTH) |
| - *offset = static_cast<LONG>(text.size()); |
| - else if (*offset == IA2_TEXT_OFFSET_CARET) |
| - get_caretOffset(offset); |
| +void BrowserAccessibilityWin::HandleSpecialTextOffset(LONG* offset) { |
| + if (*offset == IA2_TEXT_OFFSET_LENGTH) { |
| + *offset = static_cast<LONG>(GetText().length()); |
| + } else if (*offset == IA2_TEXT_OFFSET_CARET) { |
| + // We shouldn't call |get_caretOffset| here as it affects UMA counts. |
| + int selection_start, selection_end; |
| + GetSelectionOffsets(&selection_start, &selection_end); |
| + *offset = selection_end; |
| + } |
| } |
| ui::TextBoundaryType BrowserAccessibilityWin::IA2TextBoundaryToTextBoundary( |
| @@ -4866,12 +4886,11 @@ LONG BrowserAccessibilityWin::FindBoundary( |
| ui::TextBoundaryDirection direction) { |
| // If the boundary is relative to the caret, use the selection |
| // affinity, otherwise default to downstream affinity. |
| - ui::AXTextAffinity affinity = |
| - start_offset == IA2_TEXT_OFFSET_CARET ? |
| - manager()->GetTreeData().sel_focus_affinity : |
| - ui::AX_TEXT_AFFINITY_DOWNSTREAM; |
| + ui::AXTextAffinity affinity = start_offset == IA2_TEXT_OFFSET_CARET |
| + ? manager_->GetTreeData().sel_focus_affinity |
| + : ui::AX_TEXT_AFFINITY_DOWNSTREAM; |
| - HandleSpecialTextOffset(text, &start_offset); |
| + HandleSpecialTextOffset(&start_offset); |
| if (ia2_boundary == IA2_TEXT_BOUNDARY_WORD) |
| return GetWordStartBoundary(static_cast<int>(start_offset), direction); |
| if (ia2_boundary == IA2_TEXT_BOUNDARY_LINE) { |
| @@ -4916,7 +4935,7 @@ LONG BrowserAccessibilityWin::FindStartOfStyle( |
| BrowserAccessibilityWin* BrowserAccessibilityWin::GetFromID(int32_t id) const { |
| if (!instance_active()) |
| return nullptr; |
| - return ToBrowserAccessibilityWin(manager()->GetFromID(id)); |
| + return ToBrowserAccessibilityWin(manager_->GetFromID(id)); |
| } |
| bool BrowserAccessibilityWin::IsListBoxOptionOrMenuListOption() { |