push method
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++;
}