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 DocumentMarkerList::iterator | |
10 DocumentMarkerListEditor::getPosOfFirstMarkerNotEndingBeforeInSortedList( | |
11 DocumentMarkerVector* markerList, | |
12 size_t startOffset) { | |
13 return std::upper_bound( | |
14 markerList->begin(), markerList->end(), startOffset, | |
15 [](size_t startOffset, const Member<DocumentMarker>& rhv) -> bool { | |
16 return startOffset < rhv->endOffset(); | |
17 }); | |
18 } | |
19 | |
20 void DocumentMarkerListEditor::appendMarkersToInputList( | |
21 const DocumentMarkerVector& markerList, | |
22 DocumentMarkerVector* inputList) { | |
23 for (Member<DocumentMarker> marker : markerList) { | |
24 inputList->push_back(marker); | |
25 } | |
26 } | |
27 | |
28 DocumentMarkerList::DidCopyMarkerOrNot | |
29 DocumentMarkerListEditor::copyUnsortedMarkers(DocumentMarkerVector* markerList, | |
30 unsigned startOffset, | |
31 int length, | |
32 DocumentMarkerList* dstList, | |
33 int delta) { | |
34 return copyMarkersHelper(markerList, markerList->begin(), markerList->end(), | |
35 startOffset, length, dstList, delta); | |
36 } | |
37 | |
38 DocumentMarkerList::DidCopyMarkerOrNot | |
39 DocumentMarkerListEditor::copySortedMarkers(DocumentMarkerVector* markerList, | |
40 unsigned startOffset, | |
41 int length, | |
42 DocumentMarkerList* dstList, | |
43 int delta) { | |
44 return copyMarkersHelper( | |
45 markerList, | |
46 std::lower_bound( | |
47 markerList->begin(), markerList->end(), startOffset, | |
48 [](const Member<DocumentMarker>& marker, size_t startOffset) { | |
49 return marker->endOffset() < startOffset; | |
50 }), | |
51 markerList->end(), startOffset, length, dstList, delta); | |
52 } | |
53 | |
54 DocumentMarkerList::DidRemoveMarkerOrNot | |
55 DocumentMarkerListEditor::removeUnsortedMarkers( | |
56 DocumentMarkerVector* markerList, | |
57 unsigned startOffset, | |
58 int length, | |
59 bool shouldRemovePartiallyOverlappingMarkers) { | |
60 unsigned endOffset = startOffset + length; | |
61 DocumentMarkerList::DidRemoveMarkerOrNot didRemoveMarker = | |
62 DocumentMarkerList::DidRemoveMarkerOrNot::kDidNotRemoveMarker; | |
63 | |
64 for (auto it = markerList->begin(); it != markerList->end(); ++it) { | |
65 const DocumentMarker& marker = **it; | |
66 | |
67 // markers have non-empty overlap | |
68 if (marker.startOffset() < endOffset && marker.endOffset() > startOffset) { | |
69 // Erase by doing a swap-and-shrink to get O(1) performance | |
70 std::swap(*it, markerList->back()); | |
71 markerList->shrink(markerList->size() - 1); | |
72 --it; | |
73 | |
74 didRemoveMarker = | |
75 DocumentMarkerList::DidRemoveMarkerOrNot::kDidRemoveMarker; | |
76 } | |
77 } | |
78 | |
79 return didRemoveMarker; | |
80 } | |
81 | |
82 DocumentMarkerList::DocumentMarkerList::DidRemoveMarkerOrNot | |
83 DocumentMarkerListEditor::removeSortedMarkers( | |
84 DocumentMarkerVector* markerList, | |
85 unsigned startOffset, | |
86 int length, | |
87 bool shouldRemovePartiallyOverlappingMarkers) { | |
88 unsigned endOffset = startOffset + length; | |
89 | |
90 const auto startPos = | |
91 getPosOfFirstMarkerNotEndingBeforeInSortedList(markerList, startOffset); | |
92 auto it = startPos; | |
93 for (; it != markerList->end(); ++it) { | |
94 if ((*it)->startOffset() >= endOffset) | |
95 break; | |
96 } | |
97 | |
98 // it should now point at the first marker *not* to be removed (or at | |
99 // markerList->end()) | |
100 markerList->erase(startPos - markerList->begin(), it - startPos); | |
101 | |
102 if (it == startPos) | |
103 return DocumentMarkerList::DidRemoveMarkerOrNot::kDidNotRemoveMarker; | |
104 | |
105 return DocumentMarkerList::DidRemoveMarkerOrNot::kDidRemoveMarker; | |
106 } | |
107 | |
108 DocumentMarkerList::DidShiftMarkerOrNot | |
109 DocumentMarkerListEditor::shiftUnsortedMarkers(DocumentMarkerVector* markerList, | |
110 unsigned offset, | |
111 unsigned oldLength, | |
112 unsigned newLength) { | |
113 DocumentMarkerList::DidShiftMarkerOrNot didShift = | |
114 DocumentMarkerList::DidShiftMarkerOrNot::kDidNotShiftMarker; | |
115 for (auto it = markerList->begin(); it != markerList->end(); ++it) { | |
116 DocumentMarker& marker = **it; | |
117 Optional<DocumentMarker::MarkerOffsets> result = | |
118 marker.computeOffsetsAfterShift(offset, oldLength, newLength); | |
119 | |
120 if (result == WTF::nullopt) { | |
121 didShift = DocumentMarkerList::DidShiftMarkerOrNot::kDidShiftMarker; | |
122 // Erase by doing a swap-and-shrink to get O(1) performance | |
123 std::swap(*it, markerList->back()); | |
124 markerList->shrink(markerList->size() - 1); | |
125 --it; | |
126 continue; | |
127 } | |
128 | |
129 if (result.value().startOffset != marker.startOffset() || | |
130 result.value().endOffset != marker.endOffset()) { | |
131 marker.setStartOffset(result.value().startOffset); | |
132 marker.setEndOffset(result.value().endOffset); | |
133 | |
134 didShift = DocumentMarkerList::DidShiftMarkerOrNot::kDidShiftMarker; | |
135 } | |
136 } | |
137 | |
138 return didShift; | |
139 } | |
140 | |
141 DocumentMarkerList::DidShiftMarkerOrNot | |
142 DocumentMarkerListEditor::shiftSortedMarkers(DocumentMarkerVector* markerList, | |
143 unsigned offset, | |
144 unsigned oldLength, | |
145 unsigned newLength) { | |
146 DocumentMarkerVector newMarkerList; | |
147 DocumentMarkerList::DidShiftMarkerOrNot didShift = | |
148 DocumentMarkerList::DidShiftMarkerOrNot::kDidNotShiftMarker; | |
149 for (Member<DocumentMarker> marker : *markerList) { | |
150 Optional<DocumentMarker::MarkerOffsets> result = | |
151 marker->computeOffsetsAfterShift(offset, oldLength, newLength); | |
152 | |
153 if (result == WTF::nullopt) { | |
154 didShift = DocumentMarkerList::DidShiftMarkerOrNot::kDidShiftMarker; | |
155 continue; | |
156 } | |
157 | |
158 if (result.value().startOffset != marker->startOffset() || | |
159 result.value().endOffset != marker->endOffset()) { | |
160 marker->setStartOffset(result.value().startOffset); | |
161 marker->setEndOffset(result.value().endOffset); | |
162 | |
163 didShift = DocumentMarkerList::DidShiftMarkerOrNot::kDidShiftMarker; | |
164 } | |
165 | |
166 newMarkerList.push_back(marker); | |
167 } | |
168 | |
169 swap(*markerList, newMarkerList); | |
170 return didShift; | |
171 } | |
172 | |
173 DocumentMarkerList::DidCopyMarkerOrNot | |
174 DocumentMarkerListEditor::copyMarkersHelper( | |
175 DocumentMarkerVector* markerList, | |
176 DocumentMarkerList::iterator beginIt, | |
177 DocumentMarkerList::iterator endIt, | |
178 unsigned startOffset, | |
179 int length, | |
180 DocumentMarkerList* dstList, | |
181 int delta) { | |
182 DocumentMarkerList::DidCopyMarkerOrNot didCopyMarker = | |
yosin_UTC9
2017/04/11 01:39:37
Let's add |DCHECK_GT(length, 0)|
| |
183 DocumentMarkerList::DidCopyMarkerOrNot::kDidNotCopyMarker; | |
184 unsigned endOffset = startOffset + length - 1; | |
185 | |
186 for (auto it = beginIt; it != endIt; ++it) { | |
187 DocumentMarker& marker = **it; | |
188 // pin the marker to the specified range and apply the shift delta | |
189 if (marker.endOffset() >= startOffset && | |
yosin_UTC9
2017/04/11 01:39:37
Let's use early-continue to reduce indentation.
i
| |
190 marker.startOffset() <= endOffset) { | |
191 didCopyMarker = DocumentMarkerList::DidCopyMarkerOrNot::kDidCopyMarker; | |
192 | |
193 if (marker.startOffset() < startOffset) | |
194 marker.setStartOffset(startOffset); | |
195 if (marker.endOffset() > endOffset) | |
196 marker.setEndOffset(endOffset); | |
197 marker.shiftOffsets(delta); | |
198 | |
199 dstList->add(&marker); | |
200 } | |
201 } | |
202 | |
203 return didCopyMarker; | |
204 } | |
205 | |
206 } // namespace blink | |
OLD | NEW |