OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) | 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) |
3 * (C) 1999 Antti Koivisto (koivisto@kde.org) | 3 * (C) 1999 Antti Koivisto (koivisto@kde.org) |
4 * (C) 2001 Dirk Mueller (mueller@kde.org) | 4 * (C) 2001 Dirk Mueller (mueller@kde.org) |
5 * (C) 2006 Alexey Proskuryakov (ap@webkit.org) | 5 * (C) 2006 Alexey Proskuryakov (ap@webkit.org) |
6 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights | 6 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights |
7 * reserved. | 7 * reserved. |
8 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. | 8 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. |
9 * (http://www.torchmobile.com/) | 9 * (http://www.torchmobile.com/) |
10 * Copyright (C) Research In Motion Limited 2010. All rights reserved. | 10 * Copyright (C) Research In Motion Limited 2010. All rights reserved. |
(...skipping 17 matching lines...) Expand all Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |