Chromium Code Reviews| Index: Source/core/dom/DocumentMarkerController.cpp |
| diff --git a/Source/core/dom/DocumentMarkerController.cpp b/Source/core/dom/DocumentMarkerController.cpp |
| index 168772b1340a1caef289460142c492324d20beae..138c01865a4194d7490784688860d83a618ad115 100644 |
| --- a/Source/core/dom/DocumentMarkerController.cpp |
| +++ b/Source/core/dom/DocumentMarkerController.cpp |
| @@ -133,6 +133,16 @@ void DocumentMarkerController::removeMarkers(Range* range, DocumentMarker::Marke |
| } |
| } |
| +static bool startsFurther(const DocumentMarker& lhv, const DocumentMarker& rhv) |
| +{ |
| + return lhv.startOffset() < rhv.startOffset(); |
| +} |
| + |
| +static bool notOverlaps(const DocumentMarker& lhv, const DocumentMarker& rhv) |
|
tony
2013/08/29 22:44:45
Nit: doesNotOverlap sounds better to me than notOv
|
| +{ |
| + return lhv.endOffset() < rhv.startOffset(); |
| +} |
| + |
| // Markers are stored in order sorted by their start offset. |
| // Markers of the same type do not overlap each other. |
| @@ -151,42 +161,58 @@ void DocumentMarkerController::addMarker(Node* node, const DocumentMarker& newMa |
| list->append(RenderedDocumentMarker(newMarker)); |
| } else { |
| RenderedDocumentMarker toInsert(newMarker); |
| - size_t numMarkers = list->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 = list->at(i); |
| - if (marker.startOffset() > toInsert.startOffset()) |
| - break; |
| - if (marker.type() == toInsert.type() && marker.type() != DocumentMarker::TextMatch && marker.endOffset() >= toInsert.startOffset()) { |
| - toInsert.setStartOffset(marker.startOffset()); |
| - list->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 = list->at(j); |
| - if (marker.startOffset() > toInsert.endOffset()) |
| - break; |
| - if (marker.type() == toInsert.type() && marker.type() != DocumentMarker::TextMatch) { |
| - list->remove(j); |
| - if (toInsert.endOffset() <= marker.endOffset()) { |
| - toInsert.setEndOffset(marker.endOffset()); |
| - break; |
| + if (list->last().endOffset() <= newMarker.startOffset()) { |
| + if (toInsert.type() != DocumentMarker::TextMatch) { |
|
tony
2013/08/29 22:44:45
Can we move this block into a helper function? Th
|
| + // 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. |
| + size_t numMarkers = list->size(); |
| + MarkerList::iterator end = std::upper_bound(list->begin(), list->end(), toInsert, startsFurther); |
| + MarkerList::iterator overlapping = list->begin(); |
| + do { |
| + overlapping = std::lower_bound(overlapping, end, toInsert, notOverlaps); |
| + } while (overlapping != end && overlapping->type() != toInsert.type() && ++overlapping != end); |
| + |
| + size_t i; |
|
tony
2013/08/29 22:44:45
Please use a more descriptive variable than 'i'.
|
| + if (overlapping != end) { |
| + toInsert.setStartOffset(overlapping->startOffset()); |
| + i = overlapping - list->begin(); |
| + list->remove(i); |
| + numMarkers--; |
|
tony
2013/08/29 22:44:45
Nit: --numMarkers
|
| + } else { |
| + i = numMarkers; |
|
tony
2013/08/29 22:44:45
Set i = numMarkers when initializing and you can g
|
| + } |
| + 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) { |
|
tony
2013/08/29 22:44:45
Looks like you could use a for loop here so that j
|
| + DocumentMarker marker = list->at(j); |
| + if (marker.startOffset() > toInsert.endOffset()) |
| + break; |
| + if (marker.type() == toInsert.type()) { |
| + list->remove(j); |
| + if (toInsert.endOffset() <= marker.endOffset()) { |
| + toInsert.setEndOffset(marker.endOffset()); |
| + break; |
| + } |
| + numMarkers--; |
|
tony
2013/08/29 22:44:45
Nit: --numMarkers
|
| + } else { |
| + j++; |
|
tony
2013/08/29 22:44:45
Nit: ++j
|
| + } |
| } |
| - numMarkers--; |
| - } else |
| - j++; |
| + // At this point i points to the node before which we want to insert. |
| + list->insert(i, RenderedDocumentMarker(toInsert)); |
| + } else { |
| + MarkerList::iterator pos = std::lower_bound(list->begin(), list->end(), toInsert, startsFurther); |
| + if (pos != list->end()) |
| + list->insert(pos - list->begin(), RenderedDocumentMarker(toInsert)); |
| + else |
| + list->append(RenderedDocumentMarker(toInsert)); |
| + } |
| + } else { |
| + list->append(RenderedDocumentMarker(toInsert)); |
| } |
| - // At this point i points to the node before which we want to insert. |
| - list->insert(i, RenderedDocumentMarker(toInsert)); |
| } |
| // repaint the affected node |