Browse Source

refactor: from node traverser to node iterator

Vincent Chan 2 years ago
parent
commit
2eecda0483

+ 64 - 0
frontend/app_flowy/packages/flowy_editor/lib/document/node_iterator.dart

@@ -0,0 +1,64 @@
+import 'package:flowy_editor/document/node.dart';
+
+import './state_tree.dart';
+import './node.dart';
+
+/// [NodeIterator] is used to traverse the nodes in visual order.
+class NodeIterator implements Iterator<Node> {
+  final StateTree stateTree;
+  final Node _startNode;
+  final Node? _endNode;
+  Node? _currentNode;
+  bool _began = false;
+
+  NodeIterator(this.stateTree, Node startNode, [Node? endNode])
+      : _startNode = startNode,
+        _endNode = endNode;
+
+  @override
+  bool moveNext() {
+    if (!_began) {
+      _currentNode = _startNode;
+      _began = true;
+      return true;
+    }
+
+    final node = _currentNode;
+    if (node == null) {
+      return false;
+    }
+
+    if (_endNode != null && _endNode == node) {
+      _currentNode = null;
+      return false;
+    }
+
+    if (node.children.isNotEmpty) {
+      _currentNode = _findLeadingChild(node);
+    } else if (node.next != null) {
+      _currentNode = node.next!;
+    } else {
+      final parent = node.parent!;
+      final nextOfParent = parent.next;
+      if (nextOfParent == null) {
+        _currentNode = null;
+      } else {
+        _currentNode = _findLeadingChild(node);
+      }
+    }
+
+    return _currentNode != null;
+  }
+
+  Node _findLeadingChild(Node node) {
+    while (node.children.isNotEmpty) {
+      node = node.children.first;
+    }
+    return node;
+  }
+
+  @override
+  Node get current {
+    return _currentNode!;
+  }
+}

+ 0 - 42
frontend/app_flowy/packages/flowy_editor/lib/document/node_traverser.dart

@@ -1,42 +0,0 @@
-import 'package:flowy_editor/document/node.dart';
-
-import './state_tree.dart';
-import './node.dart';
-
-/// [NodeTraverser] is used to traverse the nodes in visual order.
-class NodeTraverser {
-  final StateTree stateTree;
-  Node? currentNode;
-
-  NodeTraverser(this.stateTree, Node beginNode) : currentNode = beginNode;
-
-  Node? next() {
-    final node = currentNode;
-    if (node == null) {
-      return null;
-    }
-
-    if (node.children.isNotEmpty) {
-      currentNode = _findLeadingChild(node);
-    } else if (node.next != null) {
-      currentNode = node.next!;
-    } else {
-      final parent = node.parent!;
-      final nextOfParent = parent.next;
-      if (nextOfParent == null) {
-        currentNode = null;
-      } else {
-        currentNode = _findLeadingChild(node);
-      }
-    }
-
-    return node;
-  }
-
-  Node _findLeadingChild(Node node) {
-    while (node.children.isNotEmpty) {
-      node = node.children.first;
-    }
-    return node;
-  }
-}

+ 4 - 7
frontend/app_flowy/packages/flowy_editor/lib/service/internal_key_event_handlers/copy_paste_handler.dart

@@ -1,7 +1,7 @@
 import 'package:flowy_editor/flowy_editor.dart';
 import 'package:flowy_editor/service/keyboard_service.dart';
 import 'package:flowy_editor/infra/html_converter.dart';
-import 'package:flowy_editor/document/node_traverser.dart';
+import 'package:flowy_editor/document/node_iterator.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter/services.dart';
 import 'package:rich_clipboard/rich_clipboard.dart';
@@ -29,11 +29,11 @@ _handleCopy(EditorState editorState) async {
 
   final beginNode = editorState.document.nodeAtPath(selection.start.path)!;
   final endNode = editorState.document.nodeAtPath(selection.end.path)!;
-  final traverser = NodeTraverser(editorState.document, beginNode);
+  final traverser = NodeIterator(editorState.document, beginNode, endNode);
 
   var copyString = "";
-  while (traverser.currentNode != null) {
-    final node = traverser.next()!;
+  while (traverser.moveNext()) {
+    final node = traverser.current;
     if (node.type == "text") {
       final textNode = node as TextNode;
       if (node == beginNode) {
@@ -51,9 +51,6 @@ _handleCopy(EditorState editorState) async {
     }
     // TODO: handle image and other blocks
 
-    if (node == endNode) {
-      break;
-    }
   }
   debugPrint('copy html: $copyString');
   RichClipboard.setData(RichClipboardData(html: copyString));