refactor: move node_iterator to core/document

This commit is contained in:
Lucas.Xu 2022-10-09 23:25:47 +08:00
parent cbb6b2d9b0
commit 7f92f8988f
5 changed files with 72 additions and 36 deletions

View File

@ -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;
}
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;
}
@override
Node get current {
return _currentNode!;
}
List<Node> toList() {
final result = <Node>[];
while (moveNext()) {
result.add(current);
}
return result;
}
}

View File

@ -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;

View File

@ -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 {

View File

@ -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');
}
}
});
});
}

View File

@ -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(