Index: third_party/WebKit/Source/core/editing/markers/DocumentMarkerController.cpp |
diff --git a/third_party/WebKit/Source/core/editing/markers/DocumentMarkerController.cpp b/third_party/WebKit/Source/core/editing/markers/DocumentMarkerController.cpp |
index a35faf98d9bc605e554452059d210cb6680f0860..8ca5d8ef1ab09fc907d85e199d596f03f5f160c4 100644 |
--- a/third_party/WebKit/Source/core/editing/markers/DocumentMarkerController.cpp |
+++ b/third_party/WebKit/Source/core/editing/markers/DocumentMarkerController.cpp |
@@ -77,6 +77,151 @@ DocumentMarker::MarkerTypeIndex MarkerTypeToMarkerIndex( |
} // namespace |
+static bool StartsFurther(const Member<DocumentMarker>& lhv, |
+ const DocumentMarker* rhv) { |
+ return lhv->StartOffset() < rhv->StartOffset(); |
+} |
+ |
+static bool EndsBefore(size_t start_offset, const Member<DocumentMarker>& rhv) { |
+ return start_offset < rhv->EndOffset(); |
+} |
+ |
+static bool CompareByStart(const Member<DocumentMarker>& lhv, |
+ const Member<DocumentMarker>& rhv) { |
+ return lhv->StartOffset() < rhv->StartOffset(); |
+} |
+ |
+static bool DoesNotOverlap(const Member<DocumentMarker>& lhv, |
+ const DocumentMarker* rhv) { |
+ return lhv->EndOffset() < rhv->StartOffset(); |
+} |
+ |
+bool DocumentMarkerList::IsEmpty() const { |
+ return markers_.IsEmpty(); |
+} |
+ |
+void DocumentMarkerList::Add(DocumentMarker* marker) { |
+ if (markers_.IsEmpty() || |
+ markers_.back()->EndOffset() < marker->StartOffset()) { |
+ markers_.push_back(marker); |
+ } else { |
+ if (marker->GetType() != DocumentMarker::kTextMatch && |
+ marker->GetType() != DocumentMarker::kComposition) { |
+ MergeOverlapping(marker); |
+ } else { |
+ const auto pos = std::lower_bound(markers_.begin(), markers_.end(), |
+ marker, StartsFurther); |
+ markers_.insert(pos - markers_.begin(), marker); |
+ } |
+ } |
+} |
+ |
+void DocumentMarkerList::Clear() { |
+ markers_.Clear(); |
+} |
+ |
+void DocumentMarkerList::AppendMarkersToInputList( |
+ DocumentMarkerVector* input_list) const { |
+ input_list->AppendVector(markers_); |
+} |
+ |
+bool DocumentMarkerList::MoveMarkers(int length, DocumentMarkerList* dst_list) { |
+ DCHECK_GT(length, 0); |
+ bool didMoveMarker = false; |
+ unsigned end_offset = length - 1; |
+ |
+ DocumentMarkerVector::iterator it; |
+ for (it = markers_.begin(); it != markers_.end(); ++it) { |
+ DocumentMarker& marker = **it; |
+ if (marker.StartOffset() > end_offset) |
+ break; |
+ |
+ // pin the marker to the specified range and apply the shift delta |
+ if (marker.EndOffset() > end_offset) |
+ marker.SetEndOffset(end_offset); |
+ |
+ dst_list->Add(&marker); |
+ didMoveMarker = true; |
+ } |
+ |
+ // Remove the range of markers that were moved to dstNode |
+ markers_.erase(0, it - markers_.begin()); |
+ |
+ return didMoveMarker; |
+} |
+ |
+bool DocumentMarkerList::RemoveMarkers(unsigned start_offset, int length) { |
+ unsigned end_offset = start_offset + length; |
+ |
+ const auto startPos = std::upper_bound(markers_.begin(), markers_.end(), |
+ start_offset, EndsBefore); |
+ auto it = startPos; |
+ for (; it != markers_.end(); ++it) { |
+ if ((*it)->StartOffset() >= end_offset) |
+ break; |
+ } |
+ |
+ // it should now point at the first marker *not* to be removed (or at |
+ // markers_->end()) |
+ markers_.erase(startPos - markers_.begin(), it - startPos); |
+ |
+ if (it == startPos) |
+ return false; |
+ |
+ return true; |
+} |
+ |
+bool DocumentMarkerList::ShiftMarkers(unsigned offset, |
+ unsigned old_length, |
+ unsigned new_length) { |
+ DocumentMarkerVector newMarkerList; |
+ bool didShiftMarker = false; |
+ for (Member<DocumentMarker> marker : markers_) { |
+ Optional<DocumentMarker::MarkerOffsets> result = |
+ marker->ComputeOffsetsAfterShift(offset, old_length, new_length); |
+ |
+ if (result == WTF::kNullopt) { |
+ didShiftMarker = true; |
+ continue; |
+ } |
+ |
+ if (result.value().start_offset != marker->StartOffset() || |
+ result.value().end_offset != marker->EndOffset()) { |
+ marker->SetStartOffset(result.value().start_offset); |
+ marker->SetEndOffset(result.value().end_offset); |
+ |
+ didShiftMarker = true; |
+ } |
+ |
+ newMarkerList.push_back(marker); |
+ } |
+ |
+ swap(markers_, newMarkerList); |
+ return didShiftMarker; |
+} |
+ |
+void DocumentMarkerList::MergeOverlapping(DocumentMarker* marker) { |
+ auto first_overlapping = std::lower_bound(markers_.begin(), markers_.end(), |
+ marker, DoesNotOverlap); |
+ size_t index = first_overlapping - markers_.begin(); |
+ markers_.insert(index, marker); |
+ const auto inserted = markers_.begin() + index; |
+ first_overlapping = inserted + 1; |
+ for (auto i = first_overlapping; |
+ i != markers_.end() && |
+ (*i)->StartOffset() <= (*inserted)->EndOffset();) { |
+ (*inserted)->SetStartOffset( |
+ std::min((*inserted)->StartOffset(), (*i)->StartOffset())); |
+ (*inserted)->SetEndOffset( |
+ std::max((*inserted)->EndOffset(), (*i)->EndOffset())); |
+ markers_.erase(i - markers_.begin()); |
+ } |
+} |
+ |
+DEFINE_TRACE(DocumentMarkerList) { |
+ visitor->Trace(markers_); |
+} |
+ |
inline bool DocumentMarkerController::PossiblyHasMarkers( |
DocumentMarker::MarkerTypes types) { |
return possibly_existing_marker_types_.Intersects(types); |
@@ -100,10 +245,10 @@ void DocumentMarkerController::AddMarker(const Position& start, |
// covers. |
for (TextIterator marked_text(start, end); !marked_text.AtEnd(); |
marked_text.Advance()) { |
- AddMarker( |
- marked_text.CurrentContainer(), |
- DocumentMarker(type, marked_text.StartOffsetInCurrentContainer(), |
- marked_text.EndOffsetInCurrentContainer(), description)); |
+ AddMarker(marked_text.CurrentContainer(), |
+ new DocumentMarker( |
+ type, marked_text.StartOffsetInCurrentContainer(), |
+ marked_text.EndOffsetInCurrentContainer(), description)); |
} |
} |
@@ -117,9 +262,9 @@ void DocumentMarkerController::AddTextMatchMarker( |
for (TextIterator marked_text(range.StartPosition(), range.EndPosition()); |
!marked_text.AtEnd(); marked_text.Advance()) { |
AddMarker(marked_text.CurrentContainer(), |
- DocumentMarker(marked_text.StartOffsetInCurrentContainer(), |
- marked_text.EndOffsetInCurrentContainer(), |
- match_status)); |
+ new DocumentMarker(marked_text.StartOffsetInCurrentContainer(), |
+ marked_text.EndOffsetInCurrentContainer(), |
+ match_status)); |
} |
// Don't invalidate tickmarks here. TextFinder invalidates tickmarks using a |
// throttling algorithm. crbug.com/6819. |
@@ -133,11 +278,12 @@ void DocumentMarkerController::AddCompositionMarker(const Position& start, |
DCHECK(!document_->NeedsLayoutTreeUpdate()); |
for (TextIterator marked_text(start, end); !marked_text.AtEnd(); |
- marked_text.Advance()) |
+ marked_text.Advance()) { |
AddMarker(marked_text.CurrentContainer(), |
- DocumentMarker(marked_text.StartOffsetInCurrentContainer(), |
- marked_text.EndOffsetInCurrentContainer(), |
- underline_color, thick, background_color)); |
+ new DocumentMarker(marked_text.StartOffsetInCurrentContainer(), |
+ marked_text.EndOffsetInCurrentContainer(), |
+ underline_color, thick, background_color)); |
+ } |
} |
void DocumentMarkerController::PrepareForDestruction() { |
@@ -168,26 +314,6 @@ void DocumentMarkerController::RemoveMarkers( |
DocumentMarkerController::RemoveMarkers(marked_text, marker_types); |
} |
-static bool StartsFurther(const Member<RenderedDocumentMarker>& lhv, |
Xiaocheng
2017/04/13 02:39:51
There's no need to touch these functions if we kee
|
- const DocumentMarker* rhv) { |
- return lhv->StartOffset() < rhv->StartOffset(); |
-} |
- |
-static bool EndsBefore(size_t start_offset, |
- const Member<RenderedDocumentMarker>& rhv) { |
- return start_offset < rhv->EndOffset(); |
-} |
- |
-static bool CompareByStart(const Member<DocumentMarker>& lhv, |
- const Member<DocumentMarker>& rhv) { |
- return lhv->StartOffset() < rhv->StartOffset(); |
-} |
- |
-static bool DoesNotOverlap(const Member<RenderedDocumentMarker>& lhv, |
- const DocumentMarker* rhv) { |
- return lhv->EndOffset() < rhv->StartOffset(); |
-} |
- |
static void UpdateMarkerRenderedRect(const Node& node, |
RenderedDocumentMarker& marker) { |
Range* range = Range::Create(node.GetDocument()); |
@@ -213,12 +339,12 @@ static void UpdateMarkerRenderedRect(const Node& node, |
// Markers of the same type do not overlap each other. |
void DocumentMarkerController::AddMarker(Node* node, |
- const DocumentMarker& new_marker) { |
- DCHECK_GE(new_marker.EndOffset(), new_marker.StartOffset()); |
- if (new_marker.EndOffset() == new_marker.StartOffset()) |
+ const DocumentMarker* new_marker) { |
+ DCHECK_GE(new_marker->EndOffset(), new_marker->StartOffset()); |
+ if (new_marker->EndOffset() == new_marker->StartOffset()) |
return; |
- possibly_existing_marker_types_.Add(new_marker.GetType()); |
+ possibly_existing_marker_types_.Add(new_marker->GetType()); |
Member<MarkerLists>& markers = |
markers_.insert(node, nullptr).stored_value->value; |
@@ -228,26 +354,15 @@ void DocumentMarkerController::AddMarker(Node* node, |
} |
DocumentMarker::MarkerTypeIndex marker_list_index = |
- MarkerTypeToMarkerIndex(new_marker.GetType()); |
+ MarkerTypeToMarkerIndex(new_marker->GetType()); |
if (!markers->at(marker_list_index)) { |
- markers->at(marker_list_index) = new MarkerList; |
+ markers->at(marker_list_index) = new DocumentMarkerList; |
} |
- Member<MarkerList>& list = markers->at(marker_list_index); |
+ DocumentMarkerList* list = markers->at(marker_list_index); |
RenderedDocumentMarker* new_rendered_marker = |
- RenderedDocumentMarker::Create(new_marker); |
- if (list->IsEmpty() || list->back()->EndOffset() < new_marker.StartOffset()) { |
- list->push_back(new_rendered_marker); |
- } else { |
- if (new_marker.GetType() != DocumentMarker::kTextMatch && |
- new_marker.GetType() != DocumentMarker::kComposition) { |
- MergeOverlapping(list.Get(), new_rendered_marker); |
- } else { |
- MarkerList::iterator pos = std::lower_bound(list->begin(), list->end(), |
- &new_marker, StartsFurther); |
- list->insert(pos - list->begin(), new_rendered_marker); |
- } |
- } |
+ RenderedDocumentMarker::Create(*new_marker); |
+ list->Add(new_rendered_marker); |
// repaint the affected node |
if (node->GetLayoutObject()) { |
@@ -256,25 +371,6 @@ void DocumentMarkerController::AddMarker(Node* node, |
} |
} |
-void DocumentMarkerController::MergeOverlapping( |
Xiaocheng
2017/04/13 02:39:51
DML::MergeOverlapping can be put here, so that it
|
- MarkerList* list, |
- RenderedDocumentMarker* to_insert) { |
- MarkerList::iterator first_overlapping = |
- std::lower_bound(list->begin(), list->end(), to_insert, DoesNotOverlap); |
- size_t index = first_overlapping - list->begin(); |
- list->insert(index, to_insert); |
- MarkerList::iterator inserted = list->begin() + index; |
- first_overlapping = inserted + 1; |
- for (MarkerList::iterator i = first_overlapping; |
- i != list->end() && (*i)->StartOffset() <= (*inserted)->EndOffset();) { |
- (*inserted)->SetStartOffset( |
- std::min((*inserted)->StartOffset(), (*i)->StartOffset())); |
- (*inserted)->SetEndOffset( |
- std::max((*inserted)->EndOffset(), (*i)->EndOffset())); |
- list->erase(i - list->begin()); |
- } |
-} |
- |
// Moves markers from src_node to dst_node. Markers are moved if their start |
// offset is less than length. Markers that run past that point are truncated. |
void DocumentMarkerController::MoveMarkers(Node* src_node, |
@@ -287,34 +383,29 @@ void DocumentMarkerController::MoveMarkers(Node* src_node, |
return; |
DCHECK(!markers_.IsEmpty()); |
- MarkerLists* markers = markers_.at(src_node); |
- if (!markers) |
+ MarkerLists* src_markers = markers_.at(src_node); |
+ if (!src_markers) |
return; |
+ Member<MarkerLists>& dst_markers = |
+ markers_.insert(dst_node, nullptr).stored_value->value; |
+ if (!dst_markers) { |
+ dst_markers = new MarkerLists; |
+ dst_markers->Grow(DocumentMarker::kMarkerTypeIndexesCount); |
+ } |
+ |
bool doc_dirty = false; |
- for (Member<MarkerList> list : *markers) { |
- if (!list) |
+ for (size_t marker_list_index = 0; marker_list_index < src_markers->size(); |
+ marker_list_index++) { |
+ DocumentMarkerList* src_list = src_markers->at(marker_list_index); |
+ if (!src_list) |
continue; |
- unsigned end_offset = length - 1; |
- MarkerList::iterator it; |
- for (it = list->begin(); it != list->end(); ++it) { |
- DocumentMarker* marker = it->Get(); |
- |
- // stop if we are now past the specified range |
- if (marker->StartOffset() > end_offset) |
- break; |
- |
- // pin the marker to the specified range |
- doc_dirty = true; |
- if (marker->EndOffset() > end_offset) |
- marker->SetEndOffset(end_offset); |
- |
- AddMarker(dst_node, *marker); |
+ if (!dst_markers->at(marker_list_index)) { |
+ dst_markers->at(marker_list_index) = new DocumentMarkerList; |
} |
- // Remove the range of markers that were moved to dstNode |
- list->erase(0, it - list->begin()); |
+ src_list->MoveMarkers(length, dst_markers->at(marker_list_index)); |
} |
// repaint the affected node |
@@ -342,32 +433,20 @@ void DocumentMarkerController::RemoveMarkers( |
bool doc_dirty = false; |
size_t empty_lists_count = 0; |
- for (size_t marker_list_index = 0; |
- marker_list_index < DocumentMarker::kMarkerTypeIndexesCount; |
- ++marker_list_index) { |
- Member<MarkerList>& list = (*markers)[marker_list_index]; |
+ for (DocumentMarker::MarkerType type : DocumentMarker::AllMarkers()) { |
+ size_t marker_list_index = MarkerTypeToMarkerIndex(type); |
+ |
+ Member<DocumentMarkerList>& list = (*markers)[marker_list_index]; |
if (!list || list->IsEmpty()) { |
if (list.Get() && list->IsEmpty()) |
list.Clear(); |
++empty_lists_count; |
continue; |
} |
- if (!marker_types.Contains((*list->begin())->GetType())) |
+ if (!marker_types.Contains(type)) |
continue; |
- unsigned end_offset = start_offset + length; |
- MarkerList::iterator start_pos = |
- std::upper_bound(list->begin(), list->end(), start_offset, EndsBefore); |
- for (MarkerList::iterator i = start_pos; i != list->end();) { |
- DocumentMarker marker(*i->Get()); |
- |
- // markers are returned in order, so stop if we are now past the specified |
- // range |
- if (marker.StartOffset() >= end_offset) |
- break; |
- list->erase(i - list->begin()); |
- doc_dirty = true; |
- } |
+ doc_dirty = list->RemoveMarkers(start_offset, length) || doc_dirty; |
if (list->IsEmpty()) { |
list.Clear(); |
@@ -397,16 +476,14 @@ DocumentMarkerVector DocumentMarkerController::MarkersFor( |
if (!markers) |
return result; |
- for (size_t marker_list_index = 0; |
- marker_list_index < DocumentMarker::kMarkerTypeIndexesCount; |
- ++marker_list_index) { |
- Member<MarkerList>& list = (*markers)[marker_list_index]; |
- if (!list || list->IsEmpty() || |
- !marker_types.Contains((*list->begin())->GetType())) |
+ for (DocumentMarker::MarkerType type : DocumentMarker::AllMarkers()) { |
+ size_t marker_list_index = MarkerTypeToMarkerIndex(type); |
+ |
+ DocumentMarkerList* list = (*markers)[marker_list_index]; |
+ if (!list || list->IsEmpty() || !marker_types.Contains(type)) |
continue; |
- for (size_t i = 0; i < list->size(); ++i) |
- result.push_back(list->at(i).Get()); |
+ list->AppendMarkersToInputList(&result); |
} |
std::sort(result.begin(), result.end(), CompareByStart); |
@@ -420,11 +497,14 @@ DocumentMarkerVector DocumentMarkerController::Markers() { |
for (size_t marker_list_index = 0; |
marker_list_index < DocumentMarker::kMarkerTypeIndexesCount; |
++marker_list_index) { |
- Member<MarkerList>& list = (*markers)[marker_list_index]; |
- for (size_t j = 0; list.Get() && j < list->size(); ++j) |
- result.push_back(list->at(j).Get()); |
+ DocumentMarkerList* list = (*markers)[marker_list_index]; |
+ if (!list) |
+ continue; |
+ |
+ list->AppendMarkersToInputList(&result); |
} |
} |
+ |
std::sort(result.begin(), result.end(), CompareByStart); |
return result; |
} |
@@ -475,20 +555,20 @@ Vector<IntRect> DocumentMarkerController::RenderedRectsForMarkers( |
// inner loop; process each marker in this node |
const Node& node = *node_iterator->key; |
MarkerLists* markers = node_iterator->value.Get(); |
- for (size_t marker_list_index = 0; |
- marker_list_index < DocumentMarker::kMarkerTypeIndexesCount; |
- ++marker_list_index) { |
- Member<MarkerList>& list = (*markers)[marker_list_index]; |
- if (!list || list->IsEmpty() || |
- (*list->begin())->GetType() != marker_type) |
+ for (DocumentMarker::MarkerType type : DocumentMarker::AllMarkers()) { |
+ size_t marker_list_index = MarkerTypeToMarkerIndex(type); |
+ DocumentMarkerList* list = (*markers)[marker_list_index]; |
+ if (!list || list->IsEmpty() || type != marker_type) |
continue; |
- for (unsigned marker_index = 0; marker_index < list->size(); |
- ++marker_index) { |
- RenderedDocumentMarker* marker = list->at(marker_index).Get(); |
- UpdateMarkerRenderedRectIfNeeded(node, *marker); |
- if (!marker->IsRendered()) |
+ DocumentMarkerVector markers_in_list; |
+ list->AppendMarkersToInputList(&markers_in_list); |
+ for (DocumentMarker* marker : markers_in_list) { |
+ RenderedDocumentMarker* rendered_marker = |
+ ToRenderedDocumentMarker(marker); |
+ UpdateMarkerRenderedRectIfNeeded(node, *rendered_marker); |
+ if (!rendered_marker->IsRendered()) |
continue; |
- result.push_back(marker->RenderedRect()); |
+ result.push_back(rendered_marker->RenderedRect()); |
} |
} |
} |
@@ -514,14 +594,17 @@ void DocumentMarkerController::InvalidateRectsForMarkersInNode( |
const Node& node) { |
MarkerLists* markers = markers_.at(&node); |
- for (auto& marker_list : *markers) { |
+ for (DocumentMarkerList* marker_list : *markers) { |
if (!marker_list || marker_list->IsEmpty()) |
continue; |
- for (auto& marker : *marker_list) |
- marker->Invalidate(); |
+ DocumentMarkerVector markers_in_list; |
+ marker_list->AppendMarkersToInputList(&markers_in_list); |
+ |
+ for (DocumentMarker* marker : markers_in_list) |
+ ToRenderedDocumentMarker(marker)->Invalidate(); |
- if (marker_list->front()->GetType() == DocumentMarker::kTextMatch) |
+ if (markers_in_list.front()->GetType() == DocumentMarker::kTextMatch) |
InvalidatePaintForTickmarks(node); |
} |
} |
@@ -529,14 +612,16 @@ void DocumentMarkerController::InvalidateRectsForMarkersInNode( |
void DocumentMarkerController::InvalidateRectsForAllMarkers() { |
for (auto& node_markers : markers_) { |
const Node& node = *node_markers.key; |
- for (auto& marker_list : *node_markers.value) { |
+ for (DocumentMarkerList* marker_list : *node_markers.value) { |
if (!marker_list || marker_list->IsEmpty()) |
continue; |
- for (auto& marker : *marker_list) |
- marker->Invalidate(); |
+ DocumentMarkerVector markers_in_list; |
+ marker_list->AppendMarkersToInputList(&markers_in_list); |
+ for (DocumentMarker* marker : markers_in_list) |
+ ToRenderedDocumentMarker(marker)->Invalidate(); |
- if (marker_list->front()->GetType() == DocumentMarker::kTextMatch) |
+ if (markers_in_list.front()->GetType() == DocumentMarker::kTextMatch) |
InvalidatePaintForTickmarks(node); |
} |
} |
@@ -570,17 +655,26 @@ void DocumentMarkerController::RemoveMarkers( |
for (size_t marker_list_index = 0; |
marker_list_index < DocumentMarker::kMarkerTypeIndexesCount; |
++marker_list_index) { |
- Member<MarkerList>& list = markers[marker_list_index]; |
+ DocumentMarkerList* list = markers[marker_list_index]; |
if (!list) |
continue; |
bool removed_markers = false; |
- for (size_t j = list->size(); j > 0; --j) { |
- if (should_remove_marker(*list->at(j - 1), |
+ |
+ DocumentMarkerVector markers_in_list; |
+ list->AppendMarkersToInputList(&markers_in_list); |
+ |
+ for (size_t j = markers_in_list.size(); j > 0; --j) { |
+ if (should_remove_marker(*markers_in_list[j - 1], |
static_cast<const Text&>(node))) { |
- list->erase(j - 1); |
+ markers_in_list.erase(j - 1); |
removed_markers = true; |
} |
} |
+ |
+ list->Clear(); |
+ for (DocumentMarker* marker : markers_in_list) |
+ list->Add(marker); |
+ |
if (removed_markers && |
marker_list_index == DocumentMarker::kTextMatchMarkerIndex) |
InvalidatePaintForTickmarks(node); |
@@ -619,22 +713,14 @@ void DocumentMarkerController::RemoveMarkersFromList( |
} else { |
MarkerLists* markers = iterator->value.Get(); |
- for (size_t marker_list_index = 0; |
- marker_list_index < DocumentMarker::kMarkerTypeIndexesCount; |
- ++marker_list_index) { |
- Member<MarkerList>& list = (*markers)[marker_list_index]; |
- if (!list || list->IsEmpty()) { |
- if (list.Get() && list->IsEmpty()) |
- list.Clear(); |
- ++empty_lists_count; |
- continue; |
- } |
- if (marker_types.Contains((*list->begin())->GetType())) { |
+ for (DocumentMarker::MarkerType type : marker_types) { |
+ size_t marker_list_index = MarkerTypeToMarkerIndex(type); |
+ DocumentMarkerList* list = (*markers)[marker_list_index]; |
+ if (list) |
list->Clear(); |
- list.Clear(); |
- ++empty_lists_count; |
- needs_repainting = true; |
- } |
+ |
+ ++empty_lists_count; |
+ needs_repainting = true; |
} |
node_can_be_removed = |
@@ -670,12 +756,10 @@ void DocumentMarkerController::RepaintMarkers( |
// inner loop: process each marker in the current node |
MarkerLists* markers = i->value.Get(); |
- for (size_t marker_list_index = 0; |
- marker_list_index < DocumentMarker::kMarkerTypeIndexesCount; |
- ++marker_list_index) { |
- Member<MarkerList>& list = (*markers)[marker_list_index]; |
- if (!list || list->IsEmpty() || |
- !marker_types.Contains((*list->begin())->GetType())) |
+ for (DocumentMarker::MarkerType type : DocumentMarker::AllMarkers()) { |
+ size_t marker_list_index = MarkerTypeToMarkerIndex(type); |
+ DocumentMarkerList* list = (*markers)[marker_list_index]; |
+ if (!list || list->IsEmpty() || !marker_types.Contains(type)) |
continue; |
// cause the node to be redrawn |
@@ -723,20 +807,24 @@ bool DocumentMarkerController::SetMarkersActive(Node* node, |
return false; |
bool doc_dirty = false; |
- Member<MarkerList>& list = |
- (*markers)[MarkerTypeToMarkerIndex(DocumentMarker::kTextMatch)]; |
+ DocumentMarkerList* list = |
+ markers->at(MarkerTypeToMarkerIndex(DocumentMarker::kTextMatch)); |
if (!list) |
return false; |
- MarkerList::iterator start_pos = |
- std::upper_bound(list->begin(), list->end(), start_offset, EndsBefore); |
- for (MarkerList::iterator marker = start_pos; marker != list->end(); |
- ++marker) { |
+ |
+ DocumentMarkerVector markers_in_list; |
+ list->AppendMarkersToInputList(&markers_in_list); |
+ |
+ const auto start_pos = std::upper_bound( |
+ markers_in_list.begin(), markers_in_list.end(), start_offset, EndsBefore); |
+ for (auto marker_it = start_pos; marker_it != markers_in_list.end(); |
+ ++marker_it) { |
// Markers are returned in order, so stop if we are now past the specified |
// range. |
- if ((*marker)->StartOffset() >= end_offset) |
+ if ((*marker_it)->StartOffset() >= end_offset) |
break; |
- (*marker)->SetIsActiveMatch(active); |
+ (*marker_it)->SetIsActiveMatch(active); |
doc_dirty = true; |
} |
@@ -760,10 +848,12 @@ void DocumentMarkerController::ShowMarkers() const { |
for (size_t marker_list_index = 0; |
marker_list_index < DocumentMarker::kMarkerTypeIndexesCount; |
++marker_list_index) { |
- Member<MarkerList>& list = (*markers)[marker_list_index]; |
- for (unsigned marker_index = 0; list.Get() && marker_index < list->size(); |
- ++marker_index) { |
- DocumentMarker* marker = list->at(marker_index).Get(); |
+ DocumentMarkerList* list = markers->at(marker_list_index); |
+ DocumentMarkerVector markers_in_list; |
+ list->AppendMarkersToInputList(&markers_in_list); |
+ for (unsigned marker_index = 0; |
+ list && marker_index < markers_in_list.size(); ++marker_index) { |
+ DocumentMarker* marker = markers_in_list[marker_index]; |
builder.Append(" "); |
builder.AppendNumber(marker->GetType()); |
builder.Append(":["); |
@@ -796,28 +886,12 @@ void DocumentMarkerController::DidUpdateCharacterData(CharacterData* node, |
return; |
bool did_shift_marker = false; |
- for (MarkerList* list : *markers) { |
+ for (DocumentMarkerList* list : *markers) { |
if (!list) |
continue; |
- for (MarkerList::iterator it = list->begin(); it != list->end(); ++it) { |
- RenderedDocumentMarker& marker = **it; |
- Optional<DocumentMarker::MarkerOffsets> result = |
- marker.ComputeOffsetsAfterShift(offset, old_length, new_length); |
- if (result == WTF::kNullopt) { |
- list->erase(it - list->begin()); |
- --it; |
- did_shift_marker = true; |
- continue; |
- } |
- |
- if (marker.StartOffset() != result.value().start_offset || |
- marker.EndOffset() != result.value().end_offset) { |
- did_shift_marker = true; |
- marker.SetStartOffset(result.value().start_offset); |
- marker.SetEndOffset(result.value().end_offset); |
- } |
- } |
+ did_shift_marker = |
+ list->ShiftMarkers(offset, old_length, new_length) || did_shift_marker; |
} |
if (!did_shift_marker) |