pull/142/head
Xun Gong 4 years ago
parent 106e54c3fc
commit e08009e3ff
  1. 8
      lib/models/documents/document.dart
  2. 23
      lib/models/rules/insert.dart

@ -47,7 +47,7 @@ class Document {
Stream<Tuple3<Delta, Delta, ChangeSource>> get changes => _observer.stream; Stream<Tuple3<Delta, Delta, ChangeSource>> get changes => _observer.stream;
Delta insert(int index, Object? data) { Delta insert(int index, Object? data, {int replaceLength = 0}) {
assert(index >= 0); assert(index >= 0);
assert(data is String || data is Embeddable); assert(data is String || data is Embeddable);
if (data is Embeddable) { if (data is Embeddable) {
@ -56,7 +56,7 @@ class Document {
return Delta(); return Delta();
} }
final delta = _rules.apply(RuleType.INSERT, this, index, data: data); final delta = _rules.apply(RuleType.INSERT, this, index, data: data, len: replaceLength);
compose(delta, ChangeSource.LOCAL); compose(delta, ChangeSource.LOCAL);
return delta; return delta;
} }
@ -80,8 +80,10 @@ class Document {
var delta = Delta(); var delta = Delta();
// We have to insert before applying delete rules
// Otherwise delete would be operating on stale document snapshot.
if (dataIsNotEmpty) { if (dataIsNotEmpty) {
delta = insert(index + len, data); delta = insert(index, data, replaceLength: len);
} }
if (len > 0) { if (len > 0) {

@ -13,7 +13,6 @@ abstract class InsertRule extends Rule {
@override @override
void validateArgs(int? len, Object? data, Attribute? attribute) { void validateArgs(int? len, Object? data, Attribute? attribute) {
assert(len == null);
assert(data != null); assert(data != null);
assert(attribute == null); assert(attribute == null);
} }
@ -43,7 +42,7 @@ class PreserveLineStyleOnSplitRule extends InsertRule {
final text = after.data as String; final text = after.data as String;
final delta = Delta()..retain(index); final delta = Delta()..retain(index + (len ?? 0));
if (text.contains('\n')) { if (text.contains('\n')) {
assert(after.isPlain); assert(after.isPlain);
delta.insert('\n'); delta.insert('\n');
@ -86,7 +85,7 @@ class PreserveBlockStyleOnInsertRule extends InsertRule {
} }
final lines = data.split('\n'); final lines = data.split('\n');
final delta = Delta()..retain(index); final delta = Delta()..retain(index + (len ?? 0));
for (var i = 0; i < lines.length; i++) { for (var i = 0; i < lines.length; i++) {
final line = lines[i]; final line = lines[i];
if (line.isNotEmpty) { if (line.isNotEmpty) {
@ -157,7 +156,7 @@ class AutoExitBlockRule extends InsertRule {
.firstWhere((k) => Attribute.blockKeysExceptHeader.contains(k)); .firstWhere((k) => Attribute.blockKeysExceptHeader.contains(k));
attributes[k] = null; attributes[k] = null;
// retain(1) should be '\n', set it with no attribute // retain(1) should be '\n', set it with no attribute
return Delta()..retain(index)..retain(1, attributes); return Delta()..retain(index + (len ?? 0))..retain(1, attributes);
} }
} }
@ -183,7 +182,7 @@ class ResetLineFormatOnNewLineRule extends InsertRule {
resetStyle = Attribute.header.toJson(); resetStyle = Attribute.header.toJson();
} }
return Delta() return Delta()
..retain(index) ..retain(index + (len ?? 0))
..insert('\n', cur.attributes) ..insert('\n', cur.attributes)
..retain(1, resetStyle) ..retain(1, resetStyle)
..trim(); ..trim();
@ -200,7 +199,7 @@ class InsertEmbedsRule extends InsertRule {
return null; return null;
} }
final delta = Delta()..retain(index); final delta = Delta()..retain(index + (len ?? 0));
final itr = DeltaIterator(document); final itr = DeltaIterator(document);
final prev = itr.skip(index), cur = itr.next(); final prev = itr.skip(index), cur = itr.next();
@ -258,7 +257,7 @@ class ForceNewlineForInsertsAroundEmbedRule extends InsertRule {
if (!cursorBeforeEmbed && !cursorAfterEmbed) { if (!cursorBeforeEmbed && !cursorAfterEmbed) {
return null; return null;
} }
final delta = Delta()..retain(index); final delta = Delta()..retain(index + (len ?? 0));
if (cursorBeforeEmbed && !text.endsWith('\n')) { if (cursorBeforeEmbed && !text.endsWith('\n')) {
return delta..insert(text)..insert('\n'); return delta..insert(text)..insert('\n');
} }
@ -299,7 +298,7 @@ class AutoFormatLinksRule extends InsertRule {
attributes.addAll(LinkAttribute(link.toString()).toJson()); attributes.addAll(LinkAttribute(link.toString()).toJson());
return Delta() return Delta()
..retain(index - cand.length) ..retain(index + (len ?? 0) - cand.length)
..retain(cand.length, attributes) ..retain(cand.length, attributes)
..insert(data, prev.attributes); ..insert(data, prev.attributes);
} on FormatException { } on FormatException {
@ -330,13 +329,13 @@ class PreserveInlineStylesRule extends InsertRule {
final text = data; final text = data;
if (attributes == null || !attributes.containsKey(Attribute.link.key)) { if (attributes == null || !attributes.containsKey(Attribute.link.key)) {
return Delta() return Delta()
..retain(index) ..retain(index + (len ?? 0))
..insert(text, attributes); ..insert(text, attributes);
} }
attributes.remove(Attribute.link.key); attributes.remove(Attribute.link.key);
final delta = Delta() final delta = Delta()
..retain(index) ..retain(index + (len ?? 0))
..insert(text, attributes.isEmpty ? null : attributes); ..insert(text, attributes.isEmpty ? null : attributes);
final next = itr.next(); final next = itr.next();
@ -346,7 +345,7 @@ class PreserveInlineStylesRule extends InsertRule {
} }
if (attributes[Attribute.link.key] == nextAttributes[Attribute.link.key]) { if (attributes[Attribute.link.key] == nextAttributes[Attribute.link.key]) {
return Delta() return Delta()
..retain(index) ..retain(index + (len ?? 0))
..insert(text, attributes); ..insert(text, attributes);
} }
return delta; return delta;
@ -360,7 +359,7 @@ class CatchAllInsertRule extends InsertRule {
Delta applyRule(Delta document, int index, Delta applyRule(Delta document, int index,
{int? len, Object? data, Attribute? attribute}) { {int? len, Object? data, Attribute? attribute}) {
return Delta() return Delta()
..retain(index) ..retain(index + (len ?? 0))
..insert(data); ..insert(data);
} }
} }

Loading…
Cancel
Save