| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserv
ed. | 2 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserv
ed. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
| 6 * are met: | 6 * are met: |
| 7 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright |
| 8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. |
| 9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright |
| 10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the |
| (...skipping 648 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 659 static VisiblePositionTemplate<Strategy> previousBoundary(const VisiblePositionT
emplate<Strategy>& c, BoundarySearchFunction searchFunction) | 659 static VisiblePositionTemplate<Strategy> previousBoundary(const VisiblePositionT
emplate<Strategy>& c, BoundarySearchFunction searchFunction) |
| 660 { | 660 { |
| 661 const PositionTemplate<Strategy> pos = c.deepEquivalent(); | 661 const PositionTemplate<Strategy> pos = c.deepEquivalent(); |
| 662 Node* boundary = parentEditingBoundary(pos); | 662 Node* boundary = parentEditingBoundary(pos); |
| 663 if (!boundary) | 663 if (!boundary) |
| 664 return VisiblePositionTemplate<Strategy>(); | 664 return VisiblePositionTemplate<Strategy>(); |
| 665 | 665 |
| 666 const PositionTemplate<Strategy> start = PositionTemplate<Strategy>::editing
PositionOf(boundary, 0).parentAnchoredEquivalent(); | 666 const PositionTemplate<Strategy> start = PositionTemplate<Strategy>::editing
PositionOf(boundary, 0).parentAnchoredEquivalent(); |
| 667 const PositionTemplate<Strategy> end = pos.parentAnchoredEquivalent(); | 667 const PositionTemplate<Strategy> end = pos.parentAnchoredEquivalent(); |
| 668 | 668 |
| 669 Vector<UChar, 1024> string; | 669 ForwardsTextBuffer suffixString; |
| 670 unsigned suffixLength = 0; | 670 unsigned suffixLength = 0; |
| 671 | 671 |
| 672 if (requiresContextForWordBoundary(characterBefore(c))) { | 672 if (requiresContextForWordBoundary(characterBefore(c))) { |
| 673 TextIteratorAlgorithm<Strategy> forwardsIterator(end, PositionTemplate<S
trategy>::afterNode(boundary)); | 673 TextIteratorAlgorithm<Strategy> forwardsIterator(end, PositionTemplate<S
trategy>::afterNode(boundary)); |
| 674 while (!forwardsIterator.atEnd()) { | 674 while (!forwardsIterator.atEnd()) { |
| 675 Vector<UChar, 1024> characters; | 675 // TODO(xiaochengh): Eliminate this intermediate buffer. |
| 676 ForwardsTextBuffer characters; |
| 676 forwardsIterator.copyTextTo(characters); | 677 forwardsIterator.copyTextTo(characters); |
| 677 int i = endOfFirstWordBoundaryContext(characters.data(), characters.
size()); | 678 int i = endOfFirstWordBoundaryContext(characters.data(), characters.
size()); |
| 678 string.append(characters.data(), i); | 679 suffixString.pushRange(characters.data(), i); |
| 679 suffixLength += i; | 680 suffixLength += i; |
| 680 if (static_cast<unsigned>(i) < characters.size()) | 681 if (static_cast<unsigned>(i) < characters.size()) |
| 681 break; | 682 break; |
| 682 forwardsIterator.advance(); | 683 forwardsIterator.advance(); |
| 683 } | 684 } |
| 684 } | 685 } |
| 685 | 686 |
| 687 BackwardsTextBuffer string; |
| 688 string.pushRange(suffixString.data(), suffixString.size()); |
| 689 |
| 686 SimplifiedBackwardsTextIteratorAlgorithm<Strategy> it(start, end); | 690 SimplifiedBackwardsTextIteratorAlgorithm<Strategy> it(start, end); |
| 687 unsigned next = 0; | 691 unsigned next = 0; |
| 688 bool needMoreContext = false; | 692 bool needMoreContext = false; |
| 689 while (!it.atEnd()) { | 693 while (!it.atEnd()) { |
| 690 bool inTextSecurityMode = it.isInTextSecurityMode(); | 694 bool inTextSecurityMode = it.isInTextSecurityMode(); |
| 691 // iterate to get chunks until the searchFunction returns a non-zero | 695 // iterate to get chunks until the searchFunction returns a non-zero |
| 692 // value. | 696 // value. |
| 693 // TODO(xiaochengh): Iterative prepending has quadratic running time | |
| 694 // in the worst case. Should improve it to linear. | |
| 695 if (!inTextSecurityMode) { | 697 if (!inTextSecurityMode) { |
| 696 it.copyTextTo(string); | 698 it.copyTextTo(string); |
| 697 } else { | 699 } else { |
| 698 // Treat bullets used in the text security mode as regular | 700 // Treat bullets used in the text security mode as regular |
| 699 // characters when looking for boundaries | 701 // characters when looking for boundaries |
| 700 Vector<UChar, 1024> iteratorString; | 702 string.pushCharacters('x', it.length()); |
| 701 iteratorString.fill('x', it.length()); | |
| 702 string.prepend(iteratorString.data(), iteratorString.size()); | |
| 703 } | 703 } |
| 704 // TODO(xiaochengh): The following line takes O(string.size()) time, | 704 // TODO(xiaochengh): The following line takes O(string.size()) time, |
| 705 // which makes the while loop take quadratic time in the worst case. | 705 // which makes the while loop take quadratic time in the worst case. |
| 706 // Should improve it in some way. | 706 // Should improve it in some way. |
| 707 next = searchFunction(string.data(), string.size(), string.size() - suff
ixLength, MayHaveMoreContext, needMoreContext); | 707 next = searchFunction(string.data(), string.size(), string.size() - suff
ixLength, MayHaveMoreContext, needMoreContext); |
| 708 if (next) | 708 if (next) |
| 709 break; | 709 break; |
| 710 it.advance(); | 710 it.advance(); |
| 711 } | 711 } |
| 712 if (needMoreContext) { | 712 if (needMoreContext) { |
| (...skipping 26 matching lines...) Expand all Loading... |
| 739 static VisiblePositionTemplate<Strategy> nextBoundary(const VisiblePositionTempl
ate<Strategy>& c, BoundarySearchFunction searchFunction) | 739 static VisiblePositionTemplate<Strategy> nextBoundary(const VisiblePositionTempl
ate<Strategy>& c, BoundarySearchFunction searchFunction) |
| 740 { | 740 { |
| 741 PositionTemplate<Strategy> pos = c.deepEquivalent(); | 741 PositionTemplate<Strategy> pos = c.deepEquivalent(); |
| 742 Node* boundary = parentEditingBoundary(pos); | 742 Node* boundary = parentEditingBoundary(pos); |
| 743 if (!boundary) | 743 if (!boundary) |
| 744 return VisiblePositionTemplate<Strategy>(); | 744 return VisiblePositionTemplate<Strategy>(); |
| 745 | 745 |
| 746 Document& d = boundary->document(); | 746 Document& d = boundary->document(); |
| 747 const PositionTemplate<Strategy> start(pos.parentAnchoredEquivalent()); | 747 const PositionTemplate<Strategy> start(pos.parentAnchoredEquivalent()); |
| 748 | 748 |
| 749 Vector<UChar, 1024> string; | 749 BackwardsTextBuffer prefixString; |
| 750 unsigned prefixLength = 0; | 750 unsigned prefixLength = 0; |
| 751 | 751 |
| 752 if (requiresContextForWordBoundary(characterAfter(c))) { | 752 if (requiresContextForWordBoundary(characterAfter(c))) { |
| 753 SimplifiedBackwardsTextIteratorAlgorithm<Strategy> backwardsIterator(Pos
itionTemplate<Strategy>::firstPositionInNode(&d), start); | 753 SimplifiedBackwardsTextIteratorAlgorithm<Strategy> backwardsIterator(Pos
itionTemplate<Strategy>::firstPositionInNode(&d), start); |
| 754 while (!backwardsIterator.atEnd()) { | 754 while (!backwardsIterator.atEnd()) { |
| 755 Vector<UChar, 1024> characters; | 755 // TODO(xiaochengh): Eliminate this intermediate buffer. |
| 756 BackwardsTextBuffer characters; |
| 756 backwardsIterator.copyTextTo(characters); | 757 backwardsIterator.copyTextTo(characters); |
| 757 int length = characters.size(); | 758 int length = characters.size(); |
| 758 int i = startOfLastWordBoundaryContext(characters.data(), length); | 759 int i = startOfLastWordBoundaryContext(characters.data(), length); |
| 759 // TODO(xiaochengh): Iterative prepending has quadratic running | 760 prefixString.pushRange(characters.data() + i, length - i); |
| 760 // time in the worst case. Should improve it to linear. | |
| 761 string.prepend(characters.data() + i, length - i); | |
| 762 prefixLength += length - i; | 761 prefixLength += length - i; |
| 763 if (i > 0) | 762 if (i > 0) |
| 764 break; | 763 break; |
| 765 backwardsIterator.advance(); | 764 backwardsIterator.advance(); |
| 766 } | 765 } |
| 767 } | 766 } |
| 768 | 767 |
| 768 ForwardsTextBuffer string; |
| 769 string.pushRange(prefixString.data(), prefixString.size()); |
| 770 |
| 769 const PositionTemplate<Strategy> searchStart = PositionTemplate<Strategy>::e
ditingPositionOf(start.anchorNode(), start.offsetInContainerNode()); | 771 const PositionTemplate<Strategy> searchStart = PositionTemplate<Strategy>::e
ditingPositionOf(start.anchorNode(), start.offsetInContainerNode()); |
| 770 const PositionTemplate<Strategy> searchEnd = PositionTemplate<Strategy>::las
tPositionInNode(boundary); | 772 const PositionTemplate<Strategy> searchEnd = PositionTemplate<Strategy>::las
tPositionInNode(boundary); |
| 771 TextIteratorAlgorithm<Strategy> it(searchStart, searchEnd, TextIteratorEmits
CharactersBetweenAllVisiblePositions); | 773 TextIteratorAlgorithm<Strategy> it(searchStart, searchEnd, TextIteratorEmits
CharactersBetweenAllVisiblePositions); |
| 772 const unsigned invalidOffset = static_cast<unsigned>(-1); | 774 const unsigned invalidOffset = static_cast<unsigned>(-1); |
| 773 unsigned next = invalidOffset; | 775 unsigned next = invalidOffset; |
| 774 unsigned offset = prefixLength; | 776 unsigned offset = prefixLength; |
| 775 bool needMoreContext = false; | 777 bool needMoreContext = false; |
| 776 while (!it.atEnd()) { | 778 while (!it.atEnd()) { |
| 777 // Keep asking the iterator for chunks until the search function | 779 // Keep asking the iterator for chunks until the search function |
| 778 // returns an end value not equal to the length of the string passed to | 780 // returns an end value not equal to the length of the string passed to |
| 779 // it. | 781 // it. |
| 780 bool inTextSecurityMode = it.isInTextSecurityMode(); | 782 bool inTextSecurityMode = it.isInTextSecurityMode(); |
| 781 if (!inTextSecurityMode) { | 783 if (!inTextSecurityMode) { |
| 782 it.copyTextTo(string); | 784 it.copyTextTo(string); |
| 783 } else { | 785 } else { |
| 784 // Treat bullets used in the text security mode as regular | 786 // Treat bullets used in the text security mode as regular |
| 785 // characters when looking for boundaries | 787 // characters when looking for boundaries |
| 786 Vector<UChar, 1024> iteratorString; | 788 string.pushCharacters('x', it.length()); |
| 787 iteratorString.fill('x', it.length()); | |
| 788 string.append(iteratorString.data(), iteratorString.size()); | |
| 789 } | 789 } |
| 790 next = searchFunction(string.data(), string.size(), offset, MayHaveMoreC
ontext, needMoreContext); | 790 next = searchFunction(string.data(), string.size(), offset, MayHaveMoreC
ontext, needMoreContext); |
| 791 if (next != string.size()) | 791 if (next != string.size()) |
| 792 break; | 792 break; |
| 793 it.advance(); | 793 it.advance(); |
| 794 if (!needMoreContext) { | 794 if (!needMoreContext) { |
| 795 // When the search does not need more context, skip all examined | 795 // When the search does not need more context, skip all examined |
| 796 // characters except the last one, in case it is a boundary. | 796 // characters except the last one, in case it is a boundary. |
| 797 offset = string.size(); | 797 offset = string.size(); |
| 798 U16_BACK_1(string.data(), 0, offset); | 798 U16_BACK_1(string.data(), 0, offset); |
| (...skipping 2528 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3327 { | 3327 { |
| 3328 return previousPositionOfAlgorithm<EditingStrategy>(visiblePosition, rule); | 3328 return previousPositionOfAlgorithm<EditingStrategy>(visiblePosition, rule); |
| 3329 } | 3329 } |
| 3330 | 3330 |
| 3331 VisiblePositionInComposedTree previousPositionOf(const VisiblePositionInComposed
Tree& visiblePosition, EditingBoundaryCrossingRule rule) | 3331 VisiblePositionInComposedTree previousPositionOf(const VisiblePositionInComposed
Tree& visiblePosition, EditingBoundaryCrossingRule rule) |
| 3332 { | 3332 { |
| 3333 return previousPositionOfAlgorithm<EditingInComposedTreeStrategy>(visiblePos
ition, rule); | 3333 return previousPositionOfAlgorithm<EditingInComposedTreeStrategy>(visiblePos
ition, rule); |
| 3334 } | 3334 } |
| 3335 | 3335 |
| 3336 } // namespace blink | 3336 } // namespace blink |
| OLD | NEW |