| Index: third_party/WebKit/Source/core/editing/markers/DocumentMarkerController.cpp
|
| diff --git a/third_party/WebKit/Source/core/editing/markers/DocumentMarkerController.cpp b/third_party/WebKit/Source/core/editing/markers/DocumentMarkerController.cpp
|
| index 0db8cc87179a923581b191c0ff2b131c7154db5a..8a3e2f4056c34826f2299e169fac32df7c2fe956 100644
|
| --- a/third_party/WebKit/Source/core/editing/markers/DocumentMarkerController.cpp
|
| +++ b/third_party/WebKit/Source/core/editing/markers/DocumentMarkerController.cpp
|
| @@ -82,8 +82,10 @@ inline bool DocumentMarkerController::possiblyHasMarkers(
|
| return m_possiblyExistingMarkerTypes.intersects(types);
|
| }
|
|
|
| -DocumentMarkerController::DocumentMarkerController(const Document& document)
|
| - : m_possiblyExistingMarkerTypes(0), m_document(&document) {}
|
| +DocumentMarkerController::DocumentMarkerController(Document& document)
|
| + : m_possiblyExistingMarkerTypes(0), m_document(&document) {
|
| + setContext(&document);
|
| +}
|
|
|
| void DocumentMarkerController::clear() {
|
| m_markers.clear();
|
| @@ -175,11 +177,6 @@ static bool startsFurther(const Member<RenderedDocumentMarker>& lhv,
|
| return lhv->startOffset() < rhv->startOffset();
|
| }
|
|
|
| -static bool startsAfter(const Member<RenderedDocumentMarker>& marker,
|
| - size_t startOffset) {
|
| - return marker->startOffset() < startOffset;
|
| -}
|
| -
|
| static bool endsBefore(size_t startOffset,
|
| const Member<RenderedDocumentMarker>& rhv) {
|
| return startOffset < rhv->endOffset();
|
| @@ -305,10 +302,7 @@ void DocumentMarkerController::copyMarkers(Node* srcNode,
|
| return;
|
|
|
| bool docDirty = false;
|
| - for (size_t markerListIndex = 0;
|
| - markerListIndex < DocumentMarker::MarkerTypeIndexesCount;
|
| - ++markerListIndex) {
|
| - Member<MarkerList>& list = (*markers)[markerListIndex];
|
| + for (Member<MarkerList> list : *markers) {
|
| if (!list)
|
| continue;
|
|
|
| @@ -585,6 +579,7 @@ void DocumentMarkerController::invalidateRectsForAllMarkers() {
|
| DEFINE_TRACE(DocumentMarkerController) {
|
| visitor->trace(m_markers);
|
| visitor->trace(m_document);
|
| + SynchronousMutationObserver::trace(visitor);
|
| }
|
|
|
| void DocumentMarkerController::removeMarkers(
|
| @@ -724,45 +719,6 @@ void DocumentMarkerController::repaintMarkers(
|
| }
|
| }
|
|
|
| -void DocumentMarkerController::shiftMarkers(Node* node,
|
| - unsigned startOffset,
|
| - int delta) {
|
| - if (!possiblyHasMarkers(DocumentMarker::AllMarkers()))
|
| - return;
|
| - DCHECK(!m_markers.isEmpty());
|
| -
|
| - MarkerLists* markers = m_markers.at(node);
|
| - if (!markers)
|
| - return;
|
| -
|
| - bool didShiftMarker = false;
|
| - for (size_t markerListIndex = 0;
|
| - markerListIndex < DocumentMarker::MarkerTypeIndexesCount;
|
| - ++markerListIndex) {
|
| - Member<MarkerList>& list = (*markers)[markerListIndex];
|
| - if (!list)
|
| - continue;
|
| - MarkerList::iterator startPos =
|
| - std::lower_bound(list->begin(), list->end(), startOffset, startsAfter);
|
| - for (MarkerList::iterator marker = startPos; marker != list->end();
|
| - ++marker) {
|
| -#if DCHECK_IS_ON()
|
| - int startOffset = (*marker)->startOffset();
|
| - DCHECK_GE(startOffset + delta, 0);
|
| -#endif
|
| - (*marker)->shiftOffsets(delta);
|
| - didShiftMarker = true;
|
| - }
|
| - }
|
| -
|
| - if (didShiftMarker) {
|
| - invalidateRectsForMarkersInNode(*node);
|
| - // repaint the affected node
|
| - if (node->layoutObject())
|
| - node->layoutObject()->setShouldDoFullPaintInvalidation();
|
| - }
|
| -}
|
| -
|
| bool DocumentMarkerController::setMarkersActive(const EphemeralRange& range,
|
| bool active) {
|
| if (!possiblyHasMarkers(DocumentMarker::AllMarkers()))
|
| @@ -855,6 +811,81 @@ void DocumentMarkerController::showMarkers() const {
|
| }
|
| #endif
|
|
|
| +// SynchronousMutationObserver
|
| +void DocumentMarkerController::didUpdateCharacterData(CharacterData* node,
|
| + unsigned offset,
|
| + unsigned oldLength,
|
| + unsigned newLength) {
|
| + // If we're doing a pure remove operation, remove the markers in the range
|
| + // being removed (markers containing, but larger than, the range, will be
|
| + // split)
|
| + if (newLength == 0)
|
| + removeMarkers(node, offset, oldLength);
|
| +
|
| + if (!possiblyHasMarkers(DocumentMarker::AllMarkers()))
|
| + return;
|
| + DCHECK(!m_markers.isEmpty());
|
| +
|
| + MarkerLists* markers = m_markers.at(node);
|
| + if (!markers)
|
| + return;
|
| +
|
| + bool didShiftMarker = false;
|
| + for (MarkerList* list : *markers) {
|
| + if (!list)
|
| + continue;
|
| +
|
| + for (MarkerList::iterator it = list->begin(); it != list->end(); ++it) {
|
| + RenderedDocumentMarker& marker = **it;
|
| + // algorithm inspired by https://dom.spec.whatwg.org/#concept-cd-replace
|
| + // but with some changes
|
| + if (marker.startOffset() > offset) {
|
| + // Deviation from the concept-cd-replace algorithm: < instead of <= in
|
| + // the next line
|
| + if (marker.startOffset() < offset + oldLength) {
|
| + // Marker start was in the replaced text. Move to end of new text
|
| + // (Deviation from the concept-cd-replace algorithm: that algorithm
|
| + // would move to the beginning of the new text here)
|
| + marker.setStartOffset(offset + newLength);
|
| + } else {
|
| + // Marker start was after the replaced text. Shift by length
|
| + // difference
|
| + unsigned oldStartOffset = marker.startOffset();
|
| + marker.setStartOffset(oldStartOffset + newLength - oldLength);
|
| + }
|
| + didShiftMarker = true;
|
| + }
|
| +
|
| + if (marker.endOffset() > offset) {
|
| + // Deviation from the concept-cd-replace algorithm: < instead of <= in
|
| + // the next line
|
| + if (marker.endOffset() < offset + oldLength) {
|
| + // Marker end was in the replaced text. Move to beginning of new text
|
| + marker.setEndOffset(offset);
|
| + } else {
|
| + // Marker end was after the replaced text. Shift by length difference
|
| + unsigned oldEndOffset = marker.endOffset();
|
| + marker.setEndOffset(oldEndOffset + newLength - oldLength);
|
| + }
|
| + didShiftMarker = true;
|
| + }
|
| +
|
| + if (marker.startOffset() < marker.endOffset())
|
| + continue;
|
| + list->remove(it - list->begin());
|
| + --it;
|
| + }
|
| + }
|
| +
|
| + if (!didShiftMarker)
|
| + return;
|
| + if (!node->layoutObject())
|
| + return;
|
| + invalidateRectsForMarkersInNode(*node);
|
| + // repaint the affected node
|
| + node->layoutObject()->setShouldDoFullPaintInvalidation();
|
| +}
|
| +
|
| } // namespace blink
|
|
|
| #ifndef NDEBUG
|
|
|