OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) | 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) |
3 * (C) 1999 Antti Koivisto (koivisto@kde.org) | 3 * (C) 1999 Antti Koivisto (koivisto@kde.org) |
4 * (C) 2001 Dirk Mueller (mueller@kde.org) | 4 * (C) 2001 Dirk Mueller (mueller@kde.org) |
5 * (C) 2006 Alexey Proskuryakov (ap@webkit.org) | 5 * (C) 2006 Alexey Proskuryakov (ap@webkit.org) |
6 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights | 6 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights |
7 * reserved. | 7 * reserved. |
8 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. | 8 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. |
9 * (http://www.torchmobile.com/) | 9 * (http://www.torchmobile.com/) |
10 * Copyright (C) Research In Motion Limited 2010. All rights reserved. | 10 * Copyright (C) Research In Motion Limited 2010. All rights reserved. |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
139 markedText.endOffsetInCurrentContainer(), | 139 markedText.endOffsetInCurrentContainer(), |
140 underlineColor, thick, backgroundColor)); | 140 underlineColor, thick, backgroundColor)); |
141 } | 141 } |
142 | 142 |
143 void DocumentMarkerController::prepareForDestruction() { | 143 void DocumentMarkerController::prepareForDestruction() { |
144 clear(); | 144 clear(); |
145 } | 145 } |
146 | 146 |
147 void DocumentMarkerController::removeMarkers( | 147 void DocumentMarkerController::removeMarkers( |
148 TextIterator& markedText, | 148 TextIterator& markedText, |
149 DocumentMarker::MarkerTypes markerTypes, | 149 DocumentMarker::MarkerTypes markerTypes) { |
150 RemovePartiallyOverlappingMarkerOrNot | |
151 shouldRemovePartiallyOverlappingMarker) { | |
152 for (; !markedText.atEnd(); markedText.advance()) { | 150 for (; !markedText.atEnd(); markedText.advance()) { |
153 if (!possiblyHasMarkers(markerTypes)) | 151 if (!possiblyHasMarkers(markerTypes)) |
154 return; | 152 return; |
155 DCHECK(!m_markers.isEmpty()); | 153 DCHECK(!m_markers.isEmpty()); |
156 | 154 |
157 int startOffset = markedText.startOffsetInCurrentContainer(); | 155 int startOffset = markedText.startOffsetInCurrentContainer(); |
158 int endOffset = markedText.endOffsetInCurrentContainer(); | 156 int endOffset = markedText.endOffsetInCurrentContainer(); |
159 removeMarkers(markedText.currentContainer(), startOffset, | 157 removeMarkers(markedText.currentContainer(), startOffset, |
160 endOffset - startOffset, markerTypes, | 158 endOffset - startOffset, markerTypes); |
161 shouldRemovePartiallyOverlappingMarker); | |
162 } | 159 } |
163 } | 160 } |
164 | 161 |
165 void DocumentMarkerController::removeMarkers( | 162 void DocumentMarkerController::removeMarkers( |
166 const EphemeralRange& range, | 163 const EphemeralRange& range, |
167 DocumentMarker::MarkerTypes markerTypes, | 164 DocumentMarker::MarkerTypes markerTypes) { |
168 RemovePartiallyOverlappingMarkerOrNot | |
169 shouldRemovePartiallyOverlappingMarker) { | |
170 DCHECK(!m_document->needsLayoutTreeUpdate()); | 165 DCHECK(!m_document->needsLayoutTreeUpdate()); |
171 | 166 |
172 TextIterator markedText(range.startPosition(), range.endPosition()); | 167 TextIterator markedText(range.startPosition(), range.endPosition()); |
173 DocumentMarkerController::removeMarkers( | 168 DocumentMarkerController::removeMarkers(markedText, markerTypes); |
174 markedText, markerTypes, shouldRemovePartiallyOverlappingMarker); | |
175 } | 169 } |
176 | 170 |
177 static bool startsFurther(const Member<RenderedDocumentMarker>& lhv, | 171 static bool startsFurther(const Member<RenderedDocumentMarker>& lhv, |
178 const DocumentMarker* rhv) { | 172 const DocumentMarker* rhv) { |
179 return lhv->startOffset() < rhv->startOffset(); | 173 return lhv->startOffset() < rhv->startOffset(); |
180 } | 174 } |
181 | 175 |
182 static bool endsBefore(size_t startOffset, | 176 static bool endsBefore(size_t startOffset, |
183 const Member<RenderedDocumentMarker>& rhv) { | 177 const Member<RenderedDocumentMarker>& rhv) { |
184 return startOffset < rhv->endOffset(); | 178 return startOffset < rhv->endOffset(); |
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
336 if (docDirty && dstNode->layoutObject()) { | 330 if (docDirty && dstNode->layoutObject()) { |
337 dstNode->layoutObject()->setShouldDoFullPaintInvalidation( | 331 dstNode->layoutObject()->setShouldDoFullPaintInvalidation( |
338 PaintInvalidationDocumentMarkerChange); | 332 PaintInvalidationDocumentMarkerChange); |
339 } | 333 } |
340 } | 334 } |
341 | 335 |
342 void DocumentMarkerController::removeMarkers( | 336 void DocumentMarkerController::removeMarkers( |
343 Node* node, | 337 Node* node, |
344 unsigned startOffset, | 338 unsigned startOffset, |
345 int length, | 339 int length, |
346 DocumentMarker::MarkerTypes markerTypes, | 340 DocumentMarker::MarkerTypes markerTypes) { |
347 RemovePartiallyOverlappingMarkerOrNot | |
348 shouldRemovePartiallyOverlappingMarker) { | |
349 if (length <= 0) | 341 if (length <= 0) |
350 return; | 342 return; |
351 | 343 |
352 if (!possiblyHasMarkers(markerTypes)) | 344 if (!possiblyHasMarkers(markerTypes)) |
353 return; | 345 return; |
354 DCHECK(!(m_markers.isEmpty())); | 346 DCHECK(!(m_markers.isEmpty())); |
355 | 347 |
356 MarkerLists* markers = m_markers.at(node); | 348 MarkerLists* markers = m_markers.at(node); |
357 if (!markers) | 349 if (!markers) |
358 return; | 350 return; |
(...skipping 16 matching lines...) Expand all Loading... | |
375 MarkerList::iterator startPos = | 367 MarkerList::iterator startPos = |
376 std::upper_bound(list->begin(), list->end(), startOffset, endsBefore); | 368 std::upper_bound(list->begin(), list->end(), startOffset, endsBefore); |
377 for (MarkerList::iterator i = startPos; i != list->end();) { | 369 for (MarkerList::iterator i = startPos; i != list->end();) { |
378 DocumentMarker marker(*i->get()); | 370 DocumentMarker marker(*i->get()); |
379 | 371 |
380 // markers are returned in order, so stop if we are now past the specified | 372 // markers are returned in order, so stop if we are now past the specified |
381 // range | 373 // range |
382 if (marker.startOffset() >= endOffset) | 374 if (marker.startOffset() >= endOffset) |
383 break; | 375 break; |
384 | 376 |
385 // at this point we know that marker and target intersect in some way | 377 list->erase(i - list->begin()); |
386 docDirty = true; | 378 docDirty = true; |
387 | |
388 // pitch the old marker | |
389 list->erase(i - list->begin()); | |
390 | |
391 if (shouldRemovePartiallyOverlappingMarker) { | |
392 // Stop here. Don't add resulting slices back. | |
393 continue; | |
394 } | |
395 | |
396 // add either of the resulting slices that are left after removing target | |
397 if (startOffset > marker.startOffset()) { | |
398 DocumentMarker newLeft = marker; | |
399 newLeft.setEndOffset(startOffset); | |
400 size_t insertIndex = i - list->begin(); | |
401 list->insert(insertIndex, RenderedDocumentMarker::create(newLeft)); | |
402 // Move to the marker after the inserted one. | |
403 i = list->begin() + insertIndex + 1; | |
404 } | |
405 if (marker.endOffset() > endOffset) { | |
406 DocumentMarker newRight = marker; | |
407 newRight.setStartOffset(endOffset); | |
408 size_t insertIndex = i - list->begin(); | |
409 list->insert(insertIndex, RenderedDocumentMarker::create(newRight)); | |
410 // Move to the marker after the inserted one. | |
411 i = list->begin() + insertIndex + 1; | |
412 } | |
413 } | 379 } |
414 | 380 |
415 if (list->isEmpty()) { | 381 if (list->isEmpty()) { |
416 list.clear(); | 382 list.clear(); |
417 ++emptyListsCount; | 383 ++emptyListsCount; |
418 } | 384 } |
419 } | 385 } |
420 | 386 |
421 if (emptyListsCount == DocumentMarker::MarkerTypeIndexesCount) { | 387 if (emptyListsCount == DocumentMarker::MarkerTypeIndexesCount) { |
422 m_markers.erase(node); | 388 m_markers.erase(node); |
(...skipping 399 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
822 LOG(INFO) << m_markers.size() << " nodes have markers:\n" | 788 LOG(INFO) << m_markers.size() << " nodes have markers:\n" |
823 << builder.toString().utf8().data(); | 789 << builder.toString().utf8().data(); |
824 } | 790 } |
825 #endif | 791 #endif |
826 | 792 |
827 // SynchronousMutationObserver | 793 // SynchronousMutationObserver |
828 void DocumentMarkerController::didUpdateCharacterData(CharacterData* node, | 794 void DocumentMarkerController::didUpdateCharacterData(CharacterData* node, |
829 unsigned offset, | 795 unsigned offset, |
830 unsigned oldLength, | 796 unsigned oldLength, |
831 unsigned newLength) { | 797 unsigned newLength) { |
832 // If we're doing a pure remove operation, remove the markers in the range | |
Xiaocheng
2017/04/08 00:23:36
I see.
But this change fits better in the previou
| |
833 // being removed (markers containing, but larger than, the range, will be | |
834 // split) | |
835 if (newLength == 0) | |
836 removeMarkers(node, offset, oldLength); | |
837 | |
838 if (!possiblyHasMarkers(DocumentMarker::AllMarkers())) | 798 if (!possiblyHasMarkers(DocumentMarker::AllMarkers())) |
839 return; | 799 return; |
840 DCHECK(!m_markers.isEmpty()); | 800 DCHECK(!m_markers.isEmpty()); |
841 | 801 |
842 MarkerLists* markers = m_markers.at(node); | 802 MarkerLists* markers = m_markers.at(node); |
843 if (!markers) | 803 if (!markers) |
844 return; | 804 return; |
845 | 805 |
846 bool didShiftMarker = false; | 806 bool didShiftMarker = false; |
847 for (MarkerList* list : *markers) { | 807 for (MarkerList* list : *markers) { |
(...skipping 30 matching lines...) Expand all Loading... | |
878 } | 838 } |
879 | 839 |
880 } // namespace blink | 840 } // namespace blink |
881 | 841 |
882 #ifndef NDEBUG | 842 #ifndef NDEBUG |
883 void showDocumentMarkers(const blink::DocumentMarkerController* controller) { | 843 void showDocumentMarkers(const blink::DocumentMarkerController* controller) { |
884 if (controller) | 844 if (controller) |
885 controller->showMarkers(); | 845 controller->showMarkers(); |
886 } | 846 } |
887 #endif | 847 #endif |
OLD | NEW |