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 |