| Index: third_party/WebKit/Source/core/editing/markers/DocumentMarkerController.cpp
|
| diff --git a/third_party/WebKit/Source/core/editing/markers/DocumentMarkerController.cpp b/third_party/WebKit/Source/core/editing/markers/DocumentMarkerController.cpp
|
| index 83cfe300c393880ca47410674913ef6b096fea6b..73a528db31283e59a3b206cfb424762253538936 100644
|
| --- a/third_party/WebKit/Source/core/editing/markers/DocumentMarkerController.cpp
|
| +++ b/third_party/WebKit/Source/core/editing/markers/DocumentMarkerController.cpp
|
| @@ -138,31 +138,19 @@ void DocumentMarkerController::AddSpellCheckMarker(
|
| const String& description) {
|
| DCHECK(type == DocumentMarker::kSpelling || type == DocumentMarker::kGrammar)
|
| << type;
|
| - // Use a TextIterator to visit the potentially multiple nodes the range
|
| - // covers.
|
| - for (TextIterator marked_text(range.StartPosition(), range.EndPosition());
|
| - !marked_text.AtEnd(); marked_text.Advance()) {
|
| - AddMarker(marked_text.CurrentContainer(),
|
| - new DocumentMarker(
|
| - type, marked_text.StartOffsetInCurrentContainer(),
|
| - marked_text.EndOffsetInCurrentContainer(), description));
|
| - }
|
| + AddMarkerInternal(
|
| + range, [type, &description](int start_offset, int end_offset) {
|
| + return new DocumentMarker(type, start_offset, end_offset, description);
|
| + });
|
| }
|
|
|
| void DocumentMarkerController::AddTextMatchMarker(
|
| const EphemeralRange& range,
|
| DocumentMarker::MatchStatus match_status) {
|
| DCHECK(!document_->NeedsLayoutTreeUpdate());
|
| -
|
| - // Use a TextIterator to visit the potentially multiple nodes the range
|
| - // covers.
|
| - for (TextIterator marked_text(range.StartPosition(), range.EndPosition());
|
| - !marked_text.AtEnd(); marked_text.Advance()) {
|
| - AddMarker(marked_text.CurrentContainer(),
|
| - new TextMatchMarker(marked_text.StartOffsetInCurrentContainer(),
|
| - marked_text.EndOffsetInCurrentContainer(),
|
| - match_status));
|
| - }
|
| + AddMarkerInternal(range, [match_status](int start_offset, int end_offset) {
|
| + return new TextMatchMarker(start_offset, end_offset, match_status);
|
| + });
|
| // Don't invalidate tickmarks here. TextFinder invalidates tickmarks using a
|
| // throttling algorithm. crbug.com/6819.
|
| }
|
| @@ -172,14 +160,11 @@ void DocumentMarkerController::AddCompositionMarker(const EphemeralRange& range,
|
| bool thick,
|
| Color background_color) {
|
| DCHECK(!document_->NeedsLayoutTreeUpdate());
|
| -
|
| - for (TextIterator marked_text(range.StartPosition(), range.EndPosition());
|
| - !marked_text.AtEnd(); marked_text.Advance()) {
|
| - AddMarker(marked_text.CurrentContainer(),
|
| - new DocumentMarker(marked_text.StartOffsetInCurrentContainer(),
|
| - marked_text.EndOffsetInCurrentContainer(),
|
| - underline_color, thick, background_color));
|
| - }
|
| + AddMarkerInternal(range, [underline_color, thick, background_color](
|
| + int start_offset, int end_offset) {
|
| + return new DocumentMarker(start_offset, end_offset, underline_color, thick,
|
| + background_color);
|
| + });
|
| }
|
|
|
| void DocumentMarkerController::PrepareForDestruction() {
|
| @@ -210,15 +195,41 @@ void DocumentMarkerController::RemoveMarkersInRange(
|
| DocumentMarkerController::RemoveMarkers(marked_text, marker_types);
|
| }
|
|
|
| -// Markers are stored in order sorted by their start offset.
|
| -// Markers of the same type do not overlap each other.
|
| +void DocumentMarkerController::AddMarkerInternal(
|
| + const EphemeralRange& range,
|
| + std::function<DocumentMarker*(int, int)> create_marker_from_offsets) {
|
| + for (TextIterator marked_text(range.StartPosition(), range.EndPosition());
|
| + !marked_text.AtEnd(); marked_text.Advance()) {
|
| + const int start_offset_in_current_container =
|
| + marked_text.StartOffsetInCurrentContainer();
|
| + const int end_offset_in_current_container =
|
| + marked_text.EndOffsetInCurrentContainer();
|
| +
|
| + DCHECK_GE(end_offset_in_current_container,
|
| + start_offset_in_current_container);
|
| +
|
| + // TODO(editing-dev): TextIterator sometimes emits ranges where the start
|
| + // and end offsets are the same. Investigate if TextIterator should be
|
| + // changed to not do this. See crbug.com/727929
|
| + if (end_offset_in_current_container == start_offset_in_current_container)
|
| + continue;
|
|
|
| -void DocumentMarkerController::AddMarker(Node* node,
|
| - DocumentMarker* new_marker) {
|
| - DCHECK_GE(new_marker->EndOffset(), new_marker->StartOffset());
|
| - if (new_marker->EndOffset() == new_marker->StartOffset())
|
| - return;
|
| + // Ignore text emitted by TextIterator for non-text nodes (e.g. implicit
|
| + // newlines)
|
| + Node* const node = marked_text.CurrentContainer();
|
| + if (!node->IsTextNode())
|
| + continue;
|
| +
|
| + DocumentMarker* const new_marker = create_marker_from_offsets(
|
| + start_offset_in_current_container, end_offset_in_current_container);
|
| + AddMarkerToNode(node, new_marker);
|
| + }
|
| +}
|
|
|
| +// Markers are stored in order sorted by their start offset.
|
| +// Markers of the same type do not overlap each other.
|
| +void DocumentMarkerController::AddMarkerToNode(Node* node,
|
| + DocumentMarker* new_marker) {
|
| possibly_existing_marker_types_.Add(new_marker->GetType());
|
|
|
| Member<MarkerLists>& markers =
|
|
|