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

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: Rebase 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 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 23 matching lines...) Expand all
71 case DocumentMarker::kComposition: 72 case DocumentMarker::kComposition:
72 return DocumentMarker::kCompositionMarkerIndex; 73 return DocumentMarker::kCompositionMarkerIndex;
73 } 74 }
74 75
75 NOTREACHED(); 76 NOTREACHED();
76 return DocumentMarker::kSpellingMarkerIndex; 77 return DocumentMarker::kSpellingMarkerIndex;
77 } 78 }
78 79
79 } // namespace 80 } // namespace
80 81
81 Member<DocumentMarkerController::MarkerList>& 82 Member<DocumentMarkerList>& DocumentMarkerController::ListForType(
82 DocumentMarkerController::ListForType(MarkerLists* marker_lists, 83 MarkerLists* marker_lists,
83 DocumentMarker::MarkerType type) { 84 DocumentMarker::MarkerType type) {
84 const size_t marker_list_index = MarkerTypeToMarkerIndex(type); 85 const size_t marker_list_index = MarkerTypeToMarkerIndex(type);
85 return (*marker_lists)[marker_list_index]; 86 return (*marker_lists)[marker_list_index];
86 } 87 }
87 88
88 inline bool DocumentMarkerController::PossiblyHasMarkers( 89 inline bool DocumentMarkerController::PossiblyHasMarkers(
89 DocumentMarker::MarkerTypes types) { 90 DocumentMarker::MarkerTypes types) {
90 return possibly_existing_marker_types_.Intersects(types); 91 return possibly_existing_marker_types_.Intersects(types);
91 } 92 }
92 93
93 DocumentMarkerController::DocumentMarkerController(Document& document) 94 DocumentMarkerController::DocumentMarkerController(Document& document)
94 : possibly_existing_marker_types_(0), document_(&document) { 95 : possibly_existing_marker_types_(0), document_(&document) {
95 SetContext(&document); 96 SetContext(&document);
96 } 97 }
97 98
98 void DocumentMarkerController::Clear() { 99 void DocumentMarkerController::Clear() {
99 markers_.Clear(); 100 markers_.Clear();
100 possibly_existing_marker_types_ = 0; 101 possibly_existing_marker_types_ = 0;
101 } 102 }
102 103
103 void DocumentMarkerController::AddMarker(const Position& start, 104 void DocumentMarkerController::AddMarker(const Position& start,
104 const Position& end, 105 const Position& end,
105 DocumentMarker::MarkerType type, 106 DocumentMarker::MarkerType type,
106 const String& description) { 107 const String& description) {
107 // Use a TextIterator to visit the potentially multiple nodes the range 108 // Use a TextIterator to visit the potentially multiple nodes the range
108 // covers. 109 // covers.
109 for (TextIterator marked_text(start, end); !marked_text.AtEnd(); 110 for (TextIterator marked_text(start, end); !marked_text.AtEnd();
110 marked_text.Advance()) { 111 marked_text.Advance()) {
111 AddMarker( 112 AddMarker(marked_text.CurrentContainer(),
112 marked_text.CurrentContainer(), 113 new DocumentMarker(
113 DocumentMarker(type, marked_text.StartOffsetInCurrentContainer(), 114 type, marked_text.StartOffsetInCurrentContainer(),
114 marked_text.EndOffsetInCurrentContainer(), description)); 115 marked_text.EndOffsetInCurrentContainer(), description));
115 } 116 }
116 } 117 }
117 118
118 void DocumentMarkerController::AddTextMatchMarker( 119 void DocumentMarkerController::AddTextMatchMarker(
119 const EphemeralRange& range, 120 const EphemeralRange& range,
120 DocumentMarker::MatchStatus match_status) { 121 DocumentMarker::MatchStatus match_status) {
121 DCHECK(!document_->NeedsLayoutTreeUpdate()); 122 DCHECK(!document_->NeedsLayoutTreeUpdate());
122 123
123 // Use a TextIterator to visit the potentially multiple nodes the range 124 // Use a TextIterator to visit the potentially multiple nodes the range
124 // covers. 125 // covers.
125 for (TextIterator marked_text(range.StartPosition(), range.EndPosition()); 126 for (TextIterator marked_text(range.StartPosition(), range.EndPosition());
126 !marked_text.AtEnd(); marked_text.Advance()) { 127 !marked_text.AtEnd(); marked_text.Advance()) {
127 AddMarker(marked_text.CurrentContainer(), 128 AddMarker(marked_text.CurrentContainer(),
128 DocumentMarker(marked_text.StartOffsetInCurrentContainer(), 129 new DocumentMarker(marked_text.StartOffsetInCurrentContainer(),
129 marked_text.EndOffsetInCurrentContainer(), 130 marked_text.EndOffsetInCurrentContainer(),
130 match_status)); 131 match_status));
131 } 132 }
132 // Don't invalidate tickmarks here. TextFinder invalidates tickmarks using a 133 // Don't invalidate tickmarks here. TextFinder invalidates tickmarks using a
133 // throttling algorithm. crbug.com/6819. 134 // throttling algorithm. crbug.com/6819.
134 } 135 }
135 136
136 void DocumentMarkerController::AddCompositionMarker(const Position& start, 137 void DocumentMarkerController::AddCompositionMarker(const Position& start,
137 const Position& end, 138 const Position& end,
138 Color underline_color, 139 Color underline_color,
139 bool thick, 140 bool thick,
140 Color background_color) { 141 Color background_color) {
141 DCHECK(!document_->NeedsLayoutTreeUpdate()); 142 DCHECK(!document_->NeedsLayoutTreeUpdate());
142 143
143 for (TextIterator marked_text(start, end); !marked_text.AtEnd(); 144 for (TextIterator marked_text(start, end); !marked_text.AtEnd();
144 marked_text.Advance()) 145 marked_text.Advance()) {
145 AddMarker(marked_text.CurrentContainer(), 146 AddMarker(marked_text.CurrentContainer(),
146 DocumentMarker(marked_text.StartOffsetInCurrentContainer(), 147 new DocumentMarker(marked_text.StartOffsetInCurrentContainer(),
147 marked_text.EndOffsetInCurrentContainer(), 148 marked_text.EndOffsetInCurrentContainer(),
148 underline_color, thick, background_color)); 149 underline_color, thick, background_color));
150 }
149 } 151 }
150 152
151 void DocumentMarkerController::PrepareForDestruction() { 153 void DocumentMarkerController::PrepareForDestruction() {
152 Clear(); 154 Clear();
153 } 155 }
154 156
155 void DocumentMarkerController::RemoveMarkers( 157 void DocumentMarkerController::RemoveMarkers(
156 TextIterator& marked_text, 158 TextIterator& marked_text,
157 DocumentMarker::MarkerTypes marker_types) { 159 DocumentMarker::MarkerTypes marker_types) {
158 for (; !marked_text.AtEnd(); marked_text.Advance()) { 160 for (; !marked_text.AtEnd(); marked_text.Advance()) {
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
199 } else { 201 } else {
200 marker.NullifyRenderedRect(); 202 marker.NullifyRenderedRect();
201 } 203 }
202 range->Dispose(); 204 range->Dispose();
203 } 205 }
204 206
205 // Markers are stored in order sorted by their start offset. 207 // Markers are stored in order sorted by their start offset.
206 // Markers of the same type do not overlap each other. 208 // Markers of the same type do not overlap each other.
207 209
208 void DocumentMarkerController::AddMarker(Node* node, 210 void DocumentMarkerController::AddMarker(Node* node,
209 const DocumentMarker& new_marker) { 211 DocumentMarker* new_marker) {
210 DCHECK_GE(new_marker.EndOffset(), new_marker.StartOffset()); 212 DCHECK_GE(new_marker->EndOffset(), new_marker->StartOffset());
211 if (new_marker.EndOffset() == new_marker.StartOffset()) 213 if (new_marker->EndOffset() == new_marker->StartOffset())
212 return; 214 return;
213 215
214 possibly_existing_marker_types_.Add(new_marker.GetType()); 216 possibly_existing_marker_types_.Add(new_marker->GetType());
215 217
216 Member<MarkerLists>& markers = 218 Member<MarkerLists>& markers =
217 markers_.insert(node, nullptr).stored_value->value; 219 markers_.insert(node, nullptr).stored_value->value;
218 if (!markers) { 220 if (!markers) {
219 markers = new MarkerLists; 221 markers = new MarkerLists;
220 markers->Grow(DocumentMarker::kMarkerTypeIndexesCount); 222 markers->Grow(DocumentMarker::kMarkerTypeIndexesCount);
221 } 223 }
222 224
223 const DocumentMarker::MarkerType new_marker_type = new_marker.GetType(); 225 const DocumentMarker::MarkerType new_marker_type = new_marker->GetType();
224 if (!ListForType(markers, new_marker_type)) 226 if (!ListForType(markers, new_marker_type))
225 ListForType(markers, new_marker_type) = new MarkerList; 227 ListForType(markers, new_marker_type) = new GenericDocumentMarkerListImpl;
226 228
227 Member<MarkerList>& list = ListForType(markers, new_marker_type); 229 Member<DocumentMarkerList>& list = ListForType(markers, new_marker_type);
228 DocumentMarkerListEditor::AddMarker(list, &new_marker); 230 list->Add(new_marker);
229 231
230 // repaint the affected node 232 // repaint the affected node
231 if (node->GetLayoutObject()) { 233 if (node->GetLayoutObject()) {
232 node->GetLayoutObject()->SetShouldDoFullPaintInvalidation( 234 node->GetLayoutObject()->SetShouldDoFullPaintInvalidation(
233 kPaintInvalidationDocumentMarkerChange); 235 kPaintInvalidationDocumentMarkerChange);
234 } 236 }
235 } 237 }
236 238
237 // Moves markers from src_node to dst_node. Markers are moved if their start 239 // Moves markers from src_node to dst_node. Markers are moved if their start
238 // offset is less than length. Markers that run past that point are truncated. 240 // offset is less than length. Markers that run past that point are truncated.
(...skipping 13 matching lines...) Expand all
252 254
253 if (!markers_.Contains(dst_node)) { 255 if (!markers_.Contains(dst_node)) {
254 markers_.insert(dst_node, 256 markers_.insert(dst_node,
255 new MarkerLists(DocumentMarker::kMarkerTypeIndexesCount)); 257 new MarkerLists(DocumentMarker::kMarkerTypeIndexesCount));
256 } 258 }
257 MarkerLists* dst_markers = markers_.at(dst_node); 259 MarkerLists* dst_markers = markers_.at(dst_node);
258 260
259 bool doc_dirty = false; 261 bool doc_dirty = false;
260 for (size_t marker_list_index = 0; marker_list_index < src_markers->size(); 262 for (size_t marker_list_index = 0; marker_list_index < src_markers->size();
261 ++marker_list_index) { 263 ++marker_list_index) {
262 MarkerList* src_list = src_markers->at(marker_list_index); 264 DocumentMarkerList* src_list = src_markers->at(marker_list_index);
263 if (!src_list) 265 if (!src_list)
264 continue; 266 continue;
265 267
266 if (!dst_markers->at(marker_list_index)) 268 if (!dst_markers->at(marker_list_index))
267 dst_markers->at(marker_list_index) = new MarkerList; 269 dst_markers->at(marker_list_index) = new GenericDocumentMarkerListImpl;
268 MarkerList* dst_list = dst_markers->at(marker_list_index);
269 270
270 if (DocumentMarkerListEditor::MoveMarkers(src_list, length, dst_list)) 271 if (src_list->MoveMarkers(length, dst_markers->at(marker_list_index)))
271 doc_dirty = true; 272 doc_dirty = true;
272 } 273 }
273 274
274 // repaint the affected node 275 // repaint the affected node
275 if (doc_dirty && dst_node->GetLayoutObject()) { 276 if (doc_dirty && dst_node->GetLayoutObject()) {
276 dst_node->GetLayoutObject()->SetShouldDoFullPaintInvalidation( 277 dst_node->GetLayoutObject()->SetShouldDoFullPaintInvalidation(
277 kPaintInvalidationDocumentMarkerChange); 278 kPaintInvalidationDocumentMarkerChange);
278 } 279 }
279 } 280 }
280 281
281 void DocumentMarkerController::RemoveMarkers( 282 void DocumentMarkerController::RemoveMarkers(
282 Node* node, 283 Node* node,
283 unsigned start_offset, 284 unsigned start_offset,
284 int length, 285 int length,
285 DocumentMarker::MarkerTypes marker_types) { 286 DocumentMarker::MarkerTypes marker_types) {
286 if (length <= 0) 287 if (length <= 0)
287 return; 288 return;
288 289
289 if (!PossiblyHasMarkers(marker_types)) 290 if (!PossiblyHasMarkers(marker_types))
290 return; 291 return;
291 DCHECK(!(markers_.IsEmpty())); 292 DCHECK(!(markers_.IsEmpty()));
292 293
293 MarkerLists* markers = markers_.at(node); 294 MarkerLists* markers = markers_.at(node);
294 if (!markers) 295 if (!markers)
295 return; 296 return;
296 297
297 bool doc_dirty = false; 298 bool doc_dirty = false;
298 size_t empty_lists_count = 0; 299 size_t empty_lists_count = 0;
299 for (size_t marker_list_index = 0; 300 for (DocumentMarker::MarkerType type : DocumentMarker::AllMarkers()) {
300 marker_list_index < DocumentMarker::kMarkerTypeIndexesCount; 301 size_t marker_list_index = MarkerTypeToMarkerIndex(type);
301 ++marker_list_index) { 302 DocumentMarkerList* list = (*markers)[marker_list_index];
302 Member<MarkerList>& list = (*markers)[marker_list_index];
303 if (!list || list->IsEmpty()) { 303 if (!list || list->IsEmpty()) {
304 if (list.Get() && list->IsEmpty()) 304 if (list && list->IsEmpty())
305 list.Clear(); 305 (*markers)[marker_list_index] = nullptr;
306 ++empty_lists_count; 306 ++empty_lists_count;
307 continue; 307 continue;
308 } 308 }
309 if (!marker_types.Contains((*list->begin())->GetType())) 309 if (!marker_types.Contains(type))
310 continue; 310 continue;
311 311
312 if (DocumentMarkerListEditor::RemoveMarkers(list, start_offset, length)) 312 if (list->RemoveMarkers(start_offset, length))
313 doc_dirty = true; 313 doc_dirty = true;
314 314
315 if (list->IsEmpty()) { 315 if (list->IsEmpty()) {
316 list.Clear(); 316 (*markers)[marker_list_index] = nullptr;
317 ++empty_lists_count; 317 ++empty_lists_count;
318 } 318 }
319 } 319 }
320 320
321 if (empty_lists_count == DocumentMarker::kMarkerTypeIndexesCount) { 321 if (empty_lists_count == DocumentMarker::kMarkerTypeIndexesCount) {
322 markers_.erase(node); 322 markers_.erase(node);
323 if (markers_.IsEmpty()) 323 if (markers_.IsEmpty())
324 possibly_existing_marker_types_ = 0; 324 possibly_existing_marker_types_ = 0;
325 } 325 }
326 326
327 // repaint the affected node 327 // repaint the affected node
328 if (doc_dirty && node->GetLayoutObject()) { 328 if (doc_dirty && node->GetLayoutObject()) {
329 node->GetLayoutObject()->SetShouldDoFullPaintInvalidation( 329 node->GetLayoutObject()->SetShouldDoFullPaintInvalidation(
330 kPaintInvalidationDocumentMarkerChange); 330 kPaintInvalidationDocumentMarkerChange);
331 } 331 }
332 } 332 }
333 333
334 DocumentMarkerVector DocumentMarkerController::MarkersFor( 334 DocumentMarkerVector DocumentMarkerController::MarkersFor(
335 Node* node, 335 Node* node,
336 DocumentMarker::MarkerTypes marker_types) { 336 DocumentMarker::MarkerTypes marker_types) {
337 DocumentMarkerVector result; 337 DocumentMarkerVector result;
338 338
339 MarkerLists* markers = markers_.at(node); 339 MarkerLists* markers = markers_.at(node);
340 if (!markers) 340 if (!markers)
341 return result; 341 return result;
342 342
343 for (size_t marker_list_index = 0; 343 for (DocumentMarker::MarkerType type : DocumentMarker::AllMarkers()) {
344 marker_list_index < DocumentMarker::kMarkerTypeIndexesCount; 344 size_t marker_list_index = MarkerTypeToMarkerIndex(type);
345 ++marker_list_index) { 345 DocumentMarkerList* list = (*markers)[marker_list_index];
346 Member<MarkerList>& list = (*markers)[marker_list_index]; 346 if (!list || list->IsEmpty() || !marker_types.Contains(type))
347 if (!list || list->IsEmpty() ||
348 !marker_types.Contains((*list->begin())->GetType()))
349 continue; 347 continue;
350 348
351 for (size_t i = 0; i < list->size(); ++i) 349 list->AppendMarkersToInputList(&result);
yosin_UTC9 2017/04/20 05:28:46 I prefer to have list->GetMarkers() -> Vector<Memb
352 result.push_back(list->at(i).Get());
353 } 350 }
354 351
355 std::sort(result.begin(), result.end(), CompareByStart); 352 std::sort(result.begin(), result.end(), CompareByStart);
356 return result; 353 return result;
357 } 354 }
358 355
359 DocumentMarkerVector DocumentMarkerController::Markers() { 356 DocumentMarkerVector DocumentMarkerController::Markers() {
360 DocumentMarkerVector result; 357 DocumentMarkerVector result;
361 for (MarkerMap::iterator i = markers_.begin(); i != markers_.end(); ++i) { 358 for (MarkerMap::iterator i = markers_.begin(); i != markers_.end(); ++i) {
362 MarkerLists* markers = i->value.Get(); 359 MarkerLists* markers = i->value.Get();
363 for (size_t marker_list_index = 0; 360 for (size_t marker_list_index = 0;
364 marker_list_index < DocumentMarker::kMarkerTypeIndexesCount; 361 marker_list_index < DocumentMarker::kMarkerTypeIndexesCount;
365 ++marker_list_index) { 362 ++marker_list_index) {
366 Member<MarkerList>& list = (*markers)[marker_list_index]; 363 DocumentMarkerList* list = (*markers)[marker_list_index];
367 for (size_t j = 0; list.Get() && j < list->size(); ++j) 364 if (!list)
368 result.push_back(list->at(j).Get()); 365 continue;
366 list->AppendMarkersToInputList(&result);
369 } 367 }
370 } 368 }
371 std::sort(result.begin(), result.end(), CompareByStart); 369 std::sort(result.begin(), result.end(), CompareByStart);
372 return result; 370 return result;
373 } 371 }
374 372
375 DocumentMarkerVector DocumentMarkerController::MarkersInRange( 373 DocumentMarkerVector DocumentMarkerController::MarkersInRange(
376 const EphemeralRange& range, 374 const EphemeralRange& range,
377 DocumentMarker::MarkerTypes marker_types) { 375 DocumentMarker::MarkerTypes marker_types) {
378 if (!PossiblyHasMarkers(marker_types)) 376 if (!PossiblyHasMarkers(marker_types))
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
413 411
414 // outer loop: process each node 412 // outer loop: process each node
415 MarkerMap::iterator end = markers_.end(); 413 MarkerMap::iterator end = markers_.end();
416 for (MarkerMap::iterator node_iterator = markers_.begin(); 414 for (MarkerMap::iterator node_iterator = markers_.begin();
417 node_iterator != end; ++node_iterator) { 415 node_iterator != end; ++node_iterator) {
418 // inner loop; process each marker in this node 416 // inner loop; process each marker in this node
419 const Node& node = *node_iterator->key; 417 const Node& node = *node_iterator->key;
420 if (!node.isConnected()) 418 if (!node.isConnected())
421 continue; 419 continue;
422 MarkerLists* markers = node_iterator->value.Get(); 420 MarkerLists* markers = node_iterator->value.Get();
423 for (size_t marker_list_index = 0; 421 for (DocumentMarker::MarkerType type : DocumentMarker::AllMarkers()) {
424 marker_list_index < DocumentMarker::kMarkerTypeIndexesCount; 422 size_t marker_list_index = MarkerTypeToMarkerIndex(type);
425 ++marker_list_index) { 423 DocumentMarkerList* list = (*markers)[marker_list_index];
426 Member<MarkerList>& list = (*markers)[marker_list_index]; 424 if (!list || list->IsEmpty() || type != marker_type)
427 if (!list || list->IsEmpty() ||
428 (*list->begin())->GetType() != marker_type)
429 continue; 425 continue;
430 for (unsigned marker_index = 0; marker_index < list->size(); 426
431 ++marker_index) { 427 DocumentMarkerVector markers_in_list;
432 RenderedDocumentMarker* marker = list->at(marker_index).Get(); 428 list->AppendMarkersToInputList(&markers_in_list);
433 UpdateMarkerRenderedRectIfNeeded(node, *marker); 429
434 if (!marker->IsRendered()) 430 for (DocumentMarker* marker : markers_in_list) {
431 RenderedDocumentMarker* rendered_marker =
432 ToRenderedDocumentMarker(marker);
433 UpdateMarkerRenderedRectIfNeeded(node, *rendered_marker);
434 if (!rendered_marker->IsRendered())
435 continue; 435 continue;
436 result.push_back(marker->RenderedRect()); 436 result.push_back(rendered_marker->RenderedRect());
437 } 437 }
438 } 438 }
439 } 439 }
440 440
441 return result; 441 return result;
442 } 442 }
443 443
444 static void InvalidatePaintForTickmarks(const Node& node) { 444 static void InvalidatePaintForTickmarks(const Node& node) {
445 if (FrameView* frame_view = node.GetDocument().View()) 445 if (FrameView* frame_view = node.GetDocument().View())
446 frame_view->InvalidatePaintForTickmarks(); 446 frame_view->InvalidatePaintForTickmarks();
447 } 447 }
448 448
449 void DocumentMarkerController::UpdateMarkerRenderedRectIfNeeded( 449 void DocumentMarkerController::UpdateMarkerRenderedRectIfNeeded(
450 const Node& node, 450 const Node& node,
451 RenderedDocumentMarker& marker) { 451 RenderedDocumentMarker& marker) {
452 DCHECK(!document_->View() || !document_->View()->NeedsLayout()); 452 DCHECK(!document_->View() || !document_->View()->NeedsLayout());
453 DCHECK(!document_->NeedsLayoutTreeUpdate()); 453 DCHECK(!document_->NeedsLayoutTreeUpdate());
454 if (!marker.IsValid()) 454 if (!marker.IsValid())
455 UpdateMarkerRenderedRect(node, marker); 455 UpdateMarkerRenderedRect(node, marker);
456 } 456 }
457 457
458 void DocumentMarkerController::InvalidateRectsForMarkersInNode( 458 void DocumentMarkerController::InvalidateRectsForMarkersInNode(
459 const Node& node) { 459 const Node& node) {
460 MarkerLists* markers = markers_.at(&node); 460 MarkerLists* markers = markers_.at(&node);
461 461
462 for (auto& marker_list : *markers) { 462 for (auto& marker_list : *markers) {
463 if (!marker_list || marker_list->IsEmpty()) 463 if (!marker_list || marker_list->IsEmpty())
464 continue; 464 continue;
465 465
466 for (auto& marker : *marker_list) 466 DocumentMarkerVector markers_in_list;
467 marker->Invalidate(); 467 marker_list->AppendMarkersToInputList(&markers_in_list);
468 for (auto& marker : markers_in_list)
469 ToRenderedDocumentMarker(marker)->Invalidate();
468 470
469 if (marker_list->front()->GetType() == DocumentMarker::kTextMatch) 471 if (markers_in_list.front()->GetType() == DocumentMarker::kTextMatch)
470 InvalidatePaintForTickmarks(node); 472 InvalidatePaintForTickmarks(node);
471 } 473 }
472 } 474 }
473 475
474 void DocumentMarkerController::InvalidateRectsForAllMarkers() { 476 void DocumentMarkerController::InvalidateRectsForAllMarkers() {
475 for (auto& node_markers : markers_) { 477 for (auto& node_markers : markers_) {
476 const Node& node = *node_markers.key; 478 const Node& node = *node_markers.key;
477 for (auto& marker_list : *node_markers.value) { 479 for (auto& marker_list : *node_markers.value) {
478 if (!marker_list || marker_list->IsEmpty()) 480 if (!marker_list || marker_list->IsEmpty())
479 continue; 481 continue;
480 482
481 for (auto& marker : *marker_list) 483 DocumentMarkerVector markers_in_list;
482 marker->Invalidate(); 484 marker_list->AppendMarkersToInputList(&markers_in_list);
485 for (DocumentMarker* marker : markers_in_list)
486 ToRenderedDocumentMarker(marker)->Invalidate();
483 487
484 if (marker_list->front()->GetType() == DocumentMarker::kTextMatch) 488 if (markers_in_list.front()->GetType() == DocumentMarker::kTextMatch)
485 InvalidatePaintForTickmarks(node); 489 InvalidatePaintForTickmarks(node);
486 } 490 }
487 } 491 }
488 } 492 }
489 493
490 DEFINE_TRACE(DocumentMarkerController) { 494 DEFINE_TRACE(DocumentMarkerController) {
491 visitor->Trace(markers_); 495 visitor->Trace(markers_);
492 visitor->Trace(document_); 496 visitor->Trace(document_);
493 SynchronousMutationObserver::Trace(visitor); 497 SynchronousMutationObserver::Trace(visitor);
494 } 498 }
(...skipping 13 matching lines...) Expand all
508 void DocumentMarkerController::RemoveMarkers( 512 void DocumentMarkerController::RemoveMarkers(
509 const MarkerRemoverPredicate& should_remove_marker) { 513 const MarkerRemoverPredicate& should_remove_marker) {
510 for (auto& node_markers : markers_) { 514 for (auto& node_markers : markers_) {
511 const Node& node = *node_markers.key; 515 const Node& node = *node_markers.key;
512 if (!node.IsTextNode()) // MarkerRemoverPredicate requires a Text node. 516 if (!node.IsTextNode()) // MarkerRemoverPredicate requires a Text node.
513 continue; 517 continue;
514 MarkerLists& markers = *node_markers.value; 518 MarkerLists& markers = *node_markers.value;
515 for (size_t marker_list_index = 0; 519 for (size_t marker_list_index = 0;
516 marker_list_index < DocumentMarker::kMarkerTypeIndexesCount; 520 marker_list_index < DocumentMarker::kMarkerTypeIndexesCount;
517 ++marker_list_index) { 521 ++marker_list_index) {
518 Member<MarkerList>& list = markers[marker_list_index]; 522 DocumentMarkerList* list = markers[marker_list_index];
519 if (!list) 523 if (!list)
520 continue; 524 continue;
521 bool removed_markers = false; 525 bool removed_markers = false;
522 for (size_t j = list->size(); j > 0; --j) { 526
523 if (should_remove_marker(*list->at(j - 1), 527 DocumentMarkerVector markers_in_list;
528 list->AppendMarkersToInputList(&markers_in_list);
529
530 for (size_t j = markers_in_list.size(); j > 0; --j) {
531 if (should_remove_marker(*markers_in_list[j - 1],
524 static_cast<const Text&>(node))) { 532 static_cast<const Text&>(node))) {
525 list->erase(j - 1); 533 markers_in_list.erase(j - 1);
526 removed_markers = true; 534 removed_markers = true;
527 } 535 }
528 } 536 }
537
538 list->Clear();
539 for (DocumentMarker* marker : markers_in_list)
540 list->Add(marker);
541
529 if (removed_markers && 542 if (removed_markers &&
530 marker_list_index == DocumentMarker::kTextMatchMarkerIndex) 543 marker_list_index == DocumentMarker::kTextMatchMarkerIndex)
531 InvalidatePaintForTickmarks(node); 544 InvalidatePaintForTickmarks(node);
532 } 545 }
533 } 546 }
534 } 547 }
535 548
536 void DocumentMarkerController::RemoveMarkers( 549 void DocumentMarkerController::RemoveMarkers(
537 DocumentMarker::MarkerTypes marker_types) { 550 DocumentMarker::MarkerTypes marker_types) {
538 if (!PossiblyHasMarkers(marker_types)) 551 if (!PossiblyHasMarkers(marker_types))
(...skipping 18 matching lines...) Expand all
557 bool needs_repainting = false; 570 bool needs_repainting = false;
558 bool node_can_be_removed; 571 bool node_can_be_removed;
559 572
560 size_t empty_lists_count = 0; 573 size_t empty_lists_count = 0;
561 if (marker_types == DocumentMarker::AllMarkers()) { 574 if (marker_types == DocumentMarker::AllMarkers()) {
562 needs_repainting = true; 575 needs_repainting = true;
563 node_can_be_removed = true; 576 node_can_be_removed = true;
564 } else { 577 } else {
565 MarkerLists* markers = iterator->value.Get(); 578 MarkerLists* markers = iterator->value.Get();
566 579
567 for (size_t marker_list_index = 0; 580 for (DocumentMarker::MarkerType type : DocumentMarker::AllMarkers()) {
568 marker_list_index < DocumentMarker::kMarkerTypeIndexesCount; 581 size_t marker_list_index = MarkerTypeToMarkerIndex(type);
569 ++marker_list_index) { 582 DocumentMarkerList* list = (*markers)[marker_list_index];
570 Member<MarkerList>& list = (*markers)[marker_list_index];
571 if (!list || list->IsEmpty()) { 583 if (!list || list->IsEmpty()) {
572 if (list.Get() && list->IsEmpty()) 584 if (list && list->IsEmpty())
573 list.Clear(); 585 (*markers)[marker_list_index] = nullptr;
574 ++empty_lists_count; 586 ++empty_lists_count;
575 continue; 587 continue;
576 } 588 }
577 if (marker_types.Contains((*list->begin())->GetType())) { 589 if (marker_types.Contains(type)) {
578 list->clear(); 590 list->Clear();
579 list.Clear(); 591 ListForType(markers, type) = nullptr;
580 ++empty_lists_count; 592 ++empty_lists_count;
581 needs_repainting = true; 593 needs_repainting = true;
582 } 594 }
583 } 595 }
584 596
585 node_can_be_removed = 597 node_can_be_removed =
586 empty_lists_count == DocumentMarker::kMarkerTypeIndexesCount; 598 empty_lists_count == DocumentMarker::kMarkerTypeIndexesCount;
587 } 599 }
588 600
589 if (needs_repainting) { 601 if (needs_repainting) {
(...skipping 18 matching lines...) Expand all
608 return; 620 return;
609 DCHECK(!markers_.IsEmpty()); 621 DCHECK(!markers_.IsEmpty());
610 622
611 // outer loop: process each markered node in the document 623 // outer loop: process each markered node in the document
612 MarkerMap::iterator end = markers_.end(); 624 MarkerMap::iterator end = markers_.end();
613 for (MarkerMap::iterator i = markers_.begin(); i != end; ++i) { 625 for (MarkerMap::iterator i = markers_.begin(); i != end; ++i) {
614 const Node* node = i->key; 626 const Node* node = i->key;
615 627
616 // inner loop: process each marker in the current node 628 // inner loop: process each marker in the current node
617 MarkerLists* markers = i->value.Get(); 629 MarkerLists* markers = i->value.Get();
618 for (size_t marker_list_index = 0; 630 for (DocumentMarker::MarkerType type : DocumentMarker::AllMarkers()) {
619 marker_list_index < DocumentMarker::kMarkerTypeIndexesCount; 631 size_t marker_list_index = MarkerTypeToMarkerIndex(type);
620 ++marker_list_index) { 632 DocumentMarkerList* list = (*markers)[marker_list_index];
621 Member<MarkerList>& list = (*markers)[marker_list_index]; 633 if (!list || list->IsEmpty() || !marker_types.Contains(type))
622 if (!list || list->IsEmpty() ||
623 !marker_types.Contains((*list->begin())->GetType()))
624 continue; 634 continue;
625 635
626 // cause the node to be redrawn 636 // cause the node to be redrawn
627 if (LayoutObject* layout_object = node->GetLayoutObject()) { 637 if (LayoutObject* layout_object = node->GetLayoutObject()) {
628 layout_object->SetShouldDoFullPaintInvalidation( 638 layout_object->SetShouldDoFullPaintInvalidation(
629 kPaintInvalidationDocumentMarkerChange); 639 kPaintInvalidationDocumentMarkerChange);
630 break; 640 break;
631 } 641 }
632 } 642 }
633 } 643 }
(...skipping 27 matching lines...) Expand all
661 671
662 bool DocumentMarkerController::SetMarkersActive(Node* node, 672 bool DocumentMarkerController::SetMarkersActive(Node* node,
663 unsigned start_offset, 673 unsigned start_offset,
664 unsigned end_offset, 674 unsigned end_offset,
665 bool active) { 675 bool active) {
666 MarkerLists* markers = markers_.at(node); 676 MarkerLists* markers = markers_.at(node);
667 if (!markers) 677 if (!markers)
668 return false; 678 return false;
669 679
670 bool doc_dirty = false; 680 bool doc_dirty = false;
671 Member<MarkerList>& list = ListForType(markers, DocumentMarker::kTextMatch); 681 DocumentMarkerList* list = ListForType(markers, DocumentMarker::kTextMatch);
682
672 if (!list) 683 if (!list)
673 return false; 684 return false;
674 MarkerList::iterator start_pos = std::upper_bound( 685
675 list->begin(), list->end(), start_offset, DocumentMarker::EndsBefore); 686 DocumentMarkerVector markers_in_list;
676 for (MarkerList::iterator marker = start_pos; marker != list->end(); 687 list->AppendMarkersToInputList(&markers_in_list);
677 ++marker) { 688
689 const auto start_pos =
690 std::upper_bound(markers_in_list.begin(), markers_in_list.end(),
691 start_offset, DocumentMarker::EndsBefore);
692 for (auto marker = start_pos; marker != markers_in_list.end(); ++marker) {
678 // Markers are returned in order, so stop if we are now past the specified 693 // Markers are returned in order, so stop if we are now past the specified
679 // range. 694 // range.
680 if ((*marker)->StartOffset() >= end_offset) 695 if ((*marker)->StartOffset() >= end_offset)
681 break; 696 break;
682 697
683 (*marker)->SetIsActiveMatch(active); 698 (*marker)->SetIsActiveMatch(active);
684 doc_dirty = true; 699 doc_dirty = true;
685 } 700 }
686 701
687 // repaint the affected node 702 // repaint the affected node
688 if (doc_dirty && node->GetLayoutObject()) { 703 if (doc_dirty && node->GetLayoutObject()) {
689 node->GetLayoutObject()->SetShouldDoFullPaintInvalidation( 704 node->GetLayoutObject()->SetShouldDoFullPaintInvalidation(
690 kPaintInvalidationDocumentMarkerChange); 705 kPaintInvalidationDocumentMarkerChange);
691 } 706 }
692 return doc_dirty; 707 return doc_dirty;
693 } 708 }
694 709
695 #ifndef NDEBUG 710 #ifndef NDEBUG
696 void DocumentMarkerController::ShowMarkers() const { 711 void DocumentMarkerController::ShowMarkers() const {
697 StringBuilder builder; 712 StringBuilder builder;
698 MarkerMap::const_iterator end = markers_.end(); 713 MarkerMap::const_iterator end = markers_.end();
699 for (MarkerMap::const_iterator node_iterator = markers_.begin(); 714 for (MarkerMap::const_iterator node_iterator = markers_.begin();
700 node_iterator != end; ++node_iterator) { 715 node_iterator != end; ++node_iterator) {
701 const Node* node = node_iterator->key; 716 const Node* node = node_iterator->key;
702 builder.Append(String::Format("%p", node)); 717 builder.Append(String::Format("%p", node));
703 MarkerLists* markers = markers_.at(node); 718 MarkerLists* markers = markers_.at(node);
704 for (size_t marker_list_index = 0; 719 for (size_t marker_list_index = 0;
705 marker_list_index < DocumentMarker::kMarkerTypeIndexesCount; 720 marker_list_index < DocumentMarker::kMarkerTypeIndexesCount;
706 ++marker_list_index) { 721 ++marker_list_index) {
707 Member<MarkerList>& list = (*markers)[marker_list_index]; 722 DocumentMarkerList* list = (*markers)[marker_list_index];
708 for (unsigned marker_index = 0; list.Get() && marker_index < list->size(); 723
709 ++marker_index) { 724 DocumentMarkerVector markers_in_list;
710 DocumentMarker* marker = list->at(marker_index).Get(); 725 list->AppendMarkersToInputList(&markers_in_list);
726
727 for (const DocumentMarker* marker : markers_in_list) {
711 builder.Append(" "); 728 builder.Append(" ");
712 builder.AppendNumber(marker->GetType()); 729 builder.AppendNumber(marker->GetType());
713 builder.Append(":["); 730 builder.Append(":[");
714 builder.AppendNumber(marker->StartOffset()); 731 builder.AppendNumber(marker->StartOffset());
715 builder.Append(":"); 732 builder.Append(":");
716 builder.AppendNumber(marker->EndOffset()); 733 builder.AppendNumber(marker->EndOffset());
717 builder.Append("]("); 734 builder.Append("](");
718 builder.AppendNumber(marker->IsActiveMatch()); 735 builder.AppendNumber(marker->IsActiveMatch());
719 builder.Append(")"); 736 builder.Append(")");
720 } 737 }
(...skipping 12 matching lines...) Expand all
733 unsigned new_length) { 750 unsigned new_length) {
734 if (!PossiblyHasMarkers(DocumentMarker::AllMarkers())) 751 if (!PossiblyHasMarkers(DocumentMarker::AllMarkers()))
735 return; 752 return;
736 DCHECK(!markers_.IsEmpty()); 753 DCHECK(!markers_.IsEmpty());
737 754
738 MarkerLists* markers = markers_.at(node); 755 MarkerLists* markers = markers_.at(node);
739 if (!markers) 756 if (!markers)
740 return; 757 return;
741 758
742 bool did_shift_marker = false; 759 bool did_shift_marker = false;
743 for (MarkerList* list : *markers) { 760 for (DocumentMarkerList* list : *markers) {
744 if (!list) 761 if (!list)
745 continue; 762 continue;
746 763
747 if (DocumentMarkerListEditor::ShiftMarkers(list, offset, old_length, 764 if (list->ShiftMarkers(offset, old_length, new_length))
748 new_length))
749 did_shift_marker = true; 765 did_shift_marker = true;
750 } 766 }
751 767
752 if (!did_shift_marker) 768 if (!did_shift_marker)
753 return; 769 return;
754 if (!node->GetLayoutObject()) 770 if (!node->GetLayoutObject())
755 return; 771 return;
756 InvalidateRectsForMarkersInNode(*node); 772 InvalidateRectsForMarkersInNode(*node);
757 // repaint the affected node 773 // repaint the affected node
758 node->GetLayoutObject()->SetShouldDoFullPaintInvalidation(); 774 node->GetLayoutObject()->SetShouldDoFullPaintInvalidation();
759 } 775 }
760 776
761 } // namespace blink 777 } // namespace blink
762 778
763 #ifndef NDEBUG 779 #ifndef NDEBUG
764 void showDocumentMarkers(const blink::DocumentMarkerController* controller) { 780 void showDocumentMarkers(const blink::DocumentMarkerController* controller) {
765 if (controller) 781 if (controller)
766 controller->ShowMarkers(); 782 controller->ShowMarkers();
767 } 783 }
768 #endif 784 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698