| 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)
|
|
|