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

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

Issue 2897163002: Fixed bugs with finding line boundaries using IA2 get_textAtOffset and AXPosition::AtStartOfLine. (Closed)
Patch Set: Fixed bugs with finding line boundaries using IA2 get_textAtOffset. Created 3 years, 7 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) 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 2261 matching lines...) Expand 10 before | Expand all | Expand 10 after
2272 BSTR* text) { 2272 BSTR* text) {
2273 WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_TEXT_AT_OFFSET); 2273 WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_TEXT_AT_OFFSET);
2274 AddAccessibilityModeFlags(kScreenReaderAndHTMLAccessibilityModes | 2274 AddAccessibilityModeFlags(kScreenReaderAndHTMLAccessibilityModes |
2275 AccessibilityMode::kInlineTextBoxes); 2275 AccessibilityMode::kInlineTextBoxes);
2276 if (!owner()) 2276 if (!owner())
2277 return E_FAIL; 2277 return E_FAIL;
2278 2278
2279 if (!start_offset || !end_offset || !text) 2279 if (!start_offset || !end_offset || !text)
2280 return E_INVALIDARG; 2280 return E_INVALIDARG;
2281 2281
2282 *start_offset = 0;
2283 *end_offset = 0;
2284 *text = nullptr;
2285
2282 HandleSpecialTextOffset(&offset); 2286 HandleSpecialTextOffset(&offset);
2283 if (offset < 0) 2287 if (offset < 0)
2284 return E_INVALIDARG; 2288 return E_INVALIDARG;
2285 2289
2286 const base::string16& text_str = owner()->GetText(); 2290 const base::string16& text_str = owner()->GetText();
2287 LONG text_len = text_str.length(); 2291 LONG text_len = text_str.length();
2288 if (offset > text_len) 2292 if (offset > text_len)
2289 return E_INVALIDARG; 2293 return E_INVALIDARG;
2290 2294
2291 // The IAccessible2 spec says we don't have to implement the "sentence" 2295 // The IAccessible2 spec says we don't have to implement the "sentence"
2292 // boundary type, we can just let the screenreader handle it. 2296 // boundary type, we can just let the screenreader handle it.
2293 if (boundary_type == IA2_TEXT_BOUNDARY_SENTENCE) { 2297 if (boundary_type == IA2_TEXT_BOUNDARY_SENTENCE)
2294 *start_offset = 0;
2295 *end_offset = 0;
2296 *text = NULL;
2297 return S_FALSE; 2298 return S_FALSE;
2298 }
2299 2299
2300 // According to the IA2 Spec, only line boundaries should succeed when 2300 // According to the IA2 Spec, only line boundaries should succeed when
2301 // the offset is one past the end of the text. 2301 // the offset is one past the end of the text.
2302 if (offset == text_len) { 2302 if (offset == text_len && boundary_type != IA2_TEXT_BOUNDARY_LINE)
2303 if (boundary_type == IA2_TEXT_BOUNDARY_LINE) { 2303 return S_FALSE;
2304 --offset;
2305 } else {
2306 *start_offset = 0;
2307 *end_offset = 0;
2308 *text = nullptr;
2309 return S_FALSE;
2310 }
2311 }
2312 2304
2313 *start_offset = 2305 LONG start = FindBoundary(boundary_type, offset, ui::BACKWARDS_DIRECTION);
2314 FindBoundary(text_str, boundary_type, offset, ui::BACKWARDS_DIRECTION); 2306 LONG end = FindBoundary(boundary_type, start, ui::FORWARDS_DIRECTION);
2315 *end_offset = 2307 if (end < offset)
2316 FindBoundary(text_str, boundary_type, offset, ui::FORWARDS_DIRECTION); 2308 return S_FALSE;
2317 return get_text(*start_offset, *end_offset, text); 2309
2310 *start_offset = start;
2311 *end_offset = end;
2312 return get_text(start, end, text);
2318 } 2313 }
2319 2314
2320 STDMETHODIMP BrowserAccessibilityComWin::get_textBeforeOffset( 2315 STDMETHODIMP BrowserAccessibilityComWin::get_textBeforeOffset(
2321 LONG offset, 2316 LONG offset,
2322 IA2TextBoundaryType boundary_type, 2317 IA2TextBoundaryType boundary_type,
2323 LONG* start_offset, 2318 LONG* start_offset,
2324 LONG* end_offset, 2319 LONG* end_offset,
2325 BSTR* text) { 2320 BSTR* text) {
2326 WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_TEXT_BEFORE_OFFSET); 2321 WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_TEXT_BEFORE_OFFSET);
2327 AddAccessibilityModeFlags(kScreenReaderAndHTMLAccessibilityModes | 2322 AddAccessibilityModeFlags(kScreenReaderAndHTMLAccessibilityModes |
2328 AccessibilityMode::kInlineTextBoxes); 2323 AccessibilityMode::kInlineTextBoxes);
2329 if (!owner()) 2324 if (!owner())
2330 return E_FAIL; 2325 return E_FAIL;
2331 2326
2332 if (!start_offset || !end_offset || !text) 2327 if (!start_offset || !end_offset || !text)
2333 return E_INVALIDARG; 2328 return E_INVALIDARG;
2334 2329
2330 *start_offset = 0;
2331 *end_offset = 0;
2332 *text = NULL;
2333
2334 const base::string16& text_str = owner()->GetText();
2335 LONG text_len = text_str.length();
2336 if (offset > text_len)
2337 return E_INVALIDARG;
2338
2335 // The IAccessible2 spec says we don't have to implement the "sentence" 2339 // The IAccessible2 spec says we don't have to implement the "sentence"
2336 // boundary type, we can just let the screenreader handle it. 2340 // boundary type, we can just let the screenreader handle it.
2337 if (boundary_type == IA2_TEXT_BOUNDARY_SENTENCE) { 2341 if (boundary_type == IA2_TEXT_BOUNDARY_SENTENCE)
2338 *start_offset = 0;
2339 *end_offset = 0;
2340 *text = NULL;
2341 return S_FALSE; 2342 return S_FALSE;
2342 }
2343 2343
2344 const base::string16& text_str = owner()->GetText(); 2344 *start_offset = FindBoundary(boundary_type, offset, ui::BACKWARDS_DIRECTION);
2345
2346 *start_offset =
2347 FindBoundary(text_str, boundary_type, offset, ui::BACKWARDS_DIRECTION);
2348 *end_offset = offset; 2345 *end_offset = offset;
2349 return get_text(*start_offset, *end_offset, text); 2346 return get_text(*start_offset, *end_offset, text);
2350 } 2347 }
2351 2348
2352 STDMETHODIMP BrowserAccessibilityComWin::get_textAfterOffset( 2349 STDMETHODIMP BrowserAccessibilityComWin::get_textAfterOffset(
2353 LONG offset, 2350 LONG offset,
2354 IA2TextBoundaryType boundary_type, 2351 IA2TextBoundaryType boundary_type,
2355 LONG* start_offset, 2352 LONG* start_offset,
2356 LONG* end_offset, 2353 LONG* end_offset,
2357 BSTR* text) { 2354 BSTR* text) {
2358 WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_TEXT_AFTER_OFFSET); 2355 WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_TEXT_AFTER_OFFSET);
2359 AddAccessibilityModeFlags(kScreenReaderAndHTMLAccessibilityModes | 2356 AddAccessibilityModeFlags(kScreenReaderAndHTMLAccessibilityModes |
2360 AccessibilityMode::kInlineTextBoxes); 2357 AccessibilityMode::kInlineTextBoxes);
2361 if (!owner()) 2358 if (!owner())
2362 return E_FAIL; 2359 return E_FAIL;
2363 2360
2364 if (!start_offset || !end_offset || !text) 2361 if (!start_offset || !end_offset || !text)
2365 return E_INVALIDARG; 2362 return E_INVALIDARG;
2366 2363
2364 *start_offset = 0;
2365 *end_offset = 0;
2366 *text = NULL;
2367
2368 const base::string16& text_str = owner()->GetText();
2369 LONG text_len = text_str.length();
2370 if (offset > text_len)
2371 return E_INVALIDARG;
2372
2367 // The IAccessible2 spec says we don't have to implement the "sentence" 2373 // The IAccessible2 spec says we don't have to implement the "sentence"
2368 // boundary type, we can just let the screenreader handle it. 2374 // boundary type, we can just let the screenreader handle it.
2369 if (boundary_type == IA2_TEXT_BOUNDARY_SENTENCE) { 2375 if (boundary_type == IA2_TEXT_BOUNDARY_SENTENCE)
2370 *start_offset = 0;
2371 *end_offset = 0;
2372 *text = NULL;
2373 return S_FALSE; 2376 return S_FALSE;
2374 }
2375
2376 const base::string16& text_str = owner()->GetText();
2377 2377
2378 *start_offset = offset; 2378 *start_offset = offset;
2379 *end_offset = 2379 *end_offset = FindBoundary(boundary_type, offset, ui::FORWARDS_DIRECTION);
2380 FindBoundary(text_str, boundary_type, offset, ui::FORWARDS_DIRECTION);
2381 return get_text(*start_offset, *end_offset, text); 2380 return get_text(*start_offset, *end_offset, text);
2382 } 2381 }
2383 2382
2384 STDMETHODIMP BrowserAccessibilityComWin::get_newText(IA2TextSegment* new_text) { 2383 STDMETHODIMP BrowserAccessibilityComWin::get_newText(IA2TextSegment* new_text) {
2385 WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_NEW_TEXT); 2384 WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_NEW_TEXT);
2386 AddAccessibilityModeFlags(kScreenReaderAndHTMLAccessibilityModes); 2385 AddAccessibilityModeFlags(kScreenReaderAndHTMLAccessibilityModes);
2387 if (!owner()) 2386 if (!owner())
2388 return E_FAIL; 2387 return E_FAIL;
2389 2388
2390 if (!new_text) 2389 if (!new_text)
(...skipping 2399 matching lines...) Expand 10 before | Expand all | Expand 10 after
4790 case IA2_TEXT_BOUNDARY_PARAGRAPH: 4789 case IA2_TEXT_BOUNDARY_PARAGRAPH:
4791 return ui::PARAGRAPH_BOUNDARY; 4790 return ui::PARAGRAPH_BOUNDARY;
4792 case IA2_TEXT_BOUNDARY_ALL: 4791 case IA2_TEXT_BOUNDARY_ALL:
4793 return ui::ALL_BOUNDARY; 4792 return ui::ALL_BOUNDARY;
4794 } 4793 }
4795 NOTREACHED(); 4794 NOTREACHED();
4796 return ui::CHAR_BOUNDARY; 4795 return ui::CHAR_BOUNDARY;
4797 } 4796 }
4798 4797
4799 LONG BrowserAccessibilityComWin::FindBoundary( 4798 LONG BrowserAccessibilityComWin::FindBoundary(
4800 const base::string16& text,
4801 IA2TextBoundaryType ia2_boundary, 4799 IA2TextBoundaryType ia2_boundary,
4802 LONG start_offset, 4800 LONG start_offset,
4803 ui::TextBoundaryDirection direction) { 4801 ui::TextBoundaryDirection direction) {
4804 // If the boundary is relative to the caret, use the selection 4802 // If the boundary is relative to the caret, use the selection
4805 // affinity, otherwise default to downstream affinity. 4803 // affinity, otherwise default to downstream affinity.
4806 ui::AXTextAffinity affinity = 4804 ui::AXTextAffinity affinity =
4807 start_offset == IA2_TEXT_OFFSET_CARET 4805 start_offset == IA2_TEXT_OFFSET_CARET
4808 ? Manager()->GetTreeData().sel_focus_affinity 4806 ? Manager()->GetTreeData().sel_focus_affinity
4809 : ui::AX_TEXT_AFFINITY_DOWNSTREAM; 4807 : ui::AX_TEXT_AFFINITY_DOWNSTREAM;
4810 4808
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
4858 } else { 4856 } else {
4859 previous_line = std::move(position); 4857 previous_line = std::move(position);
4860 } 4858 }
4861 return previous_line->text_offset(); 4859 return previous_line->text_offset();
4862 } 4860 }
4863 } 4861 }
4864 } 4862 }
4865 4863
4866 // TODO(nektar): |AXPosition| can handle other types of boundaries as well. 4864 // TODO(nektar): |AXPosition| can handle other types of boundaries as well.
4867 ui::TextBoundaryType boundary = IA2TextBoundaryToTextBoundary(ia2_boundary); 4865 ui::TextBoundaryType boundary = IA2TextBoundaryToTextBoundary(ia2_boundary);
4868 return ui::FindAccessibleTextBoundary(text, owner()->GetLineStartOffsets(), 4866 return ui::FindAccessibleTextBoundary(
4869 boundary, start_offset, direction, 4867 owner()->GetText(), owner()->GetLineStartOffsets(), boundary,
4870 affinity); 4868 start_offset, direction, affinity);
4871 } 4869 }
4872 4870
4873 LONG BrowserAccessibilityComWin::FindStartOfStyle( 4871 LONG BrowserAccessibilityComWin::FindStartOfStyle(
4874 LONG start_offset, 4872 LONG start_offset,
4875 ui::TextBoundaryDirection direction) const { 4873 ui::TextBoundaryDirection direction) const {
4876 LONG text_length = static_cast<LONG>(owner()->GetText().length()); 4874 LONG text_length = static_cast<LONG>(owner()->GetText().length());
4877 DCHECK_GE(start_offset, 0); 4875 DCHECK_GE(start_offset, 0);
4878 DCHECK_LE(start_offset, text_length); 4876 DCHECK_LE(start_offset, text_length);
4879 4877
4880 switch (direction) { 4878 switch (direction) {
(...skipping 836 matching lines...) Expand 10 before | Expand all | Expand 10 after
5717 5715
5718 BrowserAccessibilityComWin* ToBrowserAccessibilityComWin( 5716 BrowserAccessibilityComWin* ToBrowserAccessibilityComWin(
5719 BrowserAccessibility* obj) { 5717 BrowserAccessibility* obj) {
5720 if (!obj || !obj->IsNative()) 5718 if (!obj || !obj->IsNative())
5721 return nullptr; 5719 return nullptr;
5722 auto* result = static_cast<BrowserAccessibilityWin*>(obj)->GetCOM(); 5720 auto* result = static_cast<BrowserAccessibilityWin*>(obj)->GetCOM();
5723 return result; 5721 return result;
5724 } 5722 }
5725 5723
5726 } // namespace content 5724 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698