Browse Source

refactor: move path to core/document

Lucas.Xu 2 years ago
parent
commit
b9788bce09
24 changed files with 108 additions and 56 deletions
  1. 1 2
      frontend/app_flowy/packages/appflowy_editor/lib/appflowy_editor.dart
  2. 1 1
      frontend/app_flowy/packages/appflowy_editor/lib/src/commands/edit_text.dart
  3. 1 1
      frontend/app_flowy/packages/appflowy_editor/lib/src/commands/format_built_in_text.dart
  4. 1 1
      frontend/app_flowy/packages/appflowy_editor/lib/src/commands/format_text.dart
  5. 1 1
      frontend/app_flowy/packages/appflowy_editor/lib/src/commands/text_command_infra.dart
  6. 1 1
      frontend/app_flowy/packages/appflowy_editor/lib/src/core/document/node.dart
  7. 12 6
      frontend/app_flowy/packages/appflowy_editor/lib/src/core/document/path.dart
  8. 0 7
      frontend/app_flowy/packages/appflowy_editor/lib/src/document/path.dart
  9. 2 2
      frontend/app_flowy/packages/appflowy_editor/lib/src/document/position.dart
  10. 2 3
      frontend/app_flowy/packages/appflowy_editor/lib/src/document/selection.dart
  11. 1 1
      frontend/app_flowy/packages/appflowy_editor/lib/src/document/state_tree.dart
  12. 1 1
      frontend/app_flowy/packages/appflowy_editor/lib/src/extensions/node_extensions.dart
  13. 3 4
      frontend/app_flowy/packages/appflowy_editor/lib/src/extensions/text_node_extensions.dart
  14. 2 2
      frontend/app_flowy/packages/appflowy_editor/lib/src/operation/transaction_builder.dart
  15. 2 2
      frontend/app_flowy/packages/appflowy_editor/lib/src/render/rich_text/flowy_rich_text.dart
  16. 1 1
      frontend/app_flowy/packages/appflowy_editor/lib/src/service/default_text_operations/format_rich_text_style.dart
  17. 2 2
      frontend/app_flowy/packages/appflowy_editor/lib/src/service/internal_key_event_handlers/copy_paste_handler.dart
  18. 1 1
      frontend/app_flowy/packages/appflowy_editor/lib/src/service/selection_service.dart
  19. 1 0
      frontend/app_flowy/packages/appflowy_editor/test/core/document/node_iterator_test.dart
  20. 34 12
      frontend/app_flowy/packages/appflowy_editor/test/core/document/node_test.dart
  21. 33 0
      frontend/app_flowy/packages/appflowy_editor/test/core/document/path_test.dart
  22. 1 1
      frontend/app_flowy/packages/appflowy_editor/test/extensions/path_extensions_test.dart
  23. 3 3
      frontend/app_flowy/packages/appflowy_editor/test/legacy/flowy_editor_test.dart
  24. 1 1
      frontend/app_flowy/packages/appflowy_editor/test/legacy/undo_manager_test.dart

+ 1 - 2
frontend/app_flowy/packages/appflowy_editor/lib/appflowy_editor.dart

@@ -4,7 +4,7 @@ library appflowy_editor;
 export 'src/infra/log.dart';
 export 'src/render/style/editor_style.dart';
 export 'src/core/document/node.dart';
-export 'src/document/path.dart';
+export 'src/core/document/path.dart';
 export 'src/document/position.dart';
 export 'src/document/selection.dart';
 export 'src/document/state_tree.dart';
@@ -28,7 +28,6 @@ export 'src/service/shortcut_event/keybinding.dart';
 export 'src/service/shortcut_event/shortcut_event.dart';
 export 'src/service/shortcut_event/shortcut_event_handler.dart';
 export 'src/extensions/attributes_extension.dart';
-export 'src/extensions/path_extensions.dart';
 export 'src/render/rich_text/default_selectable.dart';
 export 'src/render/rich_text/flowy_rich_text.dart';
 export 'src/render/selection_menu/selection_menu_widget.dart';

