diff --git a/frontend/app_flowy/packages/appflowy_editor/lib/src/render/image/image_node_widget.dart b/frontend/app_flowy/packages/appflowy_editor/lib/src/render/image/image_node_widget.dart index ca52a14db1..316202b1c7 100644 --- a/frontend/app_flowy/packages/appflowy_editor/lib/src/render/image/image_node_widget.dart +++ b/frontend/app_flowy/packages/appflowy_editor/lib/src/render/image/image_node_widget.dart @@ -101,7 +101,11 @@ class _ImageNodeWidgetState extends State with Selectable { @override Selection getSelectionInRange(Offset start, Offset end) { - return Selection(start: this.start(), end: this.end()); + if (start <= end) { + return Selection(start: this.start(), end: this.end()); + } else { + return Selection(start: this.end(), end: this.start()); + } } @override diff --git a/frontend/app_flowy/packages/appflowy_editor/lib/src/service/internal_key_event_handlers/backspace_handler.dart b/frontend/app_flowy/packages/appflowy_editor/lib/src/service/internal_key_event_handlers/backspace_handler.dart index ebe1eb3bb8..0eeaf654de 100644 --- a/frontend/app_flowy/packages/appflowy_editor/lib/src/service/internal_key_event_handlers/backspace_handler.dart +++ b/frontend/app_flowy/packages/appflowy_editor/lib/src/service/internal_key_event_handlers/backspace_handler.dart @@ -80,6 +80,9 @@ KeyEventResult _handleBackspace(EditorState editorState, RawKeyEvent event) { } if (transactionBuilder.operations.isNotEmpty) { + if (nonTextNodes.isNotEmpty) { + transactionBuilder.afterSelection = Selection.collapsed(selection.start); + } transactionBuilder.commit(); } diff --git a/frontend/app_flowy/packages/appflowy_editor/test/service/internal_key_event_handlers/backspace_handler_test.dart b/frontend/app_flowy/packages/appflowy_editor/test/service/internal_key_event_handlers/backspace_handler_test.dart index 76843c4300..1976ec3250 100644 --- a/frontend/app_flowy/packages/appflowy_editor/test/service/internal_key_event_handlers/backspace_handler_test.dart +++ b/frontend/app_flowy/packages/appflowy_editor/test/service/internal_key_event_handlers/backspace_handler_test.dart @@ -215,30 +215,82 @@ void main() async { }); }); - testWidgets('Deletes the first image', (tester) async { - mockNetworkImagesFor(() async { - const text = 'Welcome to Appflowy 😁'; - const src = 'https://s1.ax1x.com/2022/08/26/v2sSbR.jpg'; - final editor = tester.editor - ..insertImageNode(src) - ..insertTextNode(text) - ..insertTextNode(text); - await editor.startTesting(); + testWidgets('Deletes the first image, and selection is backward', + (tester) async { + await _deleteFirstImage(tester, true); + }); - expect(editor.documentLength, 3); - expect(find.byType(ImageNodeWidget), findsOneWidget); + testWidgets('Deletes the first image, and selection is not backward', + (tester) async { + await _deleteFirstImage(tester, false); + }); - await editor.updateSelection( - Selection( - start: Position(path: [0], offset: 0), - end: Position(path: [0], offset: 1), - ), - ); + testWidgets('Deletes the last image and selection is backward', + (tester) async { + await _deleteLastImage(tester, true); + }); - await editor.pressLogicKey(LogicalKeyboardKey.backspace); - expect(editor.documentLength, 2); - expect(find.byType(ImageNodeWidget), findsNothing); - }); + testWidgets('Deletes the last image and selection is not backward', + (tester) async { + await _deleteLastImage(tester, false); + }); +} + +Future _deleteFirstImage(WidgetTester tester, bool isBackward) async { + mockNetworkImagesFor(() async { + const text = 'Welcome to Appflowy 😁'; + const src = 'https://s1.ax1x.com/2022/08/26/v2sSbR.jpg'; + final editor = tester.editor + ..insertImageNode(src) + ..insertTextNode(text) + ..insertTextNode(text); + await editor.startTesting(); + + expect(editor.documentLength, 3); + expect(find.byType(ImageNodeWidget), findsOneWidget); + + final start = Position(path: [0], offset: 0); + final end = Position(path: [1], offset: 1); + await editor.updateSelection( + Selection( + start: isBackward ? start : end, + end: isBackward ? end : start, + ), + ); + + await editor.pressLogicKey(LogicalKeyboardKey.backspace); + expect(editor.documentLength, 2); + expect(find.byType(ImageNodeWidget), findsNothing); + expect(editor.documentSelection, Selection.collapsed(start)); + }); +} + +Future _deleteLastImage(WidgetTester tester, bool isBackward) async { + mockNetworkImagesFor(() async { + const text = 'Welcome to Appflowy 😁'; + const src = 'https://s1.ax1x.com/2022/08/26/v2sSbR.jpg'; + final editor = tester.editor + ..insertTextNode(text) + ..insertTextNode(text) + ..insertImageNode(src); + await editor.startTesting(); + + expect(editor.documentLength, 3); + expect(find.byType(ImageNodeWidget), findsOneWidget); + + final start = Position(path: [1], offset: 0); + final end = Position(path: [2], offset: 1); + await editor.updateSelection( + Selection( + start: isBackward ? start : end, + end: isBackward ? end : start, + ), + ); + + await editor.pressLogicKey(LogicalKeyboardKey.backspace); + expect(editor.documentLength, 2); + expect(find.byType(ImageNodeWidget), findsNothing); + expect(editor.documentSelection, Selection.collapsed(start)); }); }