ソースを参照

feat: transaction to json

Vincent Chan 2 年 前
コミット
2e2de29789

+ 7 - 0
frontend/app_flowy/packages/flowy_editor/lib/document/position.dart

@@ -34,4 +34,11 @@ class Position {
 
   @override
   String toString() => 'path = $path, offset = $offset';
+
+  Map<String, dynamic> toJson() {
+    return {
+      "path": path.toList(),
+      "offset": offset,
+    };
+  }
 }

+ 7 - 0
frontend/app_flowy/packages/flowy_editor/lib/document/selection.dart

@@ -48,4 +48,11 @@ class Selection {
 
   @override
   String toString() => '[Selection] start = $start, end = $end';
+
+  Map<String, dynamic> toJson() {
+    return {
+      "start": start.toJson(),
+      "end": end.toJson(),
+    };
+  }
 }

+ 39 - 0
frontend/app_flowy/packages/flowy_editor/lib/operation/operation.dart

@@ -6,6 +6,7 @@ abstract class Operation {
   Operation({required this.path});
   Operation copyWithPath(Path path);
   Operation invert();
+  Map<String, dynamic> toJson();
 }
 
 class InsertOperation extends Operation {
@@ -29,6 +30,15 @@ class InsertOperation extends Operation {
       removedValue: value,
     );
   }
+
+  @override
+  Map<String, dynamic> toJson() {
+    return {
+      "type": "insert-operation",
+      "path": path.toList(),
+      "value": value.toJson(),
+    };
+  }
 }
 
 class UpdateOperation extends Operation {
@@ -59,6 +69,16 @@ class UpdateOperation extends Operation {
       oldAttributes: attributes,
     );
   }
+
+  @override
+  Map<String, dynamic> toJson() {
+    return {
+      "type": "update-operation",
+      "path": path.toList(),
+      "attributes": {...attributes},
+      "oldAttributes": {...oldAttributes},
+    };
+  }
 }
 
 class DeleteOperation extends Operation {
@@ -82,6 +102,15 @@ class DeleteOperation extends Operation {
       value: removedValue,
     );
   }
+
+  @override
+  Map<String, dynamic> toJson() {
+    return {
+      "type": "delete-operation",
+      "path": path.toList(),
+      "removedValue": removedValue.toJson(),
+    };
+  }
 }
 
 class TextEditOperation extends Operation {
@@ -107,6 +136,16 @@ class TextEditOperation extends Operation {
   Operation invert() {
     return TextEditOperation(path: path, delta: inverted, inverted: delta);
   }
+
+  @override
+  Map<String, dynamic> toJson() {
+    return {
+      "type": "text-edit-operation",
+      "path": path.toList(),
+      "delta": delta.toJson(),
+      "invert": inverted.toJson(),
+    };
+  }
 }
 
 Path transformPath(Path preInsertPath, Path b, [int delta = 1]) {

+ 13 - 0
frontend/app_flowy/packages/flowy_editor/lib/operation/transaction.dart

@@ -23,4 +23,17 @@ class Transaction {
     this.beforeSelection,
     this.afterSelection,
   });
+
+  Map<String, dynamic> toJson() {
+    final Map<String, dynamic> result = {
+      "operations": operations.map((e) => e.toJson()),
+    };
+    if (beforeSelection != null) {
+      result["beforeSelection"] = beforeSelection!.toJson();
+    }
+    if (afterSelection != null) {
+      result["afterSelection"] = afterSelection!.toJson();
+    }
+    return result;
+  }
 }

+ 44 - 0
frontend/app_flowy/packages/flowy_editor/test/operation_test.dart

@@ -78,4 +78,48 @@ void main() {
     expect(transaction.operations[1].path, [0]);
     expect(transaction.operations[2].path, [0]);
   });
+  group("toJson", () {
+    test("insert", () {
+      final root = Node(type: "root", attributes: {}, children: LinkedList());
+      final state = EditorState(document: StateTree(root: root));
+
+      final item1 = Node(type: "node", attributes: {}, children: LinkedList());
+      final tb = TransactionBuilder(state);
+      tb.insertNode([0], item1);
+
+      final transaction = tb.finish();
+      expect(transaction.toJson(), {
+        "operations": [
+          {
+            "type": "insert-operation",
+            "path": [0],
+            "value": item1.toJson(),
+          }
+        ],
+      });
+    });
+    test("delete", () {
+      final item1 = Node(type: "node", attributes: {}, children: LinkedList());
+      final root = Node(
+          type: "root",
+          attributes: {},
+          children: LinkedList()
+            ..addAll([
+              item1,
+            ]));
+      final state = EditorState(document: StateTree(root: root));
+      final tb = TransactionBuilder(state);
+      tb.deleteNode(item1);
+      final transaction = tb.finish();
+      expect(transaction.toJson(), {
+        "operations": [
+          {
+            "type": "delete-operation",
+            "path": [0],
+            "removedValue": item1.toJson(),
+          }
+        ],
+      });
+    });
+  });
 }