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

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

Issue 2820633002: [DMC #2] Add DocumentMarkerList interface and GenericDocumentMarkerListImpl (Closed)
Patch Set: Fix nit Created 3 years, 7 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 17 matching lines...) Expand all
28 28
29 #include "core/editing/markers/DocumentMarkerController.h" 29 #include "core/editing/markers/DocumentMarkerController.h"
30 30
31 #include <algorithm> 31 #include <algorithm>
32 #include "core/dom/Node.h" 32 #include "core/dom/Node.h"
33 #include "core/dom/NodeTraversal.h" 33 #include "core/dom/NodeTraversal.h"
34 #include "core/dom/Range.h" 34 #include "core/dom/Range.h"
35 #include "core/dom/Text.h" 35 #include "core/dom/Text.h"
36 #include "core/editing/iterators/TextIterator.h" 36 #include "core/editing/iterators/TextIterator.h"
37 #include "core/editing/markers/DocumentMarkerListEditor.h" 37 #include "core/editing/markers/DocumentMarkerListEditor.h"
38 #include "core/editing/markers/GenericDocumentMarkerListImpl.h"
38 #include "core/editing/markers/RenderedDocumentMarker.h" 39 #include "core/editing/markers/RenderedDocumentMarker.h"
39 #include "core/frame/FrameView.h" 40 #include "core/frame/FrameView.h"
40 #include "core/layout/LayoutObject.h" 41 #include "core/layout/LayoutObject.h"
41 42
42 #ifndef NDEBUG 43 #ifndef NDEBUG
43 #include <stdio.h> 44 #include <stdio.h>
44 #endif 45 #endif
45 46
46 namespace blink { 47 namespace blink {
47 48
(...skipping 11 matching lines...) Expand all
59 case DocumentMarker::kComposition: 60 case DocumentMarker::kComposition:
60 return DocumentMarker::kCompositionMarkerIndex; 61 return DocumentMarker::kCompositionMarkerIndex;
61 } 62 }
62 63
63 NOTREACHED(); 64 NOTREACHED();
64 return DocumentMarker::kSpellingMarkerIndex; 65 return DocumentMarker::kSpellingMarkerIndex;
65 } 66 }
66 67
67 } // namespace 68 } // namespace
68 69
69 Member<DocumentMarkerController::MarkerList>& 70 Member<DocumentMarkerList>& DocumentMarkerController::ListForType(
70 DocumentMarkerController::ListForType(MarkerLists* marker_lists, 71 MarkerLists* marker_lists,
71 DocumentMarker::MarkerType type) { 72 DocumentMarker::MarkerType type) {
72 const size_t marker_list_index = MarkerTypeToMarkerIndex(type); 73 const size_t marker_list_index = MarkerTypeToMarkerIndex(type);
73 return (*marker_lists)[marker_list_index]; 74 return (*marker_lists)[marker_list_index];
74 } 75 }
75 76
76 inline bool DocumentMarkerController::PossiblyHasMarkers( 77 inline bool DocumentMarkerController::PossiblyHasMarkers(
77 DocumentMarker::MarkerTypes types) { 78 DocumentMarker::MarkerTypes types) {
78 return possibly_existing_marker_types_.Intersects(types); 79 return possibly_existing_marker_types_.Intersects(types);
79 } 80 }
80 81
81 DocumentMarkerController::DocumentMarkerController(Document& document) 82 DocumentMarkerController::DocumentMarkerController(Document& document)
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
198 possibly_existing_marker_types_.Add(new_marker->GetType()); 199 possibly_existing_marker_types_.Add(new_marker->GetType());
199 200
200 Member<MarkerLists>& markers = 201 Member<MarkerLists>& markers =
201 markers_.insert(node, nullptr).stored_value->value; 202 markers_.insert(node, nullptr).stored_value->value;
202 if (!markers) { 203 if (!markers) {
203 markers = new MarkerLists; 204 markers = new MarkerLists;
204 markers->Grow(DocumentMarker::kMarkerTypeIndexesCount); 205 markers->Grow(DocumentMarker::kMarkerTypeIndexesCount);
205 } 206 }
206 207
207 const DocumentMarker::MarkerType new_marker_type = new_marker->GetType(); 208 const DocumentMarker::MarkerType new_marker_type = new_marker->GetType();
208 if (!ListForType(markers, new_marker_type)) 209 if (!ListForType(markers, new_marker_type)) {
209 ListForType(markers, new_marker_type) = new MarkerList; 210 // TODO(rlanday): add method for deciding what type of list to create based
211 // on the MarkerType
212 ListForType(markers, new_marker_type) = new GenericDocumentMarkerListImpl;
213 }
210 214
211 Member<MarkerList>& list = ListForType(markers, new_marker_type); 215 DocumentMarkerList* const list = ListForType(markers, new_marker_type);
212 DocumentMarkerListEditor::AddMarker(list, new_marker); 216 list->Add(new_marker);
213 217
214 // repaint the affected node 218 // repaint the affected node
215 if (node->GetLayoutObject()) { 219 if (node->GetLayoutObject()) {
216 node->GetLayoutObject()->SetShouldDoFullPaintInvalidation( 220 node->GetLayoutObject()->SetShouldDoFullPaintInvalidation(
217 kPaintInvalidationDocumentMarkerChange); 221 kPaintInvalidationDocumentMarkerChange);
218 } 222 }
219 } 223 }
220 224
221 // Moves markers from src_node to dst_node. Markers are moved if their start 225 // Moves markers from src_node to dst_node. Markers are moved if their start
222 // offset is less than length. Markers that run past that point are truncated. 226 // offset is less than length. Markers that run past that point are truncated.
(...skipping 12 matching lines...) Expand all
235 return; 239 return;
236 240
237 if (!markers_.Contains(dst_node)) { 241 if (!markers_.Contains(dst_node)) {
238 markers_.insert(dst_node, 242 markers_.insert(dst_node,
239 new MarkerLists(DocumentMarker::kMarkerTypeIndexesCount)); 243 new MarkerLists(DocumentMarker::kMarkerTypeIndexesCount));
240 } 244 }
241 MarkerLists* dst_markers = markers_.at(dst_node); 245 MarkerLists* dst_markers = markers_.at(dst_node);
242 246
243 bool doc_dirty = false; 247 bool doc_dirty = false;
244 for (DocumentMarker::MarkerType type : DocumentMarker::AllMarkers()) { 248 for (DocumentMarker::MarkerType type : DocumentMarker::AllMarkers()) {
245 MarkerList* src_list = ListForType(src_markers, type); 249 DocumentMarkerList* const src_list = ListForType(src_markers, type);
246 if (!src_list) 250 if (!src_list)
247 continue; 251 continue;
248 252
249 if (!ListForType(dst_markers, type)) 253 if (!ListForType(dst_markers, type)) {
250 ListForType(dst_markers, type) = new MarkerList; 254 // TODO(rlanday): add method for deciding what type of list to create
251 MarkerList* dst_list = ListForType(dst_markers, type); 255 // based on the MarkerType
256 ListForType(dst_markers, type) = new GenericDocumentMarkerListImpl;
257 }
252 258
253 if (DocumentMarkerListEditor::MoveMarkers(src_list, length, dst_list)) 259 DocumentMarkerList* const dst_list = ListForType(dst_markers, type);
260 if (src_list->MoveMarkers(length, dst_list))
254 doc_dirty = true; 261 doc_dirty = true;
255 } 262 }
256 263
257 // repaint the affected node 264 // repaint the affected node
258 if (doc_dirty && dst_node->GetLayoutObject()) { 265 if (doc_dirty && dst_node->GetLayoutObject()) {
259 dst_node->GetLayoutObject()->SetShouldDoFullPaintInvalidation( 266 dst_node->GetLayoutObject()->SetShouldDoFullPaintInvalidation(
260 kPaintInvalidationDocumentMarkerChange); 267 kPaintInvalidationDocumentMarkerChange);
261 } 268 }
262 } 269 }
263 270
264 void DocumentMarkerController::RemoveMarkersInternal( 271 void DocumentMarkerController::RemoveMarkersInternal(
265 Node* node, 272 Node* node,
266 unsigned start_offset, 273 unsigned start_offset,
267 int length, 274 int length,
268 DocumentMarker::MarkerTypes marker_types) { 275 DocumentMarker::MarkerTypes marker_types) {
269 if (length <= 0) 276 if (length <= 0)
270 return; 277 return;
271 278
272 if (!PossiblyHasMarkers(marker_types)) 279 if (!PossiblyHasMarkers(marker_types))
273 return; 280 return;
274 DCHECK(!(markers_.IsEmpty())); 281 DCHECK(!(markers_.IsEmpty()));
275 282
276 MarkerLists* markers = markers_.at(node); 283 MarkerLists* markers = markers_.at(node);
277 if (!markers) 284 if (!markers)
278 return; 285 return;
279 286
280 bool doc_dirty = false; 287 bool doc_dirty = false;
281 size_t empty_lists_count = 0; 288 size_t empty_lists_count = 0;
282 for (DocumentMarker::MarkerType type : DocumentMarker::AllMarkers()) { 289 for (DocumentMarker::MarkerType type : DocumentMarker::AllMarkers()) {
283 Member<MarkerList>& list = ListForType(markers, type); 290 DocumentMarkerList* const list = ListForType(markers, type);
284 if (!list || list->IsEmpty()) { 291 if (!list || list->IsEmpty()) {
285 if (list.Get() && list->IsEmpty()) 292 if (list && list->IsEmpty())
286 list.Clear(); 293 ListForType(markers, type) = nullptr;
287 ++empty_lists_count; 294 ++empty_lists_count;
288 continue; 295 continue;
289 } 296 }
290 if (!marker_types.Contains(type)) 297 if (!marker_types.Contains(type))
291 continue; 298 continue;
292 299
293 if (DocumentMarkerListEditor::RemoveMarkers(list, start_offset, length)) 300 if (list->RemoveMarkers(start_offset, length))
294 doc_dirty = true; 301 doc_dirty = true;
295 302
296 if (list->IsEmpty()) { 303 if (list->IsEmpty()) {
297 list.Clear(); 304 ListForType(markers, type) = nullptr;
298 ++empty_lists_count; 305 ++empty_lists_count;
299 } 306 }
300 } 307 }
301 308
302 if (empty_lists_count == DocumentMarker::kMarkerTypeIndexesCount) { 309 if (empty_lists_count == DocumentMarker::kMarkerTypeIndexesCount) {
303 markers_.erase(node); 310 markers_.erase(node);
304 if (markers_.IsEmpty()) 311 if (markers_.IsEmpty())
305 possibly_existing_marker_types_ = 0; 312 possibly_existing_marker_types_ = 0;
306 } 313 }
307 314
308 // repaint the affected node 315 // repaint the affected node
309 if (doc_dirty && node->GetLayoutObject()) { 316 if (doc_dirty && node->GetLayoutObject()) {
310 node->GetLayoutObject()->SetShouldDoFullPaintInvalidation( 317 node->GetLayoutObject()->SetShouldDoFullPaintInvalidation(
311 kPaintInvalidationDocumentMarkerChange); 318 kPaintInvalidationDocumentMarkerChange);
312 } 319 }
313 } 320 }
314 321
315 DocumentMarkerVector DocumentMarkerController::MarkersFor( 322 DocumentMarkerVector DocumentMarkerController::MarkersFor(
316 Node* node, 323 Node* node,
317 DocumentMarker::MarkerTypes marker_types) { 324 DocumentMarker::MarkerTypes marker_types) {
318 DocumentMarkerVector result; 325 DocumentMarkerVector result;
319 326
320 MarkerLists* markers = markers_.at(node); 327 MarkerLists* markers = markers_.at(node);
321 if (!markers) 328 if (!markers)
322 return result; 329 return result;
323 330
324 for (DocumentMarker::MarkerType type : DocumentMarker::AllMarkers()) { 331 for (DocumentMarker::MarkerType type : DocumentMarker::AllMarkers()) {
325 Member<MarkerList>& list = ListForType(markers, type); 332 DocumentMarkerList* const list = ListForType(markers, type);
326 if (!list || list->IsEmpty() || 333 if (!list || list->IsEmpty() || !marker_types.Contains(type))
327 !marker_types.Contains((*list->begin())->GetType()))
328 continue; 334 continue;
329 335
330 for (size_t i = 0; i < list->size(); ++i) 336 result.AppendVector(list->GetMarkers());
331 result.push_back(list->at(i).Get());
332 } 337 }
333 338
334 std::sort(result.begin(), result.end(), 339 std::sort(result.begin(), result.end(),
335 [](const Member<DocumentMarker>& marker1, 340 [](const Member<DocumentMarker>& marker1,
336 const Member<DocumentMarker>& marker2) { 341 const Member<DocumentMarker>& marker2) {
337 return marker1->StartOffset() < marker2->StartOffset(); 342 return marker1->StartOffset() < marker2->StartOffset();
338 }); 343 });
339 return result; 344 return result;
340 } 345 }
341 346
342 DocumentMarkerVector DocumentMarkerController::Markers() { 347 DocumentMarkerVector DocumentMarkerController::Markers() {
343 DocumentMarkerVector result; 348 DocumentMarkerVector result;
344 for (MarkerMap::iterator i = markers_.begin(); i != markers_.end(); ++i) { 349 for (MarkerMap::iterator i = markers_.begin(); i != markers_.end(); ++i) {
345 MarkerLists* markers = i->value.Get(); 350 MarkerLists* markers = i->value.Get();
346 for (DocumentMarker::MarkerType type : DocumentMarker::AllMarkers()) { 351 for (DocumentMarker::MarkerType type : DocumentMarker::AllMarkers()) {
347 Member<MarkerList>& list = ListForType(markers, type); 352 DocumentMarkerList* const list = ListForType(markers, type);
348 for (size_t j = 0; list.Get() && j < list->size(); ++j) 353 if (!list)
349 result.push_back(list->at(j).Get()); 354 continue;
355 result.AppendVector(list->GetMarkers());
350 } 356 }
351 } 357 }
352 std::sort(result.begin(), result.end(), 358 std::sort(result.begin(), result.end(),
353 [](const Member<DocumentMarker>& marker1, 359 [](const Member<DocumentMarker>& marker1,
354 const Member<DocumentMarker>& marker2) { 360 const Member<DocumentMarker>& marker2) {
355 return marker1->StartOffset() < marker2->StartOffset(); 361 return marker1->StartOffset() < marker2->StartOffset();
356 }); 362 });
357 return result; 363 return result;
358 } 364 }
359 365
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
399 // outer loop: process each node 405 // outer loop: process each node
400 MarkerMap::iterator end = markers_.end(); 406 MarkerMap::iterator end = markers_.end();
401 for (MarkerMap::iterator node_iterator = markers_.begin(); 407 for (MarkerMap::iterator node_iterator = markers_.begin();
402 node_iterator != end; ++node_iterator) { 408 node_iterator != end; ++node_iterator) {
403 // inner loop; process each marker in this node 409 // inner loop; process each marker in this node
404 const Node& node = *node_iterator->key; 410 const Node& node = *node_iterator->key;
405 if (!node.isConnected()) 411 if (!node.isConnected())
406 continue; 412 continue;
407 MarkerLists* markers = node_iterator->value.Get(); 413 MarkerLists* markers = node_iterator->value.Get();
408 for (DocumentMarker::MarkerType type : DocumentMarker::AllMarkers()) { 414 for (DocumentMarker::MarkerType type : DocumentMarker::AllMarkers()) {
409 Member<MarkerList>& list = ListForType(markers, type); 415 DocumentMarkerList* const list = ListForType(markers, type);
410 if (!list || list->IsEmpty() || type != marker_type) 416 if (!list || list->IsEmpty() || type != marker_type)
411 continue; 417 continue;
412 for (unsigned marker_index = 0; marker_index < list->size(); 418
413 ++marker_index) { 419 for (RenderedDocumentMarker* rendered_marker : list->GetMarkers()) {
414 RenderedDocumentMarker* marker = list->at(marker_index).Get(); 420 UpdateMarkerRenderedRectIfNeeded(node, *rendered_marker);
415 UpdateMarkerRenderedRectIfNeeded(node, *marker); 421 if (!rendered_marker->IsRendered())
416 if (!marker->IsRendered())
417 continue; 422 continue;
418 result.push_back(marker->RenderedRect()); 423 result.push_back(rendered_marker->RenderedRect());
419 } 424 }
420 } 425 }
421 } 426 }
422 427
423 return result; 428 return result;
424 } 429 }
425 430
426 static void InvalidatePaintForTickmarks(const Node& node) { 431 static void InvalidatePaintForTickmarks(const Node& node) {
427 if (FrameView* frame_view = node.GetDocument().View()) 432 if (FrameView* frame_view = node.GetDocument().View())
428 frame_view->InvalidatePaintForTickmarks(); 433 frame_view->InvalidatePaintForTickmarks();
429 } 434 }
430 435
431 void DocumentMarkerController::UpdateMarkerRenderedRectIfNeeded( 436 void DocumentMarkerController::UpdateMarkerRenderedRectIfNeeded(
432 const Node& node, 437 const Node& node,
433 RenderedDocumentMarker& marker) { 438 RenderedDocumentMarker& marker) {
434 DCHECK(!document_->View() || !document_->View()->NeedsLayout()); 439 DCHECK(!document_->View() || !document_->View()->NeedsLayout());
435 DCHECK(!document_->NeedsLayoutTreeUpdate()); 440 DCHECK(!document_->NeedsLayoutTreeUpdate());
436 if (!marker.IsValid()) 441 if (!marker.IsValid())
437 UpdateMarkerRenderedRect(node, marker); 442 UpdateMarkerRenderedRect(node, marker);
438 } 443 }
439 444
440 void DocumentMarkerController::InvalidateRectsForMarkersInNode( 445 void DocumentMarkerController::InvalidateRectsForMarkersInNode(
441 const Node& node) { 446 const Node& node) {
442 MarkerLists* markers = markers_.at(&node); 447 MarkerLists* markers = markers_.at(&node);
443 448
444 for (auto& marker_list : *markers) { 449 for (auto& marker_list : *markers) {
445 if (!marker_list || marker_list->IsEmpty()) 450 if (!marker_list || marker_list->IsEmpty())
446 continue; 451 continue;
447 452
448 for (auto& marker : *marker_list) 453 const HeapVector<Member<RenderedDocumentMarker>>& markers_in_list =
454 marker_list->GetMarkers();
455 for (auto& marker : markers_in_list)
449 marker->Invalidate(); 456 marker->Invalidate();
450 457
451 if (marker_list->front()->GetType() == DocumentMarker::kTextMatch) 458 if (markers_in_list.front()->GetType() == DocumentMarker::kTextMatch)
452 InvalidatePaintForTickmarks(node); 459 InvalidatePaintForTickmarks(node);
453 } 460 }
454 } 461 }
455 462
456 void DocumentMarkerController::InvalidateRectsForAllMarkers() { 463 void DocumentMarkerController::InvalidateRectsForAllMarkers() {
457 for (auto& node_markers : markers_) { 464 for (auto& node_markers : markers_) {
458 const Node& node = *node_markers.key; 465 const Node& node = *node_markers.key;
459 for (auto& marker_list : *node_markers.value) { 466 for (auto& marker_list : *node_markers.value) {
460 if (!marker_list || marker_list->IsEmpty()) 467 if (!marker_list || marker_list->IsEmpty())
461 continue; 468 continue;
462 469
463 for (auto& marker : *marker_list) 470 const HeapVector<Member<RenderedDocumentMarker>>& markers_in_list =
464 marker->Invalidate(); 471 marker_list->GetMarkers();
472 for (DocumentMarker* marker : markers_in_list)
473 ToRenderedDocumentMarker(marker)->Invalidate();
465 474
466 if (marker_list->front()->GetType() == DocumentMarker::kTextMatch) 475 if (markers_in_list.front()->GetType() == DocumentMarker::kTextMatch)
467 InvalidatePaintForTickmarks(node); 476 InvalidatePaintForTickmarks(node);
468 } 477 }
469 } 478 }
470 } 479 }
471 480
472 DEFINE_TRACE(DocumentMarkerController) { 481 DEFINE_TRACE(DocumentMarkerController) {
473 visitor->Trace(markers_); 482 visitor->Trace(markers_);
474 visitor->Trace(document_); 483 visitor->Trace(document_);
475 SynchronousMutationObserver::Trace(visitor); 484 SynchronousMutationObserver::Trace(visitor);
476 } 485 }
(...skipping 12 matching lines...) Expand all
489 498
490 void DocumentMarkerController::RemoveSpellingMarkersUnderWords( 499 void DocumentMarkerController::RemoveSpellingMarkersUnderWords(
491 const Vector<String>& words) { 500 const Vector<String>& words) {
492 for (auto& node_markers : markers_) { 501 for (auto& node_markers : markers_) {
493 const Node& node = *node_markers.key; 502 const Node& node = *node_markers.key;
494 if (!node.IsTextNode()) 503 if (!node.IsTextNode())
495 continue; 504 continue;
496 MarkerLists* markers = node_markers.value; 505 MarkerLists* markers = node_markers.value;
497 for (DocumentMarker::MarkerType type : 506 for (DocumentMarker::MarkerType type :
498 DocumentMarker::MisspellingMarkers()) { 507 DocumentMarker::MisspellingMarkers()) {
499 MarkerList* list = ListForType(markers, type); 508 DocumentMarkerList* const list = ListForType(markers, type);
500 if (!list) 509 if (!list)
501 continue; 510 continue;
502 DocumentMarkerListEditor::RemoveMarkersUnderWords( 511 list->RemoveMarkersUnderWords(ToText(node).data(), words);
503 list, ToText(node).data(), words);
504 } 512 }
505 } 513 }
506 } 514 }
507 515
508 void DocumentMarkerController::RemoveMarkersOfTypes( 516 void DocumentMarkerController::RemoveMarkersOfTypes(
509 DocumentMarker::MarkerTypes marker_types) { 517 DocumentMarker::MarkerTypes marker_types) {
510 if (!PossiblyHasMarkers(marker_types)) 518 if (!PossiblyHasMarkers(marker_types))
511 return; 519 return;
512 DCHECK(!markers_.IsEmpty()); 520 DCHECK(!markers_.IsEmpty());
513 521
(...skipping 16 matching lines...) Expand all
530 bool node_can_be_removed; 538 bool node_can_be_removed;
531 539
532 size_t empty_lists_count = 0; 540 size_t empty_lists_count = 0;
533 if (marker_types == DocumentMarker::AllMarkers()) { 541 if (marker_types == DocumentMarker::AllMarkers()) {
534 needs_repainting = true; 542 needs_repainting = true;
535 node_can_be_removed = true; 543 node_can_be_removed = true;
536 } else { 544 } else {
537 MarkerLists* markers = iterator->value.Get(); 545 MarkerLists* markers = iterator->value.Get();
538 546
539 for (DocumentMarker::MarkerType type : DocumentMarker::AllMarkers()) { 547 for (DocumentMarker::MarkerType type : DocumentMarker::AllMarkers()) {
540 Member<MarkerList>& list = ListForType(markers, type); 548 DocumentMarkerList* const list = ListForType(markers, type);
541 if (!list || list->IsEmpty()) { 549 if (!list || list->IsEmpty()) {
542 if (list.Get() && list->IsEmpty()) 550 if (list && list->IsEmpty())
543 list.Clear(); 551 ListForType(markers, type) = nullptr;
544 ++empty_lists_count; 552 ++empty_lists_count;
545 continue; 553 continue;
546 } 554 }
547 if (marker_types.Contains(type)) { 555 if (marker_types.Contains(type)) {
548 list->clear(); 556 list->Clear();
549 list.Clear(); 557 ListForType(markers, type) = nullptr;
550 ++empty_lists_count; 558 ++empty_lists_count;
551 needs_repainting = true; 559 needs_repainting = true;
552 } 560 }
553 } 561 }
554 562
555 node_can_be_removed = 563 node_can_be_removed =
556 empty_lists_count == DocumentMarker::kMarkerTypeIndexesCount; 564 empty_lists_count == DocumentMarker::kMarkerTypeIndexesCount;
557 } 565 }
558 566
559 if (needs_repainting) { 567 if (needs_repainting) {
(...skipping 19 matching lines...) Expand all
579 DCHECK(!markers_.IsEmpty()); 587 DCHECK(!markers_.IsEmpty());
580 588
581 // outer loop: process each markered node in the document 589 // outer loop: process each markered node in the document
582 MarkerMap::iterator end = markers_.end(); 590 MarkerMap::iterator end = markers_.end();
583 for (MarkerMap::iterator i = markers_.begin(); i != end; ++i) { 591 for (MarkerMap::iterator i = markers_.begin(); i != end; ++i) {
584 const Node* node = i->key; 592 const Node* node = i->key;
585 593
586 // inner loop: process each marker in the current node 594 // inner loop: process each marker in the current node
587 MarkerLists* markers = i->value.Get(); 595 MarkerLists* markers = i->value.Get();
588 for (DocumentMarker::MarkerType type : DocumentMarker::AllMarkers()) { 596 for (DocumentMarker::MarkerType type : DocumentMarker::AllMarkers()) {
589 Member<MarkerList>& list = ListForType(markers, type); 597 DocumentMarkerList* const list = ListForType(markers, type);
590 if (!list || list->IsEmpty() || !marker_types.Contains(type)) 598 if (!list || list->IsEmpty() || !marker_types.Contains(type))
591 continue; 599 continue;
592 600
593 // cause the node to be redrawn 601 // cause the node to be redrawn
594 if (LayoutObject* layout_object = node->GetLayoutObject()) { 602 if (LayoutObject* layout_object = node->GetLayoutObject()) {
595 layout_object->SetShouldDoFullPaintInvalidation( 603 layout_object->SetShouldDoFullPaintInvalidation(
596 kPaintInvalidationDocumentMarkerChange); 604 kPaintInvalidationDocumentMarkerChange);
597 break; 605 break;
598 } 606 }
599 } 607 }
(...skipping 28 matching lines...) Expand all
628 636
629 bool DocumentMarkerController::SetMarkersActive(Node* node, 637 bool DocumentMarkerController::SetMarkersActive(Node* node,
630 unsigned start_offset, 638 unsigned start_offset,
631 unsigned end_offset, 639 unsigned end_offset,
632 bool active) { 640 bool active) {
633 MarkerLists* markers = markers_.at(node); 641 MarkerLists* markers = markers_.at(node);
634 if (!markers) 642 if (!markers)
635 return false; 643 return false;
636 644
637 bool doc_dirty = false; 645 bool doc_dirty = false;
638 Member<MarkerList>& list = ListForType(markers, DocumentMarker::kTextMatch); 646 DocumentMarkerList* const list =
647 ListForType(markers, DocumentMarker::kTextMatch);
648
639 if (!list) 649 if (!list)
640 return false; 650 return false;
641 MarkerList::iterator start_pos = std::upper_bound( 651
642 list->begin(), list->end(), start_offset, 652 const HeapVector<Member<RenderedDocumentMarker>>& markers_in_list =
643 [](size_t start_offset, const Member<RenderedDocumentMarker>& marker) { 653 list->GetMarkers();
654 // TODO(rlanday): this assumes that the markers are stored in sorted order.
655 // This method should probably eventually be implemented by a
656 // TextMatch-specific marker list
657 const auto start_pos = std::upper_bound(
658 markers_in_list.begin(), markers_in_list.end(), start_offset,
659 [](size_t start_offset, const Member<DocumentMarker>& marker) {
644 return start_offset < marker->EndOffset(); 660 return start_offset < marker->EndOffset();
645 }); 661 });
646 for (MarkerList::iterator marker = start_pos; marker != list->end(); 662 for (auto marker = start_pos; marker != markers_in_list.end(); ++marker) {
647 ++marker) {
648 // Markers are returned in order, so stop if we are now past the specified 663 // Markers are returned in order, so stop if we are now past the specified
649 // range. 664 // range.
650 if ((*marker)->StartOffset() >= end_offset) 665 if ((*marker)->StartOffset() >= end_offset)
651 break; 666 break;
652 667
653 (*marker)->SetIsActiveMatch(active); 668 (*marker)->SetIsActiveMatch(active);
654 doc_dirty = true; 669 doc_dirty = true;
655 } 670 }
656 671
657 // repaint the affected node 672 // repaint the affected node
658 if (doc_dirty && node->GetLayoutObject()) { 673 if (doc_dirty && node->GetLayoutObject()) {
659 node->GetLayoutObject()->SetShouldDoFullPaintInvalidation( 674 node->GetLayoutObject()->SetShouldDoFullPaintInvalidation(
660 kPaintInvalidationDocumentMarkerChange); 675 kPaintInvalidationDocumentMarkerChange);
661 } 676 }
662 return doc_dirty; 677 return doc_dirty;
663 } 678 }
664 679
665 #ifndef NDEBUG 680 #ifndef NDEBUG
666 void DocumentMarkerController::ShowMarkers() const { 681 void DocumentMarkerController::ShowMarkers() const {
667 StringBuilder builder; 682 StringBuilder builder;
668 MarkerMap::const_iterator end = markers_.end(); 683 MarkerMap::const_iterator end = markers_.end();
669 for (MarkerMap::const_iterator node_iterator = markers_.begin(); 684 for (MarkerMap::const_iterator node_iterator = markers_.begin();
670 node_iterator != end; ++node_iterator) { 685 node_iterator != end; ++node_iterator) {
671 const Node* node = node_iterator->key; 686 const Node* node = node_iterator->key;
672 builder.Append(String::Format("%p", node)); 687 builder.Append(String::Format("%p", node));
673 MarkerLists* markers = markers_.at(node); 688 MarkerLists* markers = markers_.at(node);
674 for (DocumentMarker::MarkerType type : DocumentMarker::AllMarkers()) { 689 for (DocumentMarker::MarkerType type : DocumentMarker::AllMarkers()) {
675 Member<MarkerList>& list = ListForType(markers, type); 690 DocumentMarkerList* const list = ListForType(markers, type);
676 for (unsigned marker_index = 0; list.Get() && marker_index < list->size(); 691 const HeapVector<Member<RenderedDocumentMarker>>& markers_in_list =
677 ++marker_index) { 692 list->GetMarkers();
678 DocumentMarker* marker = list->at(marker_index).Get(); 693 for (const DocumentMarker* marker : markers_in_list) {
679 builder.Append(" "); 694 builder.Append(" ");
680 builder.AppendNumber(marker->GetType()); 695 builder.AppendNumber(marker->GetType());
681 builder.Append(":["); 696 builder.Append(":[");
682 builder.AppendNumber(marker->StartOffset()); 697 builder.AppendNumber(marker->StartOffset());
683 builder.Append(":"); 698 builder.Append(":");
684 builder.AppendNumber(marker->EndOffset()); 699 builder.AppendNumber(marker->EndOffset());
685 builder.Append("]("); 700 builder.Append("](");
686 builder.AppendNumber(marker->IsActiveMatch()); 701 builder.AppendNumber(marker->IsActiveMatch());
687 builder.Append(")"); 702 builder.Append(")");
688 } 703 }
(...skipping 12 matching lines...) Expand all
701 unsigned new_length) { 716 unsigned new_length) {
702 if (!PossiblyHasMarkers(DocumentMarker::AllMarkers())) 717 if (!PossiblyHasMarkers(DocumentMarker::AllMarkers()))
703 return; 718 return;
704 DCHECK(!markers_.IsEmpty()); 719 DCHECK(!markers_.IsEmpty());
705 720
706 MarkerLists* markers = markers_.at(node); 721 MarkerLists* markers = markers_.at(node);
707 if (!markers) 722 if (!markers)
708 return; 723 return;
709 724
710 bool did_shift_marker = false; 725 bool did_shift_marker = false;
711 for (MarkerList* list : *markers) { 726 for (DocumentMarkerList* const list : *markers) {
712 if (!list) 727 if (!list)
713 continue; 728 continue;
714 729
715 if (DocumentMarkerListEditor::ShiftMarkers(list, offset, old_length, 730 if (list->ShiftMarkers(offset, old_length, new_length))
716 new_length))
717 did_shift_marker = true; 731 did_shift_marker = true;
718 } 732 }
719 733
720 if (!did_shift_marker) 734 if (!did_shift_marker)
721 return; 735 return;
722 if (!node->GetLayoutObject()) 736 if (!node->GetLayoutObject())
723 return; 737 return;
724 InvalidateRectsForMarkersInNode(*node); 738 InvalidateRectsForMarkersInNode(*node);
725 // repaint the affected node 739 // repaint the affected node
726 node->GetLayoutObject()->SetShouldDoFullPaintInvalidation(); 740 node->GetLayoutObject()->SetShouldDoFullPaintInvalidation();
727 } 741 }
728 742
729 } // namespace blink 743 } // namespace blink
730 744
731 #ifndef NDEBUG 745 #ifndef NDEBUG
732 void showDocumentMarkers(const blink::DocumentMarkerController* controller) { 746 void showDocumentMarkers(const blink::DocumentMarkerController* controller) {
733 if (controller) 747 if (controller)
734 controller->ShowMarkers(); 748 controller->ShowMarkers();
735 } 749 }
736 #endif 750 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698