OLD | NEW |
---|---|
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 #include <algorithm> | |
9 | 10 |
10 #include "base/strings/string_number_conversions.h" | 11 #include "base/strings/string_number_conversions.h" |
11 #include "base/strings/string_split.h" | 12 #include "base/strings/string_split.h" |
12 #include "base/strings/string_util.h" | 13 #include "base/strings/string_util.h" |
13 #include "base/strings/utf_string_conversions.h" | 14 #include "base/strings/utf_string_conversions.h" |
14 #include "base/win/enum_variant.h" | 15 #include "base/win/enum_variant.h" |
15 #include "base/win/scoped_comptr.h" | 16 #include "base/win/scoped_comptr.h" |
16 #include "base/win/windows_version.h" | 17 #include "base/win/windows_version.h" |
17 #include "content/browser/accessibility/browser_accessibility_manager_win.h" | 18 #include "content/browser/accessibility/browser_accessibility_manager_win.h" |
18 #include "content/browser/accessibility/browser_accessibility_state_impl.h" | 19 #include "content/browser/accessibility/browser_accessibility_state_impl.h" |
(...skipping 3271 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3290 NOTREACHED(); | 3291 NOTREACHED(); |
3291 return ui::CHAR_BOUNDARY; | 3292 return ui::CHAR_BOUNDARY; |
3292 } | 3293 } |
3293 } | 3294 } |
3294 | 3295 |
3295 LONG BrowserAccessibilityWin::FindBoundary( | 3296 LONG BrowserAccessibilityWin::FindBoundary( |
3296 const base::string16& text, | 3297 const base::string16& text, |
3297 IA2TextBoundaryType ia2_boundary, | 3298 IA2TextBoundaryType ia2_boundary, |
3298 LONG start_offset, | 3299 LONG start_offset, |
3299 ui::TextBoundaryDirection direction) { | 3300 ui::TextBoundaryDirection direction) { |
3301 if (ia2_boundary == IA2_TEXT_BOUNDARY_WORD) | |
3302 return FindWordStartBoundary(text, start_offset, direction); | |
3303 | |
3300 HandleSpecialTextOffset(text, &start_offset); | 3304 HandleSpecialTextOffset(text, &start_offset); |
3301 ui::TextBoundaryType boundary = IA2TextBoundaryToTextBoundary(ia2_boundary); | 3305 ui::TextBoundaryType boundary = IA2TextBoundaryToTextBoundary(ia2_boundary); |
3302 const std::vector<int32>& line_breaks = GetIntListAttribute( | 3306 const std::vector<int32>& line_breaks = GetIntListAttribute( |
3303 ui::AX_ATTR_LINE_BREAKS); | 3307 ui::AX_ATTR_LINE_BREAKS); |
3304 return ui::FindAccessibleTextBoundary( | 3308 return ui::FindAccessibleTextBoundary( |
3305 text, line_breaks, boundary, start_offset, direction); | 3309 text, line_breaks, boundary, start_offset, direction); |
3306 } | 3310 } |
3307 | 3311 |
3312 LONG BrowserAccessibilityWin::FindWordStartBoundary( | |
dmazzoni
2014/10/15 22:03:10
Please move this to browser_accessibility.cc inste
| |
3313 const base::string16& text, | |
3314 LONG start_offset, | |
3315 ui::TextBoundaryDirection direction) { | |
3316 HandleSpecialTextOffset(text, &start_offset); | |
3317 if (!IsEditableText()) { | |
3318 // We don't actually need the line breaks. | |
3319 const std::vector<int32> line_breaks; | |
3320 return ui::FindAccessibleTextBoundary( | |
3321 text, line_breaks, ui::WORD_START_BOUNDARY, start_offset, direction); | |
3322 } | |
3323 | |
3324 LONG word_start = 0; | |
3325 LONG child_start = 0; | |
3326 LONG child_end = 0; | |
3327 | |
3328 for (size_t i = 0; i < InternalChildCount(); ++i) { | |
3329 // The next child starts where the previous one ended. | |
3330 child_start = child_end; | |
3331 BrowserAccessibilityWin* child = InternalGetChild( | |
3332 i)->ToBrowserAccessibilityWin(); | |
3333 DCHECK_EQ(child->GetRole(), ui::AX_ROLE_INLINE_TEXT_BOX); | |
3334 const base::string16& child_text = child->TextForIAccessibleText(); | |
3335 LONG child_len = static_cast<LONG>(child_text.length()); | |
3336 child_end += child_len; // End is one passed the last character. | |
3337 | |
3338 if (start_offset >= child_end) | |
3339 continue; | |
3340 | |
3341 const std::vector<int32>& word_starts = child->GetIntListAttribute( | |
3342 ui::AX_ATTR_WORD_STARTS); | |
3343 if (!word_starts.empty()) { | |
dmazzoni
2014/10/15 22:03:10
When possible, reverse the direction of a test to
| |
3344 int local_start = static_cast<int32>(start_offset, child_start); | |
3345 if (direction == ui::FORWARDS_DIRECTION) { | |
3346 std::vector<int32>::const_iterator iter = std::upper_bound( | |
3347 word_starts.cbegin(), word_starts.cend(), local_start); | |
3348 if (iter != word_starts.cend()) { | |
3349 word_start = *iter; | |
3350 break; | |
3351 } else { | |
3352 // In case there are no more children or remaining children have no | |
3353 // text, e.g., an image. | |
3354 word_start = child_end; | |
3355 continue; | |
3356 } | |
3357 } else if (direction == ui::BACKWARDS_DIRECTION) { | |
3358 std::vector<int32>::const_iterator iter = std::lower_bound( | |
3359 word_starts.cbegin(), word_starts.cend(), local_start); | |
3360 if (iter != word_starts.cbegin() { | |
3361 --iter; | |
3362 word_start = *iter; | |
3363 break; | |
3364 } else { | |
3365 // Return the start of the last word in the previous child. | |
3366 for (int j = i - 1; j >= 0; --j) { | |
3367 child = InternalGetChild(j).ToBrowserAccessibilityWin(); | |
3368 word_starts = child->GetIntListAttribute(ui::AX_ATTR_WORD_STARTS); | |
3369 if (!word_starts.empty()) | |
3370 word_start = word_starts[word_starts.length() - 1]; | |
3371 } | |
3372 break; | |
3373 } | |
3374 } | |
3375 } | |
3376 } | |
3377 | |
3378 return word_start; | |
3379 } | |
3380 | |
3308 BrowserAccessibilityWin* BrowserAccessibilityWin::GetFromID(int32 id) { | 3381 BrowserAccessibilityWin* BrowserAccessibilityWin::GetFromID(int32 id) { |
3309 return manager()->GetFromID(id)->ToBrowserAccessibilityWin(); | 3382 return manager()->GetFromID(id)->ToBrowserAccessibilityWin(); |
3310 } | 3383 } |
3311 | 3384 |
3312 void BrowserAccessibilityWin::InitRoleAndState() { | 3385 void BrowserAccessibilityWin::InitRoleAndState() { |
3313 ia_state_ = 0; | 3386 ia_state_ = 0; |
3314 ia2_state_ = IA2_STATE_OPAQUE; | 3387 ia2_state_ = IA2_STATE_OPAQUE; |
3315 ia2_attributes_.clear(); | 3388 ia2_attributes_.clear(); |
3316 | 3389 |
3317 if (HasState(ui::AX_STATE_BUSY)) | 3390 if (HasState(ui::AX_STATE_BUSY)) |
(...skipping 529 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3847 // The role should always be set. | 3920 // The role should always be set. |
3848 DCHECK(!role_name_.empty() || ia_role_); | 3921 DCHECK(!role_name_.empty() || ia_role_); |
3849 | 3922 |
3850 // If we didn't explicitly set the IAccessible2 role, make it the same | 3923 // If we didn't explicitly set the IAccessible2 role, make it the same |
3851 // as the MSAA role. | 3924 // as the MSAA role. |
3852 if (!ia2_role_) | 3925 if (!ia2_role_) |
3853 ia2_role_ = ia_role_; | 3926 ia2_role_ = ia_role_; |
3854 } | 3927 } |
3855 | 3928 |
3856 } // namespace content | 3929 } // namespace content |
OLD | NEW |