apply method

  1. @override
Delta? apply(
  1. Delta document,
  2. int index,
  3. Object data
)
override

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;
}