+ 1 - 1
frontend/app_flowy/packages/appflowy_editor/lib/src/commands/edit_text.dart

@@ -2,7 +2,7 @@ import 'dart:async';
 
 import 'package:appflowy_editor/src/commands/text_command_infra.dart';
 import 'package:appflowy_editor/src/core/document/node.dart';
-import 'package:appflowy_editor/src/document/path.dart';
+import 'package:appflowy_editor/src/core/document/path.dart';
 import 'package:appflowy_editor/src/editor_state.dart';
 import 'package:appflowy_editor/src/operation/transaction_builder.dart';
 import 'package:flutter/widgets.dart';

+ 1 - 1
frontend/app_flowy/packages/appflowy_editor/lib/src/commands/format_built_in_text.dart

@@ -3,7 +3,7 @@ import 'package:appflowy_editor/src/commands/text_command_infra.dart';
 import 'package:appflowy_editor/src/core/document/attributes.dart';
 import 'package:appflowy_editor/src/document/built_in_attribute_keys.dart';
 import 'package:appflowy_editor/src/core/document/node.dart';
-import 'package:appflowy_editor/src/document/path.dart';
+import 'package:appflowy_editor/src/core/document/path.dart';
 import 'package:appflowy_editor/src/document/selection.dart';
 import 'package:appflowy_editor/src/editor_state.dart';
 

+ 1 - 1
frontend/app_flowy/packages/appflowy_editor/lib/src/commands/format_text.dart

@@ -3,7 +3,7 @@ import 'dart:async';
 import 'package:appflowy_editor/src/commands/text_command_infra.dart';
 import 'package:appflowy_editor/src/core/document/attributes.dart';
 import 'package:appflowy_editor/src/core/document/node.dart';
-import 'package:appflowy_editor/src/document/path.dart';
+import 'package:appflowy_editor/src/core/document/path.dart';
 import 'package:appflowy_editor/src/document/selection.dart';
 import 'package:appflowy_editor/src/editor_state.dart';
 import 'package:appflowy_editor/src/operation/transaction_builder.dart';

+ 1 - 1
frontend/app_flowy/packages/appflowy_editor/lib/src/commands/text_command_infra.dart

@@ -1,5 +1,5 @@
 import 'package:appflowy_editor/src/core/document/node.dart';
-import 'package:appflowy_editor/src/document/path.dart';
+import 'package:appflowy_editor/src/core/document/path.dart';
 import 'package:appflowy_editor/src/document/selection.dart';
 import 'package:appflowy_editor/src/editor_state.dart';
 

+ 1 - 1
frontend/app_flowy/packages/appflowy_editor/lib/src/core/document/node.dart

@@ -3,8 +3,8 @@ import 'dart:collection';
 import 'package:flutter/material.dart';
 
 import 'package:appflowy_editor/src/core/document/attributes.dart';
+import 'package:appflowy_editor/src/core/document/path.dart';
 import 'package:appflowy_editor/src/document/built_in_attribute_keys.dart';
