|
@@ -80,12 +80,14 @@ class EnsureEmbedLineRule extends DeleteRule {
|
80
|
80
|
@override
|
81
|
81
|
Delta apply(Delta document, int index, int length) {
|
82
|
82
|
DeltaIterator iter = new DeltaIterator(document);
|
|
83
|
+
|
83
|
84
|
// First, check if line-break deleted after an embed.
|
84
|
85
|
Operation op = iter.skip(index);
|
85
|
86
|
int indexDelta = 0;
|
86
|
87
|
int lengthDelta = 0;
|
87
|
88
|
int remaining = length;
|
88
|
89
|
bool foundEmbed = false;
|
|
90
|
+ bool hasLineBreakBefore = false;
|
89
|
91
|
if (op != null && op.data.endsWith(kZeroWidthSpace)) {
|
90
|
92
|
foundEmbed = true;
|
91
|
93
|
Operation candidate = iter.next(1);
|
|
@@ -102,17 +104,23 @@ class EnsureEmbedLineRule extends DeleteRule {
|
102
|
104
|
lengthDelta += 1;
|
103
|
105
|
}
|
104
|
106
|
}
|
|
107
|
+ } else {
|
|
108
|
+ // If op is `null` it's a beginning of the doc, e.g. implicit line break.
|
|
109
|
+ hasLineBreakBefore = op == null || op.data.endsWith('\n');
|
105
|
110
|
}
|
106
|
111
|
|
107
|
112
|
// Second, check if line-break deleted before an embed.
|
108
|
113
|
op = iter.skip(remaining);
|
109
|
114
|
if (op != null && op.data.endsWith('\n')) {
|
110
|
115
|
final candidate = iter.next(1);
|
111
|
|
- if (candidate.data == kZeroWidthSpace) {
|
|
116
|
+ // If there is a line-break before deleted range we allow the operation
|
|
117
|
+ // since it results in a correctly formatted line with single embed in it.
|
|
118
|
+ if (candidate.data == kZeroWidthSpace && !hasLineBreakBefore) {
|
112
|
119
|
foundEmbed = true;
|
113
|
120
|
lengthDelta -= 1;
|
114
|
121
|
}
|
115
|
122
|
}
|
|
123
|
+
|
116
|
124
|
if (foundEmbed) {
|
117
|
125
|
return new Delta()
|
118
|
126
|
..retain(index + indexDelta)
|