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

Unified Diff: content/browser/accessibility/browser_accessibility.cc

Issue 2806773002: Switched to using |AXPosition| for calculating word and line boundaries on Windows. (Closed)
Patch Set: Fixed unit tests. Created 3 years, 8 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.cc
diff --git a/content/browser/accessibility/browser_accessibility.cc b/content/browser/accessibility/browser_accessibility.cc
index 1b2bf05c0c2220059677f58f0e966a793663abe5..9639954401b0bfa564832426e971fd6466394510 100644
--- a/content/browser/accessibility/browser_accessibility.cc
+++ b/content/browser/accessibility/browser_accessibility.cc
@@ -527,197 +527,6 @@ base::string16 BrowserAccessibility::GetValue() const {
return value;
}
-int BrowserAccessibility::GetLineStartBoundary(
- int start,
- ui::TextBoundaryDirection direction,
- ui::AXTextAffinity affinity) const {
- DCHECK_GE(start, 0);
- DCHECK_LE(start, static_cast<int>(GetText().length()));
-
- if (IsSimpleTextControl()) {
- return ui::FindAccessibleTextBoundary(GetText(), GetLineStartOffsets(),
- ui::LINE_BOUNDARY, start, direction,
- affinity);
- }
-
- // Keeps track of the start offset of each consecutive line.
- int line_start = 0;
- // Keeps track of the length of each consecutive line.
- int line_length = 0;
- for (size_t i = 0; i < InternalChildCount(); ++i) {
- const BrowserAccessibility* child = InternalGetChild(i);
- DCHECK(child);
- // Child objects are of length one, since they are represented by a
- // single embedded object character. The exception is text-only objects.
- int child_length = 1;
- if (child->IsTextOnlyObject())
- child_length = static_cast<int>(child->GetText().length());
-
- // Determine if |start| is within this child. As a special case, if
- // the affinity is upstream, then the cursor position between two
- // lines belongs to the previous line.
- bool start_index_within_child = start < child_length;
- if (start == child_length &&
- !child->IsNextSiblingOnSameLine() &&
- affinity == ui::AX_TEXT_AFFINITY_UPSTREAM) {
- start_index_within_child = true;
- }
-
- // Stop when we reach both the child containing our start offset and, in
- // case we are searching forward, the child that is at the end of the line
- // on which this object is located.
- if (start_index_within_child && (direction == ui::BACKWARDS_DIRECTION ||
- !child->IsNextSiblingOnSameLine())) {
- // Recurse into the inline text boxes.
- if (child->GetRole() == ui::AX_ROLE_STATIC_TEXT) {
- switch (direction) {
- case ui::FORWARDS_DIRECTION:
- line_length += child->GetLineStartBoundary(
- std::max(start, 0), direction, affinity);
- break;
- case ui::BACKWARDS_DIRECTION:
- line_start += child->GetLineStartBoundary(
- std::max(start, 0), direction, affinity);
- break;
- }
- } else {
- line_length += child_length;
- }
-
- break;
- }
- line_length += child_length;
-
- if (!child->IsNextSiblingOnSameLine()) {
- // We are on a new line.
- line_start += line_length;
- line_length = 0;
- }
-
- start -= child_length;
- }
-
- switch (direction) {
- case ui::FORWARDS_DIRECTION:
- return line_start + line_length;
- case ui::BACKWARDS_DIRECTION:
- return line_start;
- }
- NOTREACHED();
- return 0;
-}
-
-int BrowserAccessibility::GetWordStartBoundary(
- int start, ui::TextBoundaryDirection direction) const {
- DCHECK_GE(start, -1);
- // Special offset that indicates that a word boundary has not been found.
- int word_start_not_found = static_cast<int>(GetText().size());
- int word_start = word_start_not_found;
-
- switch (GetRole()) {
- case ui::AX_ROLE_STATIC_TEXT: {
- int prev_word_start = word_start_not_found;
- int child_start = 0;
- int child_end = 0;
-
- // Go through the inline text boxes.
- for (size_t i = 0; i < InternalChildCount(); ++i) {
- // The next child starts where the previous one ended.
- child_start = child_end;
- const BrowserAccessibility* child = InternalGetChild(i);
- DCHECK_EQ(child->GetRole(), ui::AX_ROLE_INLINE_TEXT_BOX);
- int child_len = static_cast<int>(child->GetText().size());
- child_end += child_len; // End is one past the last character.
-
- const std::vector<int32_t>& word_starts =
- child->GetIntListAttribute(ui::AX_ATTR_WORD_STARTS);
- if (word_starts.empty()) {
- word_start = child_end;
- continue;
- }
-
- int local_start = start - child_start;
- std::vector<int32_t>::const_iterator iter = std::upper_bound(
- word_starts.begin(), word_starts.end(), local_start);
- if (iter != word_starts.end()) {
- if (direction == ui::FORWARDS_DIRECTION) {
- word_start = child_start + *iter;
- } else if (direction == ui::BACKWARDS_DIRECTION) {
- if (iter == word_starts.begin()) {
- // Return the position of the last word in the previous child.
- word_start = prev_word_start;
- } else {
- word_start = child_start + *(iter - 1);
- }
- } else {
- NOTREACHED();
- }
- break;
- }
-
- // No word start that is greater than the requested offset has been
- // found.
- prev_word_start = child_start + *(iter - 1);
- if (direction == ui::FORWARDS_DIRECTION) {
- word_start = child_end;
- } else if (direction == ui::BACKWARDS_DIRECTION) {
- word_start = prev_word_start;
- } else {
- NOTREACHED();
- }
- }
- return word_start;
- }
-
- case ui::AX_ROLE_LINE_BREAK:
- // Words never start at a line break.
- return word_start_not_found;
-
- default:
- // If there are no children, the word start boundary is still unknown or
- // found previously depending on the direction.
- if (!InternalChildCount())
- return word_start_not_found;
-
- const BrowserAccessibility* this_object = this;
- // Standard text fields such as textarea have an embedded div inside them
- // that should be skipped.
- // TODO(nektar): This is fragile. Replace with code that flattens tree.
- if (IsSimpleTextControl() && InternalChildCount() == 1) {
- this_object = InternalGetChild(0);
- }
- int child_start = 0;
- for (size_t i = 0; i < this_object->InternalChildCount(); ++i) {
- BrowserAccessibility* child = this_object->InternalGetChild(i);
- // Child objects are of length one, since they are represented by a
- // single embedded object character. The exception is text-only objects.
- int child_len = 1;
- if (child->IsTextOnlyObject()) {
- child_len = static_cast<int>(child->GetText().length());
- int child_word_start = child->GetWordStartBoundary(start, direction);
- if (child_word_start < child_len) {
- // We have found a possible word boundary.
- word_start = child_start + child_word_start;
- }
-
- // Decide when to stop searching.
- if ((word_start != word_start_not_found &&
- direction == ui::FORWARDS_DIRECTION) ||
- (start < child_len && direction == ui::BACKWARDS_DIRECTION)) {
- break;
- }
- }
-
- child_start += child_len;
- if (start >= child_len)
- start -= child_len;
- else
- start = -1;
- }
- return word_start;
- }
-}
-
BrowserAccessibility* BrowserAccessibility::ApproximateHitTest(
const gfx::Point& point) {
// The best result found that's a child of this object.
@@ -1243,10 +1052,11 @@ std::vector<int> BrowserAccessibility::GetLineStartOffsets() const {
}
BrowserAccessibility::AXPlatformPositionInstance
-BrowserAccessibility::CreatePositionAt(int offset) const {
+BrowserAccessibility::CreatePositionAt(int offset,
+ ui::AXTextAffinity affinity) const {
DCHECK(manager_);
- return AXPlatformPosition::CreateTextPosition(
- manager_->ax_tree_id(), GetId(), offset, ui::AX_TEXT_AFFINITY_DOWNSTREAM);
+ return AXPlatformPosition::CreateTextPosition(manager_->ax_tree_id(), GetId(),
+ offset, affinity);
}
base::string16 BrowserAccessibility::GetInnerText() const {
« no previous file with comments | « content/browser/accessibility/browser_accessibility.h ('k') | content/browser/accessibility/browser_accessibility_manager.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698