Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "core/editing/markers/DocumentMarkerListEditor.h" | |
| 6 | |
| 7 namespace blink { | |
| 8 | |
| 9 DocumentMarkerVector::iterator | |
| 10 DocumentMarkerListEditor::GetPosOfFirstMarkerNotEndingBeforeInSortedList( | |
| 11 DocumentMarkerVector* marker_list, | |
| 12 size_t start_offset) { | |
| 13 return std::upper_bound( | |
| 14 marker_list->begin(), marker_list->end(), start_offset, | |
| 15 [](size_t start_offset, const Member<DocumentMarker>& rhv) -> bool { | |
| 16 return start_offset < rhv->EndOffset(); | |
| 17 }); | |
| 18 } | |
| 19 | |
| 20 DocumentMarkerList::DidMoveMarkerOrNot | |
| 21 DocumentMarkerListEditor::MoveUnsortedMarkers(DocumentMarkerVector* marker_list, | |
| 22 int length, | |
| 23 DocumentMarkerList* dst_list) { | |
| 24 return MoveMarkersHelper(marker_list, length, dst_list, false); | |
| 25 } | |
| 26 | |
| 27 DocumentMarkerList::DidMoveMarkerOrNot | |
| 28 DocumentMarkerListEditor::MoveSortedMarkers(DocumentMarkerVector* marker_list, | |
| 29 int length, | |
| 30 DocumentMarkerList* dst_list) { | |
| 31 return MoveMarkersHelper(marker_list, length, dst_list, true); | |
| 32 } | |
| 33 | |
| 34 DocumentMarkerList::DidRemoveMarkerOrNot | |
| 35 DocumentMarkerListEditor::RemoveUnsortedMarkers( | |
| 36 DocumentMarkerVector* marker_list, | |
| 37 unsigned start_offset, | |
| 38 int length) { | |
| 39 unsigned end_offset = start_offset + length; | |
| 40 DocumentMarkerList::DidRemoveMarkerOrNot didRemoveMarker = | |
| 41 DocumentMarkerList::DidRemoveMarkerOrNot::kDidNotRemoveMarker; | |
| 42 | |
| 43 for (auto it = marker_list->begin(); it != marker_list->end(); ++it) { | |
| 44 const DocumentMarker& marker = **it; | |
| 45 | |
| 46 // markers have non-empty overlap | |
| 47 if (marker.StartOffset() < end_offset && | |
| 48 marker.EndOffset() > start_offset) { | |
| 49 // Erase by doing a swap-and-shrink to get O(1) performance | |
| 50 std::swap(*it, marker_list->back()); | |
| 51 marker_list->Shrink(marker_list->size() - 1); | |
| 52 --it; | |
| 53 | |
| 54 didRemoveMarker = | |
| 55 DocumentMarkerList::DidRemoveMarkerOrNot::kDidRemoveMarker; | |
| 56 } | |
| 57 } | |
| 58 | |
| 59 return didRemoveMarker; | |
| 60 } | |
| 61 | |
| 62 DocumentMarkerList::DocumentMarkerList::DidRemoveMarkerOrNot | |
| 63 DocumentMarkerListEditor::RemoveSortedMarkers(DocumentMarkerVector* marker_list, | |
| 64 unsigned start_offset, | |
| 65 int length) { | |
| 66 unsigned end_offset = start_offset + length; | |
| 67 | |
| 68 const auto startPos = | |
| 69 GetPosOfFirstMarkerNotEndingBeforeInSortedList(marker_list, start_offset); | |
| 70 auto it = startPos; | |
| 71 for (; it != marker_list->end(); ++it) { | |
| 72 if ((*it)->StartOffset() >= end_offset) | |
| 73 break; | |
| 74 } | |
| 75 | |
| 76 // it should now point at the first marker *not* to be removed (or at | |
| 77 // marker_list->end()) | |
| 78 marker_list->erase(startPos - marker_list->begin(), it - startPos); | |
| 79 | |
| 80 if (it == startPos) | |
| 81 return DocumentMarkerList::DidRemoveMarkerOrNot::kDidNotRemoveMarker; | |
| 82 | |
| 83 return DocumentMarkerList::DidRemoveMarkerOrNot::kDidRemoveMarker; | |
| 84 } | |
| 85 | |
| 86 DocumentMarkerList::DidShiftMarkerOrNot | |
| 87 DocumentMarkerListEditor::ShiftUnsortedMarkers( | |
| 88 DocumentMarkerVector* marker_list, | |
| 89 unsigned offset, | |
| 90 unsigned old_length, | |
| 91 unsigned new_length) { | |
| 92 DocumentMarkerList::DidShiftMarkerOrNot didShift = | |
| 93 DocumentMarkerList::DidShiftMarkerOrNot::kDidNotShiftMarker; | |
| 94 for (auto it = marker_list->begin(); it != marker_list->end(); ++it) { | |
| 95 DocumentMarker& marker = **it; | |
| 96 Optional<DocumentMarker::MarkerOffsets> result = | |
| 97 marker.ComputeOffsetsAfterShift(offset, old_length, new_length); | |
| 98 | |
| 99 if (result == WTF::kNullopt) { | |
| 100 didShift = DocumentMarkerList::DidShiftMarkerOrNot::kDidShiftMarker; | |
| 101 // Erase by doing a swap-and-shrink to get O(1) performance | |
| 102 std::swap(*it, marker_list->back()); | |
| 103 marker_list->Shrink(marker_list->size() - 1); | |
| 104 --it; | |
| 105 continue; | |
| 106 } | |
| 107 | |
| 108 if (result.value().start_offset != marker.StartOffset() || | |
| 109 result.value().end_offset != marker.EndOffset()) { | |
| 110 marker.SetStartOffset(result.value().start_offset); | |
| 111 marker.SetEndOffset(result.value().end_offset); | |
| 112 | |
| 113 didShift = DocumentMarkerList::DidShiftMarkerOrNot::kDidShiftMarker; | |
| 114 } | |
| 115 } | |
| 116 | |
| 117 return didShift; | |
| 118 } | |
| 119 | |
| 120 DocumentMarkerList::DidShiftMarkerOrNot | |
| 121 DocumentMarkerListEditor::ShiftSortedMarkers(DocumentMarkerVector* marker_list, | |
| 122 unsigned offset, | |
| 123 unsigned old_length, | |
| 124 unsigned new_length) { | |
| 125 DocumentMarkerVector newMarkerList; | |
| 126 DocumentMarkerList::DidShiftMarkerOrNot didShift = | |
| 127 DocumentMarkerList::DidShiftMarkerOrNot::kDidNotShiftMarker; | |
| 128 for (Member<DocumentMarker> marker : *marker_list) { | |
| 129 Optional<DocumentMarker::MarkerOffsets> result = | |
| 130 marker->ComputeOffsetsAfterShift(offset, old_length, new_length); | |
| 131 | |
| 132 if (result == WTF::kNullopt) { | |
| 133 didShift = DocumentMarkerList::DidShiftMarkerOrNot::kDidShiftMarker; | |
| 134 continue; | |
| 135 } | |
| 136 | |
| 137 if (result.value().start_offset != marker->StartOffset() || | |
| 138 result.value().end_offset != marker->EndOffset()) { | |
| 139 marker->SetStartOffset(result.value().start_offset); | |
| 140 marker->SetEndOffset(result.value().end_offset); | |
| 141 | |
| 142 didShift = DocumentMarkerList::DidShiftMarkerOrNot::kDidShiftMarker; | |
| 143 } | |
| 144 | |
| 145 newMarkerList.push_back(marker); | |
| 146 } | |
| 147 | |
| 148 swap(*marker_list, newMarkerList); | |
| 149 return didShift; | |
| 150 } | |
| 151 | |
| 152 DocumentMarkerList::DidMoveMarkerOrNot | |
| 153 DocumentMarkerListEditor::MoveMarkersHelper(DocumentMarkerVector* marker_list, | |
| 154 int length, | |
| 155 DocumentMarkerList* dst_list, | |
| 156 bool is_sorted) { | |
| 157 DocumentMarkerList::DidMoveMarkerOrNot didMoveMarker = | |
| 158 DocumentMarkerList::DidMoveMarkerOrNot::kDidNotMoveMarker; | |
| 159 unsigned end_offset = length - 1; | |
| 160 | |
| 161 for (auto it = marker_list->begin(); it != marker_list->end(); ++it) { | |
| 162 DocumentMarker& marker = **it; | |
| 163 if (marker.StartOffset() > end_offset) { | |
| 164 if (is_sorted) | |
| 165 break; | |
| 166 continue; | |
| 167 } | |
| 168 | |
| 169 // pin the marker to the specified range and apply the shift delta | |
| 170 if (marker.StartOffset() <= end_offset) { | |
|
rlanday
2017/04/11 02:59:09
This is redundant, I will remove
| |
| 171 didMoveMarker = DocumentMarkerList::DidMoveMarkerOrNot::kDidMoveMarker; | |
| 172 | |
| 173 if (marker.EndOffset() > end_offset) | |
| 174 marker.SetEndOffset(end_offset); | |
| 175 | |
| 176 dst_list->Add(&marker); | |
| 177 } | |
| 178 } | |
| 179 | |
| 180 return didMoveMarker; | |
| 181 } | |
| 182 | |
| 183 } // namespace blink | |
| OLD | NEW |