Chromium Code Reviews| Index: third_party/WebKit/Source/core/editing/VisibleUnits.cpp |
| diff --git a/third_party/WebKit/Source/core/editing/VisibleUnits.cpp b/third_party/WebKit/Source/core/editing/VisibleUnits.cpp |
| index f9e705e999786c1fa634cd5961854fbd45829c9f..cf115751a76d4a2d631d3bd1f1aba98fcac71728 100644 |
| --- a/third_party/WebKit/Source/core/editing/VisibleUnits.cpp |
| +++ b/third_party/WebKit/Source/core/editing/VisibleUnits.cpp |
| @@ -41,6 +41,7 @@ |
| #include "core/editing/iterators/BackwardsCharacterIterator.h" |
| #include "core/editing/iterators/CharacterIterator.h" |
| #include "core/editing/iterators/SimplifiedBackwardsTextIterator.h" |
| +#include "core/editing/iterators/TextAccumulator.h" |
| #include "core/editing/iterators/TextIterator.h" |
| #include "core/frame/LocalFrame.h" |
| #include "core/frame/Settings.h" |
| @@ -666,16 +667,17 @@ static VisiblePositionTemplate<Strategy> previousBoundary(const VisiblePositionT |
| const PositionTemplate<Strategy> start = PositionTemplate<Strategy>::editingPositionOf(boundary, 0).parentAnchoredEquivalent(); |
| const PositionTemplate<Strategy> end = pos.parentAnchoredEquivalent(); |
| - Vector<UChar, 1024> string; |
| + ForwardsTextBuffer suffixString; |
| unsigned suffixLength = 0; |
| if (requiresContextForWordBoundary(characterBefore(c))) { |
| TextIteratorAlgorithm<Strategy> forwardsIterator(end, PositionTemplate<Strategy>::afterNode(boundary)); |
| while (!forwardsIterator.atEnd()) { |
| - Vector<UChar, 1024> characters; |
| + // TODO(xiaochengh): Eliminate this intermediate buffer. |
| + ForwardsTextBuffer characters; |
| forwardsIterator.copyTextTo(characters); |
| int i = endOfFirstWordBoundaryContext(characters.data(), characters.size()); |
| - string.append(characters.data(), i); |
| + suffixString.push(characters.data(), i); |
| suffixLength += i; |
| if (static_cast<unsigned>(i) < characters.size()) |
| break; |
| @@ -683,31 +685,23 @@ static VisiblePositionTemplate<Strategy> previousBoundary(const VisiblePositionT |
| } |
| } |
| + BackwardsTextAccumulator string; |
| + string.push(suffixString.data(), suffixString.size()); |
| + |
| SimplifiedBackwardsTextIteratorAlgorithm<Strategy> it(start, end); |
| unsigned next = 0; |
| bool needMoreContext = false; |
| while (!it.atEnd()) { |
| - bool inTextSecurityMode = it.isInTextSecurityMode(); |
| // iterate to get chunks until the searchFunction returns a non-zero |
| // value. |
| - // TODO(xiaochengh): Iterative prepending has quadratic running time |
| - // in the worst case. Should improve it to linear. |
| - if (!inTextSecurityMode) { |
| - it.copyTextTo(string); |
| - } else { |
| - // Treat bullets used in the text security mode as regular |
| - // characters when looking for boundaries |
| - Vector<UChar, 1024> iteratorString; |
| - iteratorString.fill('x', it.length()); |
| - string.prepend(iteratorString.data(), iteratorString.size()); |
| - } |
| + string.extract(it); |
|
yosin_UTC9
2016/02/09 02:28:04
it.copyTo(string)
|
| // TODO(xiaochengh): The following line takes O(string.size()) time, |
| // which makes the while loop take quadratic time in the worst case. |
| // Should improve it in some way. |
| next = searchFunction(string.data(), string.size(), string.size() - suffixLength, MayHaveMoreContext, needMoreContext); |
| if (next) |
| break; |
| - it.advance(); |
| + string.advance(it); |
|
yosin_UTC9
2016/02/09 02:28:05
if (string.isSomeCondition()) {
string.resetAccu
|
| } |
| if (needMoreContext) { |
| // The last search returned the beginning of the buffer and asked for |
| @@ -722,9 +716,10 @@ static VisiblePositionTemplate<Strategy> previousBoundary(const VisiblePositionT |
| return createVisiblePosition(it.atEnd() ? it.startPosition() : pos); |
| Node* node = it.startContainer(); |
| - if (node->isTextNode() && static_cast<int>(next) <= node->maxCharacterOffset()) { |
| + int boundaryOffset = it.length() - string.accumulatedLengthInCurrentNode() + next; |
| + if (node->isTextNode() && boundaryOffset <= node->maxCharacterOffset()) { |
| // The next variable contains a usable index into a text node |
| - return createVisiblePosition(PositionTemplate<Strategy>(node, next)); |
| + return createVisiblePosition(PositionTemplate<Strategy>(node, boundaryOffset)); |
| } |
| // Use the character iterator to translate the next value into a DOM |
| @@ -746,19 +741,18 @@ static VisiblePositionTemplate<Strategy> nextBoundary(const VisiblePositionTempl |
| Document& d = boundary->document(); |
| const PositionTemplate<Strategy> start(pos.parentAnchoredEquivalent()); |
| - Vector<UChar, 1024> string; |
| + BackwardsTextBuffer prefixString; |
| unsigned prefixLength = 0; |
| if (requiresContextForWordBoundary(characterAfter(c))) { |
| SimplifiedBackwardsTextIteratorAlgorithm<Strategy> backwardsIterator(PositionTemplate<Strategy>::firstPositionInNode(&d), start); |
| while (!backwardsIterator.atEnd()) { |
| - Vector<UChar, 1024> characters; |
| + // TODO(xiaochengh): Eliminate this intermediate buffer. |
| + BackwardsTextBuffer characters; |
| backwardsIterator.copyTextTo(characters); |
| int length = characters.size(); |
| int i = startOfLastWordBoundaryContext(characters.data(), length); |
| - // TODO(xiaochengh): Iterative prepending has quadratic running |
| - // time in the worst case. Should improve it to linear. |
| - string.prepend(characters.data() + i, length - i); |
| + prefixString.push(characters.data() + i, length - i); |
| prefixLength += length - i; |
| if (i > 0) |
| break; |
| @@ -766,6 +760,9 @@ static VisiblePositionTemplate<Strategy> nextBoundary(const VisiblePositionTempl |
| } |
| } |
| + ForwardsTextAccumulator string; |
| + string.push(prefixString.data(), prefixString.size()); |
| + |
| const PositionTemplate<Strategy> searchStart = PositionTemplate<Strategy>::editingPositionOf(start.anchorNode(), start.offsetInContainerNode()); |
| const PositionTemplate<Strategy> searchEnd = PositionTemplate<Strategy>::lastPositionInNode(boundary); |
| TextIteratorAlgorithm<Strategy> it(searchStart, searchEnd, TextIteratorEmitsCharactersBetweenAllVisiblePositions); |
| @@ -777,20 +774,11 @@ static VisiblePositionTemplate<Strategy> nextBoundary(const VisiblePositionTempl |
| // Keep asking the iterator for chunks until the search function |
| // returns an end value not equal to the length of the string passed to |
| // it. |
| - bool inTextSecurityMode = it.isInTextSecurityMode(); |
| - if (!inTextSecurityMode) { |
| - it.copyTextTo(string); |
| - } else { |
| - // Treat bullets used in the text security mode as regular |
| - // characters when looking for boundaries |
| - Vector<UChar, 1024> iteratorString; |
| - iteratorString.fill('x', it.length()); |
| - string.append(iteratorString.data(), iteratorString.size()); |
| - } |
| + string.extract(it); |
| next = searchFunction(string.data(), string.size(), offset, MayHaveMoreContext, needMoreContext); |
| if (next != string.size()) |
| break; |
| - it.advance(); |
| + string.advance(it); |
| if (!needMoreContext) { |
| // When the search does not need more context, skip all examined |
| // characters except the last one, in case it is a boundary. |