|
@@ -72,8 +72,9 @@ class PreserveLineStyleOnSplitRule extends InsertRule {
|
72
|
72
|
}
|
73
|
73
|
}
|
74
|
74
|
|
75
|
|
-/// Resets format for a newly inserted line when insert occurred at the end
|
76
|
75
|
/// of a line (right before a line-break).
|
|
76
|
+
|
|
77
|
+/// Resets format for a newly inserted line when insert occurred at the end
|
77
|
78
|
class ResetLineFormatOnNewLineRule extends InsertRule {
|
78
|
79
|
const ResetLineFormatOnNewLineRule();
|
79
|
80
|
|
|
@@ -256,3 +257,69 @@ class ForceNewlineForInsertsAroundEmbedRule extends InsertRule {
|
256
|
257
|
return null;
|
257
|
258
|
}
|
258
|
259
|
}
|
|
260
|
+
|
|
261
|
+/// Preserves block style when user pastes text containing line-breaks.
|
|
262
|
+/// This rule may also be activated for changes triggered by auto-correct.
|
|
263
|
+class PreserveBlockStyleOnPasteRule extends InsertRule {
|
|
264
|
+ const PreserveBlockStyleOnPasteRule();
|
|
265
|
+
|
|
266
|
+ bool isEdgeLineSplit(Operation before, Operation after) {
|
|
267
|
+ if (before == null) return true; // split at the beginning of a doc
|
|
268
|
+ return before.data.endsWith('\n') || after.data.startsWith('\n');
|
|
269
|
+ }
|
|
270
|
+
|
|
271
|
+ @override
|
|
272
|
+ Delta apply(Delta document, int index, String text) {
|
|
273
|
+ if (!text.contains('\n') || text.length == 1) {
|
|
274
|
+ // Only interested in text containing at least one line-break and at least
|
|
275
|
+ // one more character.
|
|
276
|
+ return null;
|
|
277
|
+ }
|
|
278
|
+
|
|
279
|
+ DeltaIterator iter = new DeltaIterator(document);
|
|
280
|
+ iter.skip(index);
|
|
281
|
+
|
|
282
|
+ // Look for next line-break.
|
|
283
|
+ Map<String, dynamic> lineStyle;
|
|
284
|
+ while (iter.hasNext) {
|
|
285
|
+ final op = iter.next();
|
|
286
|
+ int lf = op.data.indexOf('\n');
|
|
287
|
+ if (lf >= 0) {
|
|
288
|
+ lineStyle = op.attributes;
|
|
289
|
+ break;
|
|
290
|
+ }
|
|
291
|
+ }
|
|
292
|
+
|
|
293
|
+ Map<String, dynamic> resetStyle = null;
|
|
294
|
+ Map<String, dynamic> blockStyle = null;
|
|
295
|
+ if (lineStyle != null) {
|
|
296
|
+ if (lineStyle.containsKey(NotusAttribute.heading.key)) {
|
|
297
|
+ resetStyle = NotusAttribute.heading.unset.toJson();
|
|
298
|
+ }
|
|
299
|
+
|
|
300
|
+ if (lineStyle.containsKey(NotusAttribute.block.key)) {
|
|
301
|
+ blockStyle = <String, dynamic>{
|
|
302
|
+ NotusAttribute.block.key: lineStyle[NotusAttribute.block.key]
|
|
303
|
+ };
|
|
304
|
+ }
|
|
305
|
+ }
|
|
306
|
+
|
|
307
|
+ final lines = text.split('\n');
|
|
308
|
+ Delta result = new Delta()..retain(index);
|
|
309
|
+ for (int i = 0; i < lines.length; i++) {
|
|
310
|
+ final line = lines[i];
|
|
311
|
+ if (line.isNotEmpty) {
|
|
312
|
+ result.insert(line);
|
|
313
|
+ }
|
|
314
|
+ if (i == 0) {
|
|
315
|
+ result.insert('\n', lineStyle);
|
|
316
|
+ } else if (i == lines.length - 1) {
|
|
317
|
+ if (resetStyle != null) result.retain(1, resetStyle);
|
|
318
|
+ } else {
|
|
319
|
+ result.insert('\n', blockStyle);
|
|
320
|
+ }
|
|
321
|
+ }
|
|
322
|
+
|
|
323
|
+ return result;
|
|
324
|
+ }
|
|
325
|
+}
|