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 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
172 TextIterator marked_text(range.StartPosition(), range.EndPosition()); | 172 TextIterator marked_text(range.StartPosition(), range.EndPosition()); |
173 DocumentMarkerController::RemoveMarkers( | 173 DocumentMarkerController::RemoveMarkers( |
174 marked_text, marker_types, should_remove_partially_overlapping_marker); | 174 marked_text, marker_types, should_remove_partially_overlapping_marker); |
175 } | 175 } |
176 | 176 |
177 static bool StartsFurther(const Member<RenderedDocumentMarker>& lhv, | 177 static bool StartsFurther(const Member<RenderedDocumentMarker>& lhv, |
178 const DocumentMarker* rhv) { | 178 const DocumentMarker* rhv) { |
179 return lhv->StartOffset() < rhv->StartOffset(); | 179 return lhv->StartOffset() < rhv->StartOffset(); |
180 } | 180 } |
181 | 181 |
182 static bool StartsAfter(const Member<RenderedDocumentMarker>& marker, | |
183 size_t start_offset) { | |
184 return marker->StartOffset() < start_offset; | |
185 } | |
186 | |
187 static bool EndsBefore(size_t start_offset, | 182 static bool EndsBefore(size_t start_offset, |
188 const Member<RenderedDocumentMarker>& rhv) { | 183 const Member<RenderedDocumentMarker>& rhv) { |
189 return start_offset < rhv->EndOffset(); | 184 return start_offset < rhv->EndOffset(); |
190 } | 185 } |
191 | 186 |
192 static bool CompareByStart(const Member<DocumentMarker>& lhv, | 187 static bool CompareByStart(const Member<DocumentMarker>& lhv, |
193 const Member<DocumentMarker>& rhv) { | 188 const Member<DocumentMarker>& rhv) { |
194 return lhv->StartOffset() < rhv->StartOffset(); | 189 return lhv->StartOffset() < rhv->StartOffset(); |
195 } | 190 } |
196 | 191 |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
296 | 291 |
297 if (!PossiblyHasMarkers(DocumentMarker::AllMarkers())) | 292 if (!PossiblyHasMarkers(DocumentMarker::AllMarkers())) |
298 return; | 293 return; |
299 DCHECK(!markers_.IsEmpty()); | 294 DCHECK(!markers_.IsEmpty()); |
300 | 295 |
301 MarkerLists* markers = markers_.at(src_node); | 296 MarkerLists* markers = markers_.at(src_node); |
302 if (!markers) | 297 if (!markers) |
303 return; | 298 return; |
304 | 299 |
305 bool doc_dirty = false; | 300 bool doc_dirty = false; |
306 for (size_t marker_list_index = 0; | 301 for (Member<MarkerList> list : *markers) { |
307 marker_list_index < DocumentMarker::kMarkerTypeIndexesCount; | |
308 ++marker_list_index) { | |
309 Member<MarkerList>& list = (*markers)[marker_list_index]; | |
310 if (!list) | 302 if (!list) |
311 continue; | 303 continue; |
312 | 304 |
313 unsigned end_offset = length - 1; | 305 unsigned end_offset = length - 1; |
314 MarkerList::iterator it; | 306 MarkerList::iterator it; |
315 for (it = list->begin(); it != list->end(); ++it) { | 307 for (it = list->begin(); it != list->end(); ++it) { |
316 DocumentMarker* marker = it->Get(); | 308 DocumentMarker* marker = it->Get(); |
317 | 309 |
318 // stop if we are now past the specified range | 310 // stop if we are now past the specified range |
319 if (marker->StartOffset() > end_offset) | 311 if (marker->StartOffset() > end_offset) |
(...skipping 403 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
723 // cause the node to be redrawn | 715 // cause the node to be redrawn |
724 if (LayoutObject* layout_object = node->GetLayoutObject()) { | 716 if (LayoutObject* layout_object = node->GetLayoutObject()) { |
725 layout_object->SetShouldDoFullPaintInvalidation( | 717 layout_object->SetShouldDoFullPaintInvalidation( |
726 kPaintInvalidationDocumentMarkerChange); | 718 kPaintInvalidationDocumentMarkerChange); |
727 break; | 719 break; |
728 } | 720 } |
729 } | 721 } |
730 } | 722 } |
731 } | 723 } |
732 | 724 |
733 void DocumentMarkerController::ShiftMarkers(Node* node, | |
734 unsigned start_offset, | |
735 int delta) { | |
736 if (!PossiblyHasMarkers(DocumentMarker::AllMarkers())) | |
737 return; | |
738 DCHECK(!markers_.IsEmpty()); | |
739 | |
740 MarkerLists* markers = markers_.at(node); | |
741 if (!markers) | |
742 return; | |
743 | |
744 bool did_shift_marker = false; | |
745 for (size_t marker_list_index = 0; | |
746 marker_list_index < DocumentMarker::kMarkerTypeIndexesCount; | |
747 ++marker_list_index) { | |
748 Member<MarkerList>& list = (*markers)[marker_list_index]; | |
749 if (!list) | |
750 continue; | |
751 MarkerList::iterator start_pos = | |
752 std::lower_bound(list->begin(), list->end(), start_offset, StartsAfter); | |
753 for (MarkerList::iterator marker = start_pos; marker != list->end(); | |
754 ++marker) { | |
755 #if DCHECK_IS_ON() | |
756 int start_offset = (*marker)->StartOffset(); | |
757 DCHECK_GE(start_offset + delta, 0); | |
758 #endif | |
759 (*marker)->ShiftOffsets(delta); | |
760 did_shift_marker = true; | |
761 } | |
762 } | |
763 | |
764 if (did_shift_marker) { | |
765 InvalidateRectsForMarkersInNode(*node); | |
766 // repaint the affected node | |
767 if (node->GetLayoutObject()) { | |
768 node->GetLayoutObject()->SetShouldDoFullPaintInvalidation( | |
769 kPaintInvalidationDocumentMarkerChange); | |
770 } | |
771 } | |
772 } | |
773 | |
774 bool DocumentMarkerController::SetMarkersActive(const EphemeralRange& range, | 725 bool DocumentMarkerController::SetMarkersActive(const EphemeralRange& range, |
775 bool active) { | 726 bool active) { |
776 if (!PossiblyHasMarkers(DocumentMarker::AllMarkers())) | 727 if (!PossiblyHasMarkers(DocumentMarker::AllMarkers())) |
777 return false; | 728 return false; |
778 | 729 |
779 DCHECK(!markers_.IsEmpty()); | 730 DCHECK(!markers_.IsEmpty()); |
780 | 731 |
781 Node* const start_container = range.StartPosition().ComputeContainerNode(); | 732 Node* const start_container = range.StartPosition().ComputeContainerNode(); |
782 DCHECK(start_container); | 733 DCHECK(start_container); |
783 Node* const end_container = range.EndPosition().ComputeContainerNode(); | 734 Node* const end_container = range.EndPosition().ComputeContainerNode(); |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
863 LOG(INFO) << markers_.size() << " nodes have markers:\n" | 814 LOG(INFO) << markers_.size() << " nodes have markers:\n" |
864 << builder.ToString().Utf8().Data(); | 815 << builder.ToString().Utf8().Data(); |
865 } | 816 } |
866 #endif | 817 #endif |
867 | 818 |
868 // SynchronousMutationObserver | 819 // SynchronousMutationObserver |
869 void DocumentMarkerController::DidUpdateCharacterData(CharacterData* node, | 820 void DocumentMarkerController::DidUpdateCharacterData(CharacterData* node, |
870 unsigned offset, | 821 unsigned offset, |
871 unsigned old_length, | 822 unsigned old_length, |
872 unsigned new_length) { | 823 unsigned new_length) { |
873 // Shift markers as if we first remove the old text, then insert the new text | 824 if (!PossiblyHasMarkers(DocumentMarker::AllMarkers())) |
874 RemoveMarkers(node, offset, old_length); | 825 return; |
875 ShiftMarkers(node, offset + old_length, 0 - old_length); | 826 DCHECK(!markers_.IsEmpty()); |
876 ShiftMarkers(node, offset, new_length); | 827 |
| 828 MarkerLists* markers = markers_.at(node); |
| 829 if (!markers) |
| 830 return; |
| 831 |
| 832 bool did_shift_marker = false; |
| 833 for (MarkerList* list : *markers) { |
| 834 if (!list) |
| 835 continue; |
| 836 |
| 837 for (MarkerList::iterator it = list->begin(); it != list->end(); ++it) { |
| 838 RenderedDocumentMarker& marker = **it; |
| 839 Optional<DocumentMarker::MarkerOffsets> result = |
| 840 marker.ComputeOffsetsAfterShift(offset, old_length, new_length); |
| 841 if (result == WTF::kNullopt) { |
| 842 list->erase(it - list->begin()); |
| 843 --it; |
| 844 did_shift_marker = true; |
| 845 continue; |
| 846 } |
| 847 |
| 848 if (marker.StartOffset() != result.value().start_offset || |
| 849 marker.EndOffset() != result.value().end_offset) { |
| 850 did_shift_marker = true; |
| 851 marker.SetStartOffset(result.value().start_offset); |
| 852 marker.SetEndOffset(result.value().end_offset); |
| 853 } |
| 854 } |
| 855 } |
| 856 |
| 857 if (!did_shift_marker) |
| 858 return; |
| 859 if (!node->GetLayoutObject()) |
| 860 return; |
| 861 InvalidateRectsForMarkersInNode(*node); |
| 862 // repaint the affected node |
| 863 node->GetLayoutObject()->SetShouldDoFullPaintInvalidation(); |
877 } | 864 } |
878 | 865 |
879 } // namespace blink | 866 } // namespace blink |
880 | 867 |
881 #ifndef NDEBUG | 868 #ifndef NDEBUG |
882 void showDocumentMarkers(const blink::DocumentMarkerController* controller) { | 869 void showDocumentMarkers(const blink::DocumentMarkerController* controller) { |
883 if (controller) | 870 if (controller) |
884 controller->ShowMarkers(); | 871 controller->ShowMarkers(); |
885 } | 872 } |
886 #endif | 873 #endif |
OLD | NEW |