Browse Source

refactor: move node_iterator to core/document

Lucas.Xu 2 years ago
parent
commit
7f92f8988f

+ 22 - 24
frontend/app_flowy/packages/appflowy_editor/lib/src/document/node_iterator.dart → frontend/app_flowy/packages/appflowy_editor/lib/src/core/document/node_iterator.dart

@@ -1,23 +1,28 @@
 import 'package:appflowy_editor/src/core/document/node.dart';
-
-import './state_tree.dart';
+import 'package:appflowy_editor/src/document/state_tree.dart';
 
 /// [NodeIterator] is used to traverse the nodes in visual order.
 class NodeIterator implements Iterator<Node> {
+  NodeIterator({
+    required this.stateTree,
+    required this.startNode,
+    this.endNode,
+  });
+
   final StateTree stateTree;
-  final Node _startNode;
-  final Node? _endNode;
+  final Node startNode;
+  final Node? endNode;
+
   Node? _currentNode;
   bool _began = false;
 
-  NodeIterator(this.stateTree, Node startNode, [Node? endNode])
-      : _startNode = startNode,
-        _endNode = endNode;
+  @override
+  Node get current => _currentNode!;
 
   @override
   bool moveNext() {
     if (!_began) {
-      _currentNode = _startNode;
+      _currentNode = startNode;
       _began = true;
       return true;
     }
@@ -27,7 +32,7 @@ class NodeIterator implements Iterator<Node> {
       return false;
     }
 
-    if (_endNode != null && _endNode == node) {
+    if (endNode != null && endNode == node) {
       _currentNode = null;
       return false;
     }
@@ -42,32 +47,25 @@ class NodeIterator implements Iterator<Node> {
       if (nextOfParent == null) {
         _currentNode = null;
       } else {
-        _currentNode = _findLeadingChild(nextOfParent);
+        _currentNode = nextOfParent;
       }
     }
 
     return _currentNode != null;
   }
 
-  Node _findLeadingChild(Node node) {
-    while (node.children.isNotEmpty) {
-      node = node.children.first;
-    }
-    return node;
-  }
-
-  @override
-  Node get current {
-    return _currentNode!;
-  }
-
   List<Node> toList() {
     final result = <Node>[];
-
     while (moveNext()) {
       result.add(current);
     }
-
     return result;
   }
+
+  Node _findLeadingChild(Node node) {
+    while (node.children.isNotEmpty) {
+      node = node.children.first;
+    }
+    return node;
+  }
 }

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

@@ -1,6 +1,6 @@
 import 'package:appflowy_editor/appflowy_editor.dart';
 import 'package:appflowy_editor/src/infra/html_converter.dart';
-import 'package:appflowy_editor/src/document/node_iterator.dart';
+import 'package:appflowy_editor/src/core/document/node_iterator.dart';
 import 'package:appflowy_editor/src/service/internal_key_event_handlers/number_list_helper.dart';
 import 'package:flutter/material.dart';
 import 'package:rich_clipboard/rich_clipboard.dart';
@@ -49,7 +49,11 @@ void _handleCopy(EditorState editorState) async {
   final beginNode = editorState.document.nodeAtPath(selection.start.path)!;
   final endNode = editorState.document.nodeAtPath(selection.end.path)!;
 
-  final nodes = NodeIterator(editorState.document, beginNode, endNode).toList();
+  final nodes = NodeIterator(
+    stateTree: editorState.document,
+    startNode: beginNode,
+    endNode: endNode,
+  ).toList();
 
   final copyString = NodesToHTMLConverter(
           nodes: nodes,
@@ -316,8 +320,11 @@ void _deleteSelectedContent(EditorState editorState) {
     tb.commit();
     return;
   }
-  final traverser = NodeIterator(editorState.document, beginNode, endNode);
-
+  final traverser = NodeIterator(
+    stateTree: editorState.document,
+    startNode: beginNode,
+    endNode: endNode,
+  );
   final tb = TransactionBuilder(editorState);
   while (traverser.moveNext()) {
     final item = traverser.current;

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

@@ -2,7 +2,7 @@ import 'package:appflowy_editor/src/infra/log.dart';
 import 'package:flutter/material.dart';
 
 import 'package:appflowy_editor/src/core/document/node.dart';
-import 'package:appflowy_editor/src/document/node_iterator.dart';
+import 'package:appflowy_editor/src/core/document/node_iterator.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';
@@ -179,8 +179,11 @@ class _AppFlowySelectionState extends State<AppFlowySelection>
     final startNode = editorState.document.nodeAtPath(start);
     final endNode = editorState.document.nodeAtPath(end);
     if (startNode != null && endNode != null) {
-      final nodes =
-          NodeIterator(editorState.document, startNode, endNode).toList();
+      final nodes = NodeIterator(
+        stateTree: editorState.document,
+        startNode: startNode,
+        endNode: endNode,
+      ).toList();
       if (selection.isBackward) {
         return nodes;
       } else {

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

@@ -0,0 +1,32 @@
+import 'package:appflowy_editor/appflowy_editor.dart';
+import 'package:appflowy_editor/src/core/document/node_iterator.dart';
+import 'package:flutter_test/flutter_test.dart';
+
+void main() async {
+  group('node_iterator.dart', () {
+    test('', () {
+      final root = Node(type: 'root');
+      for (var i = 1; i <= 10; i++) {
+        final node = Node(type: 'node_$i');
+        for (var j = 1; j <= i; j++) {
+          node.insert(Node(type: 'node_${i}_$j'));
+        }
+        root.insert(node);
+      }
+      final nodes = NodeIterator(
+        stateTree: StateTree(root: root),
+        startNode: root.childAtPath([0])!,
+        endNode: root.childAtPath([10, 10]),
+      );
+
+      for (var i = 1; i <= 10; i++) {
+        nodes.moveNext();
+        expect(nodes.current.type, 'node_$i');
+        for (var j = 1; j <= i; j++) {
+          nodes.moveNext();
+          expect(nodes.current.type, 'node_${i}_$j');
+        }
+      }
+    });
+  });
+}

+ 0 - 4
frontend/app_flowy/packages/appflowy_editor/test/core/document/node_test.dart

@@ -4,10 +4,6 @@ import 'package:appflowy_editor/appflowy_editor.dart';
 import 'package:flutter_test/flutter_test.dart';
 
 void main() async {
-  setUpAll(() {
-    TestWidgetsFlutterBinding.ensureInitialized();
-  });
-
   group('node.dart', () {
     test('test node copyWith', () {
       final node = Node(