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 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
70 case DocumentMarker::kComposition: | 70 case DocumentMarker::kComposition: |
71 return DocumentMarker::kCompositionMarkerIndex; | 71 return DocumentMarker::kCompositionMarkerIndex; |
72 } | 72 } |
73 | 73 |
74 NOTREACHED(); | 74 NOTREACHED(); |
75 return DocumentMarker::kSpellingMarkerIndex; | 75 return DocumentMarker::kSpellingMarkerIndex; |
76 } | 76 } |
77 | 77 |
78 } // namespace | 78 } // namespace |
79 | 79 |
80 static bool StartsFurther(const Member<DocumentMarker>& lhv, | |
81 const DocumentMarker* rhv) { | |
82 return lhv->StartOffset() < rhv->StartOffset(); | |
83 } | |
84 | |
85 static bool EndsBefore(size_t start_offset, const Member<DocumentMarker>& rhv) { | |
86 return start_offset < rhv->EndOffset(); | |
87 } | |
88 | |
89 static bool CompareByStart(const Member<DocumentMarker>& lhv, | |
90 const Member<DocumentMarker>& rhv) { | |
91 return lhv->StartOffset() < rhv->StartOffset(); | |
92 } | |
93 | |
94 static bool DoesNotOverlap(const Member<DocumentMarker>& lhv, | |
95 const DocumentMarker* rhv) { | |
96 return lhv->EndOffset() < rhv->StartOffset(); | |
97 } | |
98 | |
99 bool DocumentMarkerList::IsEmpty() const { | |
100 return markers_.IsEmpty(); | |
101 } | |
102 | |
103 void DocumentMarkerList::Add(DocumentMarker* marker) { | |
104 if (markers_.IsEmpty() || | |
105 markers_.back()->EndOffset() < marker->StartOffset()) { | |
106 markers_.push_back(marker); | |
107 } else { | |
108 if (marker->GetType() != DocumentMarker::kTextMatch && | |
109 marker->GetType() != DocumentMarker::kComposition) { | |
110 MergeOverlapping(marker); | |
111 } else { | |
112 const auto pos = std::lower_bound(markers_.begin(), markers_.end(), | |
113 marker, StartsFurther); | |
114 markers_.insert(pos - markers_.begin(), marker); | |
115 } | |
116 } | |
117 } | |
118 | |
119 void DocumentMarkerList::Clear() { | |
120 markers_.Clear(); | |
121 } | |
122 | |
123 void DocumentMarkerList::AppendMarkersToInputList( | |
124 DocumentMarkerVector* input_list) const { | |
125 input_list->AppendVector(markers_); | |
126 } | |
127 | |
128 bool DocumentMarkerList::MoveMarkers(int length, DocumentMarkerList* dst_list) { | |
129 DCHECK_GT(length, 0); | |
130 bool didMoveMarker = false; | |
131 unsigned end_offset = length - 1; | |
132 | |
133 DocumentMarkerVector::iterator it; | |
134 for (it = markers_.begin(); it != markers_.end(); ++it) { | |
135 DocumentMarker& marker = **it; | |
136 if (marker.StartOffset() > end_offset) | |
137 break; | |
138 | |
139 // pin the marker to the specified range and apply the shift delta | |
140 if (marker.EndOffset() > end_offset) | |
141 marker.SetEndOffset(end_offset); | |
142 | |
143 dst_list->Add(&marker); | |
144 didMoveMarker = true; | |
145 } | |
146 | |
147 // Remove the range of markers that were moved to dstNode | |
148 markers_.erase(0, it - markers_.begin()); | |
149 | |
150 return didMoveMarker; | |
151 } | |
152 | |
153 bool DocumentMarkerList::RemoveMarkers(unsigned start_offset, int length) { | |
154 unsigned end_offset = start_offset + length; | |
155 | |
156 const auto startPos = std::upper_bound(markers_.begin(), markers_.end(), | |
157 start_offset, EndsBefore); | |
158 auto it = startPos; | |
159 for (; it != markers_.end(); ++it) { | |
160 if ((*it)->StartOffset() >= end_offset) | |
161 break; | |
162 } | |
163 | |
164 // it should now point at the first marker *not* to be removed (or at | |
165 // markers_->end()) | |
166 markers_.erase(startPos - markers_.begin(), it - startPos); | |
167 | |
168 if (it == startPos) | |
169 return false; | |
170 | |
171 return true; | |
172 } | |
173 | |
174 bool DocumentMarkerList::ShiftMarkers(unsigned offset, | |
175 unsigned old_length, | |
176 unsigned new_length) { | |
177 DocumentMarkerVector newMarkerList; | |
178 bool didShiftMarker = false; | |
179 for (Member<DocumentMarker> marker : markers_) { | |
180 Optional<DocumentMarker::MarkerOffsets> result = | |
181 marker->ComputeOffsetsAfterShift(offset, old_length, new_length); | |
182 | |
183 if (result == WTF::kNullopt) { | |
184 didShiftMarker = true; | |
185 continue; | |
186 } | |
187 | |
188 if (result.value().start_offset != marker->StartOffset() || | |
189 result.value().end_offset != marker->EndOffset()) { | |
190 marker->SetStartOffset(result.value().start_offset); | |
191 marker->SetEndOffset(result.value().end_offset); | |
192 | |
193 didShiftMarker = true; | |
194 } | |
195 | |
196 newMarkerList.push_back(marker); | |
197 } | |
198 | |
199 swap(markers_, newMarkerList); | |
200 return didShiftMarker; | |
201 } | |
202 | |
203 void DocumentMarkerList::MergeOverlapping(DocumentMarker* marker) { | |
204 auto first_overlapping = std::lower_bound(markers_.begin(), markers_.end(), | |
205 marker, DoesNotOverlap); | |
206 size_t index = first_overlapping - markers_.begin(); | |
207 markers_.insert(index, marker); | |
208 const auto inserted = markers_.begin() + index; | |
209 first_overlapping = inserted + 1; | |
210 for (auto i = first_overlapping; | |
211 i != markers_.end() && | |
212 (*i)->StartOffset() <= (*inserted)->EndOffset();) { | |
213 (*inserted)->SetStartOffset( | |
214 std::min((*inserted)->StartOffset(), (*i)->StartOffset())); | |
215 (*inserted)->SetEndOffset( | |
216 std::max((*inserted)->EndOffset(), (*i)->EndOffset())); | |
217 markers_.erase(i - markers_.begin()); | |
218 } | |
219 } | |
220 | |
221 DEFINE_TRACE(DocumentMarkerList) { | |
222 visitor->Trace(markers_); | |
223 } | |
224 | |
80 inline bool DocumentMarkerController::PossiblyHasMarkers( | 225 inline bool DocumentMarkerController::PossiblyHasMarkers( |
81 DocumentMarker::MarkerTypes types) { | 226 DocumentMarker::MarkerTypes types) { |
82 return possibly_existing_marker_types_.Intersects(types); | 227 return possibly_existing_marker_types_.Intersects(types); |
83 } | 228 } |
84 | 229 |
85 DocumentMarkerController::DocumentMarkerController(Document& document) | 230 DocumentMarkerController::DocumentMarkerController(Document& document) |
86 : possibly_existing_marker_types_(0), document_(&document) { | 231 : possibly_existing_marker_types_(0), document_(&document) { |
87 SetContext(&document); | 232 SetContext(&document); |
88 } | 233 } |
89 | 234 |
90 void DocumentMarkerController::Clear() { | 235 void DocumentMarkerController::Clear() { |
91 markers_.Clear(); | 236 markers_.Clear(); |
92 possibly_existing_marker_types_ = 0; | 237 possibly_existing_marker_types_ = 0; |
93 } | 238 } |
94 | 239 |
95 void DocumentMarkerController::AddMarker(const Position& start, | 240 void DocumentMarkerController::AddMarker(const Position& start, |
96 const Position& end, | 241 const Position& end, |
97 DocumentMarker::MarkerType type, | 242 DocumentMarker::MarkerType type, |
98 const String& description) { | 243 const String& description) { |
99 // Use a TextIterator to visit the potentially multiple nodes the range | 244 // Use a TextIterator to visit the potentially multiple nodes the range |
100 // covers. | 245 // covers. |
101 for (TextIterator marked_text(start, end); !marked_text.AtEnd(); | 246 for (TextIterator marked_text(start, end); !marked_text.AtEnd(); |
102 marked_text.Advance()) { | 247 marked_text.Advance()) { |
103 AddMarker( | 248 AddMarker(marked_text.CurrentContainer(), |
104 marked_text.CurrentContainer(), | 249 new DocumentMarker( |
105 DocumentMarker(type, marked_text.StartOffsetInCurrentContainer(), | 250 type, marked_text.StartOffsetInCurrentContainer(), |
106 marked_text.EndOffsetInCurrentContainer(), description)); | 251 marked_text.EndOffsetInCurrentContainer(), description)); |
107 } | 252 } |
108 } | 253 } |
109 | 254 |
110 void DocumentMarkerController::AddTextMatchMarker( | 255 void DocumentMarkerController::AddTextMatchMarker( |
111 const EphemeralRange& range, | 256 const EphemeralRange& range, |
112 DocumentMarker::MatchStatus match_status) { | 257 DocumentMarker::MatchStatus match_status) { |
113 DCHECK(!document_->NeedsLayoutTreeUpdate()); | 258 DCHECK(!document_->NeedsLayoutTreeUpdate()); |
114 | 259 |
115 // Use a TextIterator to visit the potentially multiple nodes the range | 260 // Use a TextIterator to visit the potentially multiple nodes the range |
116 // covers. | 261 // covers. |
117 for (TextIterator marked_text(range.StartPosition(), range.EndPosition()); | 262 for (TextIterator marked_text(range.StartPosition(), range.EndPosition()); |
118 !marked_text.AtEnd(); marked_text.Advance()) { | 263 !marked_text.AtEnd(); marked_text.Advance()) { |
119 AddMarker(marked_text.CurrentContainer(), | 264 AddMarker(marked_text.CurrentContainer(), |
120 DocumentMarker(marked_text.StartOffsetInCurrentContainer(), | 265 new DocumentMarker(marked_text.StartOffsetInCurrentContainer(), |
121 marked_text.EndOffsetInCurrentContainer(), | 266 marked_text.EndOffsetInCurrentContainer(), |
122 match_status)); | 267 match_status)); |
123 } | 268 } |
124 // Don't invalidate tickmarks here. TextFinder invalidates tickmarks using a | 269 // Don't invalidate tickmarks here. TextFinder invalidates tickmarks using a |
125 // throttling algorithm. crbug.com/6819. | 270 // throttling algorithm. crbug.com/6819. |
126 } | 271 } |
127 | 272 |
128 void DocumentMarkerController::AddCompositionMarker(const Position& start, | 273 void DocumentMarkerController::AddCompositionMarker(const Position& start, |
129 const Position& end, | 274 const Position& end, |
130 Color underline_color, | 275 Color underline_color, |
131 bool thick, | 276 bool thick, |
132 Color background_color) { | 277 Color background_color) { |
133 DCHECK(!document_->NeedsLayoutTreeUpdate()); | 278 DCHECK(!document_->NeedsLayoutTreeUpdate()); |
134 | 279 |
135 for (TextIterator marked_text(start, end); !marked_text.AtEnd(); | 280 for (TextIterator marked_text(start, end); !marked_text.AtEnd(); |
136 marked_text.Advance()) | 281 marked_text.Advance()) { |
137 AddMarker(marked_text.CurrentContainer(), | 282 AddMarker(marked_text.CurrentContainer(), |
138 DocumentMarker(marked_text.StartOffsetInCurrentContainer(), | 283 new DocumentMarker(marked_text.StartOffsetInCurrentContainer(), |
139 marked_text.EndOffsetInCurrentContainer(), | 284 marked_text.EndOffsetInCurrentContainer(), |
140 underline_color, thick, background_color)); | 285 underline_color, thick, background_color)); |
286 } | |
141 } | 287 } |
142 | 288 |
143 void DocumentMarkerController::PrepareForDestruction() { | 289 void DocumentMarkerController::PrepareForDestruction() { |
144 Clear(); | 290 Clear(); |
145 } | 291 } |
146 | 292 |
147 void DocumentMarkerController::RemoveMarkers( | 293 void DocumentMarkerController::RemoveMarkers( |
148 TextIterator& marked_text, | 294 TextIterator& marked_text, |
149 DocumentMarker::MarkerTypes marker_types) { | 295 DocumentMarker::MarkerTypes marker_types) { |
150 for (; !marked_text.AtEnd(); marked_text.Advance()) { | 296 for (; !marked_text.AtEnd(); marked_text.Advance()) { |
(...skipping 10 matching lines...) Expand all Loading... | |
161 | 307 |
162 void DocumentMarkerController::RemoveMarkers( | 308 void DocumentMarkerController::RemoveMarkers( |
163 const EphemeralRange& range, | 309 const EphemeralRange& range, |
164 DocumentMarker::MarkerTypes marker_types) { | 310 DocumentMarker::MarkerTypes marker_types) { |
165 DCHECK(!document_->NeedsLayoutTreeUpdate()); | 311 DCHECK(!document_->NeedsLayoutTreeUpdate()); |
166 | 312 |
167 TextIterator marked_text(range.StartPosition(), range.EndPosition()); | 313 TextIterator marked_text(range.StartPosition(), range.EndPosition()); |
168 DocumentMarkerController::RemoveMarkers(marked_text, marker_types); | 314 DocumentMarkerController::RemoveMarkers(marked_text, marker_types); |
169 } | 315 } |
170 | 316 |
171 static bool StartsFurther(const Member<RenderedDocumentMarker>& lhv, | |
Xiaocheng
2017/04/13 02:39:51
There's no need to touch these functions if we kee
| |
172 const DocumentMarker* rhv) { | |
173 return lhv->StartOffset() < rhv->StartOffset(); | |
174 } | |
175 | |
176 static bool EndsBefore(size_t start_offset, | |
177 const Member<RenderedDocumentMarker>& rhv) { | |
178 return start_offset < rhv->EndOffset(); | |
179 } | |
180 | |
181 static bool CompareByStart(const Member<DocumentMarker>& lhv, | |
182 const Member<DocumentMarker>& rhv) { | |
183 return lhv->StartOffset() < rhv->StartOffset(); | |
184 } | |
185 | |
186 static bool DoesNotOverlap(const Member<RenderedDocumentMarker>& lhv, | |
187 const DocumentMarker* rhv) { | |
188 return lhv->EndOffset() < rhv->StartOffset(); | |
189 } | |
190 | |
191 static void UpdateMarkerRenderedRect(const Node& node, | 317 static void UpdateMarkerRenderedRect(const Node& node, |
192 RenderedDocumentMarker& marker) { | 318 RenderedDocumentMarker& marker) { |
193 Range* range = Range::Create(node.GetDocument()); | 319 Range* range = Range::Create(node.GetDocument()); |
194 // The offsets of the marker may be out-dated, so check for exceptions. | 320 // The offsets of the marker may be out-dated, so check for exceptions. |
195 DummyExceptionStateForTesting exception_state; | 321 DummyExceptionStateForTesting exception_state; |
196 range->setStart(&const_cast<Node&>(node), marker.StartOffset(), | 322 range->setStart(&const_cast<Node&>(node), marker.StartOffset(), |
197 exception_state); | 323 exception_state); |
198 if (!exception_state.HadException()) { | 324 if (!exception_state.HadException()) { |
199 range->setEnd(&const_cast<Node&>(node), marker.EndOffset(), | 325 range->setEnd(&const_cast<Node&>(node), marker.EndOffset(), |
200 IGNORE_EXCEPTION_FOR_TESTING); | 326 IGNORE_EXCEPTION_FOR_TESTING); |
201 } | 327 } |
202 if (!exception_state.HadException()) { | 328 if (!exception_state.HadException()) { |
203 // TODO(yosin): Once we have a |EphemeralRange| version of |boundingBox()|, | 329 // TODO(yosin): Once we have a |EphemeralRange| version of |boundingBox()|, |
204 // we should use it instead of |Range| version. | 330 // we should use it instead of |Range| version. |
205 marker.SetRenderedRect(LayoutRect(range->BoundingBox())); | 331 marker.SetRenderedRect(LayoutRect(range->BoundingBox())); |
206 } else { | 332 } else { |
207 marker.NullifyRenderedRect(); | 333 marker.NullifyRenderedRect(); |
208 } | 334 } |
209 range->Dispose(); | 335 range->Dispose(); |
210 } | 336 } |
211 | 337 |
212 // Markers are stored in order sorted by their start offset. | 338 // Markers are stored in order sorted by their start offset. |
213 // Markers of the same type do not overlap each other. | 339 // Markers of the same type do not overlap each other. |
214 | 340 |
215 void DocumentMarkerController::AddMarker(Node* node, | 341 void DocumentMarkerController::AddMarker(Node* node, |
216 const DocumentMarker& new_marker) { | 342 const DocumentMarker* new_marker) { |
217 DCHECK_GE(new_marker.EndOffset(), new_marker.StartOffset()); | 343 DCHECK_GE(new_marker->EndOffset(), new_marker->StartOffset()); |
218 if (new_marker.EndOffset() == new_marker.StartOffset()) | 344 if (new_marker->EndOffset() == new_marker->StartOffset()) |
219 return; | 345 return; |
220 | 346 |
221 possibly_existing_marker_types_.Add(new_marker.GetType()); | 347 possibly_existing_marker_types_.Add(new_marker->GetType()); |
222 | 348 |
223 Member<MarkerLists>& markers = | 349 Member<MarkerLists>& markers = |
224 markers_.insert(node, nullptr).stored_value->value; | 350 markers_.insert(node, nullptr).stored_value->value; |
225 if (!markers) { | 351 if (!markers) { |
226 markers = new MarkerLists; | 352 markers = new MarkerLists; |
227 markers->Grow(DocumentMarker::kMarkerTypeIndexesCount); | 353 markers->Grow(DocumentMarker::kMarkerTypeIndexesCount); |
228 } | 354 } |
229 | 355 |
230 DocumentMarker::MarkerTypeIndex marker_list_index = | 356 DocumentMarker::MarkerTypeIndex marker_list_index = |
231 MarkerTypeToMarkerIndex(new_marker.GetType()); | 357 MarkerTypeToMarkerIndex(new_marker->GetType()); |
232 if (!markers->at(marker_list_index)) { | 358 if (!markers->at(marker_list_index)) { |
233 markers->at(marker_list_index) = new MarkerList; | 359 markers->at(marker_list_index) = new DocumentMarkerList; |
234 } | 360 } |
235 | 361 |
236 Member<MarkerList>& list = markers->at(marker_list_index); | 362 DocumentMarkerList* list = markers->at(marker_list_index); |
237 RenderedDocumentMarker* new_rendered_marker = | 363 RenderedDocumentMarker* new_rendered_marker = |
238 RenderedDocumentMarker::Create(new_marker); | 364 RenderedDocumentMarker::Create(*new_marker); |
239 if (list->IsEmpty() || list->back()->EndOffset() < new_marker.StartOffset()) { | 365 list->Add(new_rendered_marker); |
240 list->push_back(new_rendered_marker); | |
241 } else { | |
242 if (new_marker.GetType() != DocumentMarker::kTextMatch && | |
243 new_marker.GetType() != DocumentMarker::kComposition) { | |
244 MergeOverlapping(list.Get(), new_rendered_marker); | |
245 } else { | |
246 MarkerList::iterator pos = std::lower_bound(list->begin(), list->end(), | |
247 &new_marker, StartsFurther); | |
248 list->insert(pos - list->begin(), new_rendered_marker); | |
249 } | |
250 } | |
251 | 366 |
252 // repaint the affected node | 367 // repaint the affected node |
253 if (node->GetLayoutObject()) { | 368 if (node->GetLayoutObject()) { |
254 node->GetLayoutObject()->SetShouldDoFullPaintInvalidation( | 369 node->GetLayoutObject()->SetShouldDoFullPaintInvalidation( |
255 kPaintInvalidationDocumentMarkerChange); | 370 kPaintInvalidationDocumentMarkerChange); |
256 } | 371 } |
257 } | 372 } |
258 | 373 |
259 void DocumentMarkerController::MergeOverlapping( | |
Xiaocheng
2017/04/13 02:39:51
DML::MergeOverlapping can be put here, so that it
| |
260 MarkerList* list, | |
261 RenderedDocumentMarker* to_insert) { | |
262 MarkerList::iterator first_overlapping = | |
263 std::lower_bound(list->begin(), list->end(), to_insert, DoesNotOverlap); | |
264 size_t index = first_overlapping - list->begin(); | |
265 list->insert(index, to_insert); | |
266 MarkerList::iterator inserted = list->begin() + index; | |
267 first_overlapping = inserted + 1; | |
268 for (MarkerList::iterator i = first_overlapping; | |
269 i != list->end() && (*i)->StartOffset() <= (*inserted)->EndOffset();) { | |
270 (*inserted)->SetStartOffset( | |
271 std::min((*inserted)->StartOffset(), (*i)->StartOffset())); | |
272 (*inserted)->SetEndOffset( | |
273 std::max((*inserted)->EndOffset(), (*i)->EndOffset())); | |
274 list->erase(i - list->begin()); | |
275 } | |
276 } | |
277 | |
278 // Moves markers from src_node to dst_node. Markers are moved if their start | 374 // Moves markers from src_node to dst_node. Markers are moved if their start |
279 // offset is less than length. Markers that run past that point are truncated. | 375 // offset is less than length. Markers that run past that point are truncated. |
280 void DocumentMarkerController::MoveMarkers(Node* src_node, | 376 void DocumentMarkerController::MoveMarkers(Node* src_node, |
281 int length, | 377 int length, |
282 Node* dst_node) { | 378 Node* dst_node) { |
283 if (length <= 0) | 379 if (length <= 0) |
284 return; | 380 return; |
285 | 381 |
286 if (!PossiblyHasMarkers(DocumentMarker::AllMarkers())) | 382 if (!PossiblyHasMarkers(DocumentMarker::AllMarkers())) |
287 return; | 383 return; |
288 DCHECK(!markers_.IsEmpty()); | 384 DCHECK(!markers_.IsEmpty()); |
289 | 385 |
290 MarkerLists* markers = markers_.at(src_node); | 386 MarkerLists* src_markers = markers_.at(src_node); |
291 if (!markers) | 387 if (!src_markers) |
292 return; | 388 return; |
293 | 389 |
390 Member<MarkerLists>& dst_markers = | |
391 markers_.insert(dst_node, nullptr).stored_value->value; | |
392 if (!dst_markers) { | |
393 dst_markers = new MarkerLists; | |
394 dst_markers->Grow(DocumentMarker::kMarkerTypeIndexesCount); | |
395 } | |
396 | |
294 bool doc_dirty = false; | 397 bool doc_dirty = false; |
295 for (Member<MarkerList> list : *markers) { | 398 for (size_t marker_list_index = 0; marker_list_index < src_markers->size(); |
296 if (!list) | 399 marker_list_index++) { |
400 DocumentMarkerList* src_list = src_markers->at(marker_list_index); | |
401 if (!src_list) | |
297 continue; | 402 continue; |
298 | 403 |
299 unsigned end_offset = length - 1; | 404 if (!dst_markers->at(marker_list_index)) { |
300 MarkerList::iterator it; | 405 dst_markers->at(marker_list_index) = new DocumentMarkerList; |
301 for (it = list->begin(); it != list->end(); ++it) { | |
302 DocumentMarker* marker = it->Get(); | |
303 | |
304 // stop if we are now past the specified range | |
305 if (marker->StartOffset() > end_offset) | |
306 break; | |
307 | |
308 // pin the marker to the specified range | |
309 doc_dirty = true; | |
310 if (marker->EndOffset() > end_offset) | |
311 marker->SetEndOffset(end_offset); | |
312 | |
313 AddMarker(dst_node, *marker); | |
314 } | 406 } |
315 | 407 |
316 // Remove the range of markers that were moved to dstNode | 408 src_list->MoveMarkers(length, dst_markers->at(marker_list_index)); |
317 list->erase(0, it - list->begin()); | |
318 } | 409 } |
319 | 410 |
320 // repaint the affected node | 411 // repaint the affected node |
321 if (doc_dirty && dst_node->GetLayoutObject()) { | 412 if (doc_dirty && dst_node->GetLayoutObject()) { |
322 dst_node->GetLayoutObject()->SetShouldDoFullPaintInvalidation( | 413 dst_node->GetLayoutObject()->SetShouldDoFullPaintInvalidation( |
323 kPaintInvalidationDocumentMarkerChange); | 414 kPaintInvalidationDocumentMarkerChange); |
324 } | 415 } |
325 } | 416 } |
326 | 417 |
327 void DocumentMarkerController::RemoveMarkers( | 418 void DocumentMarkerController::RemoveMarkers( |
328 Node* node, | 419 Node* node, |
329 unsigned start_offset, | 420 unsigned start_offset, |
330 int length, | 421 int length, |
331 DocumentMarker::MarkerTypes marker_types) { | 422 DocumentMarker::MarkerTypes marker_types) { |
332 if (length <= 0) | 423 if (length <= 0) |
333 return; | 424 return; |
334 | 425 |
335 if (!PossiblyHasMarkers(marker_types)) | 426 if (!PossiblyHasMarkers(marker_types)) |
336 return; | 427 return; |
337 DCHECK(!(markers_.IsEmpty())); | 428 DCHECK(!(markers_.IsEmpty())); |
338 | 429 |
339 MarkerLists* markers = markers_.at(node); | 430 MarkerLists* markers = markers_.at(node); |
340 if (!markers) | 431 if (!markers) |
341 return; | 432 return; |
342 | 433 |
343 bool doc_dirty = false; | 434 bool doc_dirty = false; |
344 size_t empty_lists_count = 0; | 435 size_t empty_lists_count = 0; |
345 for (size_t marker_list_index = 0; | 436 for (DocumentMarker::MarkerType type : DocumentMarker::AllMarkers()) { |
346 marker_list_index < DocumentMarker::kMarkerTypeIndexesCount; | 437 size_t marker_list_index = MarkerTypeToMarkerIndex(type); |
347 ++marker_list_index) { | 438 |
348 Member<MarkerList>& list = (*markers)[marker_list_index]; | 439 Member<DocumentMarkerList>& list = (*markers)[marker_list_index]; |
349 if (!list || list->IsEmpty()) { | 440 if (!list || list->IsEmpty()) { |
350 if (list.Get() && list->IsEmpty()) | 441 if (list.Get() && list->IsEmpty()) |
351 list.Clear(); | 442 list.Clear(); |
352 ++empty_lists_count; | 443 ++empty_lists_count; |
353 continue; | 444 continue; |
354 } | 445 } |
355 if (!marker_types.Contains((*list->begin())->GetType())) | 446 if (!marker_types.Contains(type)) |
356 continue; | 447 continue; |
357 unsigned end_offset = start_offset + length; | |
358 MarkerList::iterator start_pos = | |
359 std::upper_bound(list->begin(), list->end(), start_offset, EndsBefore); | |
360 for (MarkerList::iterator i = start_pos; i != list->end();) { | |
361 DocumentMarker marker(*i->Get()); | |
362 | 448 |
363 // markers are returned in order, so stop if we are now past the specified | 449 doc_dirty = list->RemoveMarkers(start_offset, length) || doc_dirty; |
364 // range | |
365 if (marker.StartOffset() >= end_offset) | |
366 break; | |
367 | |
368 list->erase(i - list->begin()); | |
369 doc_dirty = true; | |
370 } | |
371 | 450 |
372 if (list->IsEmpty()) { | 451 if (list->IsEmpty()) { |
373 list.Clear(); | 452 list.Clear(); |
374 ++empty_lists_count; | 453 ++empty_lists_count; |
375 } | 454 } |
376 } | 455 } |
377 | 456 |
378 if (empty_lists_count == DocumentMarker::kMarkerTypeIndexesCount) { | 457 if (empty_lists_count == DocumentMarker::kMarkerTypeIndexesCount) { |
379 markers_.erase(node); | 458 markers_.erase(node); |
380 if (markers_.IsEmpty()) | 459 if (markers_.IsEmpty()) |
381 possibly_existing_marker_types_ = 0; | 460 possibly_existing_marker_types_ = 0; |
382 } | 461 } |
383 | 462 |
384 // repaint the affected node | 463 // repaint the affected node |
385 if (doc_dirty && node->GetLayoutObject()) { | 464 if (doc_dirty && node->GetLayoutObject()) { |
386 node->GetLayoutObject()->SetShouldDoFullPaintInvalidation( | 465 node->GetLayoutObject()->SetShouldDoFullPaintInvalidation( |
387 kPaintInvalidationDocumentMarkerChange); | 466 kPaintInvalidationDocumentMarkerChange); |
388 } | 467 } |
389 } | 468 } |
390 | 469 |
391 DocumentMarkerVector DocumentMarkerController::MarkersFor( | 470 DocumentMarkerVector DocumentMarkerController::MarkersFor( |
392 Node* node, | 471 Node* node, |
393 DocumentMarker::MarkerTypes marker_types) { | 472 DocumentMarker::MarkerTypes marker_types) { |
394 DocumentMarkerVector result; | 473 DocumentMarkerVector result; |
395 | 474 |
396 MarkerLists* markers = markers_.at(node); | 475 MarkerLists* markers = markers_.at(node); |
397 if (!markers) | 476 if (!markers) |
398 return result; | 477 return result; |
399 | 478 |
400 for (size_t marker_list_index = 0; | 479 for (DocumentMarker::MarkerType type : DocumentMarker::AllMarkers()) { |
401 marker_list_index < DocumentMarker::kMarkerTypeIndexesCount; | 480 size_t marker_list_index = MarkerTypeToMarkerIndex(type); |
402 ++marker_list_index) { | 481 |
403 Member<MarkerList>& list = (*markers)[marker_list_index]; | 482 DocumentMarkerList* list = (*markers)[marker_list_index]; |
404 if (!list || list->IsEmpty() || | 483 if (!list || list->IsEmpty() || !marker_types.Contains(type)) |
405 !marker_types.Contains((*list->begin())->GetType())) | |
406 continue; | 484 continue; |
407 | 485 |
408 for (size_t i = 0; i < list->size(); ++i) | 486 list->AppendMarkersToInputList(&result); |
409 result.push_back(list->at(i).Get()); | |
410 } | 487 } |
411 | 488 |
412 std::sort(result.begin(), result.end(), CompareByStart); | 489 std::sort(result.begin(), result.end(), CompareByStart); |
413 return result; | 490 return result; |
414 } | 491 } |
415 | 492 |
416 DocumentMarkerVector DocumentMarkerController::Markers() { | 493 DocumentMarkerVector DocumentMarkerController::Markers() { |
417 DocumentMarkerVector result; | 494 DocumentMarkerVector result; |
418 for (MarkerMap::iterator i = markers_.begin(); i != markers_.end(); ++i) { | 495 for (MarkerMap::iterator i = markers_.begin(); i != markers_.end(); ++i) { |
419 MarkerLists* markers = i->value.Get(); | 496 MarkerLists* markers = i->value.Get(); |
420 for (size_t marker_list_index = 0; | 497 for (size_t marker_list_index = 0; |
421 marker_list_index < DocumentMarker::kMarkerTypeIndexesCount; | 498 marker_list_index < DocumentMarker::kMarkerTypeIndexesCount; |
422 ++marker_list_index) { | 499 ++marker_list_index) { |
423 Member<MarkerList>& list = (*markers)[marker_list_index]; | 500 DocumentMarkerList* list = (*markers)[marker_list_index]; |
424 for (size_t j = 0; list.Get() && j < list->size(); ++j) | 501 if (!list) |
425 result.push_back(list->at(j).Get()); | 502 continue; |
503 | |
504 list->AppendMarkersToInputList(&result); | |
426 } | 505 } |
427 } | 506 } |
507 | |
428 std::sort(result.begin(), result.end(), CompareByStart); | 508 std::sort(result.begin(), result.end(), CompareByStart); |
429 return result; | 509 return result; |
430 } | 510 } |
431 | 511 |
432 DocumentMarkerVector DocumentMarkerController::MarkersInRange( | 512 DocumentMarkerVector DocumentMarkerController::MarkersInRange( |
433 const EphemeralRange& range, | 513 const EphemeralRange& range, |
434 DocumentMarker::MarkerTypes marker_types) { | 514 DocumentMarker::MarkerTypes marker_types) { |
435 if (!PossiblyHasMarkers(marker_types)) | 515 if (!PossiblyHasMarkers(marker_types)) |
436 return DocumentMarkerVector(); | 516 return DocumentMarkerVector(); |
437 | 517 |
(...skipping 30 matching lines...) Expand all Loading... | |
468 return result; | 548 return result; |
469 DCHECK(!(markers_.IsEmpty())); | 549 DCHECK(!(markers_.IsEmpty())); |
470 | 550 |
471 // outer loop: process each node | 551 // outer loop: process each node |
472 MarkerMap::iterator end = markers_.end(); | 552 MarkerMap::iterator end = markers_.end(); |
473 for (MarkerMap::iterator node_iterator = markers_.begin(); | 553 for (MarkerMap::iterator node_iterator = markers_.begin(); |
474 node_iterator != end; ++node_iterator) { | 554 node_iterator != end; ++node_iterator) { |
475 // inner loop; process each marker in this node | 555 // inner loop; process each marker in this node |
476 const Node& node = *node_iterator->key; | 556 const Node& node = *node_iterator->key; |
477 MarkerLists* markers = node_iterator->value.Get(); | 557 MarkerLists* markers = node_iterator->value.Get(); |
478 for (size_t marker_list_index = 0; | 558 for (DocumentMarker::MarkerType type : DocumentMarker::AllMarkers()) { |
479 marker_list_index < DocumentMarker::kMarkerTypeIndexesCount; | 559 size_t marker_list_index = MarkerTypeToMarkerIndex(type); |
480 ++marker_list_index) { | 560 DocumentMarkerList* list = (*markers)[marker_list_index]; |
481 Member<MarkerList>& list = (*markers)[marker_list_index]; | 561 if (!list || list->IsEmpty() || type != marker_type) |
482 if (!list || list->IsEmpty() || | |
483 (*list->begin())->GetType() != marker_type) | |
484 continue; | 562 continue; |
485 for (unsigned marker_index = 0; marker_index < list->size(); | 563 DocumentMarkerVector markers_in_list; |
486 ++marker_index) { | 564 list->AppendMarkersToInputList(&markers_in_list); |
487 RenderedDocumentMarker* marker = list->at(marker_index).Get(); | 565 for (DocumentMarker* marker : markers_in_list) { |
488 UpdateMarkerRenderedRectIfNeeded(node, *marker); | 566 RenderedDocumentMarker* rendered_marker = |
489 if (!marker->IsRendered()) | 567 ToRenderedDocumentMarker(marker); |
568 UpdateMarkerRenderedRectIfNeeded(node, *rendered_marker); | |
569 if (!rendered_marker->IsRendered()) | |
490 continue; | 570 continue; |
491 result.push_back(marker->RenderedRect()); | 571 result.push_back(rendered_marker->RenderedRect()); |
492 } | 572 } |
493 } | 573 } |
494 } | 574 } |
495 | 575 |
496 return result; | 576 return result; |
497 } | 577 } |
498 | 578 |
499 static void InvalidatePaintForTickmarks(const Node& node) { | 579 static void InvalidatePaintForTickmarks(const Node& node) { |
500 if (FrameView* frame_view = node.GetDocument().View()) | 580 if (FrameView* frame_view = node.GetDocument().View()) |
501 frame_view->InvalidatePaintForTickmarks(); | 581 frame_view->InvalidatePaintForTickmarks(); |
502 } | 582 } |
503 | 583 |
504 void DocumentMarkerController::UpdateMarkerRenderedRectIfNeeded( | 584 void DocumentMarkerController::UpdateMarkerRenderedRectIfNeeded( |
505 const Node& node, | 585 const Node& node, |
506 RenderedDocumentMarker& marker) { | 586 RenderedDocumentMarker& marker) { |
507 DCHECK(!document_->View() || !document_->View()->NeedsLayout()); | 587 DCHECK(!document_->View() || !document_->View()->NeedsLayout()); |
508 DCHECK(!document_->NeedsLayoutTreeUpdate()); | 588 DCHECK(!document_->NeedsLayoutTreeUpdate()); |
509 if (!marker.IsValid()) | 589 if (!marker.IsValid()) |
510 UpdateMarkerRenderedRect(node, marker); | 590 UpdateMarkerRenderedRect(node, marker); |
511 } | 591 } |
512 | 592 |
513 void DocumentMarkerController::InvalidateRectsForMarkersInNode( | 593 void DocumentMarkerController::InvalidateRectsForMarkersInNode( |
514 const Node& node) { | 594 const Node& node) { |
515 MarkerLists* markers = markers_.at(&node); | 595 MarkerLists* markers = markers_.at(&node); |
516 | 596 |
517 for (auto& marker_list : *markers) { | 597 for (DocumentMarkerList* marker_list : *markers) { |
518 if (!marker_list || marker_list->IsEmpty()) | 598 if (!marker_list || marker_list->IsEmpty()) |
519 continue; | 599 continue; |
520 | 600 |
521 for (auto& marker : *marker_list) | 601 DocumentMarkerVector markers_in_list; |
522 marker->Invalidate(); | 602 marker_list->AppendMarkersToInputList(&markers_in_list); |
523 | 603 |
524 if (marker_list->front()->GetType() == DocumentMarker::kTextMatch) | 604 for (DocumentMarker* marker : markers_in_list) |
605 ToRenderedDocumentMarker(marker)->Invalidate(); | |
606 | |
607 if (markers_in_list.front()->GetType() == DocumentMarker::kTextMatch) | |
525 InvalidatePaintForTickmarks(node); | 608 InvalidatePaintForTickmarks(node); |
526 } | 609 } |
527 } | 610 } |
528 | 611 |
529 void DocumentMarkerController::InvalidateRectsForAllMarkers() { | 612 void DocumentMarkerController::InvalidateRectsForAllMarkers() { |
530 for (auto& node_markers : markers_) { | 613 for (auto& node_markers : markers_) { |
531 const Node& node = *node_markers.key; | 614 const Node& node = *node_markers.key; |
532 for (auto& marker_list : *node_markers.value) { | 615 for (DocumentMarkerList* marker_list : *node_markers.value) { |
533 if (!marker_list || marker_list->IsEmpty()) | 616 if (!marker_list || marker_list->IsEmpty()) |
534 continue; | 617 continue; |
535 | 618 |
536 for (auto& marker : *marker_list) | 619 DocumentMarkerVector markers_in_list; |
537 marker->Invalidate(); | 620 marker_list->AppendMarkersToInputList(&markers_in_list); |
621 for (DocumentMarker* marker : markers_in_list) | |
622 ToRenderedDocumentMarker(marker)->Invalidate(); | |
538 | 623 |
539 if (marker_list->front()->GetType() == DocumentMarker::kTextMatch) | 624 if (markers_in_list.front()->GetType() == DocumentMarker::kTextMatch) |
540 InvalidatePaintForTickmarks(node); | 625 InvalidatePaintForTickmarks(node); |
541 } | 626 } |
542 } | 627 } |
543 } | 628 } |
544 | 629 |
545 DEFINE_TRACE(DocumentMarkerController) { | 630 DEFINE_TRACE(DocumentMarkerController) { |
546 visitor->Trace(markers_); | 631 visitor->Trace(markers_); |
547 visitor->Trace(document_); | 632 visitor->Trace(document_); |
548 SynchronousMutationObserver::Trace(visitor); | 633 SynchronousMutationObserver::Trace(visitor); |
549 } | 634 } |
(...skipping 13 matching lines...) Expand all Loading... | |
563 void DocumentMarkerController::RemoveMarkers( | 648 void DocumentMarkerController::RemoveMarkers( |
564 const MarkerRemoverPredicate& should_remove_marker) { | 649 const MarkerRemoverPredicate& should_remove_marker) { |
565 for (auto& node_markers : markers_) { | 650 for (auto& node_markers : markers_) { |
566 const Node& node = *node_markers.key; | 651 const Node& node = *node_markers.key; |
567 if (!node.IsTextNode()) // MarkerRemoverPredicate requires a Text node. | 652 if (!node.IsTextNode()) // MarkerRemoverPredicate requires a Text node. |
568 continue; | 653 continue; |
569 MarkerLists& markers = *node_markers.value; | 654 MarkerLists& markers = *node_markers.value; |
570 for (size_t marker_list_index = 0; | 655 for (size_t marker_list_index = 0; |
571 marker_list_index < DocumentMarker::kMarkerTypeIndexesCount; | 656 marker_list_index < DocumentMarker::kMarkerTypeIndexesCount; |
572 ++marker_list_index) { | 657 ++marker_list_index) { |
573 Member<MarkerList>& list = markers[marker_list_index]; | 658 DocumentMarkerList* list = markers[marker_list_index]; |
574 if (!list) | 659 if (!list) |
575 continue; | 660 continue; |
576 bool removed_markers = false; | 661 bool removed_markers = false; |
577 for (size_t j = list->size(); j > 0; --j) { | 662 |
578 if (should_remove_marker(*list->at(j - 1), | 663 DocumentMarkerVector markers_in_list; |
664 list->AppendMarkersToInputList(&markers_in_list); | |
665 | |
666 for (size_t j = markers_in_list.size(); j > 0; --j) { | |
667 if (should_remove_marker(*markers_in_list[j - 1], | |
579 static_cast<const Text&>(node))) { | 668 static_cast<const Text&>(node))) { |
580 list->erase(j - 1); | 669 markers_in_list.erase(j - 1); |
581 removed_markers = true; | 670 removed_markers = true; |
582 } | 671 } |
583 } | 672 } |
673 | |
674 list->Clear(); | |
675 for (DocumentMarker* marker : markers_in_list) | |
676 list->Add(marker); | |
677 | |
584 if (removed_markers && | 678 if (removed_markers && |
585 marker_list_index == DocumentMarker::kTextMatchMarkerIndex) | 679 marker_list_index == DocumentMarker::kTextMatchMarkerIndex) |
586 InvalidatePaintForTickmarks(node); | 680 InvalidatePaintForTickmarks(node); |
587 } | 681 } |
588 } | 682 } |
589 } | 683 } |
590 | 684 |
591 void DocumentMarkerController::RemoveMarkers( | 685 void DocumentMarkerController::RemoveMarkers( |
592 DocumentMarker::MarkerTypes marker_types) { | 686 DocumentMarker::MarkerTypes marker_types) { |
593 if (!PossiblyHasMarkers(marker_types)) | 687 if (!PossiblyHasMarkers(marker_types)) |
(...skipping 18 matching lines...) Expand all Loading... | |
612 bool needs_repainting = false; | 706 bool needs_repainting = false; |
613 bool node_can_be_removed; | 707 bool node_can_be_removed; |
614 | 708 |
615 size_t empty_lists_count = 0; | 709 size_t empty_lists_count = 0; |
616 if (marker_types == DocumentMarker::AllMarkers()) { | 710 if (marker_types == DocumentMarker::AllMarkers()) { |
617 needs_repainting = true; | 711 needs_repainting = true; |
618 node_can_be_removed = true; | 712 node_can_be_removed = true; |
619 } else { | 713 } else { |
620 MarkerLists* markers = iterator->value.Get(); | 714 MarkerLists* markers = iterator->value.Get(); |
621 | 715 |
622 for (size_t marker_list_index = 0; | 716 for (DocumentMarker::MarkerType type : marker_types) { |
623 marker_list_index < DocumentMarker::kMarkerTypeIndexesCount; | 717 size_t marker_list_index = MarkerTypeToMarkerIndex(type); |
624 ++marker_list_index) { | 718 DocumentMarkerList* list = (*markers)[marker_list_index]; |
625 Member<MarkerList>& list = (*markers)[marker_list_index]; | 719 if (list) |
626 if (!list || list->IsEmpty()) { | |
627 if (list.Get() && list->IsEmpty()) | |
628 list.Clear(); | |
629 ++empty_lists_count; | |
630 continue; | |
631 } | |
632 if (marker_types.Contains((*list->begin())->GetType())) { | |
633 list->Clear(); | 720 list->Clear(); |
634 list.Clear(); | 721 |
635 ++empty_lists_count; | 722 ++empty_lists_count; |
636 needs_repainting = true; | 723 needs_repainting = true; |
637 } | |
638 } | 724 } |
639 | 725 |
640 node_can_be_removed = | 726 node_can_be_removed = |
641 empty_lists_count == DocumentMarker::kMarkerTypeIndexesCount; | 727 empty_lists_count == DocumentMarker::kMarkerTypeIndexesCount; |
642 } | 728 } |
643 | 729 |
644 if (needs_repainting) { | 730 if (needs_repainting) { |
645 const Node& node = *iterator->key; | 731 const Node& node = *iterator->key; |
646 if (LayoutObject* layout_object = node.GetLayoutObject()) { | 732 if (LayoutObject* layout_object = node.GetLayoutObject()) { |
647 layout_object->SetShouldDoFullPaintInvalidation( | 733 layout_object->SetShouldDoFullPaintInvalidation( |
(...skipping 15 matching lines...) Expand all Loading... | |
663 return; | 749 return; |
664 DCHECK(!markers_.IsEmpty()); | 750 DCHECK(!markers_.IsEmpty()); |
665 | 751 |
666 // outer loop: process each markered node in the document | 752 // outer loop: process each markered node in the document |
667 MarkerMap::iterator end = markers_.end(); | 753 MarkerMap::iterator end = markers_.end(); |
668 for (MarkerMap::iterator i = markers_.begin(); i != end; ++i) { | 754 for (MarkerMap::iterator i = markers_.begin(); i != end; ++i) { |
669 const Node* node = i->key; | 755 const Node* node = i->key; |
670 | 756 |
671 // inner loop: process each marker in the current node | 757 // inner loop: process each marker in the current node |
672 MarkerLists* markers = i->value.Get(); | 758 MarkerLists* markers = i->value.Get(); |
673 for (size_t marker_list_index = 0; | 759 for (DocumentMarker::MarkerType type : DocumentMarker::AllMarkers()) { |
674 marker_list_index < DocumentMarker::kMarkerTypeIndexesCount; | 760 size_t marker_list_index = MarkerTypeToMarkerIndex(type); |
675 ++marker_list_index) { | 761 DocumentMarkerList* list = (*markers)[marker_list_index]; |
676 Member<MarkerList>& list = (*markers)[marker_list_index]; | 762 if (!list || list->IsEmpty() || !marker_types.Contains(type)) |
677 if (!list || list->IsEmpty() || | |
678 !marker_types.Contains((*list->begin())->GetType())) | |
679 continue; | 763 continue; |
680 | 764 |
681 // cause the node to be redrawn | 765 // cause the node to be redrawn |
682 if (LayoutObject* layout_object = node->GetLayoutObject()) { | 766 if (LayoutObject* layout_object = node->GetLayoutObject()) { |
683 layout_object->SetShouldDoFullPaintInvalidation( | 767 layout_object->SetShouldDoFullPaintInvalidation( |
684 kPaintInvalidationDocumentMarkerChange); | 768 kPaintInvalidationDocumentMarkerChange); |
685 break; | 769 break; |
686 } | 770 } |
687 } | 771 } |
688 } | 772 } |
(...skipping 27 matching lines...) Expand all Loading... | |
716 | 800 |
717 bool DocumentMarkerController::SetMarkersActive(Node* node, | 801 bool DocumentMarkerController::SetMarkersActive(Node* node, |
718 unsigned start_offset, | 802 unsigned start_offset, |
719 unsigned end_offset, | 803 unsigned end_offset, |
720 bool active) { | 804 bool active) { |
721 MarkerLists* markers = markers_.at(node); | 805 MarkerLists* markers = markers_.at(node); |
722 if (!markers) | 806 if (!markers) |
723 return false; | 807 return false; |
724 | 808 |
725 bool doc_dirty = false; | 809 bool doc_dirty = false; |
726 Member<MarkerList>& list = | 810 DocumentMarkerList* list = |
727 (*markers)[MarkerTypeToMarkerIndex(DocumentMarker::kTextMatch)]; | 811 markers->at(MarkerTypeToMarkerIndex(DocumentMarker::kTextMatch)); |
728 if (!list) | 812 if (!list) |
729 return false; | 813 return false; |
730 MarkerList::iterator start_pos = | 814 |
731 std::upper_bound(list->begin(), list->end(), start_offset, EndsBefore); | 815 DocumentMarkerVector markers_in_list; |
732 for (MarkerList::iterator marker = start_pos; marker != list->end(); | 816 list->AppendMarkersToInputList(&markers_in_list); |
733 ++marker) { | 817 |
818 const auto start_pos = std::upper_bound( | |
819 markers_in_list.begin(), markers_in_list.end(), start_offset, EndsBefore); | |
820 for (auto marker_it = start_pos; marker_it != markers_in_list.end(); | |
821 ++marker_it) { | |
734 // Markers are returned in order, so stop if we are now past the specified | 822 // Markers are returned in order, so stop if we are now past the specified |
735 // range. | 823 // range. |
736 if ((*marker)->StartOffset() >= end_offset) | 824 if ((*marker_it)->StartOffset() >= end_offset) |
737 break; | 825 break; |
738 | 826 |
739 (*marker)->SetIsActiveMatch(active); | 827 (*marker_it)->SetIsActiveMatch(active); |
740 doc_dirty = true; | 828 doc_dirty = true; |
741 } | 829 } |
742 | 830 |
743 // repaint the affected node | 831 // repaint the affected node |
744 if (doc_dirty && node->GetLayoutObject()) { | 832 if (doc_dirty && node->GetLayoutObject()) { |
745 node->GetLayoutObject()->SetShouldDoFullPaintInvalidation( | 833 node->GetLayoutObject()->SetShouldDoFullPaintInvalidation( |
746 kPaintInvalidationDocumentMarkerChange); | 834 kPaintInvalidationDocumentMarkerChange); |
747 } | 835 } |
748 return doc_dirty; | 836 return doc_dirty; |
749 } | 837 } |
750 | 838 |
751 #ifndef NDEBUG | 839 #ifndef NDEBUG |
752 void DocumentMarkerController::ShowMarkers() const { | 840 void DocumentMarkerController::ShowMarkers() const { |
753 StringBuilder builder; | 841 StringBuilder builder; |
754 MarkerMap::const_iterator end = markers_.end(); | 842 MarkerMap::const_iterator end = markers_.end(); |
755 for (MarkerMap::const_iterator node_iterator = markers_.begin(); | 843 for (MarkerMap::const_iterator node_iterator = markers_.begin(); |
756 node_iterator != end; ++node_iterator) { | 844 node_iterator != end; ++node_iterator) { |
757 const Node* node = node_iterator->key; | 845 const Node* node = node_iterator->key; |
758 builder.Append(String::Format("%p", node)); | 846 builder.Append(String::Format("%p", node)); |
759 MarkerLists* markers = markers_.at(node); | 847 MarkerLists* markers = markers_.at(node); |
760 for (size_t marker_list_index = 0; | 848 for (size_t marker_list_index = 0; |
761 marker_list_index < DocumentMarker::kMarkerTypeIndexesCount; | 849 marker_list_index < DocumentMarker::kMarkerTypeIndexesCount; |
762 ++marker_list_index) { | 850 ++marker_list_index) { |
763 Member<MarkerList>& list = (*markers)[marker_list_index]; | 851 DocumentMarkerList* list = markers->at(marker_list_index); |
764 for (unsigned marker_index = 0; list.Get() && marker_index < list->size(); | 852 DocumentMarkerVector markers_in_list; |
765 ++marker_index) { | 853 list->AppendMarkersToInputList(&markers_in_list); |
766 DocumentMarker* marker = list->at(marker_index).Get(); | 854 for (unsigned marker_index = 0; |
855 list && marker_index < markers_in_list.size(); ++marker_index) { | |
856 DocumentMarker* marker = markers_in_list[marker_index]; | |
767 builder.Append(" "); | 857 builder.Append(" "); |
768 builder.AppendNumber(marker->GetType()); | 858 builder.AppendNumber(marker->GetType()); |
769 builder.Append(":["); | 859 builder.Append(":["); |
770 builder.AppendNumber(marker->StartOffset()); | 860 builder.AppendNumber(marker->StartOffset()); |
771 builder.Append(":"); | 861 builder.Append(":"); |
772 builder.AppendNumber(marker->EndOffset()); | 862 builder.AppendNumber(marker->EndOffset()); |
773 builder.Append("]("); | 863 builder.Append("]("); |
774 builder.AppendNumber(marker->IsActiveMatch()); | 864 builder.AppendNumber(marker->IsActiveMatch()); |
775 builder.Append(")"); | 865 builder.Append(")"); |
776 } | 866 } |
(...skipping 12 matching lines...) Expand all Loading... | |
789 unsigned new_length) { | 879 unsigned new_length) { |
790 if (!PossiblyHasMarkers(DocumentMarker::AllMarkers())) | 880 if (!PossiblyHasMarkers(DocumentMarker::AllMarkers())) |
791 return; | 881 return; |
792 DCHECK(!markers_.IsEmpty()); | 882 DCHECK(!markers_.IsEmpty()); |
793 | 883 |
794 MarkerLists* markers = markers_.at(node); | 884 MarkerLists* markers = markers_.at(node); |
795 if (!markers) | 885 if (!markers) |
796 return; | 886 return; |
797 | 887 |
798 bool did_shift_marker = false; | 888 bool did_shift_marker = false; |
799 for (MarkerList* list : *markers) { | 889 for (DocumentMarkerList* list : *markers) { |
800 if (!list) | 890 if (!list) |
801 continue; | 891 continue; |
802 | 892 |
803 for (MarkerList::iterator it = list->begin(); it != list->end(); ++it) { | 893 did_shift_marker = |
804 RenderedDocumentMarker& marker = **it; | 894 list->ShiftMarkers(offset, old_length, new_length) || did_shift_marker; |
805 Optional<DocumentMarker::MarkerOffsets> result = | |
806 marker.ComputeOffsetsAfterShift(offset, old_length, new_length); | |
807 if (result == WTF::kNullopt) { | |
808 list->erase(it - list->begin()); | |
809 --it; | |
810 did_shift_marker = true; | |
811 continue; | |
812 } | |
813 | |
814 if (marker.StartOffset() != result.value().start_offset || | |
815 marker.EndOffset() != result.value().end_offset) { | |
816 did_shift_marker = true; | |
817 marker.SetStartOffset(result.value().start_offset); | |
818 marker.SetEndOffset(result.value().end_offset); | |
819 } | |
820 } | |
821 } | 895 } |
822 | 896 |
823 if (!did_shift_marker) | 897 if (!did_shift_marker) |
824 return; | 898 return; |
825 if (!node->GetLayoutObject()) | 899 if (!node->GetLayoutObject()) |
826 return; | 900 return; |
827 InvalidateRectsForMarkersInNode(*node); | 901 InvalidateRectsForMarkersInNode(*node); |
828 // repaint the affected node | 902 // repaint the affected node |
829 node->GetLayoutObject()->SetShouldDoFullPaintInvalidation(); | 903 node->GetLayoutObject()->SetShouldDoFullPaintInvalidation(); |
830 } | 904 } |
831 | 905 |
832 } // namespace blink | 906 } // namespace blink |
833 | 907 |
834 #ifndef NDEBUG | 908 #ifndef NDEBUG |
835 void showDocumentMarkers(const blink::DocumentMarkerController* controller) { | 909 void showDocumentMarkers(const blink::DocumentMarkerController* controller) { |
836 if (controller) | 910 if (controller) |
837 controller->ShowMarkers(); | 911 controller->ShowMarkers(); |
838 } | 912 } |
839 #endif | 913 #endif |
OLD | NEW |