apply method
Applies heuristic rule to an insert operation on a document
and returns
resulting Delta
.
Implementation
@override
Delta? apply(Delta document, int index, Object data) {
// Embeds are handled by a different rule.
if (data is! String) return null;
final text = data;
if (!text.contains('\n')) {
// Only interested in text containing at least one newline character.
return null;
}
final iter = DeltaIterator(document);
iter.skip(index);
// Look for the next newline.
final nextNewline = _findNextNewline(iter);
final lineStyle = nextNewline.op?.attributes ?? <String, dynamic>{};
// Are we currently in a block? If not then ignore.
if (!lineStyle.containsKey(NotusAttribute.block.key)) return null;
final blockStyle = <String, dynamic>{
NotusAttribute.block.key: lineStyle[NotusAttribute.block.key]
};
Map<String, dynamic>? resetStyle;
// If current line had heading style applied to it we'll need to move this
// style to the newly inserted line before it and reset style of the
// original line.
if (lineStyle.containsKey(NotusAttribute.heading.key)) {
resetStyle = NotusAttribute.heading.unset.toJson();
}
// Go over each inserted line and ensure block style is applied.
final lines = text.split('\n');
final result = Delta()..retain(index);
for (var i = 0; i < lines.length; i++) {
final line = lines[i];
if (line.isNotEmpty) {
result.insert(line);
}
if (i == 0) {
// The first line should inherit the lineStyle entirely.
result.insert('\n', lineStyle);
} else if (i < lines.length - 1) {
// we don't want to insert a newline after the last chunk of text, so -1
result.insert('\n', blockStyle);
}
}
// Reset style of the original newline character if needed.
if (resetStyle != null) {
result.retain(nextNewline.skippedLength!);
final opText = nextNewline.op!.data as String;
final lf = opText.indexOf('\n');
result..retain(lf)..retain(1, resetStyle);
}
return result;
}