replaceText method
Replaces length
characters in the document starting at index
with
provided text
.
Resulting change is registered as produced by user action, e.g. using ChangeSource.local.
It also applies the toggledStyle if needed. And then it resets it in any cases as we don't want to keep it except on inserts.
Optionally updates selection if provided.
Implementation
void replaceText(int index, int length, Object? data,
{TextSelection? selection}) {
assert(data is String || data is EmbeddableObject);
Delta? delta;
final isDataNotEmpty = data is String ? data.isNotEmpty : true;
if (length > 0 || isDataNotEmpty) {
delta = document.replace(index, length, data!);
// If the delta is an insert operation and we have toggled
// some styles, then apply those styles to the inserted text.
if (toggledStyles.isNotEmpty &&
delta.isNotEmpty &&
delta.length <= 2 && // covers single insert and a retain+insert
delta.last.isInsert) {
final dataLength = data is String ? data.length : 1;
final retainDelta = Delta()
..retain(index)
..retain(dataLength, toggledStyles.toJson());
document.compose(retainDelta, ChangeSource.local);
}
}
// Always reset it after any user action, even if it has not been applied.
_toggledStyles = NotusStyle();
if (selection != null) {
if (delta == null) {
_updateSelectionSilent(selection, source: ChangeSource.local);
} else {
// need to transform selection position in case actual delta
// is different from user's version (in deletes and inserts).
final user = Delta()
..retain(index)
..insert(data)
..delete(length);
var positionDelta = getPositionDelta(user, delta);
_updateSelectionSilent(
selection.copyWith(
baseOffset: selection.baseOffset + positionDelta,
extentOffset: selection.extentOffset + positionDelta,
),
source: ChangeSource.local,
);
}
}
// _lastChangeSource = ChangeSource.local;
notifyListeners();
}