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

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

Issue 1598583002: Fixed algorithms that compute bounding rectangles and word start offsets to take into account IA2 h… (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Addressed comments by reviewer. Created 4 years, 11 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 9f528bd0de10cb7f8c7624574c6b619cce9a763e..db867d1d18feba9f419582415062e42139e40b7d 100644
--- a/content/browser/accessibility/browser_accessibility.cc
+++ b/content/browser/accessibility/browser_accessibility.cc
@@ -104,7 +104,7 @@ bool BrowserAccessibility::IsTextOnlyObject() const {
BrowserAccessibility* BrowserAccessibility::PlatformGetChild(
uint32_t child_index) const {
- DCHECK(child_index < PlatformChildCount());
+ DCHECK_LT(child_index, PlatformChildCount());
BrowserAccessibility* result = nullptr;
if (HasIntAttribute(ui::AX_ATTR_CHILD_TREE_ID)) {
@@ -260,20 +260,31 @@ gfx::Rect BrowserAccessibility::GetGlobalBoundsRect() const {
gfx::Rect BrowserAccessibility::GetLocalBoundsForRange(int start, int len)
const {
+ // Standard text fields such as textarea have an embedded div inside them that
+ // holds all the text.
+ if (IsSimpleTextControl() && InternalChildCount() == 1)
+ return InternalGetChild(0)->GetLocalBoundsForRange(start, len);
+
if (GetRole() != ui::AX_ROLE_STATIC_TEXT) {
- // Apply recursively to all static text descendants. For example, if
- // you call it on a div with two text node children, it just calls
- // GetLocalBoundsForRange on each of the two children (adjusting
- // |start| for each one) and unions the resulting rects.
gfx::Rect bounds;
- for (size_t i = 0; i < InternalChildCount(); ++i) {
+ for (size_t i = 0; i < InternalChildCount() && start >= 0; ++i) {
BrowserAccessibility* child = InternalGetChild(i);
- int child_len = child->GetInnerTextLength();
- if (start < child_len && start + len > 0) {
- gfx::Rect child_rect = child->GetLocalBoundsForRange(start, len);
+ // Child objects are of length one, since they are represented by a single
+ // special character. The exception is text-only objects.
+ int child_length_in_parent = 1;
+ if (child->IsTextOnlyObject())
+ child_length_in_parent = static_cast<int>(child->GetText().size());
+ if (start < child_length_in_parent) {
+ gfx::Rect child_rect;
+ if (child->IsTextOnlyObject())
+ child_rect = child->GetLocalBoundsForRange(start, len);
+ else
+ child_rect = child->GetLocalBoundsForRange(
+ start, static_cast<int>(child->GetText().size()));
bounds.Union(child_rect);
+ len -= child_length_in_parent;
}
- start -= child_len;
+ start -= child_length_in_parent;
}
return ElementBoundsToLocalBounds(bounds);
}
@@ -291,9 +302,7 @@ gfx::Rect BrowserAccessibility::GetLocalBoundsForRange(int start, int len)
continue;
}
- std::string child_text;
- child->GetStringAttribute(ui::AX_ATTR_NAME, &child_text);
- int child_len = static_cast<int>(child_text.size());
+ int child_len = static_cast<int>(GetText().size());
child_start = child_end;
child_end += child_len;
@@ -382,7 +391,7 @@ 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 = GetInnerTextLength();
+ int word_start_not_found = static_cast<int>(GetText().size());
int word_start = word_start_not_found;
switch (GetRole()) {
@@ -397,9 +406,7 @@ int BrowserAccessibility::GetWordStartBoundary(
child_start = child_end;
BrowserAccessibility* child = InternalGetChild(i);
DCHECK_EQ(child->GetRole(), ui::AX_ROLE_INLINE_TEXT_BOX);
- const std::string& child_text = child->GetStringAttribute(
- ui::AX_ATTR_NAME);
- int child_len = static_cast<int>(child_text.size());
+ int child_len = static_cast<int>(GetText().size());
child_end += child_len; // End is one past the last character.
const std::vector<int32_t>& word_starts =
@@ -452,22 +459,32 @@ int BrowserAccessibility::GetWordStartBoundary(
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.
+ if (IsSimpleTextControl() && InternalChildCount() == 1) {
+ this_object = InternalGetChild(0);
+ }
int child_start = 0;
- for (size_t i = 0; i < InternalChildCount(); ++i) {
- BrowserAccessibility* child = InternalGetChild(i);
- int child_len = child->GetInnerTextLength();
- 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;
- }
+ 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 special character. The exception is text-only objects.
+ int child_len = 1;
+ if (child->IsTextOnlyObject()) {
+ child_len = static_cast<int>(child->GetText().size());
+ 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;
+ // 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;
@@ -656,7 +673,11 @@ bool BrowserAccessibility::GetAriaTristate(
if (base::EqualsASCII(value, "mixed"))
*is_mixed = true;
- return false; // Not set
+ return false; // Not set.
+}
+
+base::string16 BrowserAccessibility::GetText() const {
+ return GetInnerText();
}
bool BrowserAccessibility::HasState(ui::AXState state_enum) const {
@@ -670,7 +691,8 @@ bool BrowserAccessibility::IsCellOrTableHeaderRole() const {
}
bool BrowserAccessibility::HasCaret() const {
- if (IsEditableText() && !HasState(ui::AX_STATE_RICHLY_EDITABLE) &&
+ if (HasState(ui::AX_STATE_EDITABLE) &&
+ !HasState(ui::AX_STATE_RICHLY_EDITABLE) &&
HasIntAttribute(ui::AX_ATTR_TEXT_SEL_START) &&
HasIntAttribute(ui::AX_ATTR_TEXT_SEL_END)) {
return true;
@@ -688,10 +710,6 @@ bool BrowserAccessibility::HasCaret() const {
return true;
}
-bool BrowserAccessibility::IsEditableText() const {
- return HasState(ui::AX_STATE_EDITABLE);
-}
-
bool BrowserAccessibility::IsWebAreaForPresentationalIframe() const {
if (GetRole() != ui::AX_ROLE_WEB_AREA &&
GetRole() != ui::AX_ROLE_ROOT_WEB_AREA) {
@@ -792,10 +810,6 @@ base::string16 BrowserAccessibility::GetInnerText() const {
return text;
}
-int BrowserAccessibility::GetInnerTextLength() const {
- return static_cast<int>(GetInnerText().size());
-}
-
void BrowserAccessibility::FixEmptyBounds(gfx::Rect* bounds) const
{
if (bounds->width() > 0 && bounds->height() > 0)

Powered by Google App Engine
This is Rietveld 408576698