OLD | NEW |
---|---|
1 // Copyright 2017 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "core/editing/markers/SpellCheckMarkerListImpl.h" | 5 #include "core/editing/markers/SpellCheckMarkerListImpl.h" |
6 | 6 |
7 #include "core/editing/markers/DocumentMarkerListEditor.h" | 7 #include "core/editing/markers/DocumentMarkerListEditor.h" |
8 | 8 |
9 namespace blink { | 9 namespace blink { |
10 | 10 |
11 bool SpellCheckMarkerListImpl::IsEmpty() const { | 11 bool SpellCheckMarkerListImpl::IsEmpty() const { |
12 return markers_.IsEmpty(); | 12 return markers_.IsEmpty(); |
13 } | 13 } |
14 | 14 |
15 void SpellCheckMarkerListImpl::Add(DocumentMarker* marker) { | 15 void SpellCheckMarkerListImpl::Add(DocumentMarker* marker) { |
16 if (markers_.IsEmpty() || | 16 if (markers_.IsEmpty() || |
17 markers_.back()->EndOffset() < marker->StartOffset()) { | 17 markers_.back()->EndOffset() < marker->StartOffset()) { |
18 markers_.push_back(marker); | 18 markers_.push_back(marker); |
19 return; | 19 return; |
20 } | 20 } |
21 | 21 |
22 // Find first marker that ends after the one being inserted starts. If any | |
23 // markers overlap the one being inserted, this is the first one. | |
22 auto first_overlapping = std::lower_bound( | 24 auto first_overlapping = std::lower_bound( |
yosin_UTC9
2017/06/05 02:28:56
nit: s/auto/const auto&/
| |
23 markers_.begin(), markers_.end(), marker, | 25 markers_.begin(), markers_.end(), marker, |
24 [](const Member<DocumentMarker>& marker_in_list, | 26 [](const Member<DocumentMarker>& marker_in_list, |
25 const DocumentMarker* marker_to_insert) { | 27 const DocumentMarker* marker_to_insert) { |
26 return marker_in_list->EndOffset() < marker_to_insert->StartOffset(); | 28 return marker_in_list->EndOffset() < marker_to_insert->StartOffset(); |
27 }); | 29 }); |
28 | 30 |
29 size_t index = first_overlapping - markers_.begin(); | 31 // If this marker does not overlap the one being inserted, insert before it |
30 markers_.insert(index, marker); | 32 // and we are done. |
31 const auto inserted = markers_.begin() + index; | 33 if (marker->EndOffset() < (*first_overlapping)->StartOffset()) { |
Xiaocheng
2017/06/03 03:17:31
We should also go into this branch if |first_overl
rlanday
2017/06/03 15:02:03
I think the "insert at end without overlap" case i
Xiaocheng
2017/06/03 19:00:40
You are right.
| |
32 first_overlapping = inserted + 1; | 34 markers_.insert(first_overlapping - markers_.begin(), marker); |
33 // TODO(rlanday): optimize this loop so it runs in O(N) time and not O(N^2) | 35 return; |
34 for (const auto i = first_overlapping; | |
35 i != markers_.end() && | |
36 (*i)->StartOffset() <= (*inserted)->EndOffset();) { | |
37 (*inserted)->SetStartOffset( | |
38 std::min((*inserted)->StartOffset(), (*i)->StartOffset())); | |
39 (*inserted)->SetEndOffset( | |
40 std::max((*inserted)->EndOffset(), (*i)->EndOffset())); | |
41 markers_.erase(i - markers_.begin()); | |
42 } | 36 } |
37 | |
38 // Otherwise, find the last overlapping marker, replace the first marker with | |
39 // the newly-inserted marker (to get the new description), set its start and | |
40 // end offsets to include all the overlapped markers, and erase the rest of | |
41 // the old markers. | |
42 | |
43 auto last_overlapping = std::upper_bound( | |
Xiaocheng
2017/06/03 03:17:31
nit: rename it to |past_last_overlapping| to reduc
yosin_UTC9
2017/06/05 02:28:56
nit: s/auto/const auto&/
| |
44 first_overlapping, markers_.end(), marker, | |
45 [](const DocumentMarker* marker_to_insert, | |
46 const Member<DocumentMarker>& marker_in_list) { | |
47 return marker_to_insert->EndOffset() < marker_in_list->StartOffset(); | |
48 }); | |
49 | |
50 marker->SetStartOffset( | |
51 std::min(marker->StartOffset(), (*first_overlapping)->StartOffset())); | |
52 marker->SetEndOffset( | |
53 std::max(marker->EndOffset(), (*(last_overlapping - 1))->EndOffset())); | |
54 | |
55 *first_overlapping = marker; | |
56 size_t num_to_erase = last_overlapping - (first_overlapping + 1); | |
Xiaocheng
2017/06/03 03:17:31
nit: const size_t
| |
57 markers_.erase(first_overlapping + 1 - markers_.begin(), num_to_erase); | |
43 } | 58 } |
44 | 59 |
45 void SpellCheckMarkerListImpl::Clear() { | 60 void SpellCheckMarkerListImpl::Clear() { |
46 markers_.clear(); | 61 markers_.clear(); |
47 } | 62 } |
48 | 63 |
49 const HeapVector<Member<DocumentMarker>>& SpellCheckMarkerListImpl::GetMarkers() | 64 const HeapVector<Member<DocumentMarker>>& SpellCheckMarkerListImpl::GetMarkers() |
50 const { | 65 const { |
51 return markers_; | 66 return markers_; |
52 } | 67 } |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
85 const String& marker_text = node_text.Substring(start, length); | 100 const String& marker_text = node_text.Substring(start, length); |
86 if (words.Contains(marker_text)) { | 101 if (words.Contains(marker_text)) { |
87 markers_.erase(j - 1); | 102 markers_.erase(j - 1); |
88 removed_markers = true; | 103 removed_markers = true; |
89 } | 104 } |
90 } | 105 } |
91 return removed_markers; | 106 return removed_markers; |
92 } | 107 } |
93 | 108 |
94 } // namespace blink | 109 } // namespace blink |
OLD | NEW |