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 reserved. | 6 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved. |
7 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.t orchmobile.com/) | 7 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.t orchmobile.com/) |
8 * Copyright (C) Research In Motion Limited 2010. All rights reserved. | 8 * Copyright (C) Research In Motion Limited 2010. All rights reserved. |
9 * | 9 * |
10 * This library is free software; you can redistribute it and/or | 10 * This library is free software; you can redistribute it and/or |
(...skipping 15 matching lines...) Expand all Loading... | |
26 | 26 |
27 #include "config.h" | 27 #include "config.h" |
28 #include "core/dom/DocumentMarkerController.h" | 28 #include "core/dom/DocumentMarkerController.h" |
29 | 29 |
30 #include "core/dom/Node.h" | 30 #include "core/dom/Node.h" |
31 #include "core/dom/NodeTraversal.h" | 31 #include "core/dom/NodeTraversal.h" |
32 #include "core/dom/Range.h" | 32 #include "core/dom/Range.h" |
33 #include "core/dom/RenderedDocumentMarker.h" | 33 #include "core/dom/RenderedDocumentMarker.h" |
34 #include "core/dom/Text.h" | 34 #include "core/dom/Text.h" |
35 #include "core/editing/iterators/TextIterator.h" | 35 #include "core/editing/iterators/TextIterator.h" |
36 #include "core/frame/FrameView.h" | |
36 #include "core/layout/LayoutObject.h" | 37 #include "core/layout/LayoutObject.h" |
37 | 38 |
38 #ifndef NDEBUG | 39 #ifndef NDEBUG |
39 #include <stdio.h> | 40 #include <stdio.h> |
40 #endif | 41 #endif |
41 | 42 |
42 namespace blink { | 43 namespace blink { |
43 | 44 |
44 MarkerRemoverPredicate::MarkerRemoverPredicate(const Vector<String>& words) | 45 MarkerRemoverPredicate::MarkerRemoverPredicate(const Vector<String>& words) |
45 : m_words(words) | 46 : m_words(words) |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
108 for (TextIterator markedText(start, end); !markedText.atEnd(); markedText.ad vance()) { | 109 for (TextIterator markedText(start, end); !markedText.atEnd(); markedText.ad vance()) { |
109 addMarker(markedText.currentContainer(), DocumentMarker(type, markedText .startOffsetInCurrentContainer(), markedText.endOffsetInCurrentContainer(), desc ription, hash)); | 110 addMarker(markedText.currentContainer(), DocumentMarker(type, markedText .startOffsetInCurrentContainer(), markedText.endOffsetInCurrentContainer(), desc ription, hash)); |
110 } | 111 } |
111 } | 112 } |
112 | 113 |
113 void DocumentMarkerController::addTextMatchMarker(const Range* range, bool activ eMatch) | 114 void DocumentMarkerController::addTextMatchMarker(const Range* range, bool activ eMatch) |
114 { | 115 { |
115 // Use a TextIterator to visit the potentially multiple nodes the range cove rs. | 116 // Use a TextIterator to visit the potentially multiple nodes the range cove rs. |
116 for (TextIterator markedText(range->startPosition(), range->endPosition()); !markedText.atEnd(); markedText.advance()) | 117 for (TextIterator markedText(range->startPosition(), range->endPosition()); !markedText.atEnd(); markedText.advance()) |
117 addMarker(markedText.currentContainer(), DocumentMarker(markedText.start OffsetInCurrentContainer(), markedText.endOffsetInCurrentContainer(), activeMatc h)); | 118 addMarker(markedText.currentContainer(), DocumentMarker(markedText.start OffsetInCurrentContainer(), markedText.endOffsetInCurrentContainer(), activeMatc h)); |
119 // Don't invalidate tickmarks here. TextFinder invalidates tickmarks using a throttling algorithm. crbug.com/6819. | |
118 } | 120 } |
119 | 121 |
120 void DocumentMarkerController::prepareForDestruction() | 122 void DocumentMarkerController::prepareForDestruction() |
121 { | 123 { |
122 clear(); | 124 clear(); |
123 } | 125 } |
124 | 126 |
125 void DocumentMarkerController::removeMarkers(TextIterator& markedText, DocumentM arker::MarkerTypes markerTypes, RemovePartiallyOverlappingMarkerOrNot shouldRemo vePartiallyOverlappingMarker) | 127 void DocumentMarkerController::removeMarkers(TextIterator& markedText, DocumentM arker::MarkerTypes markerTypes, RemovePartiallyOverlappingMarkerOrNot shouldRemo vePartiallyOverlappingMarker) |
126 { | 128 { |
127 for (; !markedText.atEnd(); markedText.advance()) { | 129 for (; !markedText.atEnd(); markedText.advance()) { |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
170 static bool doesNotOverlap(const OwnPtrWillBeMember<RenderedDocumentMarker>& lhv , const DocumentMarker* rhv) | 172 static bool doesNotOverlap(const OwnPtrWillBeMember<RenderedDocumentMarker>& lhv , const DocumentMarker* rhv) |
171 { | 173 { |
172 return lhv->endOffset() < rhv->startOffset(); | 174 return lhv->endOffset() < rhv->startOffset(); |
173 } | 175 } |
174 | 176 |
175 static bool doesNotInclude(const OwnPtrWillBeMember<RenderedDocumentMarker>& mar ker, size_t startOffset) | 177 static bool doesNotInclude(const OwnPtrWillBeMember<RenderedDocumentMarker>& mar ker, size_t startOffset) |
176 { | 178 { |
177 return marker->endOffset() < startOffset; | 179 return marker->endOffset() < startOffset; |
178 } | 180 } |
179 | 181 |
180 static void updateMarkerRenderedRect(Node* node, RenderedDocumentMarker& marker) | 182 static bool updateMarkerRenderedRect(Node* node, RenderedDocumentMarker& marker) |
181 { | 183 { |
182 RefPtrWillBeRawPtr<Range> range = Range::create(node->document()); | 184 RefPtrWillBeRawPtr<Range> range = Range::create(node->document()); |
183 // The offsets of the marker may be out-dated, so check for exceptions. | 185 // The offsets of the marker may be out-dated, so check for exceptions. |
184 TrackExceptionState exceptionState; | 186 TrackExceptionState exceptionState; |
185 range->setStart(node, marker.startOffset(), exceptionState); | 187 range->setStart(node, marker.startOffset(), exceptionState); |
186 if (!exceptionState.hadException()) | 188 if (!exceptionState.hadException()) |
187 range->setEnd(node, marker.endOffset(), IGNORE_EXCEPTION); | 189 range->setEnd(node, marker.endOffset(), IGNORE_EXCEPTION); |
188 if (exceptionState.hadException()) { | 190 if (exceptionState.hadException()) |
189 marker.invalidateRenderedRect(); | 191 return marker.invalidateRenderedRect(); |
190 return; | 192 return marker.setRenderedRect(LayoutRect(range->boundingBox())); |
191 } | |
192 | |
193 marker.setRenderedRect(LayoutRect(range->boundingBox())); | |
194 } | 193 } |
195 | 194 |
196 // Markers are stored in order sorted by their start offset. | 195 // Markers are stored in order sorted by their start offset. |
197 // Markers of the same type do not overlap each other. | 196 // Markers of the same type do not overlap each other. |
198 | 197 |
199 void DocumentMarkerController::addMarker(Node* node, const DocumentMarker& newMa rker) | 198 void DocumentMarkerController::addMarker(Node* node, const DocumentMarker& newMa rker) |
200 { | 199 { |
201 ASSERT(newMarker.endOffset() >= newMarker.startOffset()); | 200 ASSERT(newMarker.endOffset() >= newMarker.startOffset()); |
202 if (newMarker.endOffset() == newMarker.startOffset()) | 201 if (newMarker.endOffset() == newMarker.startOffset()) |
203 return; | 202 return; |
(...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
484 if (!marker->isRendered()) | 483 if (!marker->isRendered()) |
485 continue; | 484 continue; |
486 result.append(marker->renderedRect()); | 485 result.append(marker->renderedRect()); |
487 } | 486 } |
488 } | 487 } |
489 } | 488 } |
490 | 489 |
491 return result; | 490 return result; |
492 } | 491 } |
493 | 492 |
493 static void invalidatePaintForTickmarks(const Node& node) | |
494 { | |
495 if (FrameView* frameView = node.document().view()) | |
496 frameView->invalidatePaintForTickmarks(); | |
497 } | |
498 | |
494 void DocumentMarkerController::updateRenderedRectsForMarkers() | 499 void DocumentMarkerController::updateRenderedRectsForMarkers() |
495 { | 500 { |
496 for (auto& nodeMarkers : m_markers) { | 501 for (auto& nodeMarkers : m_markers) { |
497 const Node* node = nodeMarkers.key; | 502 const Node* node = nodeMarkers.key; |
498 for (auto& markerList : *nodeMarkers.value) { | 503 for (auto& markerList : *nodeMarkers.value) { |
499 if (!markerList) | 504 if (!markerList) |
500 continue; | 505 continue; |
506 bool markersChanged = false; | |
501 for (auto& marker : *markerList) | 507 for (auto& marker : *markerList) |
502 updateMarkerRenderedRect(const_cast<Node*>(node), *marker); | 508 markersChanged |= updateMarkerRenderedRect(const_cast<Node*>(nod e), *marker); |
509 | |
510 if (markersChanged && markerList->first()->type() == DocumentMarker: :TextMatch) | |
511 invalidatePaintForTickmarks(*node); | |
503 } | 512 } |
504 } | 513 } |
505 } | 514 } |
506 | 515 |
507 DEFINE_TRACE(DocumentMarkerController) | 516 DEFINE_TRACE(DocumentMarkerController) |
508 { | 517 { |
509 #if ENABLE(OILPAN) | 518 #if ENABLE(OILPAN) |
510 visitor->trace(m_markers); | 519 visitor->trace(m_markers); |
511 #endif | 520 #endif |
512 } | 521 } |
513 | 522 |
514 void DocumentMarkerController::removeMarkers(Node* node, DocumentMarker::MarkerT ypes markerTypes) | 523 void DocumentMarkerController::removeMarkers(Node* node, DocumentMarker::MarkerT ypes markerTypes) |
515 { | 524 { |
516 if (!possiblyHasMarkers(markerTypes)) | 525 if (!possiblyHasMarkers(markerTypes)) |
517 return; | 526 return; |
518 ASSERT(!m_markers.isEmpty()); | 527 ASSERT(!m_markers.isEmpty()); |
519 | 528 |
520 MarkerMap::iterator iterator = m_markers.find(node); | 529 MarkerMap::iterator iterator = m_markers.find(node); |
521 if (iterator != m_markers.end()) | 530 if (iterator != m_markers.end()) |
522 removeMarkersFromList(iterator, markerTypes); | 531 removeMarkersFromList(iterator, markerTypes); |
523 } | 532 } |
524 | 533 |
525 void DocumentMarkerController::removeMarkers(const MarkerRemoverPredicate& shoul dRemoveMarker) | 534 void DocumentMarkerController::removeMarkers(const MarkerRemoverPredicate& shoul dRemoveMarker) |
526 { | 535 { |
527 for (MarkerMap::iterator i = m_markers.begin(); i != m_markers.end(); ++i) { | 536 for (auto& nodeMarkers : m_markers) { |
528 MarkerLists* markers = i->value.get(); | 537 const Node& node = *nodeMarkers.key; |
538 if (!node.isTextNode()) // MarkerRemoverPridicate requires a Text node. | |
chrishtr
2015/04/20 17:53:25
sp: MarkerRemoverPredicate
Also, why could the pr
Xianzhu
2015/04/20 18:13:48
Done.
| |
539 continue; | |
540 MarkerLists& markers = *nodeMarkers.value; | |
529 for (size_t markerListIndex = 0; markerListIndex < DocumentMarker::Marke rTypeIndexesCount; ++markerListIndex) { | 541 for (size_t markerListIndex = 0; markerListIndex < DocumentMarker::Marke rTypeIndexesCount; ++markerListIndex) { |
530 OwnPtrWillBeMember<MarkerList>& list = (*markers)[markerListIndex]; | 542 OwnPtrWillBeMember<MarkerList>& list = markers[markerListIndex]; |
531 | 543 if (!list) |
532 WillBeHeapVector<RawPtrWillBeMember<RenderedDocumentMarker>> markers ToBeRemoved; | 544 continue; |
533 for (size_t j = 0; list.get() && j < list->size(); ++j) { | 545 bool removedMarkers = false; |
534 if (i->key->isTextNode() && shouldRemoveMarker(*list->at(j).get( ), static_cast<const Text&>(*i->key))) | 546 for (size_t j = list->size(); j > 0; --j) { |
535 markersToBeRemoved.append(list->at(j).get()); | 547 if (shouldRemoveMarker(*list->at(j - 1), static_cast<const Text& >(node))) { |
548 list->remove(j - 1); | |
549 removedMarkers = true; | |
550 } | |
536 } | 551 } |
537 | 552 if (removedMarkers && markerListIndex == DocumentMarker::TextMatchMa rkerIndex) |
538 for (size_t j = 0; j < markersToBeRemoved.size(); ++j) | 553 invalidatePaintForTickmarks(node); |
539 list->remove(list->find(markersToBeRemoved[j].get())); | |
540 } | 554 } |
541 } | 555 } |
542 } | 556 } |
543 | 557 |
544 void DocumentMarkerController::removeMarkers(DocumentMarker::MarkerTypes markerT ypes) | 558 void DocumentMarkerController::removeMarkers(DocumentMarker::MarkerTypes markerT ypes) |
545 { | 559 { |
546 if (!possiblyHasMarkers(markerTypes)) | 560 if (!possiblyHasMarkers(markerTypes)) |
547 return; | 561 return; |
548 ASSERT(!m_markers.isEmpty()); | 562 ASSERT(!m_markers.isEmpty()); |
549 | 563 |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
584 list.clear(); | 598 list.clear(); |
585 ++emptyListsCount; | 599 ++emptyListsCount; |
586 needsRepainting = true; | 600 needsRepainting = true; |
587 } | 601 } |
588 } | 602 } |
589 | 603 |
590 nodeCanBeRemoved = emptyListsCount == DocumentMarker::MarkerTypeIndexesC ount; | 604 nodeCanBeRemoved = emptyListsCount == DocumentMarker::MarkerTypeIndexesC ount; |
591 } | 605 } |
592 | 606 |
593 if (needsRepainting) { | 607 if (needsRepainting) { |
594 if (LayoutObject* renderer = iterator->key->layoutObject()) | 608 const Node& node = *iterator->key; |
609 if (LayoutObject* renderer = node.layoutObject()) | |
595 renderer->setShouldDoFullPaintInvalidation(); | 610 renderer->setShouldDoFullPaintInvalidation(); |
611 invalidatePaintForTickmarks(node); | |
596 } | 612 } |
597 | 613 |
598 if (nodeCanBeRemoved) { | 614 if (nodeCanBeRemoved) { |
599 m_markers.remove(iterator); | 615 m_markers.remove(iterator); |
600 if (m_markers.isEmpty()) | 616 if (m_markers.isEmpty()) |
601 m_possiblyExistingMarkerTypes = 0; | 617 m_possiblyExistingMarkerTypes = 0; |
602 } | 618 } |
603 } | 619 } |
604 | 620 |
605 void DocumentMarkerController::repaintMarkers(DocumentMarker::MarkerTypes marker Types) | 621 void DocumentMarkerController::repaintMarkers(DocumentMarker::MarkerTypes marker Types) |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
730 | 746 |
731 } // namespace blink | 747 } // namespace blink |
732 | 748 |
733 #ifndef NDEBUG | 749 #ifndef NDEBUG |
734 void showDocumentMarkers(const blink::DocumentMarkerController* controller) | 750 void showDocumentMarkers(const blink::DocumentMarkerController* controller) |
735 { | 751 { |
736 if (controller) | 752 if (controller) |
737 controller->showMarkers(); | 753 controller->showMarkers(); |
738 } | 754 } |
739 #endif | 755 #endif |
OLD | NEW |