|
|
@ -51,8 +51,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}) { |
|
|
|
{int replaceLength = 0, bool autoAppendNewlineAfterImage = true}) { |
|
|
|
|
|
|
|
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) { |
|
|
@ -63,8 +62,7 @@ class Document { |
|
|
|
|
|
|
|
|
|
|
|
final delta = _rules.apply(RuleType.INSERT, this, index, |
|
|
|
final delta = _rules.apply(RuleType.INSERT, this, index, |
|
|
|
data: data, len: replaceLength); |
|
|
|
data: data, len: replaceLength); |
|
|
|
compose(delta, ChangeSource.LOCAL, |
|
|
|
compose(delta, ChangeSource.LOCAL); |
|
|
|
autoAppendNewlineAfterImage: autoAppendNewlineAfterImage); |
|
|
|
|
|
|
|
return delta; |
|
|
|
return delta; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -77,8 +75,7 @@ class Document { |
|
|
|
return delta; |
|
|
|
return delta; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
Delta replace(int index, int len, Object? data, |
|
|
|
Delta replace(int index, int len, Object? data) { |
|
|
|
{bool autoAppendNewlineAfterImage = true}) { |
|
|
|
|
|
|
|
assert(index >= 0); |
|
|
|
assert(index >= 0); |
|
|
|
assert(data is String || data is Embeddable); |
|
|
|
assert(data is String || data is Embeddable); |
|
|
|
|
|
|
|
|
|
|
@ -91,9 +88,7 @@ class Document { |
|
|
|
// We have to insert before applying delete rules |
|
|
|
// We have to insert before applying delete rules |
|
|
|
// Otherwise delete would be operating on stale document snapshot. |
|
|
|
// Otherwise delete would be operating on stale document snapshot. |
|
|
|
if (dataIsNotEmpty) { |
|
|
|
if (dataIsNotEmpty) { |
|
|
|
delta = insert(index, data, |
|
|
|
delta = insert(index, data, replaceLength: len); |
|
|
|
replaceLength: len, |
|
|
|
|
|
|
|
autoAppendNewlineAfterImage: autoAppendNewlineAfterImage); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (len > 0) { |
|
|
|
if (len > 0) { |
|
|
@ -141,17 +136,13 @@ class Document { |
|
|
|
return block.queryChild(res.offset, true); |
|
|
|
return block.queryChild(res.offset, true); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void compose(Delta delta, ChangeSource changeSource, |
|
|
|
void compose(Delta delta, ChangeSource changeSource) { |
|
|
|
{bool autoAppendNewlineAfterImage = true, |
|
|
|
|
|
|
|
bool autoAppendNewlineAfterVideo = true}) { |
|
|
|
|
|
|
|
assert(!_observer.isClosed); |
|
|
|
assert(!_observer.isClosed); |
|
|
|
delta.trim(); |
|
|
|
delta.trim(); |
|
|
|
assert(delta.isNotEmpty); |
|
|
|
assert(delta.isNotEmpty); |
|
|
|
|
|
|
|
|
|
|
|
var offset = 0; |
|
|
|
var offset = 0; |
|
|
|
delta = _transform(delta, |
|
|
|
delta = _transform(delta); |
|
|
|
autoAppendNewlineAfterImage: autoAppendNewlineAfterImage, |
|
|
|
|
|
|
|
autoAppendNewlineAfterVideo: autoAppendNewlineAfterVideo); |
|
|
|
|
|
|
|
final originalDelta = toDelta(); |
|
|
|
final originalDelta = toDelta(); |
|
|
|
for (final op in delta.toList()) { |
|
|
|
for (final op in delta.toList()) { |
|
|
|
final style = |
|
|
|
final style = |
|
|
@ -195,21 +186,14 @@ class Document { |
|
|
|
|
|
|
|
|
|
|
|
bool get hasRedo => _history.hasRedo; |
|
|
|
bool get hasRedo => _history.hasRedo; |
|
|
|
|
|
|
|
|
|
|
|
static Delta _transform(Delta delta, |
|
|
|
static Delta _transform(Delta delta) { |
|
|
|
{bool autoAppendNewlineAfterImage = true, |
|
|
|
|
|
|
|
bool autoAppendNewlineAfterVideo = true}) { |
|
|
|
|
|
|
|
final res = Delta(); |
|
|
|
final res = Delta(); |
|
|
|
final ops = delta.toList(); |
|
|
|
final ops = delta.toList(); |
|
|
|
for (var i = 0; i < ops.length; i++) { |
|
|
|
for (var i = 0; i < ops.length; i++) { |
|
|
|
final op = ops[i]; |
|
|
|
final op = ops[i]; |
|
|
|
res.push(op); |
|
|
|
res.push(op); |
|
|
|
if (autoAppendNewlineAfterImage) { |
|
|
|
|
|
|
|
_autoAppendNewlineAfterEmbeddable(i, ops, op, res, 'image'); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (autoAppendNewlineAfterVideo) { |
|
|
|
|
|
|
|
_autoAppendNewlineAfterEmbeddable(i, ops, op, res, 'video'); |
|
|
|
_autoAppendNewlineAfterEmbeddable(i, ops, op, res, 'video'); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
return res; |
|
|
|
return res; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|