Pārlūkot izejas kodu

feat: implement enter key event handler and keep attributes after insert

Lucas.Xu 2 gadi atpakaļ
vecāks
revīzija
14bd18e21c

+ 13 - 0
frontend/app_flowy/packages/flowy_editor/lib/document/node.dart

@@ -205,6 +205,19 @@ class TextNode extends Node {
     return map;
     return map;
   }
   }
 
 
+  TextNode copyWith({
+    String? type,
+    LinkedList<Node>? children,
+    Attributes? attributes,
+    Delta? delta,
+  }) =>
+      TextNode(
+        type: type ?? this.type,
+        children: children ?? this.children,
+        attributes: attributes ?? this.attributes,
+        delta: delta ?? this.delta,
+      );
+
   // TODO: It's unneccesry to compute everytime.
   // TODO: It's unneccesry to compute everytime.
   String toRawString() =>
   String toRawString() =>
       _delta.operations.whereType<TextInsert>().map((op) => op.content).join();
       _delta.operations.whereType<TextInsert>().map((op) => op.content).join();

+ 12 - 9
frontend/app_flowy/packages/flowy_editor/lib/operation/transaction_builder.dart

@@ -1,19 +1,18 @@
 import 'dart:collection';
 import 'dart:collection';
-import 'dart:math';
-import 'package:flowy_editor/editor_state.dart';
+
+import 'package:flowy_editor/document/attributes.dart';
 import 'package:flowy_editor/document/node.dart';
 import 'package:flowy_editor/document/node.dart';
 import 'package:flowy_editor/document/path.dart';
 import 'package:flowy_editor/document/path.dart';
 import 'package:flowy_editor/document/position.dart';
 import 'package:flowy_editor/document/position.dart';
-import 'package:flowy_editor/document/text_delta.dart';
-import 'package:flowy_editor/document/attributes.dart';
 import 'package:flowy_editor/document/selection.dart';
 import 'package:flowy_editor/document/selection.dart';
-
-import './operation.dart';
-import './transaction.dart';
+import 'package:flowy_editor/document/text_delta.dart';
+import 'package:flowy_editor/editor_state.dart';
+import 'package:flowy_editor/operation/operation.dart';
+import 'package:flowy_editor/operation/transaction.dart';
 
 
 /// A [TransactionBuilder] is used to build the transaction from the state.
 /// A [TransactionBuilder] is used to build the transaction from the state.
 /// It will save make a snapshot of the cursor selection state automatically.
 /// It will save make a snapshot of the cursor selection state automatically.
-/// The cursor can be resoted if the transaction is undo.
+/// The cursor can be resorted if the transaction is undo.
 
 
 class TransactionBuilder {
 class TransactionBuilder {
   final List<Operation> operations = [];
   final List<Operation> operations = [];
@@ -30,8 +29,12 @@ class TransactionBuilder {
   }
   }
 
 
   insertNode(Path path, Node node) {
   insertNode(Path path, Node node) {
-    beforeSelection = state.cursorSelection;
+    beforeSelection = state.service.selectionService.currentSelection;
     add(InsertOperation(path: path, value: node));
     add(InsertOperation(path: path, value: node));
+    // FIXME: Not exactly correct, needs to be customized.
+    afterSelection = Selection.collapsed(
+      Position(path: path, offset: 0),
+    );
   }
   }
 
 
   updateNode(Node node, Attributes attributes) {
   updateNode(Node node, Attributes attributes) {

+ 23 - 9
frontend/app_flowy/packages/flowy_editor/lib/service/internal_key_event_handlers/enter_in_edge_of_text_node_handler.dart

@@ -1,12 +1,15 @@
+import 'dart:collection';
+
+import 'package:flutter/material.dart';
+import 'package:flutter/services.dart';
+
 import 'package:flowy_editor/document/node.dart';
 import 'package:flowy_editor/document/node.dart';
-import 'package:flowy_editor/document/position.dart';
-import 'package:flowy_editor/document/selection.dart';
+import 'package:flowy_editor/document/text_delta.dart';
+import 'package:flowy_editor/extensions/node_extensions.dart';
+import 'package:flowy_editor/extensions/path_extensions.dart';
 import 'package:flowy_editor/operation/transaction_builder.dart';
 import 'package:flowy_editor/operation/transaction_builder.dart';
+import 'package:flowy_editor/render/rich_text/rich_text_style.dart';
 import 'package:flowy_editor/service/keyboard_service.dart';
 import 'package:flowy_editor/service/keyboard_service.dart';
-import 'package:flowy_editor/extensions/path_extensions.dart';
-import 'package:flowy_editor/extensions/node_extensions.dart';
-import 'package:flutter/material.dart';
-import 'package:flutter/services.dart';
 
 
 FlowyKeyEventHandler enterInEdgeOfTextNodeHandler = (editorState, event) {
 FlowyKeyEventHandler enterInEdgeOfTextNodeHandler = (editorState, event) {
   if (event.logicalKey != LogicalKeyboardKey.enter) {
   if (event.logicalKey != LogicalKeyboardKey.enter) {
@@ -23,12 +26,19 @@ FlowyKeyEventHandler enterInEdgeOfTextNodeHandler = (editorState, event) {
   }
   }
 
 
   final textNode = nodes.first as TextNode;
   final textNode = nodes.first as TextNode;
-
   if (textNode.selectable!.end() == selection.end) {
   if (textNode.selectable!.end() == selection.end) {
+    final needCopyAttributes = StyleKey.globalStyleKeys
+        .where((key) => key != StyleKey.heading)
+        .contains(textNode.subtype);
     TransactionBuilder(editorState)
     TransactionBuilder(editorState)
       ..insertNode(
       ..insertNode(
         textNode.path.next,
         textNode.path.next,
-        TextNode.empty(),
+        textNode.copyWith(
+          children: LinkedList(),
+          delta: Delta([TextInsert(' ')]),
+          attributes:
+              needCopyAttributes ? {StyleKey.subtype: textNode.subtype} : null,
+        ),
       )
       )
       ..commit();
       ..commit();
     return KeyEventResult.handled;
     return KeyEventResult.handled;
@@ -36,7 +46,11 @@ FlowyKeyEventHandler enterInEdgeOfTextNodeHandler = (editorState, event) {
     TransactionBuilder(editorState)
     TransactionBuilder(editorState)
       ..insertNode(
       ..insertNode(
         textNode.path,
         textNode.path,
-        TextNode.empty(),
+        textNode.copyWith(
+          children: LinkedList(),
+          delta: Delta([TextInsert(' ')]),
+          attributes: {},
+        ),
       )
       )
       ..commit();
       ..commit();
     return KeyEventResult.handled;
     return KeyEventResult.handled;

+ 0 - 2
frontend/app_flowy/packages/flowy_editor/lib/service/internal_key_event_handlers/update_text_style_by_command_x_handler.dart

@@ -1,8 +1,6 @@
 import 'package:flutter/material.dart';
 import 'package:flutter/material.dart';
 
 
 import 'package:flowy_editor/document/node.dart';
 import 'package:flowy_editor/document/node.dart';
-import 'package:flowy_editor/extensions/text_node_extensions.dart';
-import 'package:flowy_editor/render/rich_text/rich_text_style.dart';
 import 'package:flowy_editor/service/default_text_operations/format_rich_text_style.dart';
 import 'package:flowy_editor/service/default_text_operations/format_rich_text_style.dart';
 import 'package:flowy_editor/service/keyboard_service.dart';
 import 'package:flowy_editor/service/keyboard_service.dart';