diff --git a/frontend/app_flowy/packages/flowy_editor/lib/document/node_iterator.dart b/frontend/app_flowy/packages/flowy_editor/lib/document/node_iterator.dart new file mode 100644 index 0000000000..8603c043e4 --- /dev/null +++ b/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 { + 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!; + } +} diff --git a/frontend/app_flowy/packages/flowy_editor/lib/document/node_traverser.dart b/frontend/app_flowy/packages/flowy_editor/lib/document/node_traverser.dart deleted file mode 100644 index b4005f054a..0000000000 --- a/frontend/app_flowy/packages/flowy_editor/lib/document/node_traverser.dart +++ /dev/null @@ -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; - } -} diff --git a/frontend/app_flowy/packages/flowy_editor/lib/service/internal_key_event_handlers/copy_paste_handler.dart b/frontend/app_flowy/packages/flowy_editor/lib/service/internal_key_event_handlers/copy_paste_handler.dart index a79c121684..cde1c4e122 100644 --- a/frontend/app_flowy/packages/flowy_editor/lib/service/internal_key_event_handlers/copy_paste_handler.dart +++ b/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));