-import 'package:appflowy_editor/src/document/path.dart';
 import 'package:appflowy_editor/src/document/text_delta.dart';
 
 class Node extends ChangeNotifier with LinkedListEntry<Node> {

+ 12 - 6
frontend/app_flowy/packages/appflowy_editor/lib/src/extensions/path_extensions.dart → frontend/app_flowy/packages/appflowy_editor/lib/src/core/document/path.dart

@@ -1,17 +1,23 @@
-import 'package:appflowy_editor/src/document/path.dart';
-
 import 'dart:math';
 
+import 'package:flutter/foundation.dart';
+
+typedef Path = List<int>;
+
 extension PathExtensions on Path {
+  bool equals(Path other) {
+    return listEquals(this, other);
+  }
+
   bool operator >=(Path other) {
-    if (pathEquals(this, other)) {
+    if (equals(other)) {
       return true;
     }
     return this > other;
   }
 
   bool operator >(Path other) {
-    if (pathEquals(this, other)) {
+    if (equals(other)) {
       return false;
     }
     final length = min(this.length, other.length);
@@ -29,14 +35,14 @@ extension PathExtensions on Path {
   }
 
   bool operator <=(Path other) {
-    if (pathEquals(this, other)) {
+    if (equals(other)) {
       return true;
     }
     return this < other;
   }
 
   bool operator <(Path other) {
-    if (pathEquals(this, other)) {
+    if (equals(other)) {
       return false;
     }
     final length = min(this.length, other.length);

+ 0 - 7
frontend/app_flowy/packages/appflowy_editor/lib/src/document/path.dart

@@ -1,7 +0,0 @@
-import 'package:flutter/foundation.dart';
-
-typedef Path = List<int>;
-
-bool pathEquals(Path path1, Path path2) {
-  return listEquals(path1, path2);
-}

+ 2 - 2
frontend/app_flowy/packages/appflowy_editor/lib/src/document/position.dart

@@ -1,4 +1,4 @@
-import './path.dart';
+import 'package:appflowy_editor/src/core/document/path.dart';
 
 class Position {
   final Path path;
@@ -14,7 +14,7 @@ class Position {
     if (other is! Position) {
       return false;
     }
-    return pathEquals(path, other.path) && offset == other.offset;
+    return path.equals(other.path) && offset == other.offset;
   }
 
   @override

+ 2 - 3
frontend/app_flowy/packages/appflowy_editor/lib/src/document/selection.dart

@@ -1,6 +1,5 @@
-import 'package:appflowy_editor/src/document/path.dart';
+import 'package:appflowy_editor/src/core/document/path.dart';
 import 'package:appflowy_editor/src/document/position.dart';
-import 'package:appflowy_editor/src/extensions/path_extensions.dart';
 
 /// Selection represents the selected area or the cursor area in the editor.
 ///
@@ -38,7 +37,7 @@ class Selection {
   final Position end;
 
   bool get isCollapsed => start == end;
-  bool get isSingle => pathEquals(start.path, end.path);
+  bool get isSingle => start.path.equals(end.path);
   bool get isForward =>
       (start.path > end.path) || (isSingle && start.offset > end.offset);
   bool get isBackward =>

+ 1 - 1
frontend/app_flowy/packages/appflowy_editor/lib/src/document/state_tree.dart

@@ -1,7 +1,7 @@
 import 'dart:math';
 
 import 'package:appflowy_editor/src/core/document/node.dart';
-import 'package:appflowy_editor/src/document/path.dart';
+import 'package:appflowy_editor/src/core/document/path.dart';
 import 'package:appflowy_editor/src/document/text_delta.dart';
 import '../core/document/attributes.dart';
 

+ 1 - 1
frontend/app_flowy/packages/appflowy_editor/lib/src/extensions/node_extensions.dart

@@ -1,7 +1,7 @@
 import 'package:appflowy_editor/src/core/document/node.dart';
+import 'package:appflowy_editor/src/core/document/path.dart';
 import 'package:appflowy_editor/src/document/selection.dart';
 import 'package:appflowy_editor/src/extensions/object_extensions.dart';
-import 'package:appflowy_editor/src/extensions/path_extensions.dart';
 import 'package:appflowy_editor/src/render/selection/selectable.dart';
 import 'package:flutter/material.dart';
 

+ 3 - 4
frontend/app_flowy/packages/appflowy_editor/lib/src/extensions/text_node_extensions.dart

@@ -1,5 +1,5 @@
 import 'package:appflowy_editor/src/core/document/node.dart';
-import 'package:appflowy_editor/src/document/path.dart';
+import 'package:appflowy_editor/src/core/document/path.dart';
 import 'package:appflowy_editor/src/document/position.dart';
 import 'package:appflowy_editor/src/document/selection.dart';
 import 'package:appflowy_editor/src/document/text_delta.dart';
@@ -168,7 +168,7 @@ extension TextNodesExtension on List<TextNode> {
       for (var i = 0; i < length; i++) {
         final node = this[i];
         final Selection newSelection;
-        if (i == 0 && pathEquals(node.path, selection.start.path)) {
+        if (i == 0 && node.path.equals(selection.start.path)) {
           if (selection.isBackward) {
             newSelection = selection.copyWith(
               end: Position(path: node.path, offset: node.toPlainText().length),
@@ -178,8 +178,7 @@ extension TextNodesExtension on List<TextNode> {
               end: Position(path: node.path, offset: 0),
             );
           }
-        } else if (i == length - 1 &&
-            pathEquals(node.path, selection.end.path)) {
+        } else if (i == length - 1 && node.path.equals(selection.end.path)) {
           if (selection.isBackward) {
             newSelection = selection.copyWith(
               start: Position(path: node.path, offset: 0),

+ 2 - 2
frontend/app_flowy/packages/appflowy_editor/lib/src/operation/transaction_builder.dart

@@ -3,7 +3,7 @@ import 'dart:math';
 
 import 'package:appflowy_editor/src/core/document/attributes.dart';
 import 'package:appflowy_editor/src/core/document/node.dart';
-import 'package:appflowy_editor/src/document/path.dart';
+import 'package:appflowy_editor/src/core/document/path.dart';
 import 'package:appflowy_editor/src/document/position.dart';
 import 'package:appflowy_editor/src/document/selection.dart';
 import 'package:appflowy_editor/src/document/text_delta.dart';
@@ -197,7 +197,7 @@ class TransactionBuilder {
     if (last != null) {
       if (op is TextEditOperation &&
           last is TextEditOperation &&
-          pathEquals(op.path, last.path)) {
+          op.path.equals(last.path)) {
         final newOp = TextEditOperation(
           op.path,
           last.delta.compose(op.delta),

+ 2 - 2
frontend/app_flowy/packages/appflowy_editor/lib/src/render/rich_text/flowy_rich_text.dart

@@ -6,7 +6,7 @@ import 'package:flutter/material.dart';
 import 'package:flutter/rendering.dart';
 
 import 'package:appflowy_editor/src/core/document/node.dart';
-import 'package:appflowy_editor/src/document/path.dart';
+import 'package:appflowy_editor/src/core/document/path.dart';
 import 'package:appflowy_editor/src/document/position.dart';
 import 'package:appflowy_editor/src/document/selection.dart';
 import 'package:appflowy_editor/src/document/text_delta.dart';
@@ -123,7 +123,7 @@ class _FlowyRichTextState extends State<FlowyRichText> with SelectableMixin {
   @override
   List<Rect> getRectsInSelection(Selection selection) {
     assert(selection.isSingle &&
-        pathEquals(selection.start.path, widget.textNode.path));
+        selection.start.path.equals(widget.textNode.path));
 
     final textSelection = TextSelection(
       baseOffset: selection.start.offset,

+ 1 - 1
frontend/app_flowy/packages/appflowy_editor/lib/src/service/default_text_operations/format_rich_text_style.dart

@@ -1,10 +1,10 @@
 import 'package:appflowy_editor/src/core/document/attributes.dart';
 import 'package:appflowy_editor/src/core/document/node.dart';
+import 'package:appflowy_editor/src/core/document/path.dart';
 import 'package:appflowy_editor/src/document/position.dart';
 import 'package:appflowy_editor/src/document/selection.dart';
 import 'package:appflowy_editor/src/editor_state.dart';
 import 'package:appflowy_editor/src/extensions/text_node_extensions.dart';
-import 'package:appflowy_editor/src/extensions/path_extensions.dart';
 import 'package:appflowy_editor/src/operation/transaction_builder.dart';
 import 'package:appflowy_editor/src/document/built_in_attribute_keys.dart';
 

+ 2 - 2
frontend/app_flowy/packages/appflowy_editor/lib/src/service/internal_key_event_handlers/copy_paste_handler.dart

@@ -29,7 +29,7 @@ void _handleCopy(EditorState editorState) async {
   if (selection == null || selection.isCollapsed) {
     return;
   }
-  if (pathEquals(selection.start.path, selection.end.path)) {
+  if (selection.start.path.equals(selection.end.path)) {
     final nodeAtPath = editorState.document.nodeAtPath(selection.end.path)!;
     if (nodeAtPath.type == "text") {
       final textNode = nodeAtPath as TextNode;
@@ -306,7 +306,7 @@ void _deleteSelectedContent(EditorState editorState) {
   }
   final beginNode = editorState.document.nodeAtPath(selection.start.path)!;
   final endNode = editorState.document.nodeAtPath(selection.end.path)!;
-  if (pathEquals(selection.start.path, selection.end.path) &&
+  if (selection.start.path.equals(selection.end.path) &&
       beginNode.type == "text") {
     final textItem = beginNode as TextNode;
     final tb = TransactionBuilder(editorState);

+ 1 - 1
frontend/app_flowy/packages/appflowy_editor/lib/src/service/selection_service.dart

@@ -3,12 +3,12 @@ import 'package:flutter/material.dart';
 
 import 'package:appflowy_editor/src/core/document/node.dart';
 import 'package:appflowy_editor/src/core/document/node_iterator.dart';
+import 'package:appflowy_editor/src/core/document/path.dart';
 import 'package:appflowy_editor/src/document/position.dart';
 import 'package:appflowy_editor/src/document/selection.dart';
 import 'package:appflowy_editor/src/editor_state.dart';
 import 'package:appflowy_editor/src/extensions/node_extensions.dart';
 import 'package:appflowy_editor/src/extensions/object_extensions.dart';
-import 'package:appflowy_editor/src/extensions/path_extensions.dart';
 import 'package:appflowy_editor/src/render/selection/cursor_widget.dart';
 import 'package:appflowy_editor/src/render/selection/selectable.dart';
 import 'package:appflowy_editor/src/render/selection/selection_widget.dart';

+ 1 - 0
frontend/app_flowy/packages/appflowy_editor/test/core/document/node_iterator_test.dart

@@ -27,6 +27,7 @@ void main() async {
           expect(nodes.current.type, 'node_${i}_$j');
         }
       }
+      expect(nodes.moveNext(), false);
     });
   });
 }

+ 34 - 12
frontend/app_flowy/packages/appflowy_editor/test/core/document/node_test.dart

@@ -149,23 +149,23 @@ void main() async {
         type: 'base',
       );
 
-      // insert at the front
+      // insert at the front when node's children is empty
       final childA = Node(
         type: 'child',
       );
-      base.insert(childA, index: -1);
+      base.insert(childA);
       expect(
         identical(base.childAtIndex(0), childA),
         true,
       );
 
-      // insert at the last
+      // insert at the front
       final childB = Node(
         type: 'child',
       );
-      base.insert(childB, index: 1000);
+      base.insert(childB, index: -1);
       expect(
-        identical(base.childAtIndex(base.children.length - 1), childB),
+        identical(base.childAtIndex(0), childB),
         true,
       );
 
@@ -173,19 +173,39 @@ void main() async {
       final childC = Node(
         type: 'child',
       );
-      base.insert(childC);
+      base.insert(childC, index: 1000);
       expect(
         identical(base.childAtIndex(base.children.length - 1), childC),
         true,
       );
+
+      // insert at the last
+      final childD = Node(
+        type: 'child',
+      );
+      base.insert(childD);
+      expect(
+        identical(base.childAtIndex(base.children.length - 1), childD),
+        true,
+      );
+
+      // insert at the second
+      final childE = Node(
+        type: 'child',
+      );
+      base.insert(childE, index: 1);
+      expect(
+        identical(base.childAtIndex(1), childE),
+        true,
+      );
     });
 
     test('test fromJson', () {
       final node = Node.fromJson({
-        'type': 'example',
-        'attributes': {
-          'example': 'example',
-        },
+        'type': 'text',
+        'delta': [
+          {'insert': 'example'},
+        ],
         'children': [
           {
             'type': 'example',
@@ -195,8 +215,10 @@ void main() async {
           },
         ],
       });
-      expect(node.type, 'example');
-      expect(node.attributes, {'example': 'example'});
+      expect(node.type, 'text');
+      expect(node is TextNode, true);
+      expect((node as TextNode).delta.toPlainText(), 'example');
+      expect(node.attributes, {});
       expect(node.children.length, 1);
       expect(node.children.first.type, 'example');
       expect(node.children.first.attributes, {'example': 'example'});

+ 33 - 0
frontend/app_flowy/packages/appflowy_editor/test/core/document/path_test.dart

@@ -0,0 +1,33 @@
+import 'package:appflowy_editor/appflowy_editor.dart';
+import 'package:flutter_test/flutter_test.dart';
+
+void main() async {
+  group('path.dart', () {
+    test('test path equality', () {
+      var p1 = [0, 0];
+      var p2 = [0];
+
+      expect(p1 > p2, true);
+      expect(p1 >= p2, true);
+      expect(p1 < p2, false);
+      expect(p1 <= p2, false);
+
+      p1 = [1, 1, 2];
+      p2 = [1, 1, 3];
+
+      expect(p2 > p1, true);
+      expect(p2 >= p1, true);
+      expect(p2 < p1, false);
+      expect(p2 <= p1, false);
+
+      p1 = [2, 0, 1];
+      p2 = [2, 0, 1];
+
+      expect(p2 > p1, false);
+      expect(p1 > p2, false);
+      expect(p2 >= p1, true);
+      expect(p2 <= p1, true);
+      expect(p1.equals(p2), true);
+    });
+  });
+}

+ 1 - 1
frontend/app_flowy/packages/appflowy_editor/test/extensions/path_extensions_test.dart

@@ -31,7 +31,7 @@ void main() async {
       expect(p1 > p2, false);
       expect(p2 >= p1, true);
       expect(p2 <= p1, true);
-      expect(pathEquals(p1, p2), true);
+      expect(p1.equals(p2), true);
     });
   });
 }

+ 3 - 3
frontend/app_flowy/packages/appflowy_editor/test/legacy/flowy_editor_test.dart

@@ -1,4 +1,4 @@
-import 'package:appflowy_editor/src/document/path.dart';
+import 'package:appflowy_editor/src/core/document/path.dart';
 import 'package:appflowy_editor/src/document/position.dart';
 import 'package:appflowy_editor/src/document/selection.dart';
 import 'package:flutter_test/flutter_test.dart';
@@ -72,7 +72,7 @@ void main() {
   test('test path utils 1', () {
     final path1 = <int>[1];
     final path2 = <int>[1];
-    expect(pathEquals(path1, path2), true);
+    expect(path1.equals(path2), true);
 
     expect(Object.hashAll(path1), Object.hashAll(path2));
   });
@@ -80,7 +80,7 @@ void main() {
   test('test path utils 2', () {
     final path1 = <int>[1];
     final path2 = <int>[2];
-    expect(pathEquals(path1, path2), false);
+    expect(path1.equals(path2), false);
 
     expect(Object.hashAll(path1) != Object.hashAll(path2), true);
   });

+ 1 - 1
frontend/app_flowy/packages/appflowy_editor/test/legacy/undo_manager_test.dart

@@ -59,7 +59,7 @@ bool isInsertAndPathEqual(Operation operation, Path path, [String? content]) {
     return false;
   }
 
-  if (!pathEquals(operation.path, path)) {
+  if (!operation.path.equals(path)) {
     return false;
   }