From 4794203e7448d8ca852af492da45c7b74e5e5372 Mon Sep 17 00:00:00 2001 From: Vincent Chan Date: Thu, 11 Aug 2022 16:09:45 +0800 Subject: [PATCH] feat: handle delete keys --- .../delete_text_handler.dart | 105 ++++++++++++++---- 1 file changed, 83 insertions(+), 22 deletions(-) diff --git a/frontend/app_flowy/packages/flowy_editor/lib/src/service/internal_key_event_handlers/delete_text_handler.dart b/frontend/app_flowy/packages/flowy_editor/lib/src/service/internal_key_event_handlers/delete_text_handler.dart index 5e2fdfd453..5e96e75a99 100644 --- a/frontend/app_flowy/packages/flowy_editor/lib/src/service/internal_key_event_handlers/delete_text_handler.dart +++ b/frontend/app_flowy/packages/flowy_editor/lib/src/service/internal_key_event_handlers/delete_text_handler.dart @@ -2,14 +2,8 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flowy_editor/flowy_editor.dart'; -import 'package:flowy_editor/src/service/keyboard_service.dart'; - -// Handle delete text. -FlowyKeyEventHandler deleteTextHandler = (editorState, event) { - if (event.logicalKey != LogicalKeyboardKey.backspace) { - return KeyEventResult.ignored; - } +KeyEventResult _handleBackspace(EditorState editorState, RawKeyEvent event) { final selection = editorState.service.selectionService.currentSelection.value; if (selection == null) { return KeyEventResult.ignored; @@ -22,7 +16,7 @@ FlowyKeyEventHandler deleteTextHandler = (editorState, event) { return KeyEventResult.ignored; } - TransactionBuilder transactionBuilder = TransactionBuilder(editorState); + final transactionBuilder = TransactionBuilder(editorState); if (textNodes.length == 1) { final textNode = textNodes.first; final index = textNode.delta.prevRunePosition(selection.start.offset); @@ -74,23 +68,90 @@ FlowyKeyEventHandler deleteTextHandler = (editorState, event) { } } } else { - final first = textNodes.first; - final last = textNodes.last; - var content = textNodes.last.toRawString(); - content = content.substring(selection.end.offset, content.length); - // Merge the fist and the last text node content, - // and delete the all nodes expect for the first. - transactionBuilder - ..deleteNodes(textNodes.sublist(1)) - ..mergeText( - first, - last, - firstOffset: selection.start.offset, - secondOffset: selection.end.offset, - ); + _deleteNodes(transactionBuilder, textNodes, selection); } transactionBuilder.commit(); return KeyEventResult.handled; +} + +KeyEventResult _handleDelete(EditorState editorState, RawKeyEvent event) { + final selection = editorState.service.selectionService.currentSelection.value; + if (selection == null) { + return KeyEventResult.ignored; + } + final nodes = editorState.service.selectionService.currentSelectedNodes; + // make sure all nodes is [TextNode]. + final textNodes = nodes.whereType().toList(); + if (textNodes.length != nodes.length) { + return KeyEventResult.ignored; + } + + final transactionBuilder = TransactionBuilder(editorState); + if (textNodes.length == 1) { + final textNode = textNodes.first; + if (selection.start.offset >= textNode.delta.length) { + debugPrint("merge next line"); + final nextNode = textNode.next; + if (nextNode == null) { + return KeyEventResult.ignored; + } + if (nextNode is TextNode) { + transactionBuilder.mergeText(textNode, nextNode); + } + transactionBuilder.deleteNode(nextNode); + } else { + final index = textNode.delta.nextRunePosition(selection.start.offset); + if (selection.isCollapsed) { + transactionBuilder.deleteText( + textNode, + selection.start.offset, + index - selection.start.offset, + ); + } else { + transactionBuilder.deleteText( + textNode, + selection.start.offset, + selection.end.offset - selection.start.offset, + ); + } + } + } else { + _deleteNodes(transactionBuilder, textNodes, selection); + } + + transactionBuilder.commit(); + + return KeyEventResult.handled; +} + +void _deleteNodes(TransactionBuilder transactionBuilder, + List textNodes, Selection selection) { + final first = textNodes.first; + final last = textNodes.last; + var content = textNodes.last.toRawString(); + content = content.substring(selection.end.offset, content.length); + // Merge the fist and the last text node content, + // and delete the all nodes expect for the first. + transactionBuilder + ..deleteNodes(textNodes.sublist(1)) + ..mergeText( + first, + last, + firstOffset: selection.start.offset, + secondOffset: selection.end.offset, + ); +} + +// Handle delete text. +FlowyKeyEventHandler deleteTextHandler = (editorState, event) { + if (event.logicalKey == LogicalKeyboardKey.backspace) { + return _handleBackspace(editorState, event); + } + if (event.logicalKey == LogicalKeyboardKey.delete) { + return _handleDelete(editorState, event); + } + + return KeyEventResult.ignored; };