| 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.h" | 5 #include "content/browser/accessibility/browser_accessibility.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include <algorithm> | 9 #include <algorithm> |
| 10 | 10 |
| (...skipping 358 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 369 return bounds; | 369 return bounds; |
| 370 } | 370 } |
| 371 | 371 |
| 372 gfx::Rect BrowserAccessibility::GetLocalBoundsForRange(int start, int len) | 372 gfx::Rect BrowserAccessibility::GetLocalBoundsForRange(int start, int len) |
| 373 const { | 373 const { |
| 374 DCHECK_GE(start, 0); | 374 DCHECK_GE(start, 0); |
| 375 DCHECK_GE(len, 0); | 375 DCHECK_GE(len, 0); |
| 376 | 376 |
| 377 // Standard text fields such as textarea have an embedded div inside them that | 377 // Standard text fields such as textarea have an embedded div inside them that |
| 378 // holds all the text. | 378 // holds all the text. |
| 379 // TODO(nektar): This is fragile! Replace with code that flattens tree. |
| 379 if (IsSimpleTextControl() && InternalChildCount() == 1) | 380 if (IsSimpleTextControl() && InternalChildCount() == 1) |
| 380 return InternalGetChild(0)->GetLocalBoundsForRange(start, len); | 381 return InternalGetChild(0)->GetLocalBoundsForRange(start, len); |
| 381 | 382 |
| 382 if (GetRole() != ui::AX_ROLE_STATIC_TEXT) { | 383 if (GetRole() != ui::AX_ROLE_STATIC_TEXT) { |
| 383 gfx::Rect bounds; | 384 gfx::Rect bounds; |
| 384 for (size_t i = 0; i < InternalChildCount() && len > 0; ++i) { | 385 for (size_t i = 0; i < InternalChildCount() && len > 0; ++i) { |
| 385 BrowserAccessibility* child = InternalGetChild(i); | 386 BrowserAccessibility* child = InternalGetChild(i); |
| 386 // Child objects are of length one, since they are represented by a single | 387 // Child objects are of length one, since they are represented by a single |
| 387 // embedded object character. The exception is text-only objects. | 388 // embedded object character. The exception is text-only objects. |
| 388 int child_length_in_parent = 1; | 389 int child_length_in_parent = 1; |
| (...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 533 // Keeps track of the length of each consecutive line. | 534 // Keeps track of the length of each consecutive line. |
| 534 int line_length = 0; | 535 int line_length = 0; |
| 535 for (size_t i = 0; i < InternalChildCount(); ++i) { | 536 for (size_t i = 0; i < InternalChildCount(); ++i) { |
| 536 const BrowserAccessibility* child = InternalGetChild(i); | 537 const BrowserAccessibility* child = InternalGetChild(i); |
| 537 DCHECK(child); | 538 DCHECK(child); |
| 538 // Child objects are of length one, since they are represented by a | 539 // Child objects are of length one, since they are represented by a |
| 539 // single embedded object character. The exception is text-only objects. | 540 // single embedded object character. The exception is text-only objects. |
| 540 int child_length = 1; | 541 int child_length = 1; |
| 541 if (child->IsTextOnlyObject()) | 542 if (child->IsTextOnlyObject()) |
| 542 child_length = static_cast<int>(child->GetText().length()); | 543 child_length = static_cast<int>(child->GetText().length()); |
| 544 |
| 545 // Stop when we reach both the child containing our start offset and, in |
| 546 // case we are searching forward, the child that is at the end of the line |
| 547 // on which this object is located. |
| 548 if (start < child_length && (direction == ui::BACKWARDS_DIRECTION || |
| 549 !child->IsNextSiblingOnSameLine())) { |
| 550 // Recurse into the inline text boxes. |
| 551 if (child->GetRole() == ui::AX_ROLE_STATIC_TEXT) { |
| 552 switch (direction) { |
| 553 case ui::FORWARDS_DIRECTION: |
| 554 line_length += |
| 555 child->GetLineStartBoundary(std::max(start, 0), direction); |
| 556 break; |
| 557 case ui::BACKWARDS_DIRECTION: |
| 558 line_start += |
| 559 child->GetLineStartBoundary(std::max(start, 0), direction); |
| 560 break; |
| 561 } |
| 562 } else { |
| 563 line_length += child_length; |
| 564 } |
| 565 |
| 566 break; |
| 567 } |
| 543 line_length += child_length; | 568 line_length += child_length; |
| 544 start -= child_length; | |
| 545 | |
| 546 // Stop when we reach both the object containing our start offset and the | |
| 547 // end of the line on which this object is located. | |
| 548 if (start < 0 && !child->IsNextSiblingOnSameLine()) | |
| 549 break; | |
| 550 | 569 |
| 551 if (!child->IsNextSiblingOnSameLine()) { | 570 if (!child->IsNextSiblingOnSameLine()) { |
| 571 // We are on a new line. |
| 552 line_start += line_length; | 572 line_start += line_length; |
| 553 line_length = 0; | 573 line_length = 0; |
| 554 } | 574 } |
| 575 |
| 576 start -= child_length; |
| 555 } | 577 } |
| 556 | 578 |
| 557 int result = 0; | |
| 558 switch (direction) { | 579 switch (direction) { |
| 559 case ui::FORWARDS_DIRECTION: | 580 case ui::FORWARDS_DIRECTION: |
| 560 result = line_start + line_length; | 581 return line_start + line_length; |
| 561 break; | |
| 562 case ui::BACKWARDS_DIRECTION: | 582 case ui::BACKWARDS_DIRECTION: |
| 563 result = line_start; | 583 return line_start; |
| 564 break; | |
| 565 default: | |
| 566 NOTREACHED(); | |
| 567 } | 584 } |
| 568 return result; | 585 NOTREACHED(); |
| 586 return 0; |
| 569 } | 587 } |
| 570 | 588 |
| 571 int BrowserAccessibility::GetWordStartBoundary( | 589 int BrowserAccessibility::GetWordStartBoundary( |
| 572 int start, ui::TextBoundaryDirection direction) const { | 590 int start, ui::TextBoundaryDirection direction) const { |
| 573 DCHECK_GE(start, -1); | 591 DCHECK_GE(start, -1); |
| 574 // Special offset that indicates that a word boundary has not been found. | 592 // Special offset that indicates that a word boundary has not been found. |
| 575 int word_start_not_found = static_cast<int>(GetText().size()); | 593 int word_start_not_found = static_cast<int>(GetText().size()); |
| 576 int word_start = word_start_not_found; | 594 int word_start = word_start_not_found; |
| 577 | 595 |
| 578 switch (GetRole()) { | 596 switch (GetRole()) { |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 636 | 654 |
| 637 default: | 655 default: |
| 638 // If there are no children, the word start boundary is still unknown or | 656 // If there are no children, the word start boundary is still unknown or |
| 639 // found previously depending on the direction. | 657 // found previously depending on the direction. |
| 640 if (!InternalChildCount()) | 658 if (!InternalChildCount()) |
| 641 return word_start_not_found; | 659 return word_start_not_found; |
| 642 | 660 |
| 643 const BrowserAccessibility* this_object = this; | 661 const BrowserAccessibility* this_object = this; |
| 644 // Standard text fields such as textarea have an embedded div inside them | 662 // Standard text fields such as textarea have an embedded div inside them |
| 645 // that should be skipped. | 663 // that should be skipped. |
| 664 // TODO(nektar): This is fragile. Replace with code that flattens tree. |
| 646 if (IsSimpleTextControl() && InternalChildCount() == 1) { | 665 if (IsSimpleTextControl() && InternalChildCount() == 1) { |
| 647 this_object = InternalGetChild(0); | 666 this_object = InternalGetChild(0); |
| 648 } | 667 } |
| 649 int child_start = 0; | 668 int child_start = 0; |
| 650 for (size_t i = 0; i < this_object->InternalChildCount(); ++i) { | 669 for (size_t i = 0; i < this_object->InternalChildCount(); ++i) { |
| 651 BrowserAccessibility* child = this_object->InternalGetChild(i); | 670 BrowserAccessibility* child = this_object->InternalGetChild(i); |
| 652 // Child objects are of length one, since they are represented by a | 671 // Child objects are of length one, since they are represented by a |
| 653 // single embedded object character. The exception is text-only objects. | 672 // single embedded object character. The exception is text-only objects. |
| 654 int child_len = 1; | 673 int child_len = 1; |
| 655 if (child->IsTextOnlyObject()) { | 674 if (child->IsTextOnlyObject()) { |
| (...skipping 512 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1168 break; | 1187 break; |
| 1169 | 1188 |
| 1170 manager = root->GetParent()->manager(); | 1189 manager = root->GetParent()->manager(); |
| 1171 root = manager->GetRoot(); | 1190 root = manager->GetRoot(); |
| 1172 } | 1191 } |
| 1173 | 1192 |
| 1174 return bounds; | 1193 return bounds; |
| 1175 } | 1194 } |
| 1176 | 1195 |
| 1177 } // namespace content | 1196 } // namespace content |
| OLD | NEW |