Chromium Code Reviews| 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 |