Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(57)

Side by Side Diff: third_party/WebKit/Source/core/editing/markers/DocumentMarkerController.cpp

Issue 2812423002: [DMC #1] Refactor DocumentMarkerController on top of new DocumentMarkerListEditor class (Closed)
Patch Set: Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698