push method

void push(
  1. Operation operation
)

Pushes new operation into this delta.

Performs compaction by composing operation with current tail operation of this delta, when possible. For instance, if current tail is insert('abc') and pushed operation is insert('123') then existing tail is replaced with insert('abc123') - a compound result of the two operations.

Implementation

void push(Operation operation) {
  if (operation.isEmpty) return;

  var index = operations.length;
  final lastOp = operations.isNotEmpty ? operations.last : null;
  if (lastOp != null) {
    if (lastOp.isDelete && operation.isDelete) {
      _mergeWithTail(operation);
      return;
    }

    if (lastOp.isDelete && operation.isInsert) {
      index -= 1; // Always insert before deleting
      final nLastOp = (index > 0) ? operations.elementAt(index - 1) : null;
      if (nLastOp == null) {
        operations.insert(0, operation);
        return;
      }
    }

    if (lastOp.isInsert && operation.isInsert) {
      if (lastOp.hasSameAttributes(operation) &&
          operation.data is String &&
          lastOp.data is String) {
        _mergeWithTail(operation);
        return;
      }
    }

    if (lastOp.isRetain && operation.isRetain) {
      if (lastOp.hasSameAttributes(operation)) {
        _mergeWithTail(operation);
        return;
      }
    }
  }
  if (index == operations.length) {
    operations.add(operation);
  } else {
    final opAtIndex = operations.elementAt(index);
    operations.replaceRange(index, index + 1, [operation, opAtIndex]);
  }
  modificationCount++;
}