ソースを参照

feat: implement deleting text in multiple lines.

Lucas.Xu 2 年 前
コミット
58856ccb1e

+ 5 - 0
frontend/app_flowy/packages/flowy_editor/lib/document/text_delta.dart

@@ -275,6 +275,11 @@ class Delta {
 
   Delta([List<TextOperation>? ops]) : operations = ops ?? <TextOperation>[];
 
+  Delta addAll(List<TextOperation> textOps) {
+    textOps.forEach(add);
+    return this;
+  }
+
   Delta add(TextOperation textOp) {
     if (textOp.isEmpty) {
       return this;

+ 22 - 2
frontend/app_flowy/packages/flowy_editor/lib/operation/transaction_builder.dart

@@ -63,8 +63,28 @@ class TransactionBuilder {
     add(TextEditOperation(path: path, delta: delta, inverted: inverted));
   }
 
-  insertText(TextNode node, int index, String content) {
-    textEdit(node, () => Delta().retain(index).insert(content));
+  mergeText(TextNode firstNode, TextNode secondNode,
+      {int? firstOffset, int secondOffset = 0}) {
+    final firstLength = firstNode.delta.length;
+    final secondLength = secondNode.delta.length;
+    textEdit(
+      firstNode,
+      () => Delta()
+        ..retain(firstOffset ?? firstLength)
+        ..delete(firstLength - (firstOffset ?? firstLength))
+        ..addAll(secondNode.delta.slice(secondOffset, secondLength).operations),
+    );
+    afterSelection = Selection.collapsed(
+      Position(
+        path: firstNode.path,
+        offset: firstOffset ?? firstLength,
+      ),
+    );
+  }
+
+  insertText(TextNode node, int index, String content,
+      [Attributes? attributes]) {
+    textEdit(node, () => Delta().retain(index).insert(content, attributes));
     afterSelection = Selection.collapsed(
         Position(path: node.path, offset: index + content.length));
   }

+ 6 - 10
frontend/app_flowy/packages/flowy_editor/lib/service/internal_key_event_handlers/delele_text_handler.dart

@@ -39,12 +39,7 @@ FlowyKeyEventHandler deleteTextHandler = (editorState, event) {
             final previous = textNode.previous as TextNode;
             transactionBuilder
               ..deleteNode(textNode)
-              ..insertText(
-                previous,
-                previous.toRawString().length,
-                textNode.toRawString(),
-              );
-            // FIXME: keep the attributes.
+              ..mergeText(previous, textNode);
             break;
           }
         }
@@ -66,17 +61,18 @@ FlowyKeyEventHandler deleteTextHandler = (editorState, event) {
     }
   } else {
     final first = textNodes.first;
+    final last = textNodes.last;
     var content = textNodes.last.toRawString();
     content = content.substring(selection.end.offset, content.length);
     // Merge the fist and the last text node content,
     //  and delete the all nodes expect for the first.
     transactionBuilder
       ..deleteNodes(textNodes.sublist(1))
-      ..replaceText(
+      ..mergeText(
         first,
-        selection.start.offset,
-        first.toRawString().length - selection.start.offset,
-        content,
+        last,
+        firstOffset: selection.start.offset,
+        secondOffset: selection.end.offset,
       );
   }