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 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 134 AddSpellCheckMarker(start, end, DocumentMarker::kGrammar, description); | 134 AddSpellCheckMarker(start, end, DocumentMarker::kGrammar, description); |
| 135 } | 135 } |
| 136 | 136 |
| 137 void DocumentMarkerController::AddSpellCheckMarker( | 137 void DocumentMarkerController::AddSpellCheckMarker( |
| 138 const Position& start, | 138 const Position& start, |
| 139 const Position& end, | 139 const Position& end, |
| 140 DocumentMarker::MarkerType type, | 140 DocumentMarker::MarkerType type, |
| 141 const String& description) { | 141 const String& description) { |
| 142 DCHECK(type == DocumentMarker::kSpelling || type == DocumentMarker::kGrammar) | 142 DCHECK(type == DocumentMarker::kSpelling || type == DocumentMarker::kGrammar) |
| 143 << type; | 143 << type; |
| 144 // Use a TextIterator to visit the potentially multiple nodes the range | 144 AddMarkerInternal(EphemeralRange(start, end), |
| 145 // covers. | 145 [type, &description](int start_offset, int end_offset) { |
| 146 for (TextIterator marked_text(start, end); !marked_text.AtEnd(); | 146 return new DocumentMarker(type, start_offset, end_offset, |
| 147 marked_text.Advance()) { | 147 description); |
| 148 AddMarker(marked_text.CurrentContainer(), | 148 }); |
| 149 new DocumentMarker( | |
| 150 type, marked_text.StartOffsetInCurrentContainer(), | |
| 151 marked_text.EndOffsetInCurrentContainer(), description)); | |
| 152 } | |
| 153 } | 149 } |
| 154 | 150 |
| 155 void DocumentMarkerController::AddTextMatchMarker( | 151 void DocumentMarkerController::AddTextMatchMarker( |
| 156 const EphemeralRange& range, | 152 const EphemeralRange& range, |
| 157 DocumentMarker::MatchStatus match_status) { | 153 DocumentMarker::MatchStatus match_status) { |
| 158 DCHECK(!document_->NeedsLayoutTreeUpdate()); | 154 DCHECK(!document_->NeedsLayoutTreeUpdate()); |
| 159 | 155 AddMarkerInternal(range, [match_status](int start_offset, int end_offset) { |
| 160 // Use a TextIterator to visit the potentially multiple nodes the range | 156 return new DocumentMarker(start_offset, end_offset, match_status); |
| 161 // covers. | 157 }); |
| 162 for (TextIterator marked_text(range.StartPosition(), range.EndPosition()); | |
| 163 !marked_text.AtEnd(); marked_text.Advance()) { | |
| 164 AddMarker(marked_text.CurrentContainer(), | |
| 165 new DocumentMarker(marked_text.StartOffsetInCurrentContainer(), | |
| 166 marked_text.EndOffsetInCurrentContainer(), | |
| 167 match_status)); | |
| 168 } | |
| 169 // Don't invalidate tickmarks here. TextFinder invalidates tickmarks using a | 158 // Don't invalidate tickmarks here. TextFinder invalidates tickmarks using a |
| 170 // throttling algorithm. crbug.com/6819. | 159 // throttling algorithm. crbug.com/6819. |
| 171 } | 160 } |
| 172 | 161 |
| 173 void DocumentMarkerController::AddCompositionMarker(const EphemeralRange& range, | 162 void DocumentMarkerController::AddCompositionMarker(const EphemeralRange& range, |
| 174 Color underline_color, | 163 Color underline_color, |
| 175 bool thick, | 164 bool thick, |
| 176 Color background_color) { | 165 Color background_color) { |
| 177 DCHECK(!document_->NeedsLayoutTreeUpdate()); | 166 DCHECK(!document_->NeedsLayoutTreeUpdate()); |
| 178 | 167 AddMarkerInternal(range, [underline_color, thick, background_color]( |
| 179 for (TextIterator marked_text(range.StartPosition(), range.EndPosition()); | 168 int start_offset, int end_offset) { |
| 180 !marked_text.AtEnd(); marked_text.Advance()) { | 169 return new DocumentMarker(start_offset, end_offset, underline_color, thick, |
| 181 AddMarker(marked_text.CurrentContainer(), | 170 background_color); |
| 182 new DocumentMarker(marked_text.StartOffsetInCurrentContainer(), | 171 }); |
| 183 marked_text.EndOffsetInCurrentContainer(), | |
| 184 underline_color, thick, background_color)); | |
| 185 } | |
| 186 } | 172 } |
| 187 | 173 |
| 188 void DocumentMarkerController::PrepareForDestruction() { | 174 void DocumentMarkerController::PrepareForDestruction() { |
| 189 Clear(); | 175 Clear(); |
| 190 } | 176 } |
| 191 | 177 |
| 192 void DocumentMarkerController::RemoveMarkers( | 178 void DocumentMarkerController::RemoveMarkers( |
| 193 TextIterator& marked_text, | 179 TextIterator& marked_text, |
| 194 DocumentMarker::MarkerTypes marker_types) { | 180 DocumentMarker::MarkerTypes marker_types) { |
| 195 for (; !marked_text.AtEnd(); marked_text.Advance()) { | 181 for (; !marked_text.AtEnd(); marked_text.Advance()) { |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 206 | 192 |
| 207 void DocumentMarkerController::RemoveMarkersInRange( | 193 void DocumentMarkerController::RemoveMarkersInRange( |
| 208 const EphemeralRange& range, | 194 const EphemeralRange& range, |
| 209 DocumentMarker::MarkerTypes marker_types) { | 195 DocumentMarker::MarkerTypes marker_types) { |
| 210 DCHECK(!document_->NeedsLayoutTreeUpdate()); | 196 DCHECK(!document_->NeedsLayoutTreeUpdate()); |
| 211 | 197 |
| 212 TextIterator marked_text(range.StartPosition(), range.EndPosition()); | 198 TextIterator marked_text(range.StartPosition(), range.EndPosition()); |
| 213 DocumentMarkerController::RemoveMarkers(marked_text, marker_types); | 199 DocumentMarkerController::RemoveMarkers(marked_text, marker_types); |
| 214 } | 200 } |
| 215 | 201 |
| 202 void DocumentMarkerController::AddMarkerInternal( | |
| 203 const EphemeralRange& range, | |
| 204 std::function<DocumentMarker*(int, int)> create_marker_from_offsets) { | |
| 205 for (TextIterator marked_text(range.StartPosition(), range.EndPosition()); | |
| 206 !marked_text.AtEnd(); marked_text.Advance()) { | |
| 207 const int start_offset_in_current_container = | |
| 208 marked_text.StartOffsetInCurrentContainer(); | |
| 209 const int end_offset_in_current_container = | |
| 210 marked_text.EndOffsetInCurrentContainer(); | |
| 211 | |
| 212 DCHECK_GE(end_offset_in_current_container, | |
| 213 start_offset_in_current_container); | |
| 214 | |
| 215 // 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
| |
| 216 // container isn't a text node, or where the start and end offsets are the | |
| 217 // same. Investigate if TextIterator should be changed to not do this. See | |
| 218 // crbug.com/727929 | |
| 219 if (end_offset_in_current_container == start_offset_in_current_container) | |
| 220 continue; | |
| 221 Node* node = marked_text.CurrentContainer(); | |
| 222 if (!node->IsTextNode()) | |
| 223 continue; | |
| 224 | |
| 225 DocumentMarker* const new_marker = create_marker_from_offsets( | |
| 226 start_offset_in_current_container, end_offset_in_current_container); | |
| 227 AddMarkerToNode(node, new_marker); | |
| 228 } | |
| 229 } | |
| 230 | |
| 216 // Markers are stored in order sorted by their start offset. | 231 // Markers are stored in order sorted by their start offset. |
| 217 // Markers of the same type do not overlap each other. | 232 // Markers of the same type do not overlap each other. |
| 218 | 233 void DocumentMarkerController::AddMarkerToNode(Node* node, |
| 219 void DocumentMarkerController::AddMarker(Node* node, | 234 DocumentMarker* new_marker) { |
| 220 DocumentMarker* new_marker) { | |
| 221 DCHECK_GE(new_marker->EndOffset(), new_marker->StartOffset()); | |
| 222 if (new_marker->EndOffset() == new_marker->StartOffset()) | |
| 223 return; | |
| 224 | |
| 225 possibly_existing_marker_types_.Add(new_marker->GetType()); | 235 possibly_existing_marker_types_.Add(new_marker->GetType()); |
| 226 | 236 |
| 227 Member<MarkerLists>& markers = | 237 Member<MarkerLists>& markers = |
| 228 markers_.insert(node, nullptr).stored_value->value; | 238 markers_.insert(node, nullptr).stored_value->value; |
| 229 if (!markers) { | 239 if (!markers) { |
| 230 markers = new MarkerLists; | 240 markers = new MarkerLists; |
| 231 markers->Grow(DocumentMarker::kMarkerTypeIndexesCount); | 241 markers->Grow(DocumentMarker::kMarkerTypeIndexesCount); |
| 232 } | 242 } |
| 233 | 243 |
| 234 const DocumentMarker::MarkerType new_marker_type = new_marker->GetType(); | 244 const DocumentMarker::MarkerType new_marker_type = new_marker->GetType(); |
| (...skipping 473 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 708 } | 718 } |
| 709 | 719 |
| 710 } // namespace blink | 720 } // namespace blink |
| 711 | 721 |
| 712 #ifndef NDEBUG | 722 #ifndef NDEBUG |
| 713 void showDocumentMarkers(const blink::DocumentMarkerController* controller) { | 723 void showDocumentMarkers(const blink::DocumentMarkerController* controller) { |
| 714 if (controller) | 724 if (controller) |
| 715 controller->ShowMarkers(); | 725 controller->ShowMarkers(); |
| 716 } | 726 } |
| 717 #endif | 727 #endif |
| OLD | NEW |