apply method
Applies heuristic rule to a delete operation on a document
and returns
resulting Delta
.
Implementation
@override
Delta? apply(Delta document, int index, int length) {
final iter = DeltaIterator(document);
// First, check if newline deleted after an embed.
var op = iter.skip(index);
var indexDelta = 0;
var lengthDelta = 0;
var remaining = length;
var foundEmbed = false;
var hasLineBreakBefore = false;
if (op != null && op.data is! String) {
foundEmbed = true;
var candidate = iter.next(1);
remaining--;
if (candidate.data == '\n') {
indexDelta += 1;
lengthDelta -= 1;
/// Check if it's an empty line
candidate = iter.next(1);
remaining--;
if (candidate.data == '\n') {
// Allow deleting empty line after an embed.
lengthDelta += 1;
}
}
} else {
// If op is `null` it's beginning of the doc, e.g. implicit line break.
final opText = op?.data as String?;
hasLineBreakBefore = op == null || opText!.endsWith('\n');
}
// Second, check if newline deleted before an embed.
op = iter.skip(remaining);
final opText = op?.data is String ? op!.data as String? : '';
if (op != null && opText!.endsWith('\n')) {
final candidate = iter.next(1);
// If there is a newline before deleted range we allow the operation
// since it results in a correctly formatted line with a single embed in
// it.
if (candidate.data is! String && !hasLineBreakBefore) {
foundEmbed = true;
lengthDelta -= 1;
}
}
if (foundEmbed) {
return Delta()
..retain(index + indexDelta)
..delete(length + lengthDelta);
}
return null;
}