blob: 65f1db0f36b3bd5bfb69fbb3a4c2ac340ec65f50 [file] [log] [blame]
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "third_party/blink/renderer/core/editing/markers/unsorted_document_marker_list_editor.h"
#include "third_party/blink/renderer/core/editing/markers/spell_check_marker_list_impl.h"
namespace blink {
bool UnsortedDocumentMarkerListEditor::MoveMarkers(
MarkerList* src_list,
int length,
DocumentMarkerList* dst_list) {
DCHECK_GT(length, 0);
bool did_move_marker = false;
const unsigned end_offset = length - 1;
HeapVector<Member<DocumentMarker>> unmoved_markers;
for (DocumentMarker* marker : *src_list) {
if (marker->StartOffset() > end_offset) {
unmoved_markers.push_back(marker);
continue;
}
// If we're splitting a text node in the middle of a suggestion marker,
// remove the marker
if (marker->EndOffset() > end_offset)
continue;
dst_list->Add(marker);
did_move_marker = true;
}
*src_list = std::move(unmoved_markers);
return did_move_marker;
}
bool UnsortedDocumentMarkerListEditor::RemoveMarkers(MarkerList* list,
unsigned start_offset,
int length) {
// For an unsorted marker list, the quickest way to perform this operation is
// to build a new list with the markers that aren't being removed.
const unsigned end_offset = start_offset + length;
HeapVector<Member<DocumentMarker>> unremoved_markers;
for (const Member<DocumentMarker>& marker : *list) {
if (marker->EndOffset() <= start_offset ||
marker->StartOffset() >= end_offset) {
unremoved_markers.push_back(marker);
continue;
}
}
const bool did_remove_marker = (unremoved_markers.size() != list->size());
*list = std::move(unremoved_markers);
return did_remove_marker;
}
bool UnsortedDocumentMarkerListEditor::ShiftMarkersContentIndependent(
MarkerList* list,
unsigned offset,
unsigned old_length,
unsigned new_length) {
// For an unsorted marker list, the quickest way to perform this operation is
// to build a new list with the markers not removed by the shift.
bool did_shift_marker = false;
HeapVector<Member<DocumentMarker>> unremoved_markers;
for (const Member<DocumentMarker>& marker : *list) {
base::Optional<DocumentMarker::MarkerOffsets> result =
marker->ComputeOffsetsAfterShift(offset, old_length, new_length);
if (!result) {
did_shift_marker = true;
continue;
}
if (marker->StartOffset() != result.value().start_offset ||
marker->EndOffset() != result.value().end_offset) {
marker->SetStartOffset(result.value().start_offset);
marker->SetEndOffset(result.value().end_offset);
did_shift_marker = true;
}
unremoved_markers.push_back(marker);
}
*list = std::move(unremoved_markers);
return did_shift_marker;
}
DocumentMarker* UnsortedDocumentMarkerListEditor::FirstMarkerIntersectingRange(
const MarkerList& list,
unsigned start_offset,
unsigned end_offset) {
DCHECK_LE(start_offset, end_offset);
auto* const it =
std::find_if(list.begin(), list.end(),
[start_offset, end_offset](const DocumentMarker* marker) {
return marker->StartOffset() < end_offset &&
marker->EndOffset() > start_offset;
});
if (it == list.end())
return nullptr;
return *it;
}
HeapVector<Member<DocumentMarker>>
UnsortedDocumentMarkerListEditor::MarkersIntersectingRange(
const MarkerList& list,
unsigned start_offset,
unsigned end_offset) {
DCHECK_LE(start_offset, end_offset);
HeapVector<Member<DocumentMarker>> results;
std::copy_if(list.begin(), list.end(), std::back_inserter(results),
[start_offset, end_offset](const DocumentMarker* marker) {
return marker->StartOffset() < end_offset &&
marker->EndOffset() > start_offset;
});
return results;
}
} // namespace blink