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

Unified Diff: Source/core/dom/DocumentMarkerController.cpp

Issue 1293683003: Move DocumentMarker related files to editing/markers/ from dom/ (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: 2015-08-14T22:49:39 Rebase Created 5 years, 4 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « Source/core/dom/DocumentMarkerController.h ('k') | Source/core/dom/DocumentMarkerControllerTest.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: Source/core/dom/DocumentMarkerController.cpp
diff --git a/Source/core/dom/DocumentMarkerController.cpp b/Source/core/dom/DocumentMarkerController.cpp
deleted file mode 100644
index 148c90614fed9ac352283fe45e46a780284c8aab..0000000000000000000000000000000000000000
--- a/Source/core/dom/DocumentMarkerController.cpp
+++ /dev/null
@@ -1,743 +0,0 @@
-/*
- * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
- * (C) 1999 Antti Koivisto (koivisto@kde.org)
- * (C) 2001 Dirk Mueller (mueller@kde.org)
- * (C) 2006 Alexey Proskuryakov (ap@webkit.org)
- * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
- * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
- * Copyright (C) Research In Motion Limited 2010. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- */
-
-#include "config.h"
-#include "core/dom/DocumentMarkerController.h"
-
-#include "core/dom/Node.h"
-#include "core/dom/NodeTraversal.h"
-#include "core/dom/Range.h"
-#include "core/dom/RenderedDocumentMarker.h"
-#include "core/dom/Text.h"
-#include "core/editing/iterators/TextIterator.h"
-#include "core/frame/FrameView.h"
-#include "core/layout/LayoutObject.h"
-
-#ifndef NDEBUG
-#include <stdio.h>
-#endif
-
-namespace blink {
-
-MarkerRemoverPredicate::MarkerRemoverPredicate(const Vector<String>& words)
- : m_words(words)
-{
-}
-
-bool MarkerRemoverPredicate::operator()(const DocumentMarker& documentMarker, const Text& textNode) const
-{
- unsigned start = documentMarker.startOffset();
- unsigned length = documentMarker.endOffset() - documentMarker.startOffset();
-
- String markerText = textNode.data().substring(start, length);
- return m_words.contains(markerText);
-}
-
-namespace {
-
-DocumentMarker::MarkerTypeIndex MarkerTypeToMarkerIndex(DocumentMarker::MarkerType type)
-{
- switch (type) {
- case DocumentMarker::Spelling:
- return DocumentMarker::SpellingMarkerIndex;
- case DocumentMarker::Grammar:
- return DocumentMarker::GramarMarkerIndex;
- case DocumentMarker::TextMatch:
- return DocumentMarker::TextMatchMarkerIndex;
- case DocumentMarker::InvisibleSpellcheck:
- return DocumentMarker::InvisibleSpellcheckMarkerIndex;
- }
-
- ASSERT_NOT_REACHED();
- return DocumentMarker::SpellingMarkerIndex;
-}
-
-} // namespace
-
-inline bool DocumentMarkerController::possiblyHasMarkers(DocumentMarker::MarkerTypes types)
-{
- return m_possiblyExistingMarkerTypes.intersects(types);
-}
-
-DocumentMarkerController::DocumentMarkerController()
- : m_possiblyExistingMarkerTypes(0)
-{
-}
-
-DEFINE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(DocumentMarkerController);
-
-void DocumentMarkerController::clear()
-{
- m_markers.clear();
- m_possiblyExistingMarkerTypes = 0;
-}
-
-void DocumentMarkerController::addMarker(const Position& start, const Position& end, DocumentMarker::MarkerType type, const String& description, uint32_t hash)
-{
- // Use a TextIterator to visit the potentially multiple nodes the range covers.
- for (TextIterator markedText(start, end); !markedText.atEnd(); markedText.advance()) {
- addMarker(markedText.currentContainer(), DocumentMarker(type, markedText.startOffsetInCurrentContainer(), markedText.endOffsetInCurrentContainer(), description, hash));
- }
-}
-
-void DocumentMarkerController::addTextMatchMarker(const Range* range, bool activeMatch)
-{
- // Use a TextIterator to visit the potentially multiple nodes the range covers.
- for (TextIterator markedText(range->startPosition(), range->endPosition()); !markedText.atEnd(); markedText.advance())
- addMarker(markedText.currentContainer(), DocumentMarker(markedText.startOffsetInCurrentContainer(), markedText.endOffsetInCurrentContainer(), activeMatch));
- // Don't invalidate tickmarks here. TextFinder invalidates tickmarks using a throttling algorithm. crbug.com/6819.
-}
-
-void DocumentMarkerController::prepareForDestruction()
-{
- clear();
-}
-
-void DocumentMarkerController::removeMarkers(TextIterator& markedText, DocumentMarker::MarkerTypes markerTypes, RemovePartiallyOverlappingMarkerOrNot shouldRemovePartiallyOverlappingMarker)
-{
- for (; !markedText.atEnd(); markedText.advance()) {
- if (!possiblyHasMarkers(markerTypes))
- return;
- ASSERT(!m_markers.isEmpty());
-
- int startOffset = markedText.startOffsetInCurrentContainer();
- int endOffset = markedText.endOffsetInCurrentContainer();
- removeMarkers(markedText.currentContainer(), startOffset, endOffset - startOffset, markerTypes, shouldRemovePartiallyOverlappingMarker);
- }
-}
-
-void DocumentMarkerController::removeMarkers(const EphemeralRange& range, DocumentMarker::MarkerTypes markerTypes, RemovePartiallyOverlappingMarkerOrNot shouldRemovePartiallyOverlappingMarker)
-{
- TextIterator markedText(range.startPosition(), range.endPosition());
- DocumentMarkerController::removeMarkers(markedText, markerTypes, shouldRemovePartiallyOverlappingMarker);
-}
-
-static bool startsFurther(const OwnPtrWillBeMember<RenderedDocumentMarker>& lhv, const DocumentMarker* rhv)
-{
- return lhv->startOffset() < rhv->startOffset();
-}
-
-static bool startsAfter(const OwnPtrWillBeMember<RenderedDocumentMarker>& marker, size_t startOffset)
-{
- return marker->startOffset() < startOffset;
-}
-
-static bool endsBefore(size_t startOffset, const OwnPtrWillBeMember<RenderedDocumentMarker>& rhv)
-{
- return startOffset < rhv->endOffset();
-}
-
-static bool compareByStart(const RawPtrWillBeMember<DocumentMarker>& lhv, const RawPtrWillBeMember<DocumentMarker>& rhv)
-{
- return lhv->startOffset() < rhv->startOffset();
-}
-
-static bool doesNotOverlap(const OwnPtrWillBeMember<RenderedDocumentMarker>& lhv, const DocumentMarker* rhv)
-{
- return lhv->endOffset() < rhv->startOffset();
-}
-
-static bool doesNotInclude(const OwnPtrWillBeMember<RenderedDocumentMarker>& marker, size_t startOffset)
-{
- return marker->endOffset() < startOffset;
-}
-
-static bool updateMarkerRenderedRect(Node* node, RenderedDocumentMarker& marker)
-{
- RefPtrWillBeRawPtr<Range> range = Range::create(node->document());
- // The offsets of the marker may be out-dated, so check for exceptions.
- TrackExceptionState exceptionState;
- range->setStart(node, marker.startOffset(), exceptionState);
- if (!exceptionState.hadException())
- range->setEnd(node, marker.endOffset(), IGNORE_EXCEPTION);
- if (exceptionState.hadException())
- return marker.invalidateRenderedRect();
- return marker.setRenderedRect(LayoutRect(range->boundingBox()));
-}
-
-// Markers are stored in order sorted by their start offset.
-// Markers of the same type do not overlap each other.
-
-void DocumentMarkerController::addMarker(Node* node, const DocumentMarker& newMarker)
-{
- ASSERT(newMarker.endOffset() >= newMarker.startOffset());
- if (newMarker.endOffset() == newMarker.startOffset())
- return;
-
- m_possiblyExistingMarkerTypes.add(newMarker.type());
-
- OwnPtrWillBeMember<MarkerLists>& markers = m_markers.add(node, nullptr).storedValue->value;
- if (!markers) {
- markers = adoptPtrWillBeNoop(new MarkerLists);
- markers->grow(DocumentMarker::MarkerTypeIndexesCount);
- }
-
- DocumentMarker::MarkerTypeIndex markerListIndex = MarkerTypeToMarkerIndex(newMarker.type());
- if (!markers->at(markerListIndex)) {
- markers->insert(markerListIndex, adoptPtrWillBeNoop(new MarkerList));
- }
-
- OwnPtrWillBeMember<MarkerList>& list = markers->at(markerListIndex);
- OwnPtrWillBeRawPtr<RenderedDocumentMarker> newRenderedMarker = RenderedDocumentMarker::create(newMarker);
- updateMarkerRenderedRect(node, *newRenderedMarker);
- if (list->isEmpty() || list->last()->endOffset() < newMarker.startOffset()) {
- list->append(newRenderedMarker.release());
- } else {
- if (newMarker.type() != DocumentMarker::TextMatch) {
- mergeOverlapping(list.get(), newRenderedMarker.release());
- } else {
- MarkerList::iterator pos = std::lower_bound(list->begin(), list->end(), &newMarker, startsFurther);
- list->insert(pos - list->begin(), newRenderedMarker.release());
- }
- }
-
- // repaint the affected node
- if (node->layoutObject())
- node->layoutObject()->setShouldDoFullPaintInvalidation();
-}
-
-void DocumentMarkerController::mergeOverlapping(MarkerList* list, PassOwnPtrWillBeRawPtr<RenderedDocumentMarker> toInsert)
-{
- MarkerList::iterator firstOverlapping = std::lower_bound(list->begin(), list->end(), toInsert.get(), doesNotOverlap);
- size_t index = firstOverlapping - list->begin();
- list->insert(index, toInsert);
- MarkerList::iterator inserted = list->begin() + index;
- firstOverlapping = inserted + 1;
- for (MarkerList::iterator i = firstOverlapping; i != list->end() && (*i)->startOffset() <= (*inserted)->endOffset(); ) {
- (*inserted)->setStartOffset(std::min((*inserted)->startOffset(), (*i)->startOffset()));
- (*inserted)->setEndOffset(std::max((*inserted)->endOffset(), (*i)->endOffset()));
- list->remove(i - list->begin());
- }
-}
-
-// copies markers from srcNode to dstNode, applying the specified shift delta to the copies. The shift is
-// useful if, e.g., the caller has created the dstNode from a non-prefix substring of the srcNode.
-void DocumentMarkerController::copyMarkers(Node* srcNode, unsigned startOffset, int length, Node* dstNode, int delta)
-{
- if (length <= 0)
- return;
-
- if (!possiblyHasMarkers(DocumentMarker::AllMarkers()))
- return;
- ASSERT(!m_markers.isEmpty());
-
- MarkerLists* markers = m_markers.get(srcNode);
- if (!markers)
- return;
-
- bool docDirty = false;
- for (size_t markerListIndex = 0; markerListIndex < DocumentMarker::MarkerTypeIndexesCount; ++markerListIndex) {
- OwnPtrWillBeMember<MarkerList>& list = (*markers)[markerListIndex];
- if (!list)
- continue;
-
- unsigned endOffset = startOffset + length - 1;
- MarkerList::iterator startPos = std::lower_bound(list->begin(), list->end(), startOffset, doesNotInclude);
- for (MarkerList::iterator i = startPos; i != list->end(); ++i) {
- DocumentMarker* marker = i->get();
-
- // stop if we are now past the specified range
- if (marker->startOffset() > endOffset)
- break;
-
- // pin the marker to the specified range and apply the shift delta
- docDirty = true;
- if (marker->startOffset() < startOffset)
- marker->setStartOffset(startOffset);
- if (marker->endOffset() > endOffset)
- marker->setEndOffset(endOffset);
- marker->shiftOffsets(delta);
-
- addMarker(dstNode, *marker);
- }
- }
-
- // repaint the affected node
- if (docDirty && dstNode->layoutObject())
- dstNode->layoutObject()->setShouldDoFullPaintInvalidation();
-}
-
-void DocumentMarkerController::removeMarkers(Node* node, unsigned startOffset, int length, DocumentMarker::MarkerTypes markerTypes, RemovePartiallyOverlappingMarkerOrNot shouldRemovePartiallyOverlappingMarker)
-{
- if (length <= 0)
- return;
-
- if (!possiblyHasMarkers(markerTypes))
- return;
- ASSERT(!(m_markers.isEmpty()));
-
- MarkerLists* markers = m_markers.get(node);
- if (!markers)
- return;
-
- bool docDirty = false;
- size_t emptyListsCount = 0;
- for (size_t markerListIndex = 0; markerListIndex < DocumentMarker::MarkerTypeIndexesCount; ++markerListIndex) {
- OwnPtrWillBeMember<MarkerList>& list = (*markers)[markerListIndex];
- if (!list || list->isEmpty()) {
- if (list.get() && list->isEmpty())
- list.clear();
- ++emptyListsCount;
- continue;
- }
- if (!markerTypes.contains((*list->begin())->type()))
- continue;
- unsigned endOffset = startOffset + length;
- MarkerList::iterator startPos = std::upper_bound(list->begin(), list->end(), startOffset, endsBefore);
- for (MarkerList::iterator i = startPos; i != list->end(); ) {
- DocumentMarker marker(*i->get());
-
- // markers are returned in order, so stop if we are now past the specified range
- if (marker.startOffset() >= endOffset)
- break;
-
- // at this point we know that marker and target intersect in some way
- docDirty = true;
-
- // pitch the old marker
- list->remove(i - list->begin());
-
- if (shouldRemovePartiallyOverlappingMarker) {
- // Stop here. Don't add resulting slices back.
- continue;
- }
-
- // add either of the resulting slices that are left after removing target
- if (startOffset > marker.startOffset()) {
- DocumentMarker newLeft = marker;
- newLeft.setEndOffset(startOffset);
- size_t insertIndex = i - list->begin();
- list->insert(insertIndex, RenderedDocumentMarker::create(newLeft));
- // Move to the marker after the inserted one.
- i = list->begin() + insertIndex + 1;
- }
- if (marker.endOffset() > endOffset) {
- DocumentMarker newRight = marker;
- newRight.setStartOffset(endOffset);
- size_t insertIndex = i - list->begin();
- list->insert(insertIndex, RenderedDocumentMarker::create(newRight));
- // Move to the marker after the inserted one.
- i = list->begin() + insertIndex + 1;
- }
- }
-
- if (list->isEmpty()) {
- list.clear();
- ++emptyListsCount;
- }
- }
-
- if (emptyListsCount == DocumentMarker::MarkerTypeIndexesCount) {
- m_markers.remove(node);
- if (m_markers.isEmpty())
- m_possiblyExistingMarkerTypes = 0;
- }
-
- // repaint the affected node
- if (docDirty && node->layoutObject())
- node->layoutObject()->setShouldDoFullPaintInvalidation();
-}
-
-DocumentMarker* DocumentMarkerController::markerContainingPoint(const LayoutPoint& point, DocumentMarker::MarkerType markerType)
-{
- if (!possiblyHasMarkers(markerType))
- return 0;
- ASSERT(!(m_markers.isEmpty()));
-
- // outer loop: process each node that contains any markers
- MarkerMap::iterator end = m_markers.end();
- for (MarkerMap::iterator nodeIterator = m_markers.begin(); nodeIterator != end; ++nodeIterator) {
- // inner loop; process each marker in this node
- MarkerLists* markers = nodeIterator->value.get();
- OwnPtrWillBeMember<MarkerList>& list = (*markers)[MarkerTypeToMarkerIndex(markerType)];
- unsigned markerCount = list.get() ? list->size() : 0;
- for (unsigned markerIndex = 0; markerIndex < markerCount; ++markerIndex) {
- RenderedDocumentMarker* marker = list->at(markerIndex).get();
- if (marker->contains(point))
- return marker;
- }
- }
-
- return 0;
-}
-
-DocumentMarkerVector DocumentMarkerController::markersFor(Node* node, DocumentMarker::MarkerTypes markerTypes)
-{
- DocumentMarkerVector result;
-
- MarkerLists* markers = m_markers.get(node);
- if (!markers)
- return result;
-
- for (size_t markerListIndex = 0; markerListIndex < DocumentMarker::MarkerTypeIndexesCount; ++markerListIndex) {
- OwnPtrWillBeMember<MarkerList>& list = (*markers)[markerListIndex];
- if (!list || list->isEmpty() || !markerTypes.contains((*list->begin())->type()))
- continue;
-
- for (size_t i = 0; i < list->size(); ++i)
- result.append(list->at(i).get());
- }
-
- std::sort(result.begin(), result.end(), compareByStart);
- return result;
-}
-
-DocumentMarkerVector DocumentMarkerController::markers()
-{
- DocumentMarkerVector result;
- for (MarkerMap::iterator i = m_markers.begin(); i != m_markers.end(); ++i) {
- MarkerLists* markers = i->value.get();
- for (size_t markerListIndex = 0; markerListIndex < DocumentMarker::MarkerTypeIndexesCount; ++markerListIndex) {
- OwnPtrWillBeMember<MarkerList>& list = (*markers)[markerListIndex];
- for (size_t j = 0; list.get() && j < list->size(); ++j)
- result.append(list->at(j).get());
- }
- }
- std::sort(result.begin(), result.end(), compareByStart);
- return result;
-}
-
-DocumentMarkerVector DocumentMarkerController::markersInRange(const EphemeralRange& range, DocumentMarker::MarkerTypes markerTypes)
-{
- if (!possiblyHasMarkers(markerTypes))
- return DocumentMarkerVector();
-
- DocumentMarkerVector foundMarkers;
-
- Node* startContainer = range.startPosition().computeContainerNode();
- ASSERT(startContainer);
- unsigned startOffset = static_cast<unsigned>(range.startPosition().computeOffsetInContainerNode());
- Node* endContainer = range.endPosition().computeContainerNode();
- ASSERT(endContainer);
- unsigned endOffset = static_cast<unsigned>(range.endPosition().computeOffsetInContainerNode());
-
- Node* pastLastNode = range.endPosition().nodeAsRangePastLastNode();
- for (Node* node = range.startPosition().nodeAsRangeFirstNode(); node != pastLastNode; node = NodeTraversal::next(*node)) {
- for (DocumentMarker* marker : markersFor(node)) {
- if (!markerTypes.contains(marker->type()))
- continue;
- if (node == startContainer && marker->endOffset() <= startOffset)
- continue;
- if (node == endContainer && marker->startOffset() >= endOffset)
- continue;
- foundMarkers.append(marker);
- }
- }
- return foundMarkers;
-}
-
-Vector<IntRect> DocumentMarkerController::renderedRectsForMarkers(DocumentMarker::MarkerType markerType)
-{
- Vector<IntRect> result;
-
- if (!possiblyHasMarkers(markerType))
- return result;
- ASSERT(!(m_markers.isEmpty()));
-
- // outer loop: process each node
- MarkerMap::iterator end = m_markers.end();
- for (MarkerMap::iterator nodeIterator = m_markers.begin(); nodeIterator != end; ++nodeIterator) {
- // inner loop; process each marker in this node
- MarkerLists* markers = nodeIterator->value.get();
- for (size_t markerListIndex = 0; markerListIndex < DocumentMarker::MarkerTypeIndexesCount; ++markerListIndex) {
- OwnPtrWillBeMember<MarkerList>& list = (*markers)[markerListIndex];
- if (!list || list->isEmpty() || (*list->begin())->type() != markerType)
- continue;
- for (unsigned markerIndex = 0; markerIndex < list->size(); ++markerIndex) {
- RenderedDocumentMarker* marker = list->at(markerIndex).get();
- if (!marker->isRendered())
- continue;
- result.append(marker->renderedRect());
- }
- }
- }
-
- return result;
-}
-
-static void invalidatePaintForTickmarks(const Node& node)
-{
- if (FrameView* frameView = node.document().view())
- frameView->invalidatePaintForTickmarks();
-}
-
-void DocumentMarkerController::updateRenderedRectsForMarkers()
-{
- for (auto& nodeMarkers : m_markers) {
- const Node* node = nodeMarkers.key;
- for (auto& markerList : *nodeMarkers.value) {
- if (!markerList)
- continue;
- bool markersChanged = false;
- for (auto& marker : *markerList)
- markersChanged |= updateMarkerRenderedRect(const_cast<Node*>(node), *marker);
-
- if (markersChanged && markerList->first()->type() == DocumentMarker::TextMatch)
- invalidatePaintForTickmarks(*node);
- }
- }
-}
-
-DEFINE_TRACE(DocumentMarkerController)
-{
-#if ENABLE(OILPAN)
- visitor->trace(m_markers);
-#endif
-}
-
-void DocumentMarkerController::removeMarkers(Node* node, DocumentMarker::MarkerTypes markerTypes)
-{
- if (!possiblyHasMarkers(markerTypes))
- return;
- ASSERT(!m_markers.isEmpty());
-
- MarkerMap::iterator iterator = m_markers.find(node);
- if (iterator != m_markers.end())
- removeMarkersFromList(iterator, markerTypes);
-}
-
-void DocumentMarkerController::removeMarkers(const MarkerRemoverPredicate& shouldRemoveMarker)
-{
- for (auto& nodeMarkers : m_markers) {
- const Node& node = *nodeMarkers.key;
- if (!node.isTextNode()) // MarkerRemoverPredicate requires a Text node.
- continue;
- MarkerLists& markers = *nodeMarkers.value;
- for (size_t markerListIndex = 0; markerListIndex < DocumentMarker::MarkerTypeIndexesCount; ++markerListIndex) {
- OwnPtrWillBeMember<MarkerList>& list = markers[markerListIndex];
- if (!list)
- continue;
- bool removedMarkers = false;
- for (size_t j = list->size(); j > 0; --j) {
- if (shouldRemoveMarker(*list->at(j - 1), static_cast<const Text&>(node))) {
- list->remove(j - 1);
- removedMarkers = true;
- }
- }
- if (removedMarkers && markerListIndex == DocumentMarker::TextMatchMarkerIndex)
- invalidatePaintForTickmarks(node);
- }
- }
-}
-
-void DocumentMarkerController::removeMarkers(DocumentMarker::MarkerTypes markerTypes)
-{
- if (!possiblyHasMarkers(markerTypes))
- return;
- ASSERT(!m_markers.isEmpty());
-
- Vector<const Node*> nodesWithMarkers;
- copyKeysToVector(m_markers, nodesWithMarkers);
- unsigned size = nodesWithMarkers.size();
- for (unsigned i = 0; i < size; ++i) {
- MarkerMap::iterator iterator = m_markers.find(nodesWithMarkers[i]);
- if (iterator != m_markers.end())
- removeMarkersFromList(iterator, markerTypes);
- }
-
- m_possiblyExistingMarkerTypes.remove(markerTypes);
-}
-
-void DocumentMarkerController::removeMarkersFromList(MarkerMap::iterator iterator, DocumentMarker::MarkerTypes markerTypes)
-{
- bool needsRepainting = false;
- bool nodeCanBeRemoved;
-
- size_t emptyListsCount = 0;
- if (markerTypes == DocumentMarker::AllMarkers()) {
- needsRepainting = true;
- nodeCanBeRemoved = true;
- } else {
- MarkerLists* markers = iterator->value.get();
-
- for (size_t markerListIndex = 0; markerListIndex < DocumentMarker::MarkerTypeIndexesCount; ++markerListIndex) {
- OwnPtrWillBeMember<MarkerList>& list = (*markers)[markerListIndex];
- if (!list || list->isEmpty()) {
- if (list.get() && list->isEmpty())
- list.clear();
- ++emptyListsCount;
- continue;
- }
- if (markerTypes.contains((*list->begin())->type())) {
- list->clear();
- list.clear();
- ++emptyListsCount;
- needsRepainting = true;
- }
- }
-
- nodeCanBeRemoved = emptyListsCount == DocumentMarker::MarkerTypeIndexesCount;
- }
-
- if (needsRepainting) {
- const Node& node = *iterator->key;
- if (LayoutObject* layoutObject = node.layoutObject())
- layoutObject->setShouldDoFullPaintInvalidation();
- invalidatePaintForTickmarks(node);
- }
-
- if (nodeCanBeRemoved) {
- m_markers.remove(iterator);
- if (m_markers.isEmpty())
- m_possiblyExistingMarkerTypes = 0;
- }
-}
-
-void DocumentMarkerController::repaintMarkers(DocumentMarker::MarkerTypes markerTypes)
-{
- if (!possiblyHasMarkers(markerTypes))
- return;
- ASSERT(!m_markers.isEmpty());
-
- // outer loop: process each markered node in the document
- MarkerMap::iterator end = m_markers.end();
- for (MarkerMap::iterator i = m_markers.begin(); i != end; ++i) {
- const Node* node = i->key;
-
- // inner loop: process each marker in the current node
- MarkerLists* markers = i->value.get();
- for (size_t markerListIndex = 0; markerListIndex < DocumentMarker::MarkerTypeIndexesCount; ++markerListIndex) {
- OwnPtrWillBeMember<MarkerList>& list = (*markers)[markerListIndex];
- if (!list || list->isEmpty() || !markerTypes.contains((*list->begin())->type()))
- continue;
-
- // cause the node to be redrawn
- if (LayoutObject* layoutObject = node->layoutObject()) {
- layoutObject->setShouldDoFullPaintInvalidation();
- break;
- }
- }
- }
-}
-
-void DocumentMarkerController::shiftMarkers(Node* node, unsigned startOffset, int delta)
-{
- if (!possiblyHasMarkers(DocumentMarker::AllMarkers()))
- return;
- ASSERT(!m_markers.isEmpty());
-
- MarkerLists* markers = m_markers.get(node);
- if (!markers)
- return;
-
- bool docDirty = false;
- for (size_t markerListIndex = 0; markerListIndex < DocumentMarker::MarkerTypeIndexesCount; ++markerListIndex) {
- OwnPtrWillBeMember<MarkerList>& list = (*markers)[markerListIndex];
- if (!list)
- continue;
- MarkerList::iterator startPos = std::lower_bound(list->begin(), list->end(), startOffset, startsAfter);
- for (MarkerList::iterator marker = startPos; marker != list->end(); ++marker) {
-#if ENABLE(ASSERT)
- int startOffset = (*marker)->startOffset();
- ASSERT(startOffset + delta >= 0);
-#endif
- (*marker)->shiftOffsets(delta);
- docDirty = true;
-
- updateMarkerRenderedRect(node, **marker);
- }
- }
-
- // repaint the affected node
- if (docDirty && node->layoutObject())
- node->layoutObject()->setShouldDoFullPaintInvalidation();
-}
-
-void DocumentMarkerController::setMarkersActive(Range* range, bool active)
-{
- if (!possiblyHasMarkers(DocumentMarker::AllMarkers()))
- return;
- ASSERT(!m_markers.isEmpty());
-
- Node* startContainer = range->startContainer();
- Node* endContainer = range->endContainer();
-
- Node* pastLastNode = range->pastLastNode();
-
- for (Node* node = range->firstNode(); node != pastLastNode; node = NodeTraversal::next(*node)) {
- int startOffset = node == startContainer ? range->startOffset() : 0;
- int endOffset = node == endContainer ? range->endOffset() : INT_MAX;
- setMarkersActive(node, startOffset, endOffset, active);
- }
-}
-
-void DocumentMarkerController::setMarkersActive(Node* node, unsigned startOffset, unsigned endOffset, bool active)
-{
- MarkerLists* markers = m_markers.get(node);
- if (!markers)
- return;
-
- bool docDirty = false;
- OwnPtrWillBeMember<MarkerList>& list = (*markers)[MarkerTypeToMarkerIndex(DocumentMarker::TextMatch)];
- if (!list)
- return;
- MarkerList::iterator startPos = std::upper_bound(list->begin(), list->end(), startOffset, endsBefore);
- for (MarkerList::iterator marker = startPos; marker != list->end(); ++marker) {
-
- // Markers are returned in order, so stop if we are now past the specified range.
- if ((*marker)->startOffset() >= endOffset)
- break;
-
- (*marker)->setActiveMatch(active);
- docDirty = true;
- }
-
- // repaint the affected node
- if (docDirty && node->layoutObject())
- node->layoutObject()->setShouldDoFullPaintInvalidation();
-}
-
-#ifndef NDEBUG
-void DocumentMarkerController::showMarkers() const
-{
- fprintf(stderr, "%d nodes have markers:\n", m_markers.size());
- MarkerMap::const_iterator end = m_markers.end();
- for (MarkerMap::const_iterator nodeIterator = m_markers.begin(); nodeIterator != end; ++nodeIterator) {
- const Node* node = nodeIterator->key;
- fprintf(stderr, "%p", node);
- MarkerLists* markers = m_markers.get(node);
- for (size_t markerListIndex = 0; markerListIndex < DocumentMarker::MarkerTypeIndexesCount; ++markerListIndex) {
- OwnPtrWillBeMember<MarkerList>& list = (*markers)[markerListIndex];
- for (unsigned markerIndex = 0; list.get() && markerIndex < list->size(); ++markerIndex) {
- DocumentMarker* marker = list->at(markerIndex).get();
- fprintf(stderr, " %d:[%d:%d](%d)", marker->type(), marker->startOffset(), marker->endOffset(), marker->activeMatch());
- }
- }
-
- fprintf(stderr, "\n");
- }
-}
-#endif
-
-} // namespace blink
-
-#ifndef NDEBUG
-void showDocumentMarkers(const blink::DocumentMarkerController* controller)
-{
- if (controller)
- controller->showMarkers();
-}
-#endif
« no previous file with comments | « Source/core/dom/DocumentMarkerController.h ('k') | Source/core/dom/DocumentMarkerControllerTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698