applyRule method

  1. @override
Delta? applyRule(
  1. Delta document,
  2. int index, {
  3. int? len,
  4. Object? data,
  5. Attribute? attribute,
})
override

Implementation

@override
Delta? applyRule(Delta document, int index,
    {int? len, Object? data, Attribute? attribute}) {
  if (attribute!.scope != AttributeScope.BLOCK) {
    return null;
  }

  var delta = Delta()..retain(index);
  final itr = DeltaIterator(document)..skip(index);
  Operation op;
  for (var cur = 0; cur < len! && itr.hasNext; cur += op.length!) {
    op = itr.next(len - cur);
    if (op.data is! String || !(op.data as String).contains('\n')) {
      delta.retain(op.length!);
      continue;
    }
    final text = op.data as String;
    final tmp = Delta();
    var offset = 0;

    // Enforce Block Format exclusivity by rule
    final removedBlocks = Attribute.exclusiveBlockKeys.contains(attribute.key)
        ? op.attributes?.keys
                .where((key) =>
                    Attribute.exclusiveBlockKeys.contains(key) &&
                    attribute.key != key &&
                    attribute.value != null)
                .map((key) => MapEntry<String, dynamic>(key, null)) ??
            []
        : <MapEntry<String, dynamic>>[];

    for (var lineBreak = text.indexOf('\n');
        lineBreak >= 0;
        lineBreak = text.indexOf('\n', offset)) {
      tmp
        ..retain(lineBreak - offset)
        ..retain(1, attribute.toJson()..addEntries(removedBlocks));
      offset = lineBreak + 1;
    }
    tmp.retain(text.length - offset);
    delta = delta.concat(tmp);
  }

  while (itr.hasNext) {
    op = itr.next();
    final text = op.data is String ? (op.data as String?)! : '';
    final lineBreak = text.indexOf('\n');
    if (lineBreak < 0) {
      delta.retain(op.length!);
      continue;
    }
    // Enforce Block Format exclusivity by rule
    final removedBlocks = Attribute.exclusiveBlockKeys.contains(attribute.key)
        ? op.attributes?.keys
                .where((key) =>
                    Attribute.exclusiveBlockKeys.contains(key) &&
                    attribute.key != key &&
                    attribute.value != null)
                .map((key) => MapEntry<String, dynamic>(key, null)) ??
            []
        : <MapEntry<String, dynamic>>[];
    delta
      ..retain(lineBreak)
      ..retain(1, attribute.toJson()..addEntries(removedBlocks));
    break;
  }
  return delta;
}