diff options
Diffstat (limited to 'Source/WebCore/dom/DocumentMarkerController.cpp')
-rw-r--r-- | Source/WebCore/dom/DocumentMarkerController.cpp | 420 |
1 files changed, 243 insertions, 177 deletions
diff --git a/Source/WebCore/dom/DocumentMarkerController.cpp b/Source/WebCore/dom/DocumentMarkerController.cpp index bcc7369cc..ccddcf58c 100644 --- a/Source/WebCore/dom/DocumentMarkerController.cpp +++ b/Source/WebCore/dom/DocumentMarkerController.cpp @@ -27,9 +27,15 @@ #include "config.h" #include "DocumentMarkerController.h" +#include "Chrome.h" +#include "ChromeClient.h" +#include "MainFrame.h" #include "NodeTraversal.h" +#include "Page.h" #include "Range.h" -#include "RenderObject.h" +#include "RenderBlockFlow.h" +#include "RenderLayer.h" +#include "RenderText.h" #include "RenderedDocumentMarker.h" #include "TextIterator.h" #include <stdio.h> @@ -41,8 +47,8 @@ inline bool DocumentMarkerController::possiblyHasMarkers(DocumentMarker::MarkerT return m_possiblyExistingMarkerTypes.intersects(types); } -DocumentMarkerController::DocumentMarkerController() - : m_possiblyExistingMarkerTypes(0) +DocumentMarkerController::DocumentMarkerController(Document& document) + : m_document(document) { } @@ -58,19 +64,17 @@ void DocumentMarkerController::detach() void DocumentMarkerController::addMarker(Range* range, DocumentMarker::MarkerType type, const String& description) { - // Use a TextIterator to visit the potentially multiple nodes the range covers. for (TextIterator markedText(range); !markedText.atEnd(); markedText.advance()) { RefPtr<Range> textPiece = markedText.range(); - addMarker(textPiece->startContainer(), DocumentMarker(type, textPiece->startOffset(), textPiece->endOffset(), description)); + addMarker(&textPiece->startContainer(), DocumentMarker(type, textPiece->startOffset(), textPiece->endOffset(), description)); } } void DocumentMarkerController::addMarker(Range* range, DocumentMarker::MarkerType type) { - // Use a TextIterator to visit the potentially multiple nodes the range covers. for (TextIterator markedText(range); !markedText.atEnd(); markedText.advance()) { RefPtr<Range> textPiece = markedText.range(); - addMarker(textPiece->startContainer(), DocumentMarker(type, textPiece->startOffset(), textPiece->endOffset())); + addMarker(&textPiece->startContainer(), DocumentMarker(type, textPiece->startOffset(), textPiece->endOffset())); } } @@ -80,39 +84,28 @@ void DocumentMarkerController::addMarkerToNode(Node* node, unsigned startOffset, addMarker(node, DocumentMarker(type, startOffset, startOffset + length)); } -void DocumentMarkerController::addMarkerToNode(Node* node, unsigned startOffset, unsigned length, DocumentMarker::MarkerType type, PassRefPtr<DocumentMarkerDetails> details) +void DocumentMarkerController::addMarkerToNode(Node* node, unsigned startOffset, unsigned length, DocumentMarker::MarkerType type, DocumentMarker::Data&& data) { - addMarker(node, DocumentMarker(type, startOffset, startOffset + length, details)); + addMarker(node, DocumentMarker(type, startOffset, startOffset + length, WTFMove(data))); } - void DocumentMarkerController::addTextMatchMarker(const Range* range, bool activeMatch) { - // Use a TextIterator to visit the potentially multiple nodes the range covers. for (TextIterator markedText(range); !markedText.atEnd(); markedText.advance()) { RefPtr<Range> textPiece = markedText.range(); unsigned startOffset = textPiece->startOffset(); unsigned endOffset = textPiece->endOffset(); - addMarker(textPiece->startContainer(), DocumentMarker(startOffset, endOffset, activeMatch)); - if (endOffset > startOffset) { - // Rendered rects for markers in WebKit are not populated until each time - // the markers are painted. However, we need it to happen sooner, because - // the whole purpose of tickmarks on the scrollbar is to show where - // matches off-screen are (that haven't been painted yet). - Node* node = textPiece->startContainer(); - Vector<DocumentMarker*> markers = markersFor(node); - static_cast<RenderedDocumentMarker*>(markers[markers.size() - 1])->setRenderedRect(range->boundingBox()); - } + addMarker(&textPiece->startContainer(), DocumentMarker(startOffset, endOffset, activeMatch)); } } #if PLATFORM(IOS) -void DocumentMarkerController::addMarker(Range* range, DocumentMarker::MarkerType type, String description, const Vector<String>& interpretations, const RetainPtr<id>& metadata) + +void DocumentMarkerController::addMarker(Range* range, DocumentMarker::MarkerType type, const String& description, const Vector<String>& interpretations, const RetainPtr<id>& metadata) { - // Use a TextIterator to visit the potentially multiple nodes the range covers. for (TextIterator markedText(range); !markedText.atEnd(); markedText.advance()) { RefPtr<Range> textPiece = markedText.range(); - addMarker(textPiece->startContainer(), DocumentMarker(type, textPiece->startOffset(), textPiece->endOffset(), description, interpretations, metadata)); + addMarker(&textPiece->startContainer(), DocumentMarker(type, textPiece->startOffset(), textPiece->endOffset(), description, interpretations, metadata)); } } @@ -123,24 +116,23 @@ void DocumentMarkerController::addDictationPhraseWithAlternativesMarker(Range* r return; size_t numberOfAlternatives = interpretations.size() - 1; - // Use a TextIterator to visit the potentially multiple nodes the range covers. for (TextIterator markedText(range); !markedText.atEnd(); markedText.advance()) { RefPtr<Range> textPiece = markedText.range(); - DocumentMarker marker(DocumentMarker::DictationPhraseWithAlternatives, textPiece->startOffset(), textPiece->endOffset(), "", Vector<String>(numberOfAlternatives), RetainPtr<id>()); + DocumentMarker marker(DocumentMarker::DictationPhraseWithAlternatives, textPiece->startOffset(), textPiece->endOffset(), emptyString(), Vector<String>(numberOfAlternatives), RetainPtr<id>()); for (size_t i = 0; i < numberOfAlternatives; ++i) marker.setAlternative(interpretations[i + 1], i); - addMarker(textPiece->startContainer(), marker); + addMarker(&textPiece->startContainer(), marker); } } void DocumentMarkerController::addDictationResultMarker(Range* range, const RetainPtr<id>& metadata) { - // Use a TextIterator to visit the potentially multiple nodes the range covers. for (TextIterator markedText(range); !markedText.atEnd(); markedText.advance()) { RefPtr<Range> textPiece = markedText.range(); - addMarker(textPiece->startContainer(), DocumentMarker(DocumentMarker::DictationResult, textPiece->startOffset(), textPiece->endOffset(), String(), Vector<String>(), metadata)); + addMarker(&textPiece->startContainer(), DocumentMarker(DocumentMarker::DictationResult, textPiece->startOffset(), textPiece->endOffset(), String(), Vector<String>(), metadata)); } } + #endif void DocumentMarkerController::removeMarkers(Range* range, DocumentMarker::MarkerTypes markerTypes, RemovePartiallyOverlappingMarkerOrNot shouldRemovePartiallyOverlappingMarker) @@ -151,10 +143,154 @@ void DocumentMarkerController::removeMarkers(Range* range, DocumentMarker::Marke ASSERT(!m_markers.isEmpty()); RefPtr<Range> textPiece = markedText.range(); - int startOffset = textPiece->startOffset(); - int endOffset = textPiece->endOffset(); - removeMarkers(textPiece->startContainer(), startOffset, endOffset - startOffset, markerTypes, shouldRemovePartiallyOverlappingMarker); + unsigned startOffset = textPiece->startOffset(); + unsigned endOffset = textPiece->endOffset(); + removeMarkers(&textPiece->startContainer(), startOffset, endOffset - startOffset, markerTypes, shouldRemovePartiallyOverlappingMarker); + } +} + +static void updateRenderedRectsForMarker(RenderedDocumentMarker& marker, Node& node) +{ + ASSERT(!node.document().view() || !node.document().view()->needsLayout()); + + // FIXME: We should refactor this so that we don't use Range (because we only have one Node), but still share code with absoluteTextQuads(). + RefPtr<Range> markerRange = Range::create(node.document(), &node, marker.startOffset(), &node, marker.endOffset()); + if (!markerRange) + return; + Vector<FloatQuad> absoluteMarkerQuads; + markerRange->absoluteTextQuads(absoluteMarkerQuads, true); + + Vector<FloatRect> absoluteMarkerRects; + absoluteMarkerRects.reserveInitialCapacity(absoluteMarkerQuads.size()); + for (const auto& quad : absoluteMarkerQuads) + absoluteMarkerRects.uncheckedAppend(quad.boundingBox()); + + marker.setUnclippedAbsoluteRects(absoluteMarkerRects); +} + +void DocumentMarkerController::invalidateRectsForAllMarkers() +{ + if (!hasMarkers()) + return; + + for (auto& markers : m_markers.values()) { + for (auto& marker : *markers) + marker.invalidate(); + } + + if (Page* page = m_document.page()) + page->chrome().client().didInvalidateDocumentMarkerRects(); +} + +void DocumentMarkerController::invalidateRectsForMarkersInNode(Node& node) +{ + if (!hasMarkers()) + return; + + MarkerList* markers = m_markers.get(&node); + ASSERT(markers); + + for (auto& marker : *markers) + marker.invalidate(); + + if (Page* page = m_document.page()) + page->chrome().client().didInvalidateDocumentMarkerRects(); +} + +static void updateMainFrameLayoutIfNeeded(Document& document) +{ + Frame* frame = document.frame(); + if (!frame) + return; + + FrameView* mainFrameView = frame->mainFrame().view(); + if (!mainFrameView) + return; + + mainFrameView->updateLayoutAndStyleIfNeededRecursive(); +} + +void DocumentMarkerController::updateRectsForInvalidatedMarkersOfType(DocumentMarker::MarkerType markerType) +{ + if (!possiblyHasMarkers(markerType)) + return; + ASSERT(!(m_markers.isEmpty())); + + bool needsLayoutIfAnyRectsAreDirty = true; + + for (auto& nodeAndMarkers : m_markers) { + Node& node = *nodeAndMarkers.key; + for (auto& marker : *nodeAndMarkers.value) { + if (marker.type() != markerType) + continue; + + if (marker.isValid()) + continue; + + // We'll do up to one layout per call if we have any dirty markers. + if (needsLayoutIfAnyRectsAreDirty) { + updateMainFrameLayoutIfNeeded(m_document); + needsLayoutIfAnyRectsAreDirty = false; + } + + updateRenderedRectsForMarker(marker, node); + } + } +} + +Vector<FloatRect> DocumentMarkerController::renderedRectsForMarkers(DocumentMarker::MarkerType markerType) +{ + Vector<FloatRect> result; + + if (!possiblyHasMarkers(markerType)) + return result; + ASSERT(!(m_markers.isEmpty())); + + Frame* frame = m_document.frame(); + if (!frame) + return result; + FrameView* frameView = frame->view(); + if (!frameView) + return result; + + updateRectsForInvalidatedMarkersOfType(markerType); + + bool isSubframe = !frame->isMainFrame(); + IntRect subframeClipRect; + if (isSubframe) + subframeClipRect = frameView->windowToContents(frameView->windowClipRect()); + + for (auto& nodeAndMarkers : m_markers) { + Node& node = *nodeAndMarkers.key; + FloatRect overflowClipRect; + if (RenderObject* renderer = node.renderer()) + overflowClipRect = renderer->absoluteClippedOverflowRect(); + for (auto& marker : *nodeAndMarkers.value) { + if (marker.type() != markerType) + continue; + + auto renderedRects = marker.unclippedAbsoluteRects(); + + // Clip document markers by their overflow clip. + if (node.renderer()) { + for (auto& rect : renderedRects) + rect.intersect(overflowClipRect); + } + + // Clip subframe document markers by their frame. + if (isSubframe) { + for (auto& rect : renderedRects) + rect.intersect(subframeClipRect); + } + + for (const auto& rect : renderedRects) { + if (!rect.isEmpty()) + result.append(rect); + } + } } + + return result; } // Markers are stored in order sorted by their start offset. @@ -166,12 +302,20 @@ void DocumentMarkerController::addMarker(Node* node, const DocumentMarker& newMa if (newMarker.endOffset() == newMarker.startOffset()) return; + if (auto* renderer = node->renderer()) { + // FIXME: Factor the marker painting code out of InlineTextBox and teach simple line layout to use it. + if (is<RenderText>(*renderer)) + downcast<RenderText>(*renderer).ensureLineBoxes(); + else if (is<RenderBlockFlow>(*renderer)) + downcast<RenderBlockFlow>(*renderer).ensureLineBoxes(); + } + m_possiblyExistingMarkerTypes.add(newMarker.type()); - OwnPtr<MarkerList>& list = m_markers.add(node, nullptr).iterator->value; + std::unique_ptr<MarkerList>& list = m_markers.add(node, nullptr).iterator->value; if (!list) { - list = adoptPtr(new MarkerList); + list = std::make_unique<MarkerList>(); list->append(RenderedDocumentMarker(newMarker)); #if PLATFORM(IOS) } else if (newMarker.type() == DocumentMarker::DictationPhraseWithAlternatives || newMarker.type() == DocumentMarker::DictationResult) { @@ -225,9 +369,10 @@ void DocumentMarkerController::addMarker(Node* node, const DocumentMarker& newMa list->insert(i, RenderedDocumentMarker(toInsert)); } - // repaint the affected node if (node->renderer()) node->renderer()->repaint(); + + invalidateRectsForMarkersInNode(*node); } // copies markers from srcNode to dstNode, applying the specified shift delta to the copies. The shift is @@ -247,9 +392,7 @@ void DocumentMarkerController::copyMarkers(Node* srcNode, unsigned startOffset, bool docDirty = false; unsigned endOffset = startOffset + length - 1; - for (size_t i = 0; i != list->size(); ++i) { - DocumentMarker marker = list->at(i); - + for (auto& marker : *list) { // stop if we are now past the specified range if (marker.startOffset() > endOffset) break; @@ -269,7 +412,6 @@ void DocumentMarkerController::copyMarkers(Node* srcNode, unsigned startOffset, addMarker(dstNode, marker); } - // repaint the affected node if (docDirty && dstNode->renderer()) dstNode->renderer()->repaint(); } @@ -335,7 +477,6 @@ void DocumentMarkerController::removeMarkers(Node* node, unsigned startOffset, i m_possiblyExistingMarkerTypes = 0; } - // repaint the affected node if (docDirty && node->renderer()) node->renderer()->repaint(); } @@ -343,19 +484,13 @@ void DocumentMarkerController::removeMarkers(Node* node, unsigned startOffset, i DocumentMarker* DocumentMarkerController::markerContainingPoint(const LayoutPoint& point, DocumentMarker::MarkerType markerType) { if (!possiblyHasMarkers(markerType)) - return 0; + return nullptr; 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 - MarkerList* list = nodeIterator->value.get(); - unsigned markerCount = list->size(); - for (unsigned markerIndex = 0; markerIndex < markerCount; ++markerIndex) { - RenderedDocumentMarker& marker = list->at(markerIndex); + updateRectsForInvalidatedMarkersOfType(markerType); - // skip marker that is wrong type + for (auto& nodeAndMarkers : m_markers) { + for (auto& marker : *nodeAndMarkers.value) { if (marker.type() != markerType) continue; @@ -364,47 +499,42 @@ DocumentMarker* DocumentMarkerController::markerContainingPoint(const LayoutPoin } } - return 0; + return nullptr; } -Vector<DocumentMarker*> DocumentMarkerController::markersFor(Node* node, DocumentMarker::MarkerTypes markerTypes) +Vector<RenderedDocumentMarker*> DocumentMarkerController::markersFor(Node* node, DocumentMarker::MarkerTypes markerTypes) { - Vector<DocumentMarker*> result; + Vector<RenderedDocumentMarker*> result; MarkerList* list = m_markers.get(node); if (!list) return result; - for (size_t i = 0; i < list->size(); ++i) { - if (markerTypes.contains(list->at(i).type())) - result.append(&(list->at(i))); + for (auto& marker : *list) { + if (markerTypes.contains(marker.type())) + result.append(&marker); } return result; } -Vector<DocumentMarker*> DocumentMarkerController::markersInRange(Range* range, DocumentMarker::MarkerTypes markerTypes) +Vector<RenderedDocumentMarker*> DocumentMarkerController::markersInRange(Range* range, DocumentMarker::MarkerTypes markerTypes) { if (!possiblyHasMarkers(markerTypes)) - return Vector<DocumentMarker*>(); + return Vector<RenderedDocumentMarker*>(); - Vector<DocumentMarker*> foundMarkers; + Vector<RenderedDocumentMarker*> foundMarkers; - Node* startContainer = range->startContainer(); - ASSERT(startContainer); - Node* endContainer = range->endContainer(); - ASSERT(endContainer); + Node& startContainer = range->startContainer(); + Node& endContainer = range->endContainer(); Node* pastLastNode = range->pastLastNode(); - for (Node* node = range->firstNode(); node != pastLastNode; node = NodeTraversal::next(node)) { - Vector<DocumentMarker*> markers = markersFor(node); - Vector<DocumentMarker*>::const_iterator end = markers.end(); - for (Vector<DocumentMarker*>::const_iterator it = markers.begin(); it != end; ++it) { - DocumentMarker* marker = *it; + for (Node* node = range->firstNode(); node != pastLastNode; node = NodeTraversal::next(*node)) { + for (auto* marker : markersFor(node)) { if (!markerTypes.contains(marker->type())) continue; - if (node == startContainer && marker->endOffset() <= static_cast<unsigned>(range->startOffset())) + if (node == &startContainer && marker->endOffset() <= range->startOffset()) continue; - if (node == endContainer && marker->startOffset() >= static_cast<unsigned>(range->endOffset())) + if (node == &endContainer && marker->startOffset() >= range->endOffset()) continue; foundMarkers.append(marker); } @@ -412,37 +542,6 @@ Vector<DocumentMarker*> DocumentMarkerController::markersInRange(Range* range, D 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 - MarkerList* list = nodeIterator->value.get(); - unsigned markerCount = list->size(); - for (unsigned markerIndex = 0; markerIndex < markerCount; ++markerIndex) { - const RenderedDocumentMarker& marker = list->at(markerIndex); - - // skip marker that is wrong type - if (marker.type() != markerType) - continue; - - if (!marker.isRendered()) - continue; - - result.append(marker.renderedRect()); - } - } - - return result; -} - void DocumentMarkerController::removeMarkers(Node* node, DocumentMarker::MarkerTypes markerTypes) { if (!possiblyHasMarkers(markerTypes)) @@ -462,9 +561,8 @@ void DocumentMarkerController::removeMarkers(DocumentMarker::MarkerTypes markerT Vector<RefPtr<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]); + for (auto& node : nodesWithMarkers) { + auto iterator = m_markers.find(node); if (iterator != m_markers.end()) removeMarkersFromList(iterator, markerTypes); } @@ -520,18 +618,13 @@ void DocumentMarkerController::repaintMarkers(DocumentMarker::MarkerTypes marker 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) { - Node* node = i->key.get(); + for (auto& marker : m_markers) { + Node* node = marker.key.get(); // inner loop: process each marker in the current node - MarkerList* list = i->value.get(); bool nodeNeedsRepaint = false; - for (size_t i = 0; i != list->size(); ++i) { - DocumentMarker marker = list->at(i); - - // skip nodes that are not of the specified type - if (markerTypes.contains(marker.type())) { + for (auto& documentMarker : *marker.value) { + if (markerTypes.contains(documentMarker.type())) { nodeNeedsRepaint = true; break; } @@ -546,19 +639,6 @@ void DocumentMarkerController::repaintMarkers(DocumentMarker::MarkerTypes marker } } -void DocumentMarkerController::invalidateRenderedRectsForMarkersInRect(const LayoutRect& r) -{ - // 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) { - - // inner loop: process each rect in the current node - MarkerList* list = i->value.get(); - for (size_t listIndex = 0; listIndex < list->size(); ++listIndex) - list->at(listIndex).invalidate(r); - } -} - void DocumentMarkerController::shiftMarkers(Node* node, unsigned startOffset, int delta) { if (!possiblyHasMarkers(DocumentMarker::AllMarkers())) @@ -569,9 +649,10 @@ void DocumentMarkerController::shiftMarkers(Node* node, unsigned startOffset, in if (!list) return; - bool docDirty = false; + bool didShiftMarker = false; for (size_t i = 0; i != list->size(); ) { RenderedDocumentMarker& marker = list->at(i); + // FIXME: How can this possibly be iOS-specific code? #if PLATFORM(IOS) int targetStartOffset = marker.startOffset() + delta; int targetEndOffset = marker.endOffset() + delta; @@ -583,10 +664,7 @@ void DocumentMarkerController::shiftMarkers(Node* node, unsigned startOffset, in if (marker.startOffset() >= startOffset) { ASSERT((int)marker.startOffset() + delta >= 0); marker.shiftOffsets(delta); - docDirty = true; - - // Marker moved, so previously-computed rendered rectangle is now invalid - marker.invalidate(); + didShiftMarker = true; #if !PLATFORM(IOS) } #else @@ -598,18 +676,18 @@ void DocumentMarkerController::shiftMarkers(Node* node, unsigned startOffset, in continue; } marker.setEndOffset(targetEndOffset < node->maxCharacterOffset() ? targetEndOffset : node->maxCharacterOffset()); - docDirty = true; - - // Marker moved, so previously-computed rendered rectangle is now invalid - marker.invalidate(); + didShiftMarker = true; } #endif ++i; } - // repaint the affected node - if (docDirty && node->renderer()) - node->renderer()->repaint(); + if (didShiftMarker) { + invalidateRectsForMarkersInNode(*node); + + if (node->renderer()) + node->renderer()->repaint(); + } } void DocumentMarkerController::setMarkersActive(Range* range, bool active) @@ -618,14 +696,14 @@ void DocumentMarkerController::setMarkersActive(Range* range, bool active) return; ASSERT(!m_markers.isEmpty()); - Node* startContainer = range->startContainer(); - Node* endContainer = range->endContainer(); + 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; + for (Node* node = range->firstNode(); node != pastLastNode; node = NodeTraversal::next(*node)) { + unsigned startOffset = node == &startContainer ? range->startOffset() : 0; + unsigned endOffset = node == &endContainer ? range->endOffset() : std::numeric_limits<unsigned>::max(); setMarkersActive(node, startOffset, endOffset, active); } } @@ -636,10 +714,8 @@ void DocumentMarkerController::setMarkersActive(Node* node, unsigned startOffset if (!list) return; - bool docDirty = false; - for (size_t i = 0; i != list->size(); ++i) { - DocumentMarker& marker = list->at(i); - + bool didActivateMarker = false; + for (auto& marker : *list) { // Markers are returned in order, so stop if we are now past the specified range. if (marker.startOffset() >= endOffset) break; @@ -649,11 +725,10 @@ void DocumentMarkerController::setMarkersActive(Node* node, unsigned startOffset continue; marker.setActiveMatch(active); - docDirty = true; + didActivateMarker = true; } - // repaint the affected node - if (docDirty && node->renderer()) + if (didActivateMarker && node->renderer()) node->renderer()->repaint(); } @@ -663,22 +738,17 @@ bool DocumentMarkerController::hasMarkers(Range* range, DocumentMarker::MarkerTy return false; ASSERT(!m_markers.isEmpty()); - Node* startContainer = range->startContainer(); - ASSERT(startContainer); - Node* endContainer = range->endContainer(); - ASSERT(endContainer); + Node& startContainer = range->startContainer(); + Node& endContainer = range->endContainer(); Node* pastLastNode = range->pastLastNode(); - for (Node* node = range->firstNode(); node != pastLastNode; node = NodeTraversal::next(node)) { - Vector<DocumentMarker*> markers = markersFor(node); - Vector<DocumentMarker*>::const_iterator end = markers.end(); - for (Vector<DocumentMarker*>::const_iterator it = markers.begin(); it != end; ++it) { - DocumentMarker* marker = *it; + for (Node* node = range->firstNode(); node != pastLastNode; node = NodeTraversal::next(*node)) { + for (auto* marker : markersFor(node)) { if (!markerTypes.contains(marker->type())) continue; - if (node == startContainer && marker->endOffset() <= static_cast<unsigned>(range->startOffset())) + if (node == &startContainer && marker->endOffset() <= static_cast<unsigned>(range->startOffset())) continue; - if (node == endContainer && marker->startOffset() >= static_cast<unsigned>(range->endOffset())) + if (node == &endContainer && marker->startOffset() >= static_cast<unsigned>(range->endOffset())) continue; return true; } @@ -692,13 +762,13 @@ void DocumentMarkerController::clearDescriptionOnMarkersIntersectingRange(Range* return; ASSERT(!m_markers.isEmpty()); - Node* startContainer = range->startContainer(); - Node* endContainer = range->endContainer(); + Node& startContainer = range->startContainer(); + Node& endContainer = range->endContainer(); Node* pastLastNode = range->pastLastNode(); - for (Node* node = range->firstNode(); node != pastLastNode; node = NodeTraversal::next(node)) { - unsigned startOffset = node == startContainer ? range->startOffset() : 0; - unsigned endOffset = node == endContainer ? static_cast<unsigned>(range->endOffset()) : std::numeric_limits<unsigned>::max(); + for (Node* node = range->firstNode(); node != pastLastNode; node = NodeTraversal::next(*node)) { + unsigned startOffset = node == &startContainer ? range->startOffset() : 0; + unsigned endOffset = node == &endContainer ? static_cast<unsigned>(range->endOffset()) : std::numeric_limits<unsigned>::max(); MarkerList* list = m_markers.get(node); if (!list) continue; @@ -716,24 +786,20 @@ void DocumentMarkerController::clearDescriptionOnMarkersIntersectingRange(Range* continue; } - marker.clearDetails(); + marker.clearData(); } } } -#ifndef NDEBUG +#if ENABLE(TREE_DEBUGGING) 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) { - Node* node = nodeIterator->key.get(); + for (auto& marker : m_markers) { + Node* node = marker.key.get(); fprintf(stderr, "%p", node); - MarkerList* list = nodeIterator->value.get(); - for (unsigned markerIndex = 0; markerIndex < list->size(); ++markerIndex) { - const DocumentMarker& marker = list->at(markerIndex); - fprintf(stderr, " %d:[%d:%d](%d)", marker.type(), marker.startOffset(), marker.endOffset(), marker.activeMatch()); - } + for (auto& documentMarker : *marker.value) + fprintf(stderr, " %d:[%d:%d](%d)", documentMarker.type(), documentMarker.startOffset(), documentMarker.endOffset(), documentMarker.isActiveMatch()); fprintf(stderr, "\n"); } @@ -742,7 +808,7 @@ void DocumentMarkerController::showMarkers() const } // namespace WebCore -#ifndef NDEBUG +#if ENABLE(TREE_DEBUGGING) void showDocumentMarkers(const WebCore::DocumentMarkerController* controller) { if (controller) |