Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(609)

Side by Side Diff: third_party/WebKit/Source/core/editing/markers/DocumentMarkerListEditor.cpp

Issue 2805553003: DocumentMarkerList refactor as an interface (Closed)
Patch Set: Rebase on renaming patch, respond to comments Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698