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) {
// There is no other text around embeds so no inline styles to preserve.
if (data is! String) return null;
final text = data;
// This rule is only applicable to characters other than newline.
if (text.contains('\n')) return null;
final iter = DeltaIterator(document);
final previous = iter.skip(index);
// If there is a newline in previous chunk, there should be no inline
// styles. Also if there is no previous operation we are at the beginning
// of the document so no styles to inherit from.
if (previous == null) return null;
final previousText =
previous.data is String ? (previous.data as String?)! : '';
if (previousText.contains('\n')) return null;
final attributes = previous.attributes;
final hasLink =
(attributes != null && attributes.containsKey(NotusAttribute.link.key));
if (!hasLink) {
return Delta()
..retain(index)
..insert(text, attributes);
}
// Special handling needed for inserts inside fragments with link attribute.
// Link style should only be preserved if insert occurs inside the fragment.
// Link style should NOT be preserved on the boundaries.
var noLinkAttributes = previous.attributes!;
noLinkAttributes.remove(NotusAttribute.link.key);
final noLinkResult = Delta()
..retain(index)
..insert(text, noLinkAttributes.isEmpty ? null : noLinkAttributes);
final next = iter.next();
final nextAttributes = next.attributes ?? const <String, dynamic>{};
if (!nextAttributes.containsKey(NotusAttribute.link.key)) {
// Next fragment is not styled as link.
return noLinkResult;
}
// We must make sure links are identical in previous and next operations.
if (attributes![NotusAttribute.link.key] ==
nextAttributes[NotusAttribute.link.key]) {
return Delta()
..retain(index)
..insert(text, attributes);
} else {
return noLinkResult;
}
}