| 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 |