Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) | 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) |
| 3 * (C) 1999 Antti Koivisto (koivisto@kde.org) | 3 * (C) 1999 Antti Koivisto (koivisto@kde.org) |
| 4 * (C) 2001 Dirk Mueller (mueller@kde.org) | 4 * (C) 2001 Dirk Mueller (mueller@kde.org) |
| 5 * (C) 2006 Alexey Proskuryakov (ap@webkit.org) | 5 * (C) 2006 Alexey Proskuryakov (ap@webkit.org) |
| 6 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights | 6 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights |
| 7 * reserved. | 7 * reserved. |
| 8 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. | 8 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. |
| 9 * (http://www.torchmobile.com/) | 9 * (http://www.torchmobile.com/) |
| 10 * Copyright (C) Research In Motion Limited 2010. All rights reserved. | 10 * Copyright (C) Research In Motion Limited 2010. All rights reserved. |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 131 const String& description) { | 131 const String& description) { |
| 132 AddSpellCheckMarker(range, DocumentMarker::kGrammar, description); | 132 AddSpellCheckMarker(range, DocumentMarker::kGrammar, description); |
| 133 } | 133 } |
| 134 | 134 |
| 135 void DocumentMarkerController::AddSpellCheckMarker( | 135 void DocumentMarkerController::AddSpellCheckMarker( |
| 136 const EphemeralRange& range, | 136 const EphemeralRange& range, |
| 137 DocumentMarker::MarkerType type, | 137 DocumentMarker::MarkerType type, |
| 138 const String& description) { | 138 const String& description) { |
| 139 DCHECK(type == DocumentMarker::kSpelling || type == DocumentMarker::kGrammar) | 139 DCHECK(type == DocumentMarker::kSpelling || type == DocumentMarker::kGrammar) |
| 140 << type; | 140 << type; |
| 141 // Use a TextIterator to visit the potentially multiple nodes the range | 141 AddMarkerInternal( |
| 142 // covers. | 142 range, [type, &description](int start_offset, int end_offset) { |
| 143 for (TextIterator marked_text(range.StartPosition(), range.EndPosition()); | 143 return new DocumentMarker(type, start_offset, end_offset, description); |
| 144 !marked_text.AtEnd(); marked_text.Advance()) { | 144 }); |
| 145 AddMarker(marked_text.CurrentContainer(), | |
| 146 new DocumentMarker( | |
| 147 type, marked_text.StartOffsetInCurrentContainer(), | |
| 148 marked_text.EndOffsetInCurrentContainer(), description)); | |
| 149 } | |
| 150 } | 145 } |
| 151 | 146 |
| 152 void DocumentMarkerController::AddTextMatchMarker( | 147 void DocumentMarkerController::AddTextMatchMarker( |
| 153 const EphemeralRange& range, | 148 const EphemeralRange& range, |
| 154 DocumentMarker::MatchStatus match_status) { | 149 DocumentMarker::MatchStatus match_status) { |
| 155 DCHECK(!document_->NeedsLayoutTreeUpdate()); | 150 DCHECK(!document_->NeedsLayoutTreeUpdate()); |
| 156 | 151 AddMarkerInternal(range, [match_status](int start_offset, int end_offset) { |
| 157 // Use a TextIterator to visit the potentially multiple nodes the range | 152 return new DocumentMarker(start_offset, end_offset, match_status); |
| 158 // covers. | 153 }); |
| 159 for (TextIterator marked_text(range.StartPosition(), range.EndPosition()); | |
| 160 !marked_text.AtEnd(); marked_text.Advance()) { | |
| 161 AddMarker(marked_text.CurrentContainer(), | |
| 162 new DocumentMarker(marked_text.StartOffsetInCurrentContainer(), | |
| 163 marked_text.EndOffsetInCurrentContainer(), | |
| 164 match_status)); | |
| 165 } | |
| 166 // Don't invalidate tickmarks here. TextFinder invalidates tickmarks using a | 154 // Don't invalidate tickmarks here. TextFinder invalidates tickmarks using a |
| 167 // throttling algorithm. crbug.com/6819. | 155 // throttling algorithm. crbug.com/6819. |
| 168 } | 156 } |
| 169 | 157 |
| 170 void DocumentMarkerController::AddCompositionMarker(const EphemeralRange& range, | 158 void DocumentMarkerController::AddCompositionMarker(const EphemeralRange& range, |
| 171 Color underline_color, | 159 Color underline_color, |
| 172 bool thick, | 160 bool thick, |
| 173 Color background_color) { | 161 Color background_color) { |
| 174 DCHECK(!document_->NeedsLayoutTreeUpdate()); | 162 DCHECK(!document_->NeedsLayoutTreeUpdate()); |
| 175 | 163 AddMarkerInternal(range, [underline_color, thick, background_color]( |
| 176 for (TextIterator marked_text(range.StartPosition(), range.EndPosition()); | 164 int start_offset, int end_offset) { |
| 177 !marked_text.AtEnd(); marked_text.Advance()) { | 165 return new DocumentMarker(start_offset, end_offset, underline_color, thick, |
| 178 AddMarker(marked_text.CurrentContainer(), | 166 background_color); |
| 179 new DocumentMarker(marked_text.StartOffsetInCurrentContainer(), | 167 }); |
| 180 marked_text.EndOffsetInCurrentContainer(), | |
| 181 underline_color, thick, background_color)); | |
| 182 } | |
| 183 } | 168 } |
| 184 | 169 |
| 185 void DocumentMarkerController::PrepareForDestruction() { | 170 void DocumentMarkerController::PrepareForDestruction() { |
| 186 Clear(); | 171 Clear(); |
| 187 } | 172 } |
| 188 | 173 |
| 189 void DocumentMarkerController::RemoveMarkers( | 174 void DocumentMarkerController::RemoveMarkers( |
| 190 TextIterator& marked_text, | 175 TextIterator& marked_text, |
| 191 DocumentMarker::MarkerTypes marker_types) { | 176 DocumentMarker::MarkerTypes marker_types) { |
| 192 for (; !marked_text.AtEnd(); marked_text.Advance()) { | 177 for (; !marked_text.AtEnd(); marked_text.Advance()) { |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 203 | 188 |
| 204 void DocumentMarkerController::RemoveMarkersInRange( | 189 void DocumentMarkerController::RemoveMarkersInRange( |
| 205 const EphemeralRange& range, | 190 const EphemeralRange& range, |
| 206 DocumentMarker::MarkerTypes marker_types) { | 191 DocumentMarker::MarkerTypes marker_types) { |
| 207 DCHECK(!document_->NeedsLayoutTreeUpdate()); | 192 DCHECK(!document_->NeedsLayoutTreeUpdate()); |
| 208 | 193 |
| 209 TextIterator marked_text(range.StartPosition(), range.EndPosition()); | 194 TextIterator marked_text(range.StartPosition(), range.EndPosition()); |
| 210 DocumentMarkerController::RemoveMarkers(marked_text, marker_types); | 195 DocumentMarkerController::RemoveMarkers(marked_text, marker_types); |
| 211 } | 196 } |
| 212 | 197 |
| 198 void DocumentMarkerController::AddMarkerInternal( | |
| 199 const EphemeralRange& range, | |
| 200 std::function<DocumentMarker*(int, int)> create_marker_from_offsets) { | |
| 201 for (TextIterator marked_text(range.StartPosition(), range.EndPosition()); | |
|
yosin_UTC9
2017/05/31 02:01:13
FYI: It is nice that we have TextIterator::begin()
| |
| 202 !marked_text.AtEnd(); marked_text.Advance()) { | |
| 203 const int start_offset_in_current_container = | |
| 204 marked_text.StartOffsetInCurrentContainer(); | |
| 205 const int end_offset_in_current_container = | |
| 206 marked_text.EndOffsetInCurrentContainer(); | |
| 207 | |
| 208 DCHECK_GE(end_offset_in_current_container, | |
| 209 start_offset_in_current_container); | |
| 210 | |
| 211 // TODO(editing-dev): TextIterator sometimes emits ranges where the start | |
| 212 // and end offsets are the same. Investigate if TextIterator should be | |
| 213 // changed to not do this. See crbug.com/727929 | |
| 214 if (end_offset_in_current_container == start_offset_in_current_container) | |
| 215 continue; | |
| 216 | |
| 217 // Ignore text emitted by TextIterator for non-text nodes (e.g. implicit | |
| 218 // newlines) | |
| 219 Node* node = marked_text.CurrentContainer(); | |
|
yosin_UTC9
2017/05/31 02:01:14
nit: s/Node*/Node* const/
| |
| 220 if (!node->IsTextNode()) | |
| 221 continue; | |
| 222 | |
| 223 DocumentMarker* const new_marker = create_marker_from_offsets( | |
| 224 start_offset_in_current_container, end_offset_in_current_container); | |
| 225 AddMarkerToNode(node, new_marker); | |
| 226 } | |
| 227 } | |
| 228 | |
| 213 // Markers are stored in order sorted by their start offset. | 229 // Markers are stored in order sorted by their start offset. |
| 214 // Markers of the same type do not overlap each other. | 230 // Markers of the same type do not overlap each other. |
| 215 | 231 void DocumentMarkerController::AddMarkerToNode(Node* node, |
| 216 void DocumentMarkerController::AddMarker(Node* node, | 232 DocumentMarker* new_marker) { |
| 217 DocumentMarker* new_marker) { | |
| 218 DCHECK_GE(new_marker->EndOffset(), new_marker->StartOffset()); | |
| 219 if (new_marker->EndOffset() == new_marker->StartOffset()) | |
| 220 return; | |
| 221 | |
| 222 possibly_existing_marker_types_.Add(new_marker->GetType()); | 233 possibly_existing_marker_types_.Add(new_marker->GetType()); |
| 223 | 234 |
| 224 Member<MarkerLists>& markers = | 235 Member<MarkerLists>& markers = |
| 225 markers_.insert(node, nullptr).stored_value->value; | 236 markers_.insert(node, nullptr).stored_value->value; |
| 226 if (!markers) { | 237 if (!markers) { |
| 227 markers = new MarkerLists; | 238 markers = new MarkerLists; |
| 228 markers->Grow(DocumentMarker::kMarkerTypeIndexesCount); | 239 markers->Grow(DocumentMarker::kMarkerTypeIndexesCount); |
| 229 } | 240 } |
| 230 | 241 |
| 231 const DocumentMarker::MarkerType new_marker_type = new_marker->GetType(); | 242 const DocumentMarker::MarkerType new_marker_type = new_marker->GetType(); |
| (...skipping 473 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 705 } | 716 } |
| 706 | 717 |
| 707 } // namespace blink | 718 } // namespace blink |
| 708 | 719 |
| 709 #ifndef NDEBUG | 720 #ifndef NDEBUG |
| 710 void showDocumentMarkers(const blink::DocumentMarkerController* controller) { | 721 void showDocumentMarkers(const blink::DocumentMarkerController* controller) { |
| 711 if (controller) | 722 if (controller) |
| 712 controller->ShowMarkers(); | 723 controller->ShowMarkers(); |
| 713 } | 724 } |
| 714 #endif | 725 #endif |
| OLD | NEW |