15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/*
25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *           (C) 1999 Antti Koivisto (koivisto@kde.org)
45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *           (C) 2001 Dirk Mueller (mueller@kde.org)
55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *           (C) 2006 Alexey Proskuryakov (ap@webkit.org)
65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) Research In Motion Limited 2010. All rights reserved.
95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * This library is free software; you can redistribute it and/or
115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modify it under the terms of the GNU Library General Public
125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * License as published by the Free Software Foundation; either
135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * version 2 of the License, or (at your option) any later version.
145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * This library is distributed in the hope that it will be useful,
165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * but WITHOUT ANY WARRANTY; without even the implied warranty of
175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Library General Public License for more details.
195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * You should have received a copy of the GNU Library General Public License
215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * along with this library; see the file COPYING.LIB.  If not, write to
225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Boston, MA 02110-1301, USA.
245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */
265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "config.h"
2853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/DocumentMarkerController.h"
295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/Node.h"
3153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/NodeTraversal.h"
3253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/Range.h"
3353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/RenderedDocumentMarker.h"
349e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)#include "core/dom/Text.h"
3553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/editing/TextIterator.h"
3653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/RenderObject.h"
375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#ifndef NDEBUG
395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include <stdio.h>
405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif
415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
42c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink {
435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
449e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)MarkerRemoverPredicate::MarkerRemoverPredicate(const Vector<String>& words)
459e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)    : m_words(words)
469e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles){
479e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)}
489e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)
499e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)bool MarkerRemoverPredicate::operator()(const DocumentMarker& documentMarker, const Text& textNode) const
509e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles){
519e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)    unsigned start  = documentMarker.startOffset();
529e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)    unsigned length = documentMarker.endOffset() - documentMarker.startOffset();
539e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)
549e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)    String markerText = textNode.data().substring(start, length);
559e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)    return m_words.contains(markerText);
569e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)}
579e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)
5806f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)namespace {
5906f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)
6006f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)DocumentMarker::MarkerTypeIndex MarkerTypeToMarkerIndex(DocumentMarker::MarkerType type)
6106f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles){
6206f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    switch (type) {
6306f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    case DocumentMarker::Spelling:
6406f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)        return DocumentMarker::SpellingMarkerIndex;
6506f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    case DocumentMarker::Grammar:
6606f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)        return DocumentMarker::GramarMarkerIndex;
6706f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    case DocumentMarker::TextMatch:
6806f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)        return DocumentMarker::TextMatchMarkerIndex;
691e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    case DocumentMarker::InvisibleSpellcheck:
701e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        return DocumentMarker::InvisibleSpellcheckMarkerIndex;
7106f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    }
7206f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)
7306f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    ASSERT_NOT_REACHED();
7406f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    return DocumentMarker::SpellingMarkerIndex;
7506f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)}
7606f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)
7706f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)} // namespace
7806f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)
795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)inline bool DocumentMarkerController::possiblyHasMarkers(DocumentMarker::MarkerTypes types)
805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return m_possiblyExistingMarkerTypes.intersects(types);
825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)DocumentMarkerController::DocumentMarkerController()
855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    : m_possiblyExistingMarkerTypes(0)
865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
89d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)DEFINE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(DocumentMarkerController);
90e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)
9151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)void DocumentMarkerController::clear()
925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_markers.clear();
94e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)    m_possiblyExistingMarkerTypes = 0;
955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
9753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)void DocumentMarkerController::addMarker(Range* range, DocumentMarker::MarkerType type, const String& description, uint32_t hash)
9853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
9953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    // Use a TextIterator to visit the potentially multiple nodes the range covers.
10053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    for (TextIterator markedText(range); !markedText.atEnd(); markedText.advance()) {
1017242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        addMarker(markedText.startContainer(), DocumentMarker(type, markedText.startOffset(), markedText.endOffset(), description, hash));
10253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    }
10353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
10453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
1057242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccivoid DocumentMarkerController::addMarker(const Position& start, const Position& end, DocumentMarker::MarkerType type, const String& description, uint32_t hash)
1065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Use a TextIterator to visit the potentially multiple nodes the range covers.
1087242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    for (TextIterator markedText(start, end); !markedText.atEnd(); markedText.advance()) {
1097242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        addMarker(markedText.startContainer(), DocumentMarker(type, markedText.startOffset(), markedText.endOffset(), description, hash));
1105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void DocumentMarkerController::addTextMatchMarker(const Range* range, bool activeMatch)
1145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Use a TextIterator to visit the potentially multiple nodes the range covers.
1165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (TextIterator markedText(range); !markedText.atEnd(); markedText.advance()) {
1177242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        unsigned startOffset = markedText.startOffset();
1187242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        unsigned endOffset = markedText.endOffset();
1197242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        addMarker(markedText.startContainer(), DocumentMarker(startOffset, endOffset, activeMatch));
1205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (endOffset > startOffset) {
1215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // Rendered rects for markers in WebKit are not populated until each time
1225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // the markers are painted. However, we need it to happen sooner, because
1235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // the whole purpose of tickmarks on the scrollbar is to show where
1245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // matches off-screen are (that haven't been painted yet).
1257242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            Node* node = markedText.startContainer();
126197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            DocumentMarkerVector markers = markersFor(node);
12706f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)            toRenderedDocumentMarker(markers[markers.size() - 1])->setRenderedRect(range->boundingBox());
1285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
1295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
13251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)void DocumentMarkerController::prepareForDestruction()
13351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles){
13451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    clear();
13551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)}
13651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
1377242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccivoid DocumentMarkerController::removeMarkers(TextIterator& markedText, DocumentMarker::MarkerTypes markerTypes, RemovePartiallyOverlappingMarkerOrNot shouldRemovePartiallyOverlappingMarker)
1385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1397242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    for (; !markedText.atEnd(); markedText.advance()) {
1405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (!possiblyHasMarkers(markerTypes))
1415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return;
1425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        ASSERT(!m_markers.isEmpty());
1435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1447242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        int startOffset = markedText.startOffset();
1457242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        int endOffset = markedText.endOffset();
1467242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        removeMarkers(markedText.startContainer(), startOffset, endOffset - startOffset, markerTypes, shouldRemovePartiallyOverlappingMarker);
1475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1507242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccivoid DocumentMarkerController::removeMarkers(Range* range, DocumentMarker::MarkerTypes markerTypes, RemovePartiallyOverlappingMarkerOrNot shouldRemovePartiallyOverlappingMarker)
1517242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci{
1527242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    TextIterator markedText(range);
1537242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    DocumentMarkerController::removeMarkers(markedText, markerTypes, shouldRemovePartiallyOverlappingMarker);
1547242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci}
1557242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
1567242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccivoid DocumentMarkerController::removeMarkers(const Position& start, const Position& end, DocumentMarker::MarkerTypes markerTypes, RemovePartiallyOverlappingMarkerOrNot shouldRemovePartiallyOverlappingMarker)
1577242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci{
1587242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    TextIterator markedText(start, end);
1597242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    DocumentMarkerController::removeMarkers(markedText, markerTypes, shouldRemovePartiallyOverlappingMarker);
1607242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci}
1617242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
162197021e6b966cfb06891637935ef33fff06433d1Ben Murdochstatic bool startsFurther(const OwnPtrWillBeMember<RenderedDocumentMarker>& lhv, const DocumentMarker* rhv)
16306f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles){
164197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    return lhv->startOffset() < rhv->startOffset();
16506f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)}
16606f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)
167197021e6b966cfb06891637935ef33fff06433d1Ben Murdochstatic bool startsAfter(const OwnPtrWillBeMember<RenderedDocumentMarker>& marker, size_t startOffset)
16806f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles){
169197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    return marker->startOffset() < startOffset;
17006f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)}
17106f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)
172197021e6b966cfb06891637935ef33fff06433d1Ben Murdochstatic bool endsBefore(size_t startOffset, const OwnPtrWillBeMember<RenderedDocumentMarker>& rhv)
17306f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles){
174197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    return startOffset < rhv->endOffset();
17506f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)}
17606f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)
177197021e6b966cfb06891637935ef33fff06433d1Ben Murdochstatic bool compareByStart(const RawPtrWillBeMember<DocumentMarker>& lhv, const RawPtrWillBeMember<DocumentMarker>& rhv)
17806f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles){
179197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    return lhv->startOffset() < rhv->startOffset();
18006f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)}
18106f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)
182197021e6b966cfb06891637935ef33fff06433d1Ben Murdochstatic bool doesNotOverlap(const OwnPtrWillBeMember<RenderedDocumentMarker>& lhv, const DocumentMarker* rhv)
18306f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles){
184197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    return lhv->endOffset() < rhv->startOffset();
18506f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)}
18606f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)
187197021e6b966cfb06891637935ef33fff06433d1Ben Murdochstatic bool doesNotInclude(const OwnPtrWillBeMember<RenderedDocumentMarker>& marker, size_t startOffset)
18806f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles){
189197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    return marker->endOffset() < startOffset;
19006f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)}
19106f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)
1925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// Markers are stored in order sorted by their start offset.
1935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// Markers of the same type do not overlap each other.
1945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
19502772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdochvoid DocumentMarkerController::addMarker(Node* node, const DocumentMarker& newMarker)
1965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(newMarker.endOffset() >= newMarker.startOffset());
1985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (newMarker.endOffset() == newMarker.startOffset())
1995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
2005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_possiblyExistingMarkerTypes.add(newMarker.type());
2025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
203d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    OwnPtrWillBeMember<MarkerLists>& markers = m_markers.add(node, nullptr).storedValue->value;
20406f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    if (!markers) {
205d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        markers = adoptPtrWillBeNoop(new MarkerLists);
20606f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)        markers->grow(DocumentMarker::MarkerTypeIndexesCount);
20706f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    }
20806f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)
20906f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    DocumentMarker::MarkerTypeIndex markerListIndex = MarkerTypeToMarkerIndex(newMarker.type());
21006f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    if (!markers->at(markerListIndex)) {
211d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        markers->insert(markerListIndex, adoptPtrWillBeNoop(new MarkerList));
21206f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    }
2135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
214d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    OwnPtrWillBeMember<MarkerList>& list = markers->at(markerListIndex);
215197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    if (list->isEmpty() || list->last()->endOffset() < newMarker.startOffset()) {
216197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        list->append(RenderedDocumentMarker::create(newMarker));
2175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    } else {
218197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        DocumentMarker toInsert(newMarker);
21906f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)        if (toInsert.type() != DocumentMarker::TextMatch) {
22006f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)            mergeOverlapping(list.get(), toInsert);
22106f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)        } else {
222197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            MarkerList::iterator pos = std::lower_bound(list->begin(), list->end(), &toInsert, startsFurther);
223197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            list->insert(pos - list->begin(), RenderedDocumentMarker::create(toInsert));
2245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
2255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // repaint the affected node
2285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (node->renderer())
2299e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)        node->renderer()->setShouldDoFullPaintInvalidation(true);
2305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
23206f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)void DocumentMarkerController::mergeOverlapping(MarkerList* list, DocumentMarker& toInsert)
23306f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles){
234197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    MarkerList::iterator firstOverlapping = std::lower_bound(list->begin(), list->end(), &toInsert, doesNotOverlap);
23506f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    size_t index = firstOverlapping - list->begin();
236197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    list->insert(index, RenderedDocumentMarker::create(toInsert));
23706f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    MarkerList::iterator inserted = list->begin() + index;
23806f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    firstOverlapping = inserted + 1;
239197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    for (MarkerList::iterator i = firstOverlapping; i != list->end() && (*i)->startOffset() <= (*inserted)->endOffset(); ) {
240197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        (*inserted)->setStartOffset(std::min((*inserted)->startOffset(), (*i)->startOffset()));
241197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        (*inserted)->setEndOffset(std::max((*inserted)->endOffset(), (*i)->endOffset()));
24206f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)        list->remove(i - list->begin());
24306f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    }
24406f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)}
24506f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)
2465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// copies markers from srcNode to dstNode, applying the specified shift delta to the copies.  The shift is
2475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// useful if, e.g., the caller has created the dstNode from a non-prefix substring of the srcNode.
2485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void DocumentMarkerController::copyMarkers(Node* srcNode, unsigned startOffset, int length, Node* dstNode, int delta)
2495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (length <= 0)
2515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
2525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!possiblyHasMarkers(DocumentMarker::AllMarkers()))
2545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
2555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(!m_markers.isEmpty());
2565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
25706f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    MarkerLists* markers = m_markers.get(srcNode);
25806f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    if (!markers)
2595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
2605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool docDirty = false;
26206f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    for (size_t markerListIndex = 0; markerListIndex < DocumentMarker::MarkerTypeIndexesCount; ++markerListIndex) {
263d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        OwnPtrWillBeMember<MarkerList>& list = (*markers)[markerListIndex];
26406f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)        if (!list)
26506f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)            continue;
2665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
26706f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)        unsigned endOffset = startOffset + length - 1;
26806f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)        MarkerList::iterator startPos = std::lower_bound(list->begin(), list->end(), startOffset, doesNotInclude);
26906f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)        for (MarkerList::iterator i = startPos; i != list->end(); ++i) {
270197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            DocumentMarker* marker = i->get();
2715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
27206f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)            // stop if we are now past the specified range
273197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            if (marker->startOffset() > endOffset)
27406f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)                break;
2755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
27606f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)            // pin the marker to the specified range and apply the shift delta
27706f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)            docDirty = true;
278197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            if (marker->startOffset() < startOffset)
279197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch                marker->setStartOffset(startOffset);
280197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            if (marker->endOffset() > endOffset)
281197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch                marker->setEndOffset(endOffset);
282197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            marker->shiftOffsets(delta);
2835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
284197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            addMarker(dstNode, *marker);
28506f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)        }
2865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // repaint the affected node
2895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (docDirty && dstNode->renderer())
2909e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)        dstNode->renderer()->setShouldDoFullPaintInvalidation(true);
2915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void DocumentMarkerController::removeMarkers(Node* node, unsigned startOffset, int length, DocumentMarker::MarkerTypes markerTypes, RemovePartiallyOverlappingMarkerOrNot shouldRemovePartiallyOverlappingMarker)
2945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (length <= 0)
2965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
2975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!possiblyHasMarkers(markerTypes))
2995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
3005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(!(m_markers.isEmpty()));
3015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
30206f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    MarkerLists* markers = m_markers.get(node);
30306f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    if (!markers)
3045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
3055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool docDirty = false;
30706f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    size_t emptyListsCount = 0;
30806f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    for (size_t markerListIndex = 0; markerListIndex < DocumentMarker::MarkerTypeIndexesCount; ++markerListIndex) {
309d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        OwnPtrWillBeMember<MarkerList>& list = (*markers)[markerListIndex];
31006f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)        if (!list || list->isEmpty()) {
31106f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)            if (list.get() && list->isEmpty())
31206f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)                list.clear();
31306f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)            ++emptyListsCount;
3145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            continue;
3155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
316197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        if (!markerTypes.contains((*list->begin())->type()))
31706f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)            continue;
31806f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)        unsigned endOffset = startOffset + length;
31906f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)        MarkerList::iterator startPos = std::upper_bound(list->begin(), list->end(), startOffset, endsBefore);
32006f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)        for (MarkerList::iterator i = startPos; i != list->end(); ) {
321197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            DocumentMarker marker(*i->get());
3225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
32306f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)            // markers are returned in order, so stop if we are now past the specified range
32406f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)            if (marker.startOffset() >= endOffset)
32506f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)                break;
3265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
32706f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)            // at this point we know that marker and target intersect in some way
32806f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)            docDirty = true;
3295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
33006f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)            // pitch the old marker
33106f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)            list->remove(i - list->begin());
33206f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)
33306f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)            if (shouldRemovePartiallyOverlappingMarker) {
33406f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)                // Stop here. Don't add resulting slices back.
33506f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)                continue;
33606f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)            }
3375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
33806f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)            // add either of the resulting slices that are left after removing target
33906f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)            if (startOffset > marker.startOffset()) {
34006f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)                DocumentMarker newLeft = marker;
34106f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)                newLeft.setEndOffset(startOffset);
34206f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)                size_t insertIndex = i - list->begin();
343197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch                list->insert(insertIndex, RenderedDocumentMarker::create(newLeft));
34406f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)                // Move to the marker after the inserted one.
34506f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)                i = list->begin() + insertIndex + 1;
34606f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)            }
34706f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)            if (marker.endOffset() > endOffset) {
34806f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)                DocumentMarker newRight = marker;
34906f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)                newRight.setStartOffset(endOffset);
35006f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)                size_t insertIndex = i - list->begin();
351197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch                list->insert(insertIndex, RenderedDocumentMarker::create(newRight));
35206f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)                // Move to the marker after the inserted one.
35306f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)                i = list->begin() + insertIndex + 1;
35406f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)            }
3555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
35606f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)
35706f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)        if (list->isEmpty()) {
35806f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)            list.clear();
35906f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)            ++emptyListsCount;
3605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
3615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
3625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
36306f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    if (emptyListsCount == DocumentMarker::MarkerTypeIndexesCount) {
3645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_markers.remove(node);
365e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)        if (m_markers.isEmpty())
366e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)            m_possiblyExistingMarkerTypes = 0;
3675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
3685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // repaint the affected node
3705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (docDirty && node->renderer())
3719e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)        node->renderer()->setShouldDoFullPaintInvalidation(true);
3725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)DocumentMarker* DocumentMarkerController::markerContainingPoint(const LayoutPoint& point, DocumentMarker::MarkerType markerType)
3755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
3765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!possiblyHasMarkers(markerType))
3775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return 0;
3785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(!(m_markers.isEmpty()));
3795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // outer loop: process each node that contains any markers
3815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    MarkerMap::iterator end = m_markers.end();
3825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (MarkerMap::iterator nodeIterator = m_markers.begin(); nodeIterator != end; ++nodeIterator) {
3835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // inner loop; process each marker in this node
38406f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)        MarkerLists* markers = nodeIterator->value.get();
385d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        OwnPtrWillBeMember<MarkerList>& list = (*markers)[MarkerTypeToMarkerIndex(markerType)];
38606f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)        unsigned markerCount = list.get() ? list->size() : 0;
3875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        for (unsigned markerIndex = 0; markerIndex < markerCount; ++markerIndex) {
388197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            RenderedDocumentMarker* marker = list->at(markerIndex).get();
389197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            if (marker->contains(point))
390197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch                return marker;
3915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
3925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
3935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return 0;
3955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
397197021e6b966cfb06891637935ef33fff06433d1Ben MurdochDocumentMarkerVector DocumentMarkerController::markersFor(Node* node, DocumentMarker::MarkerTypes markerTypes)
3985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
399197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    DocumentMarkerVector result;
40006f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)
40106f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    MarkerLists* markers = m_markers.get(node);
40206f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    if (!markers)
4035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return result;
4045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
40506f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    for (size_t markerListIndex = 0; markerListIndex < DocumentMarker::MarkerTypeIndexesCount; ++markerListIndex) {
406d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        OwnPtrWillBeMember<MarkerList>& list = (*markers)[markerListIndex];
407197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        if (!list || list->isEmpty() || !markerTypes.contains((*list->begin())->type()))
40806f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)            continue;
40906f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)
41006f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)        for (size_t i = 0; i < list->size(); ++i)
411197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            result.append(list->at(i).get());
4125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
4135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
41406f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    std::sort(result.begin(), result.end(), compareByStart);
4155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return result;
4165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
4175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
418197021e6b966cfb06891637935ef33fff06433d1Ben MurdochDocumentMarkerVector DocumentMarkerController::markers()
41953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
420197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    DocumentMarkerVector result;
42153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    for (MarkerMap::iterator i = m_markers.begin(); i != m_markers.end(); ++i) {
42206f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)        MarkerLists* markers = i->value.get();
42306f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)        for (size_t markerListIndex = 0; markerListIndex < DocumentMarker::MarkerTypeIndexesCount; ++markerListIndex) {
424d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)            OwnPtrWillBeMember<MarkerList>& list = (*markers)[markerListIndex];
42506f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)            for (size_t j = 0; list.get() && j < list->size(); ++j)
426197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch                result.append(list->at(j).get());
42706f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)        }
42853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    }
42906f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    std::sort(result.begin(), result.end(), compareByStart);
43053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    return result;
43153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
43253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
433197021e6b966cfb06891637935ef33fff06433d1Ben MurdochDocumentMarkerVector DocumentMarkerController::markersInRange(Range* range, DocumentMarker::MarkerTypes markerTypes)
4345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
4355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!possiblyHasMarkers(markerTypes))
436197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        return DocumentMarkerVector();
4375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
438197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    DocumentMarkerVector foundMarkers;
4395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Node* startContainer = range->startContainer();
4415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(startContainer);
4425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Node* endContainer = range->endContainer();
4435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(endContainer);
4445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Node* pastLastNode = range->pastLastNode();
44651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    for (Node* node = range->firstNode(); node != pastLastNode; node = NodeTraversal::next(*node)) {
447197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        DocumentMarkerVector markers = markersFor(node);
448197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        DocumentMarkerVector::const_iterator end = markers.end();
449197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        for (DocumentMarkerVector::const_iterator it = markers.begin(); it != end; ++it) {
4505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            DocumentMarker* marker = *it;
4515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (!markerTypes.contains(marker->type()))
4525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                continue;
4535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (node == startContainer && marker->endOffset() <= static_cast<unsigned>(range->startOffset()))
4545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                continue;
4555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (node == endContainer && marker->startOffset() >= static_cast<unsigned>(range->endOffset()))
4565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                continue;
4575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            foundMarkers.append(marker);
4585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
4595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
4605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return foundMarkers;
4615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
4625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)Vector<IntRect> DocumentMarkerController::renderedRectsForMarkers(DocumentMarker::MarkerType markerType)
4645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
4655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Vector<IntRect> result;
4665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!possiblyHasMarkers(markerType))
4685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return result;
4695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(!(m_markers.isEmpty()));
4705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // outer loop: process each node
4725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    MarkerMap::iterator end = m_markers.end();
4735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (MarkerMap::iterator nodeIterator = m_markers.begin(); nodeIterator != end; ++nodeIterator) {
4745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // inner loop; process each marker in this node
47506f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)        MarkerLists* markers = nodeIterator->value.get();
47606f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)        for (size_t markerListIndex = 0; markerListIndex < DocumentMarker::MarkerTypeIndexesCount; ++markerListIndex) {
477d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)            OwnPtrWillBeMember<MarkerList>& list = (*markers)[markerListIndex];
478197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            if (!list || list->isEmpty() || (*list->begin())->type() != markerType)
4795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                continue;
48006f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)            for (unsigned markerIndex = 0; markerIndex < list->size(); ++markerIndex) {
481197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch                RenderedDocumentMarker* marker = list->at(markerIndex).get();
482197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch                if (!marker->isRendered())
48306f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)                    continue;
484197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch                result.append(marker->renderedRect());
48506f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)            }
4865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
4875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
4885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return result;
4905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
4915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
492d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)void DocumentMarkerController::trace(Visitor* visitor)
493d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles){
494c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#if ENABLE(OILPAN)
495d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    visitor->trace(m_markers);
496c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#endif
497d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)}
498d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)
4995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void DocumentMarkerController::removeMarkers(Node* node, DocumentMarker::MarkerTypes markerTypes)
5005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
5015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!possiblyHasMarkers(markerTypes))
5025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
5035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(!m_markers.isEmpty());
50402772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
5055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    MarkerMap::iterator iterator = m_markers.find(node);
5065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (iterator != m_markers.end())
507e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)        removeMarkersFromList(iterator, markerTypes);
5085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
5095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5109e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)void DocumentMarkerController::removeMarkers(const MarkerRemoverPredicate& shouldRemoveMarker)
5119e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles){
5129e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)    for (MarkerMap::iterator i = m_markers.begin(); i != m_markers.end(); ++i) {
5139e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)        MarkerLists* markers = i->value.get();
5149e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)        for (size_t markerListIndex = 0; markerListIndex < DocumentMarker::MarkerTypeIndexesCount; ++markerListIndex) {
5159e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)            OwnPtrWillBeMember<MarkerList>& list = (*markers)[markerListIndex];
5169e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)
5179e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)            WillBeHeapVector<RawPtrWillBeMember<RenderedDocumentMarker> > markersToBeRemoved;
5189e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)            for (size_t j = 0; list.get() && j < list->size(); ++j) {
5199e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)                if (i->key->isTextNode() && shouldRemoveMarker(*list->at(j).get(), static_cast<const Text&>(*i->key)))
5209e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)                    markersToBeRemoved.append(list->at(j).get());
5219e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)            }
5229e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)
5239e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)            for (size_t j = 0; j < markersToBeRemoved.size(); ++j)
5249e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)                list->remove(list->find(markersToBeRemoved[j].get()));
5259e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)        }
5269e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)    }
5279e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)}
5289e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)
5295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void DocumentMarkerController::removeMarkers(DocumentMarker::MarkerTypes markerTypes)
5305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
5315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!possiblyHasMarkers(markerTypes))
5325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
5335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(!m_markers.isEmpty());
5345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
53551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    Vector<const Node*> nodesWithMarkers;
536e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)    copyKeysToVector(m_markers, nodesWithMarkers);
537e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)    unsigned size = nodesWithMarkers.size();
538e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)    for (unsigned i = 0; i < size; ++i) {
539e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)        MarkerMap::iterator iterator = m_markers.find(nodesWithMarkers[i]);
540e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)        if (iterator != m_markers.end())
541e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)            removeMarkersFromList(iterator, markerTypes);
542e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)    }
543e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)
5445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_possiblyExistingMarkerTypes.remove(markerTypes);
5455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
5465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
547e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)void DocumentMarkerController::removeMarkersFromList(MarkerMap::iterator iterator, DocumentMarker::MarkerTypes markerTypes)
5485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
549e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)    bool needsRepainting = false;
55006f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    bool nodeCanBeRemoved;
551e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)
55206f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    size_t emptyListsCount = 0;
5535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (markerTypes == DocumentMarker::AllMarkers()) {
554e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)        needsRepainting = true;
55506f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)        nodeCanBeRemoved = true;
5565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    } else {
55706f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)        MarkerLists* markers = iterator->value.get();
55806f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)
55906f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)        for (size_t markerListIndex = 0; markerListIndex < DocumentMarker::MarkerTypeIndexesCount; ++markerListIndex) {
560d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)            OwnPtrWillBeMember<MarkerList>& list = (*markers)[markerListIndex];
56106f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)            if (!list || list->isEmpty()) {
56206f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)                if (list.get() && list->isEmpty())
56306f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)                    list.clear();
56406f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)                ++emptyListsCount;
5655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                continue;
5665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
567197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            if (markerTypes.contains((*list->begin())->type())) {
56806f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)                list->clear();
56906f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)                list.clear();
57006f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)                ++emptyListsCount;
57106f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)                needsRepainting = true;
57206f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)            }
5735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
5745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
57506f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)        nodeCanBeRemoved = emptyListsCount == DocumentMarker::MarkerTypeIndexesCount;
576e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)    }
5775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
578e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)    if (needsRepainting) {
579e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)        if (RenderObject* renderer = iterator->key->renderer())
5809e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)            renderer->setShouldDoFullPaintInvalidation(true);
581e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)    }
582e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)
58306f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    if (nodeCanBeRemoved) {
584e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)        m_markers.remove(iterator);
585e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)        if (m_markers.isEmpty())
586e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)            m_possiblyExistingMarkerTypes = 0;
5875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
5885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
5895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void DocumentMarkerController::repaintMarkers(DocumentMarker::MarkerTypes markerTypes)
5915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
5925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!possiblyHasMarkers(markerTypes))
5935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
5945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(!m_markers.isEmpty());
5955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // outer loop: process each markered node in the document
5975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    MarkerMap::iterator end = m_markers.end();
5985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (MarkerMap::iterator i = m_markers.begin(); i != end; ++i) {
59951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        const Node* node = i->key;
6005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // inner loop: process each marker in the current node
60206f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)        MarkerLists* markers = i->value.get();
60306f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)        for (size_t markerListIndex = 0; markerListIndex < DocumentMarker::MarkerTypeIndexesCount; ++markerListIndex) {
604d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)            OwnPtrWillBeMember<MarkerList>& list = (*markers)[markerListIndex];
605197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            if (!list || list->isEmpty() || !markerTypes.contains((*list->begin())->type()))
60606f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)                continue;
60706f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)
60806f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)            // cause the node to be redrawn
60906f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)            if (RenderObject* renderer = node->renderer()) {
6109e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)                renderer->setShouldDoFullPaintInvalidation(true);
6115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                break;
6125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
6135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
6145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
6155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
6165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void DocumentMarkerController::invalidateRenderedRectsForMarkersInRect(const LayoutRect& r)
6185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
6195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // outer loop: process each markered node in the document
6205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    MarkerMap::iterator end = m_markers.end();
6215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (MarkerMap::iterator i = m_markers.begin(); i != end; ++i) {
6225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // inner loop: process each rect in the current node
62406f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)        MarkerLists* markers = i->value.get();
62506f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)        for (size_t markerListIndex = 0; markerListIndex < DocumentMarker::MarkerTypeIndexesCount; ++markerListIndex) {
626d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)            OwnPtrWillBeMember<MarkerList>& list = (*markers)[markerListIndex];
62706f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)            for (size_t markerIndex = 0; list.get() && markerIndex < list->size(); ++markerIndex)
628197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch                list->at(markerIndex)->invalidate(r);
62906f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)        }
6305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
6315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
6325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void DocumentMarkerController::shiftMarkers(Node* node, unsigned startOffset, int delta)
6345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
6355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!possiblyHasMarkers(DocumentMarker::AllMarkers()))
6365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
6375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(!m_markers.isEmpty());
6385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
63906f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    MarkerLists* markers = m_markers.get(node);
64006f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    if (!markers)
6415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
6425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool docDirty = false;
64406f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    for (size_t markerListIndex = 0; markerListIndex < DocumentMarker::MarkerTypeIndexesCount; ++markerListIndex) {
645d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        OwnPtrWillBeMember<MarkerList>& list = (*markers)[markerListIndex];
64606f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)        if (!list)
64706f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)            continue;
64806f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)        MarkerList::iterator startPos = std::lower_bound(list->begin(), list->end(), startOffset, startsAfter);
64906f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)        for (MarkerList::iterator marker = startPos; marker != list->end(); ++marker) {
650197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#if ENABLE(ASSERT)
651197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            int startOffset = (*marker)->startOffset();
652197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            ASSERT(startOffset + delta >= 0);
653197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#endif
654197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            (*marker)->shiftOffsets(delta);
6555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            docDirty = true;
6565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // Marker moved, so previously-computed rendered rectangle is now invalid
658197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            (*marker)->invalidate();
6595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
6605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
6615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // repaint the affected node
6635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (docDirty && node->renderer())
6649e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)        node->renderer()->setShouldDoFullPaintInvalidation(true);
6655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
6665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void DocumentMarkerController::setMarkersActive(Range* range, bool active)
6685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
6695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!possiblyHasMarkers(DocumentMarker::AllMarkers()))
6705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
6715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(!m_markers.isEmpty());
6725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
673926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    Node* startContainer = range->startContainer();
674926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    Node* endContainer = range->endContainer();
6755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Node* pastLastNode = range->pastLastNode();
677926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
67851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    for (Node* node = range->firstNode(); node != pastLastNode; node = NodeTraversal::next(*node)) {
679926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        int startOffset = node == startContainer ? range->startOffset() : 0;
680926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        int endOffset = node == endContainer ? range->endOffset() : INT_MAX;
6815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        setMarkersActive(node, startOffset, endOffset, active);
6825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
6835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
6845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void DocumentMarkerController::setMarkersActive(Node* node, unsigned startOffset, unsigned endOffset, bool active)
6865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
68706f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    MarkerLists* markers = m_markers.get(node);
68806f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    if (!markers)
6895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
6905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool docDirty = false;
692d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    OwnPtrWillBeMember<MarkerList>& list = (*markers)[MarkerTypeToMarkerIndex(DocumentMarker::TextMatch)];
69306f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    if (!list)
69406f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)        return;
69506f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    MarkerList::iterator startPos = std::upper_bound(list->begin(), list->end(), startOffset, endsBefore);
69606f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    for (MarkerList::iterator marker = startPos; marker != list->end(); ++marker) {
6975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Markers are returned in order, so stop if we are now past the specified range.
699197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        if ((*marker)->startOffset() >= endOffset)
7005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            break;
7015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
702197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        (*marker)->setActiveMatch(active);
7035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        docDirty = true;
7045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
7055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // repaint the affected node
7075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (docDirty && node->renderer())
7089e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)        node->renderer()->setShouldDoFullPaintInvalidation(true);
7095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
7105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool DocumentMarkerController::hasMarkers(Range* range, DocumentMarker::MarkerTypes markerTypes)
7125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
7135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!possiblyHasMarkers(markerTypes))
7145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return false;
7155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(!m_markers.isEmpty());
7165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Node* startContainer = range->startContainer();
7185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(startContainer);
7195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Node* endContainer = range->endContainer();
7205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(endContainer);
7215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Node* pastLastNode = range->pastLastNode();
72351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    for (Node* node = range->firstNode(); node != pastLastNode; node = NodeTraversal::next(*node)) {
724197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        DocumentMarkerVector markers = markersFor(node);
725197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        DocumentMarkerVector::const_iterator end = markers.end();
726197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        for (DocumentMarkerVector::const_iterator it = markers.begin(); it != end; ++it) {
7275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            DocumentMarker* marker = *it;
7285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (!markerTypes.contains(marker->type()))
7295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                continue;
7305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (node == startContainer && marker->endOffset() <= static_cast<unsigned>(range->startOffset()))
7315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                continue;
7325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (node == endContainer && marker->startOffset() >= static_cast<unsigned>(range->endOffset()))
7335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                continue;
7345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return true;
7355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
7365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
7375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return false;
7385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
7395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#ifndef NDEBUG
7415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void DocumentMarkerController::showMarkers() const
7425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
7435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    fprintf(stderr, "%d nodes have markers:\n", m_markers.size());
7445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    MarkerMap::const_iterator end = m_markers.end();
7455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (MarkerMap::const_iterator nodeIterator = m_markers.begin(); nodeIterator != end; ++nodeIterator) {
74651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        const Node* node = nodeIterator->key;
7475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        fprintf(stderr, "%p", node);
74806f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)        MarkerLists* markers = m_markers.get(node);
74906f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)        for (size_t markerListIndex = 0; markerListIndex < DocumentMarker::MarkerTypeIndexesCount; ++markerListIndex) {
750d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)            OwnPtrWillBeMember<MarkerList>& list = (*markers)[markerListIndex];
75106f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)            for (unsigned markerIndex = 0; list.get() && markerIndex < list->size(); ++markerIndex) {
752197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch                DocumentMarker* marker = list->at(markerIndex).get();
753197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch                fprintf(stderr, " %d:[%d:%d](%d)", marker->type(), marker->startOffset(), marker->endOffset(), marker->activeMatch());
75406f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)            }
7555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
7565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        fprintf(stderr, "\n");
7585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
7595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
7605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif
7615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
762c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)} // namespace blink
7635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#ifndef NDEBUG
765c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)void showDocumentMarkers(const blink::DocumentMarkerController* controller)
7665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
7675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (controller)
7685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        controller->showMarkers();
7695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
7705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif
771