Source/WebCore/dom/DocumentMarkerController.cpp
void DocumentMarkerController::addMarker(Node* node, DocumentMarker newMarker) 
{
    ASSERT(newMarker.endOffset >= newMarker.startOffset);
    if (newMarker.endOffset == newMarker.startOffset)
        return;

    m_possiblyExistingMarkerTypes |= newMarker.type;

    MarkerMapVectorPair* vectorPair = m_markers.get(node);

    if (!vectorPair) {
        vectorPair = new MarkerMapVectorPair;
        vectorPair->first.append(newMarker);
        vectorPair->second.append(placeholderRectForMarker());
        m_markers.set(node, vectorPair);
    } else {
        Vector<DocumentMarker>& markers = vectorPair->first;
        Vector<IntRect>& rects = vectorPair->second;
        size_t numMarkers = markers.size();
        ASSERT(numMarkers == rects.size());
        size_t i;
        // Iterate over all markers whose start offset is less than or equal to the new marker's.
        // If one of them is of the same type as the new marker and touches it or intersects with it
        // (there is at most one), remove it and adjust the new marker's start offset to encompass it.
        for (i = 0; i < numMarkers; ++i) {
            DocumentMarker marker = markers[i];
            if (marker.startOffset > newMarker.startOffset)
                break;
            if (marker.type == newMarker.type && marker.endOffset >= newMarker.startOffset) {
                newMarker.startOffset = marker.startOffset;
                markers.remove(i);
                rects.remove(i);
                numMarkers--;
                break;
            }
        }
        size_t j = i;
        // Iterate over all markers whose end offset is less than or equal to the new marker's,
        // removing markers of the same type as the new marker which touch it or intersect with it,
        // adjusting the new marker's end offset to cover them if necessary.
        while (j < numMarkers) {
            DocumentMarker marker = markers[j];
            if (marker.startOffset > newMarker.endOffset)
                break;
            if (marker.type == newMarker.type) {
                markers.remove(j);
                rects.remove(j);
                if (newMarker.endOffset <= marker.endOffset) {
                    newMarker.endOffset = marker.endOffset;
                    break;
                }
                numMarkers--;
            } else
                j++;
        }
        // At this point i points to the node before which we want to insert.
        markers.insert(i, newMarker);
        rects.insert(i, placeholderRectForMarker());
    }

    // repaint the affected node
    if (node->renderer())
        node->renderer()->repaint();
}
// Markers are stored in order sorted by their start offset.
// Markers of the same type do not overlap each other.
Markers are stored in order sorted by their start offset.
Markers of the same type do not overlap each other.
Markers are stored in order sorted by their start offset . Markers of the same type do not overlap each other .
void DocumentMarkerController::addMarker(Node* node, DocumentMarker newMarker) 
{
    ASSERT(newMarker.endOffset >= newMarker.startOffset);
    if (newMarker.endOffset == newMarker.startOffset)
        return;
    m_possiblyExistingMarkerTypes |= newMarker.type;
    MarkerMapVectorPair* vectorPair = m_markers.get(node);
    if (!vectorPair) {
        vectorPair = new MarkerMapVectorPair;
        vectorPair->first.append(newMarker);
        vectorPair->second.append(placeholderRectForMarker());
        m_markers.set(node, vectorPair);
    } else {
        Vector<DocumentMarker>& markers = vectorPair->first;
        Vector<IntRect>& rects = vectorPair->second;
        size_t numMarkers = markers.size();
        ASSERT(numMarkers == rects.size());
        size_t i;
        for (i = 0; i < numMarkers; ++i) {
            DocumentMarker marker = markers[i];
            if (marker.startOffset > newMarker.startOffset)
                break;
            if (marker.type == newMarker.type && marker.endOffset >= newMarker.startOffset) {
                newMarker.startOffset = marker.startOffset;
                markers.remove(i);
                rects.remove(i);
                numMarkers--;
                break;
            }
        }
        size_t j = i;
        while (j < numMarkers) {
            DocumentMarker marker = markers[j];
            if (marker.startOffset > newMarker.endOffset)
                break;
            if (marker.type == newMarker.type) {
                markers.remove(j);
                rects.remove(j);
                if (newMarker.endOffset <= marker.endOffset) {
                    newMarker.endOffset = marker.endOffset;
                    break;
                }
                numMarkers--;
            } else
                j++;
        }
        markers.insert(i, newMarker);
        rects.insert(i, placeholderRectForMarker());
    }
    if (node->renderer())
        node->renderer()->repaint();
}
void DocumentMarkerController :: addMarker ( Node * node , DocumentMarker newMarker ) { ASSERT ( newMarker . endOffset >= newMarker . startOffset ) ; if ( newMarker . endOffset == newMarker . startOffset ) return ; m_possiblyExistingMarkerTypes |= newMarker . type ; MarkerMapVectorPair * vectorPair = m_markers . get ( node ) ; if ( ! vectorPair ) { vectorPair = new MarkerMapVectorPair ; vectorPair -> first . append ( newMarker ) ; vectorPair -> second . append ( placeholderRectForMarker ( ) ) ; m_markers . set ( node , vectorPair ) ; } else { Vector < DocumentMarker > & markers = vectorPair -> first ; Vector < IntRect > & rects = vectorPair -> second ; size_t numMarkers = markers . size ( ) ; ASSERT ( numMarkers == rects . size ( ) ) ; size_t i ; for ( i = 0 ; i < numMarkers ; ++ i ) { DocumentMarker marker = markers [ i ] ; if ( marker . startOffset > newMarker . startOffset ) break ; if ( marker . type == newMarker . type && marker . endOffset >= newMarker . startOffset ) { newMarker . startOffset = marker . startOffset ; markers . remove ( i ) ; rects . remove ( i ) ; numMarkers -- ; break ; } } size_t j = i ; while ( j < numMarkers ) { DocumentMarker marker = markers [ j ] ; if ( marker . startOffset > newMarker . endOffset ) break ; if ( marker . type == newMarker . type ) { markers . remove ( j ) ; rects . remove ( j ) ; if ( newMarker . endOffset <= marker . endOffset ) { newMarker . endOffset = marker . endOffset ; break ; } numMarkers -- ; } else j ++ ; } markers . insert ( i , newMarker ) ; rects . insert ( i , placeholderRectForMarker ( ) ) ; } if ( node -> renderer ( ) ) node -> renderer ( ) -> repaint ( ) ; }
Markers are stored in order sorted by their start offset.
Markers are stored in order sorted by their start offset .
// Iterate over all markers whose start offset is less than or equal to the new marker's. // If one of them is of the same type as the new marker and touches it or intersects with it // (there is at most one), remove it and adjust the new marker's start offset to encompass it. // Iterate over all markers whose end offset is less than or equal to the new marker's, // removing markers of the same type as the new marker which touch it or intersect with it, // adjusting the new marker's end offset to cover them if necessary. // At this point i points to the node before which we want to insert. // repaint the affected node