From 2e2de297899a7332db607447fbd78a71323fce8c Mon Sep 17 00:00:00 2001 From: Vincent Chan Date: Mon, 1 Aug 2022 11:34:35 +0800 Subject: [PATCH 1/4] feat: transaction to json --- .../flowy_editor/lib/document/position.dart | 7 +++ .../flowy_editor/lib/document/selection.dart | 7 +++ .../flowy_editor/lib/operation/operation.dart | 39 ++++++++++++++++ .../lib/operation/transaction.dart | 13 ++++++ .../flowy_editor/test/operation_test.dart | 44 +++++++++++++++++++ 5 files changed, 110 insertions(+) diff --git a/frontend/app_flowy/packages/flowy_editor/lib/document/position.dart b/frontend/app_flowy/packages/flowy_editor/lib/document/position.dart index a60f04e89b..a87064d85a 100644 --- a/frontend/app_flowy/packages/flowy_editor/lib/document/position.dart +++ b/frontend/app_flowy/packages/flowy_editor/lib/document/position.dart @@ -34,4 +34,11 @@ class Position { @override String toString() => 'path = $path, offset = $offset'; + + Map toJson() { + return { + "path": path.toList(), + "offset": offset, + }; + } } diff --git a/frontend/app_flowy/packages/flowy_editor/lib/document/selection.dart b/frontend/app_flowy/packages/flowy_editor/lib/document/selection.dart index a3919a21f6..f1fa0682f6 100644 --- a/frontend/app_flowy/packages/flowy_editor/lib/document/selection.dart +++ b/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 toJson() { + return { + "start": start.toJson(), + "end": end.toJson(), + }; + } } diff --git a/frontend/app_flowy/packages/flowy_editor/lib/operation/operation.dart b/frontend/app_flowy/packages/flowy_editor/lib/operation/operation.dart index eafa4a31da..e4d2c1d8ed 100644 --- a/frontend/app_flowy/packages/flowy_editor/lib/operation/operation.dart +++ b/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 toJson(); } class InsertOperation extends Operation { @@ -29,6 +30,15 @@ class InsertOperation extends Operation { removedValue: value, ); } + + @override + Map 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 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 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 toJson() { + return { + "type": "text-edit-operation", + "path": path.toList(), + "delta": delta.toJson(), + "invert": inverted.toJson(), + }; + } } Path transformPath(Path preInsertPath, Path b, [int delta = 1]) { diff --git a/frontend/app_flowy/packages/flowy_editor/lib/operation/transaction.dart b/frontend/app_flowy/packages/flowy_editor/lib/operation/transaction.dart index 85bc43f537..5dcf167628 100644 --- a/frontend/app_flowy/packages/flowy_editor/lib/operation/transaction.dart +++ b/frontend/app_flowy/packages/flowy_editor/lib/operation/transaction.dart @@ -23,4 +23,17 @@ class Transaction { this.beforeSelection, this.afterSelection, }); + + Map toJson() { + final Map result = { + "operations": operations.map((e) => e.toJson()), + }; + if (beforeSelection != null) { + result["beforeSelection"] = beforeSelection!.toJson(); + } + if (afterSelection != null) { + result["afterSelection"] = afterSelection!.toJson(); + } + return result; + } } diff --git a/frontend/app_flowy/packages/flowy_editor/test/operation_test.dart b/frontend/app_flowy/packages/flowy_editor/test/operation_test.dart index b0b6cec141..a027fa8027 100644 --- a/frontend/app_flowy/packages/flowy_editor/test/operation_test.dart +++ b/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(), + } + ], + }); + }); + }); } From 5e86b83eee8ae7395d2affde5692ef1b49b56bb6 Mon Sep 17 00:00:00 2001 From: Vincent Chan Date: Mon, 1 Aug 2022 12:41:51 +0800 Subject: [PATCH 2/4] feat: fromJson --- .../packages/flowy_editor/lib/operation/operation.dart | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/frontend/app_flowy/packages/flowy_editor/lib/operation/operation.dart b/frontend/app_flowy/packages/flowy_editor/lib/operation/operation.dart index e4d2c1d8ed..d3b3144873 100644 --- a/frontend/app_flowy/packages/flowy_editor/lib/operation/operation.dart +++ b/frontend/app_flowy/packages/flowy_editor/lib/operation/operation.dart @@ -2,6 +2,16 @@ import 'package:flowy_editor/document/attributes.dart'; import 'package:flowy_editor/flowy_editor.dart'; abstract class Operation { + factory Operation.fromJson(Map map) { + String t = map["type"] as String; + if (t == "insert-operation") { + final path = map["path"] as List; + final value = Node.fromJson(map["value"]); + return InsertOperation(path: path, value: value); + } + + throw ArgumentError('unexpected type $t'); + } final Path path; Operation({required this.path}); Operation copyWithPath(Path path); From 46dba122bde150812e608b50d91ffce5d342ff9d Mon Sep 17 00:00:00 2001 From: Vincent Chan Date: Mon, 1 Aug 2022 12:58:32 +0800 Subject: [PATCH 3/4] refactor: remove named parameters --- .../flowy_editor/lib/operation/operation.dart | 104 +++++++++++------- .../lib/operation/transaction_builder.dart | 19 ++-- .../flowy_editor/test/operation_test.dart | 24 ++-- 3 files changed, 79 insertions(+), 68 deletions(-) diff --git a/frontend/app_flowy/packages/flowy_editor/lib/operation/operation.dart b/frontend/app_flowy/packages/flowy_editor/lib/operation/operation.dart index d3b3144873..a505df4b1d 100644 --- a/frontend/app_flowy/packages/flowy_editor/lib/operation/operation.dart +++ b/frontend/app_flowy/packages/flowy_editor/lib/operation/operation.dart @@ -5,15 +5,19 @@ abstract class Operation { factory Operation.fromJson(Map map) { String t = map["type"] as String; if (t == "insert-operation") { - final path = map["path"] as List; - final value = Node.fromJson(map["value"]); - return InsertOperation(path: path, value: value); + return InsertOperation.fromJson(map); + } else if (t == "update-operation") { + return UpdateOperation.fromJson(map); + } else if (t == "delete-operation") { + return DeleteOperation.fromJson(map); + } else if (t == "text-edit-operation") { + return TextEditOperation.fromJson(map); } throw ArgumentError('unexpected type $t'); } final Path path; - Operation({required this.path}); + Operation(this.path); Operation copyWithPath(Path path); Operation invert(); Map toJson(); @@ -22,13 +26,16 @@ abstract class Operation { class InsertOperation extends Operation { final Node value; - InsertOperation({ - required super.path, - required this.value, - }); + factory InsertOperation.fromJson(Map map) { + final path = map["path"] as List; + final value = Node.fromJson(map["value"]); + return InsertOperation(path, value); + } + + InsertOperation(Path path, this.value) : super(path); InsertOperation copyWith({Path? path, Node? value}) => - InsertOperation(path: path ?? this.path, value: value ?? this.value); + InsertOperation(path ?? this.path, value ?? this.value); @override Operation copyWithPath(Path path) => copyWith(path: path); @@ -36,8 +43,8 @@ class InsertOperation extends Operation { @override Operation invert() { return DeleteOperation( - path: path, - removedValue: value, + path, + value, ); } @@ -55,18 +62,23 @@ class UpdateOperation extends Operation { final Attributes attributes; final Attributes oldAttributes; - UpdateOperation({ - required super.path, - required this.attributes, - required this.oldAttributes, - }); + factory UpdateOperation.fromJson(Map map) { + final path = map["path"] as List; + final attributes = map["attributes"] as Map; + final oldAttributes = map["oldAttributes"] as Map; + return UpdateOperation(path, attributes, oldAttributes); + } + + UpdateOperation( + Path path, + this.attributes, + this.oldAttributes, + ) : super(path); UpdateOperation copyWith( {Path? path, Attributes? attributes, Attributes? oldAttributes}) => - UpdateOperation( - path: path ?? this.path, - attributes: attributes ?? this.attributes, - oldAttributes: oldAttributes ?? this.oldAttributes); + UpdateOperation(path ?? this.path, attributes ?? this.attributes, + oldAttributes ?? this.oldAttributes); @override Operation copyWithPath(Path path) => copyWith(path: path); @@ -74,9 +86,9 @@ class UpdateOperation extends Operation { @override Operation invert() { return UpdateOperation( - path: path, - attributes: oldAttributes, - oldAttributes: attributes, + path, + oldAttributes, + attributes, ); } @@ -94,23 +106,26 @@ class UpdateOperation extends Operation { class DeleteOperation extends Operation { final Node removedValue; - DeleteOperation({ - required super.path, - required this.removedValue, - }); + factory DeleteOperation.fromJson(Map map) { + final path = map["path"] as List; + final removedValue = Node.fromJson(map["removedValue"]); + return DeleteOperation(path, removedValue); + } - DeleteOperation copyWith({Path? path, Node? removedValue}) => DeleteOperation( - path: path ?? this.path, removedValue: removedValue ?? this.removedValue); + DeleteOperation( + Path path, + this.removedValue, + ) : super(path); + + DeleteOperation copyWith({Path? path, Node? removedValue}) => + DeleteOperation(path ?? this.path, removedValue ?? this.removedValue); @override Operation copyWithPath(Path path) => copyWith(path: path); @override Operation invert() { - return InsertOperation( - path: path, - value: removedValue, - ); + return InsertOperation(path, removedValue); } @override @@ -127,24 +142,29 @@ class TextEditOperation extends Operation { final Delta delta; final Delta inverted; - TextEditOperation({ - required super.path, - required this.delta, - required this.inverted, - }); + factory TextEditOperation.fromJson(Map map) { + final path = map["path"] as List; + final delta = Delta.fromJson(map["delta"]); + final invert = Delta.fromJson(map["invert"]); + return TextEditOperation(path, delta, invert); + } + + TextEditOperation( + Path path, + this.delta, + this.inverted, + ) : super(path); TextEditOperation copyWith({Path? path, Delta? delta, Delta? inverted}) => TextEditOperation( - path: path ?? this.path, - delta: delta ?? this.delta, - inverted: inverted ?? this.inverted); + path ?? this.path, delta ?? this.delta, inverted ?? this.inverted); @override Operation copyWithPath(Path path) => copyWith(path: path); @override Operation invert() { - return TextEditOperation(path: path, delta: inverted, inverted: delta); + return TextEditOperation(path, inverted, delta); } @override diff --git a/frontend/app_flowy/packages/flowy_editor/lib/operation/transaction_builder.dart b/frontend/app_flowy/packages/flowy_editor/lib/operation/transaction_builder.dart index fb042fe566..2877e62588 100644 --- a/frontend/app_flowy/packages/flowy_editor/lib/operation/transaction_builder.dart +++ b/frontend/app_flowy/packages/flowy_editor/lib/operation/transaction_builder.dart @@ -1,5 +1,4 @@ import 'dart:collection'; -import 'dart:math'; import 'package:flowy_editor/editor_state.dart'; import 'package:flowy_editor/document/node.dart'; import 'package:flowy_editor/document/path.dart'; @@ -31,21 +30,21 @@ class TransactionBuilder { insertNode(Path path, Node node) { beforeSelection = state.cursorSelection; - add(InsertOperation(path: path, value: node)); + add(InsertOperation(path, node)); } updateNode(Node node, Attributes attributes) { beforeSelection = state.cursorSelection; add(UpdateOperation( - path: node.path, - attributes: Attributes.from(node.attributes)..addAll(attributes), - oldAttributes: node.attributes, + node.path, + Attributes.from(node.attributes)..addAll(attributes), + node.attributes, )); } deleteNode(Node node) { beforeSelection = state.cursorSelection; - add(DeleteOperation(path: node.path, removedValue: node)); + add(DeleteOperation(node.path, node)); } textEdit(TextNode node, Delta Function() f) { @@ -56,7 +55,7 @@ class TransactionBuilder { final inverted = delta.invert(node.delta); - add(TextEditOperation(path: path, delta: delta, inverted: inverted)); + add(TextEditOperation(path, delta, inverted)); } insertText(TextNode node, int index, String content) { @@ -82,9 +81,9 @@ class TransactionBuilder { last is TextEditOperation && pathEquals(op.path, last.path)) { final newOp = TextEditOperation( - path: op.path, - delta: last.delta.compose(op.delta), - inverted: op.inverted.compose(last.inverted), + op.path, + last.delta.compose(op.delta), + op.inverted.compose(last.inverted), ); operations[operations.length - 1] = newOp; return; diff --git a/frontend/app_flowy/packages/flowy_editor/test/operation_test.dart b/frontend/app_flowy/packages/flowy_editor/test/operation_test.dart index a027fa8027..c6811b86e2 100644 --- a/frontend/app_flowy/packages/flowy_editor/test/operation_test.dart +++ b/frontend/app_flowy/packages/flowy_editor/test/operation_test.dart @@ -27,26 +27,18 @@ void main() { group('transform operation', () { test('insert + insert', () { final t = transformOperation( - InsertOperation(path: [ - 0, - 1 - ], value: Node(type: "node", attributes: {}, children: LinkedList())), - InsertOperation( - path: [0, 1], - value: - Node(type: "node", attributes: {}, children: LinkedList()))); + InsertOperation([0, 1], + Node(type: "node", attributes: {}, children: LinkedList())), + InsertOperation([0, 1], + Node(type: "node", attributes: {}, children: LinkedList()))); expect(t.path, [0, 2]); }); test('delete + delete', () { final t = transformOperation( - DeleteOperation( - path: [0, 1], - removedValue: - Node(type: "node", attributes: {}, children: LinkedList())), - DeleteOperation( - path: [0, 2], - removedValue: - Node(type: "node", attributes: {}, children: LinkedList()))); + DeleteOperation([0, 1], + Node(type: "node", attributes: {}, children: LinkedList())), + DeleteOperation([0, 2], + Node(type: "node", attributes: {}, children: LinkedList()))); expect(t.path, [0, 1]); }); }); From 2f58c54b81e01e302f6baea218cba549f91a6b87 Mon Sep 17 00:00:00 2001 From: Vincent Chan Date: Mon, 1 Aug 2022 17:36:31 +0800 Subject: [PATCH 4/4] refactor: batch insert and delete nodes --- .../flowy_editor/lib/document/state_tree.dart | 22 +++++++++---- .../flowy_editor/lib/editor_state.dart | 4 +-- .../flowy_editor/lib/operation/operation.dart | 32 ++++++++++--------- .../lib/operation/transaction_builder.dart | 24 ++++++++++++-- .../flowy_editor/test/flowy_editor_test.dart | 7 ++-- .../flowy_editor/test/operation_test.dart | 12 +++---- 6 files changed, 63 insertions(+), 38 deletions(-) diff --git a/frontend/app_flowy/packages/flowy_editor/lib/document/state_tree.dart b/frontend/app_flowy/packages/flowy_editor/lib/document/state_tree.dart index 22f4b88c24..cf49f48ac8 100644 --- a/frontend/app_flowy/packages/flowy_editor/lib/document/state_tree.dart +++ b/frontend/app_flowy/packages/flowy_editor/lib/document/state_tree.dart @@ -22,17 +22,21 @@ class StateTree { return root.childAtPath(path); } - bool insert(Path path, Node node) { + bool insert(Path path, List nodes) { if (path.isEmpty) { return false; } - final insertedNode = root.childAtPath( + Node? insertedNode = root.childAtPath( path.sublist(0, path.length - 1) + [path.last - 1], ); if (insertedNode == null) { return false; } - insertedNode.insertAfter(node); + for (var i = 0; i < nodes.length; i++) { + final node = nodes[i]; + insertedNode!.insertAfter(node); + insertedNode = node; + } return true; } @@ -48,13 +52,17 @@ class StateTree { return false; } - Node? delete(Path path) { + delete(Path path, [int length = 1]) { if (path.isEmpty) { return null; } - final deletedNode = root.childAtPath(path); - deletedNode?.unlink(); - return deletedNode; + var deletedNode = root.childAtPath(path); + while (deletedNode != null && length > 0) { + final next = deletedNode.next; + deletedNode.unlink(); + length--; + deletedNode = next; + } } Attributes? update(Path path, Attributes attributes) { diff --git a/frontend/app_flowy/packages/flowy_editor/lib/editor_state.dart b/frontend/app_flowy/packages/flowy_editor/lib/editor_state.dart index 1019ad3510..277b742604 100644 --- a/frontend/app_flowy/packages/flowy_editor/lib/editor_state.dart +++ b/frontend/app_flowy/packages/flowy_editor/lib/editor_state.dart @@ -94,11 +94,11 @@ class EditorState { _applyOperation(Operation op) { if (op is InsertOperation) { - document.insert(op.path, op.value); + document.insert(op.path, op.nodes); } else if (op is UpdateOperation) { document.update(op.path, op.attributes); } else if (op is DeleteOperation) { - document.delete(op.path); + document.delete(op.path, op.nodes.length); } else if (op is TextEditOperation) { document.textEdit(op.path, op.delta); } diff --git a/frontend/app_flowy/packages/flowy_editor/lib/operation/operation.dart b/frontend/app_flowy/packages/flowy_editor/lib/operation/operation.dart index a505df4b1d..e07c196768 100644 --- a/frontend/app_flowy/packages/flowy_editor/lib/operation/operation.dart +++ b/frontend/app_flowy/packages/flowy_editor/lib/operation/operation.dart @@ -24,18 +24,19 @@ abstract class Operation { } class InsertOperation extends Operation { - final Node value; + final List nodes; factory InsertOperation.fromJson(Map map) { final path = map["path"] as List; - final value = Node.fromJson(map["value"]); + final value = + (map["nodes"] as List).map((n) => Node.fromJson(n)).toList(); return InsertOperation(path, value); } - InsertOperation(Path path, this.value) : super(path); + InsertOperation(Path path, this.nodes) : super(path); - InsertOperation copyWith({Path? path, Node? value}) => - InsertOperation(path ?? this.path, value ?? this.value); + InsertOperation copyWith({Path? path, List? nodes}) => + InsertOperation(path ?? this.path, nodes ?? this.nodes); @override Operation copyWithPath(Path path) => copyWith(path: path); @@ -44,7 +45,7 @@ class InsertOperation extends Operation { Operation invert() { return DeleteOperation( path, - value, + nodes, ); } @@ -53,7 +54,7 @@ class InsertOperation extends Operation { return { "type": "insert-operation", "path": path.toList(), - "value": value.toJson(), + "nodes": nodes.map((n) => n.toJson()), }; } } @@ -104,28 +105,29 @@ class UpdateOperation extends Operation { } class DeleteOperation extends Operation { - final Node removedValue; + final List nodes; factory DeleteOperation.fromJson(Map map) { final path = map["path"] as List; - final removedValue = Node.fromJson(map["removedValue"]); - return DeleteOperation(path, removedValue); + final List nodes = + (map["nodes"] as List).map((e) => Node.fromJson(e)).toList(); + return DeleteOperation(path, nodes); } DeleteOperation( Path path, - this.removedValue, + this.nodes, ) : super(path); - DeleteOperation copyWith({Path? path, Node? removedValue}) => - DeleteOperation(path ?? this.path, removedValue ?? this.removedValue); + DeleteOperation copyWith({Path? path, List? nodes}) => + DeleteOperation(path ?? this.path, nodes ?? this.nodes); @override Operation copyWithPath(Path path) => copyWith(path: path); @override Operation invert() { - return InsertOperation(path, removedValue); + return InsertOperation(path, nodes); } @override @@ -133,7 +135,7 @@ class DeleteOperation extends Operation { return { "type": "delete-operation", "path": path.toList(), - "removedValue": removedValue.toJson(), + "nodes": nodes.map((n) => n.toJson()), }; } } diff --git a/frontend/app_flowy/packages/flowy_editor/lib/operation/transaction_builder.dart b/frontend/app_flowy/packages/flowy_editor/lib/operation/transaction_builder.dart index 3b88ed1627..ac7fd4353f 100644 --- a/frontend/app_flowy/packages/flowy_editor/lib/operation/transaction_builder.dart +++ b/frontend/app_flowy/packages/flowy_editor/lib/operation/transaction_builder.dart @@ -29,8 +29,12 @@ class TransactionBuilder { } insertNode(Path path, Node node) { + insertNodes(path, [node]); + } + + insertNodes(Path path, List nodes) { beforeSelection = state.cursorSelection; - add(InsertOperation(path, node)); + add(InsertOperation(path, nodes)); } updateNode(Node node, Attributes attributes) { @@ -43,14 +47,28 @@ class TransactionBuilder { } deleteNode(Node node) { - beforeSelection = state.cursorSelection; - add(DeleteOperation(node.path, node)); + deleteNodesAtPath(node.path); } deleteNodes(List nodes) { nodes.forEach(deleteNode); } + deleteNodesAtPath(Path path, [int length = 1]) { + if (path.isEmpty) { + return; + } + final nodes = []; + final prefix = path.sublist(0, path.length - 1); + final last = path.last; + for (var i = 0; i < length; i++) { + final node = state.document.nodeAtPath(prefix + [last + i])!; + nodes.add(node); + } + + add(DeleteOperation(path, nodes)); + } + textEdit(TextNode node, Delta Function() f) { beforeSelection = state.cursorSelection; final path = node.path; diff --git a/frontend/app_flowy/packages/flowy_editor/test/flowy_editor_test.dart b/frontend/app_flowy/packages/flowy_editor/test/flowy_editor_test.dart index 16ccadb079..49d0fd00f5 100644 --- a/frontend/app_flowy/packages/flowy_editor/test/flowy_editor_test.dart +++ b/frontend/app_flowy/packages/flowy_editor/test/flowy_editor_test.dart @@ -1,5 +1,4 @@ import 'dart:convert'; -import 'dart:math'; import 'package:flowy_editor/document/node.dart'; import 'package:flowy_editor/document/state_tree.dart'; @@ -50,7 +49,7 @@ void main() { final insertNode = Node.fromJson({ 'type': 'text', }); - bool result = stateTree.insert([1, 1], insertNode); + bool result = stateTree.insert([1, 1], [insertNode]); expect(result, true); expect(identical(insertNode, stateTree.nodeAtPath([1, 1])), true); }); @@ -59,9 +58,7 @@ void main() { final String response = await rootBundle.loadString('assets/document.json'); final data = Map.from(json.decode(response)); final stateTree = StateTree.fromJson(data); - final deletedNode = stateTree.delete([1, 1]); - expect(deletedNode != null, true); - expect(deletedNode!.attributes['text-type'], 'checkbox'); + stateTree.delete([1, 1], 1); final node = stateTree.nodeAtPath([1, 1]); expect(node != null, true); expect(node!.attributes['tag'], '**'); diff --git a/frontend/app_flowy/packages/flowy_editor/test/operation_test.dart b/frontend/app_flowy/packages/flowy_editor/test/operation_test.dart index c6811b86e2..7507cb65bf 100644 --- a/frontend/app_flowy/packages/flowy_editor/test/operation_test.dart +++ b/frontend/app_flowy/packages/flowy_editor/test/operation_test.dart @@ -28,17 +28,17 @@ void main() { test('insert + insert', () { final t = transformOperation( InsertOperation([0, 1], - Node(type: "node", attributes: {}, children: LinkedList())), + [Node(type: "node", attributes: {}, children: LinkedList())]), InsertOperation([0, 1], - Node(type: "node", attributes: {}, children: LinkedList()))); + [Node(type: "node", attributes: {}, children: LinkedList())])); expect(t.path, [0, 2]); }); test('delete + delete', () { final t = transformOperation( DeleteOperation([0, 1], - Node(type: "node", attributes: {}, children: LinkedList())), + [Node(type: "node", attributes: {}, children: LinkedList())]), DeleteOperation([0, 2], - Node(type: "node", attributes: {}, children: LinkedList()))); + [Node(type: "node", attributes: {}, children: LinkedList())])); expect(t.path, [0, 1]); }); }); @@ -85,7 +85,7 @@ void main() { { "type": "insert-operation", "path": [0], - "value": item1.toJson(), + "nodes": [item1.toJson()], } ], }); @@ -108,7 +108,7 @@ void main() { { "type": "delete-operation", "path": [0], - "removedValue": item1.toJson(), + "nodes": [item1.toJson()], } ], });