Chromium Code Reviews| 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 68b952a8a981242ea5f6b104b1bb30cbd84d0b57..cac277b16ccdbcb602d150ac00ef0fa89e703042 100644 |
| --- a/third_party/WebKit/Source/core/editing/markers/DocumentMarkerController.cpp |
| +++ b/third_party/WebKit/Source/core/editing/markers/DocumentMarkerController.cpp |
| @@ -141,31 +141,20 @@ 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(start, end); !marked_text.AtEnd(); |
| - marked_text.Advance()) { |
| - AddMarker(marked_text.CurrentContainer(), |
| - new DocumentMarker( |
| - type, marked_text.StartOffsetInCurrentContainer(), |
| - marked_text.EndOffsetInCurrentContainer(), description)); |
| - } |
| + AddMarkerInternal(EphemeralRange(start, end), |
| + [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 DocumentMarker(marked_text.StartOffsetInCurrentContainer(), |
| - marked_text.EndOffsetInCurrentContainer(), |
| - match_status)); |
| - } |
| + AddMarkerInternal(range, [match_status](int start_offset, int end_offset) { |
| + return new DocumentMarker(start_offset, end_offset, match_status); |
| + }); |
| // Don't invalidate tickmarks here. TextFinder invalidates tickmarks using a |
| // throttling algorithm. crbug.com/6819. |
| } |
| @@ -175,14 +164,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() { |
| @@ -213,15 +199,39 @@ 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 current |
|
Xiaocheng
2017/05/30 23:51:19
Emitting text with non-text container is legit. Fo
rlanday
2017/05/30 23:52:27
It does mention the equal-offset issue; I will upd
|
| + // container isn't a text node, or 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; |
| + Node* node = marked_text.CurrentContainer(); |
| + if (!node->IsTextNode()) |
| + 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; |
| + 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 = |