diff --git a/frontend/app_flowy/packages/appflowy_editor/lib/appflowy_editor.dart b/frontend/app_flowy/packages/appflowy_editor/lib/appflowy_editor.dart index 72a515e3fa..8cb220401c 100644 --- a/frontend/app_flowy/packages/appflowy_editor/lib/appflowy_editor.dart +++ b/frontend/app_flowy/packages/appflowy_editor/lib/appflowy_editor.dart @@ -5,8 +5,8 @@ export 'src/infra/log.dart'; export 'src/render/style/editor_style.dart'; export 'src/core/document/node.dart'; export 'src/core/document/path.dart'; -export 'src/core/selection/position.dart'; -export 'src/document/selection.dart'; +export 'src/core/location/position.dart'; +export 'src/core/location/selection.dart'; export 'src/document/state_tree.dart'; export 'src/core/document/text_delta.dart'; export 'src/core/document/attributes.dart'; diff --git a/frontend/app_flowy/packages/appflowy_editor/lib/src/commands/format_built_in_text.dart b/frontend/app_flowy/packages/appflowy_editor/lib/src/commands/format_built_in_text.dart index 70010f61e7..320a0dd616 100644 --- a/frontend/app_flowy/packages/appflowy_editor/lib/src/commands/format_built_in_text.dart +++ b/frontend/app_flowy/packages/appflowy_editor/lib/src/commands/format_built_in_text.dart @@ -4,7 +4,7 @@ import 'package:appflowy_editor/src/core/document/attributes.dart'; import 'package:appflowy_editor/src/document/built_in_attribute_keys.dart'; import 'package:appflowy_editor/src/core/document/node.dart'; import 'package:appflowy_editor/src/core/document/path.dart'; -import 'package:appflowy_editor/src/document/selection.dart'; +import 'package:appflowy_editor/src/core/location/selection.dart'; import 'package:appflowy_editor/src/editor_state.dart'; Future formatBuiltInTextAttributes( diff --git a/frontend/app_flowy/packages/appflowy_editor/lib/src/commands/format_text.dart b/frontend/app_flowy/packages/appflowy_editor/lib/src/commands/format_text.dart index 7c1a8c0431..7d00754afc 100644 --- a/frontend/app_flowy/packages/appflowy_editor/lib/src/commands/format_text.dart +++ b/frontend/app_flowy/packages/appflowy_editor/lib/src/commands/format_text.dart @@ -4,7 +4,7 @@ import 'package:appflowy_editor/src/commands/text_command_infra.dart'; import 'package:appflowy_editor/src/core/document/attributes.dart'; import 'package:appflowy_editor/src/core/document/node.dart'; import 'package:appflowy_editor/src/core/document/path.dart'; -import 'package:appflowy_editor/src/document/selection.dart'; +import 'package:appflowy_editor/src/core/location/selection.dart'; import 'package:appflowy_editor/src/editor_state.dart'; import 'package:appflowy_editor/src/operation/transaction_builder.dart'; import 'package:flutter/widgets.dart'; diff --git a/frontend/app_flowy/packages/appflowy_editor/lib/src/commands/text_command_infra.dart b/frontend/app_flowy/packages/appflowy_editor/lib/src/commands/text_command_infra.dart index 56342c670a..b5df6e4dff 100644 --- a/frontend/app_flowy/packages/appflowy_editor/lib/src/commands/text_command_infra.dart +++ b/frontend/app_flowy/packages/appflowy_editor/lib/src/commands/text_command_infra.dart @@ -1,6 +1,6 @@ import 'package:appflowy_editor/src/core/document/node.dart'; import 'package:appflowy_editor/src/core/document/path.dart'; -import 'package:appflowy_editor/src/document/selection.dart'; +import 'package:appflowy_editor/src/core/location/selection.dart'; import 'package:appflowy_editor/src/editor_state.dart'; // get formatted [TextNode] diff --git a/frontend/app_flowy/packages/appflowy_editor/lib/src/core/selection/position.dart b/frontend/app_flowy/packages/appflowy_editor/lib/src/core/location/position.dart similarity index 100% rename from frontend/app_flowy/packages/appflowy_editor/lib/src/core/selection/position.dart rename to frontend/app_flowy/packages/appflowy_editor/lib/src/core/location/position.dart diff --git a/frontend/app_flowy/packages/appflowy_editor/lib/src/document/selection.dart b/frontend/app_flowy/packages/appflowy_editor/lib/src/core/location/selection.dart similarity index 58% rename from frontend/app_flowy/packages/appflowy_editor/lib/src/document/selection.dart rename to frontend/app_flowy/packages/appflowy_editor/lib/src/core/location/selection.dart index eaf3f5f4fb..b22d743c7d 100644 --- a/frontend/app_flowy/packages/appflowy_editor/lib/src/document/selection.dart +++ b/frontend/app_flowy/packages/appflowy_editor/lib/src/core/location/selection.dart @@ -1,5 +1,5 @@ import 'package:appflowy_editor/src/core/document/path.dart'; -import 'package:appflowy_editor/src/core/selection/position.dart'; +import 'package:appflowy_editor/src/core/location/position.dart'; /// Selection represents the selected area or the cursor area in the editor. /// @@ -36,31 +36,58 @@ class Selection { final Position start; final Position end; + @override + bool operator ==(Object other) { + if (identical(this, other)) return true; + + return other is Selection && other.start == start && other.end == end; + } + + @override + int get hashCode => start.hashCode ^ end.hashCode; + + @override + String toString() => 'start = $start, end = $end'; + + /// Returns a Boolean indicating whether the selection's start and end points + /// are at the same position. bool get isCollapsed => start == end; + + /// Returns a Boolean indicating whether the selection's start and end points + /// are at the same path. bool get isSingle => start.path.equals(end.path); + + /// Returns a Boolean indicating whether the selection is forward. bool get isForward => (start.path > end.path) || (isSingle && start.offset > end.offset); + + /// Returns a Boolean indicating whether the selection is backward. bool get isBackward => (start.path < end.path) || (isSingle && start.offset < end.offset); - Selection get normalize { - if (isForward) { - return reversed; - } - return this; - } + /// Returns a normalized selection that direction is forward. + Selection get normalized => isBackward ? copyWith() : reversed.copyWith(); + /// Returns a reversed selection. Selection get reversed => copyWith(start: end, end: start); - int get startIndex => normalize.start.offset; - int get endIndex => normalize.end.offset; + /// Returns the offset in the starting position under the normalized selection. + int get startIndex => normalized.start.offset; + + /// Returns the offset in the ending position under the normalized selection. + int get endIndex => normalized.end.offset; + int get length => endIndex - startIndex; + /// Collapses the current selection to a single point. + /// + /// If [atStart] is true, the selection will be collapsed to the start point. + /// If [atStart] is false, the selection will be collapsed to the end point. Selection collapse({bool atStart = false}) { if (atStart) { - return Selection(start: start, end: start); + return copyWith(end: start); } else { - return Selection(start: end, end: end); + return copyWith(start: end); } } @@ -71,29 +98,10 @@ class Selection { ); } - Selection copy() => Selection(start: start, end: end); - Map toJson() { return { 'start': start.toJson(), 'end': end.toJson(), }; } - - @override - bool operator ==(Object other) { - if (other is! Selection) { - return false; - } - if (identical(this, other)) { - return true; - } - return start == other.start && end == other.end; - } - - @override - int get hashCode => Object.hash(start, end); - - @override - String toString() => '[Selection] start = $start, end = $end'; } diff --git a/frontend/app_flowy/packages/appflowy_editor/lib/src/editor_state.dart b/frontend/app_flowy/packages/appflowy_editor/lib/src/editor_state.dart index 4aeb7ab599..995ffcbdd7 100644 --- a/frontend/app_flowy/packages/appflowy_editor/lib/src/editor_state.dart +++ b/frontend/app_flowy/packages/appflowy_editor/lib/src/editor_state.dart @@ -5,7 +5,7 @@ import 'package:appflowy_editor/src/render/style/editor_style.dart'; import 'package:appflowy_editor/src/service/service.dart'; import 'package:flutter/material.dart'; -import 'package:appflowy_editor/src/document/selection.dart'; +import 'package:appflowy_editor/src/core/location/selection.dart'; import 'package:appflowy_editor/src/document/state_tree.dart'; import 'package:appflowy_editor/src/operation/operation.dart'; import 'package:appflowy_editor/src/operation/transaction.dart'; diff --git a/frontend/app_flowy/packages/appflowy_editor/lib/src/extensions/node_extensions.dart b/frontend/app_flowy/packages/appflowy_editor/lib/src/extensions/node_extensions.dart index 4fdc224398..82d28bd469 100644 --- a/frontend/app_flowy/packages/appflowy_editor/lib/src/extensions/node_extensions.dart +++ b/frontend/app_flowy/packages/appflowy_editor/lib/src/extensions/node_extensions.dart @@ -1,6 +1,6 @@ import 'package:appflowy_editor/src/core/document/node.dart'; import 'package:appflowy_editor/src/core/document/path.dart'; -import 'package:appflowy_editor/src/document/selection.dart'; +import 'package:appflowy_editor/src/core/location/selection.dart'; import 'package:appflowy_editor/src/extensions/object_extensions.dart'; import 'package:appflowy_editor/src/render/selection/selectable.dart'; import 'package:flutter/material.dart'; diff --git a/frontend/app_flowy/packages/appflowy_editor/lib/src/extensions/text_node_extensions.dart b/frontend/app_flowy/packages/appflowy_editor/lib/src/extensions/text_node_extensions.dart index 2c31008c79..9ceff7e373 100644 --- a/frontend/app_flowy/packages/appflowy_editor/lib/src/extensions/text_node_extensions.dart +++ b/frontend/app_flowy/packages/appflowy_editor/lib/src/extensions/text_node_extensions.dart @@ -1,7 +1,7 @@ import 'package:appflowy_editor/src/core/document/node.dart'; import 'package:appflowy_editor/src/core/document/path.dart'; -import 'package:appflowy_editor/src/core/selection/position.dart'; -import 'package:appflowy_editor/src/document/selection.dart'; +import 'package:appflowy_editor/src/core/location/position.dart'; +import 'package:appflowy_editor/src/core/location/selection.dart'; import 'package:appflowy_editor/src/core/document/text_delta.dart'; import 'package:appflowy_editor/src/document/built_in_attribute_keys.dart'; diff --git a/frontend/app_flowy/packages/appflowy_editor/lib/src/operation/transaction.dart b/frontend/app_flowy/packages/appflowy_editor/lib/src/operation/transaction.dart index 8527e15325..145112fde9 100644 --- a/frontend/app_flowy/packages/appflowy_editor/lib/src/operation/transaction.dart +++ b/frontend/app_flowy/packages/appflowy_editor/lib/src/operation/transaction.dart @@ -1,6 +1,6 @@ import 'dart:collection'; import 'package:flutter/material.dart'; -import 'package:appflowy_editor/src/document/selection.dart'; +import 'package:appflowy_editor/src/core/location/selection.dart'; import './operation.dart'; /// A [Transaction] has a list of [Operation] objects that will be applied diff --git a/frontend/app_flowy/packages/appflowy_editor/lib/src/operation/transaction_builder.dart b/frontend/app_flowy/packages/appflowy_editor/lib/src/operation/transaction_builder.dart index 31b2be659e..101c2bc9cf 100644 --- a/frontend/app_flowy/packages/appflowy_editor/lib/src/operation/transaction_builder.dart +++ b/frontend/app_flowy/packages/appflowy_editor/lib/src/operation/transaction_builder.dart @@ -4,8 +4,8 @@ import 'dart:math'; import 'package:appflowy_editor/src/core/document/attributes.dart'; import 'package:appflowy_editor/src/core/document/node.dart'; import 'package:appflowy_editor/src/core/document/path.dart'; -import 'package:appflowy_editor/src/core/selection/position.dart'; -import 'package:appflowy_editor/src/document/selection.dart'; +import 'package:appflowy_editor/src/core/location/position.dart'; +import 'package:appflowy_editor/src/core/location/selection.dart'; import 'package:appflowy_editor/src/core/document/text_delta.dart'; import 'package:appflowy_editor/src/editor_state.dart'; import 'package:appflowy_editor/src/operation/operation.dart'; 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 6f173a3c98..5f9b2142fe 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 @@ -1,7 +1,7 @@ import 'package:appflowy_editor/src/extensions/object_extensions.dart'; import 'package:appflowy_editor/src/core/document/node.dart'; -import 'package:appflowy_editor/src/core/selection/position.dart'; -import 'package:appflowy_editor/src/document/selection.dart'; +import 'package:appflowy_editor/src/core/location/position.dart'; +import 'package:appflowy_editor/src/core/location/selection.dart'; import 'package:appflowy_editor/src/infra/flowy_svg.dart'; import 'package:appflowy_editor/src/render/selection/selectable.dart'; import 'package:flutter/material.dart'; diff --git a/frontend/app_flowy/packages/appflowy_editor/lib/src/render/rich_text/default_selectable.dart b/frontend/app_flowy/packages/appflowy_editor/lib/src/render/rich_text/default_selectable.dart index 69176c544e..724a45b469 100644 --- a/frontend/app_flowy/packages/appflowy_editor/lib/src/render/rich_text/default_selectable.dart +++ b/frontend/app_flowy/packages/appflowy_editor/lib/src/render/rich_text/default_selectable.dart @@ -1,5 +1,5 @@ -import 'package:appflowy_editor/src/core/selection/position.dart'; -import 'package:appflowy_editor/src/document/selection.dart'; +import 'package:appflowy_editor/src/core/location/position.dart'; +import 'package:appflowy_editor/src/core/location/selection.dart'; import 'package:appflowy_editor/src/render/selection/selectable.dart'; import 'package:flutter/material.dart'; diff --git a/frontend/app_flowy/packages/appflowy_editor/lib/src/render/rich_text/flowy_rich_text.dart b/frontend/app_flowy/packages/appflowy_editor/lib/src/render/rich_text/flowy_rich_text.dart index 1b4acaf24f..c49122dea4 100644 --- a/frontend/app_flowy/packages/appflowy_editor/lib/src/render/rich_text/flowy_rich_text.dart +++ b/frontend/app_flowy/packages/appflowy_editor/lib/src/render/rich_text/flowy_rich_text.dart @@ -7,8 +7,8 @@ import 'package:flutter/rendering.dart'; import 'package:appflowy_editor/src/core/document/node.dart'; import 'package:appflowy_editor/src/core/document/path.dart'; -import 'package:appflowy_editor/src/core/selection/position.dart'; -import 'package:appflowy_editor/src/document/selection.dart'; +import 'package:appflowy_editor/src/core/location/position.dart'; +import 'package:appflowy_editor/src/core/location/selection.dart'; import 'package:appflowy_editor/src/core/document/text_delta.dart'; import 'package:appflowy_editor/src/editor_state.dart'; import 'package:appflowy_editor/src/extensions/url_launcher_extension.dart'; diff --git a/frontend/app_flowy/packages/appflowy_editor/lib/src/render/selection/selectable.dart b/frontend/app_flowy/packages/appflowy_editor/lib/src/render/selection/selectable.dart index 56ebc9cc71..523f60de47 100644 --- a/frontend/app_flowy/packages/appflowy_editor/lib/src/render/selection/selectable.dart +++ b/frontend/app_flowy/packages/appflowy_editor/lib/src/render/selection/selectable.dart @@ -1,5 +1,5 @@ -import 'package:appflowy_editor/src/core/selection/position.dart'; -import 'package:appflowy_editor/src/document/selection.dart'; +import 'package:appflowy_editor/src/core/location/position.dart'; +import 'package:appflowy_editor/src/core/location/selection.dart'; import 'package:flutter/material.dart'; enum CursorStyle { diff --git a/frontend/app_flowy/packages/appflowy_editor/lib/src/service/default_text_operations/format_rich_text_style.dart b/frontend/app_flowy/packages/appflowy_editor/lib/src/service/default_text_operations/format_rich_text_style.dart index 9cc45c7f11..ac9670173e 100644 --- a/frontend/app_flowy/packages/appflowy_editor/lib/src/service/default_text_operations/format_rich_text_style.dart +++ b/frontend/app_flowy/packages/appflowy_editor/lib/src/service/default_text_operations/format_rich_text_style.dart @@ -1,8 +1,8 @@ import 'package:appflowy_editor/src/core/document/attributes.dart'; import 'package:appflowy_editor/src/core/document/node.dart'; import 'package:appflowy_editor/src/core/document/path.dart'; -import 'package:appflowy_editor/src/core/selection/position.dart'; -import 'package:appflowy_editor/src/document/selection.dart'; +import 'package:appflowy_editor/src/core/location/position.dart'; +import 'package:appflowy_editor/src/core/location/selection.dart'; import 'package:appflowy_editor/src/editor_state.dart'; import 'package:appflowy_editor/src/extensions/text_node_extensions.dart'; import 'package:appflowy_editor/src/operation/transaction_builder.dart'; diff --git a/frontend/app_flowy/packages/appflowy_editor/lib/src/service/input_service.dart b/frontend/app_flowy/packages/appflowy_editor/lib/src/service/input_service.dart index faae72793e..f0cc94c677 100644 --- a/frontend/app_flowy/packages/appflowy_editor/lib/src/service/input_service.dart +++ b/frontend/app_flowy/packages/appflowy_editor/lib/src/service/input_service.dart @@ -4,7 +4,7 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:appflowy_editor/src/core/document/node.dart'; -import 'package:appflowy_editor/src/document/selection.dart'; +import 'package:appflowy_editor/src/core/location/selection.dart'; import 'package:appflowy_editor/src/editor_state.dart'; import 'package:appflowy_editor/src/extensions/node_extensions.dart'; import 'package:appflowy_editor/src/operation/transaction_builder.dart'; diff --git a/frontend/app_flowy/packages/appflowy_editor/lib/src/service/internal_key_event_handlers/arrow_keys_handler.dart b/frontend/app_flowy/packages/appflowy_editor/lib/src/service/internal_key_event_handlers/arrow_keys_handler.dart index c04dafe986..80f139a4fe 100644 --- a/frontend/app_flowy/packages/appflowy_editor/lib/src/service/internal_key_event_handlers/arrow_keys_handler.dart +++ b/frontend/app_flowy/packages/appflowy_editor/lib/src/service/internal_key_event_handlers/arrow_keys_handler.dart @@ -220,7 +220,7 @@ ShortcutEventHandler cursorEndSelect = (editorState, event) { KeyEventResult cursorUp(EditorState editorState, RawKeyEvent event) { final nodes = editorState.service.selectionService.currentSelectedNodes; final selection = - editorState.service.selectionService.currentSelection.value?.normalize; + editorState.service.selectionService.currentSelection.value?.normalized; if (nodes.isEmpty || selection == null) { return KeyEventResult.ignored; } @@ -234,7 +234,7 @@ KeyEventResult cursorUp(EditorState editorState, RawKeyEvent event) { KeyEventResult cursorDown(EditorState editorState, RawKeyEvent event) { final nodes = editorState.service.selectionService.currentSelectedNodes; final selection = - editorState.service.selectionService.currentSelection.value?.normalize; + editorState.service.selectionService.currentSelection.value?.normalized; if (nodes.isEmpty || selection == null) { return KeyEventResult.ignored; } @@ -248,7 +248,7 @@ KeyEventResult cursorDown(EditorState editorState, RawKeyEvent event) { KeyEventResult cursorLeft(EditorState editorState, RawKeyEvent event) { final nodes = editorState.service.selectionService.currentSelectedNodes; final selection = - editorState.service.selectionService.currentSelection.value?.normalize; + editorState.service.selectionService.currentSelection.value?.normalized; if (nodes.isEmpty || selection == null) { return KeyEventResult.ignored; } @@ -270,7 +270,7 @@ KeyEventResult cursorLeft(EditorState editorState, RawKeyEvent event) { KeyEventResult cursorRight(EditorState editorState, RawKeyEvent event) { final nodes = editorState.service.selectionService.currentSelectedNodes; final selection = - editorState.service.selectionService.currentSelection.value?.normalize; + editorState.service.selectionService.currentSelection.value?.normalized; if (nodes.isEmpty || selection == null) { return KeyEventResult.ignored; } diff --git a/frontend/app_flowy/packages/appflowy_editor/lib/src/service/internal_key_event_handlers/copy_paste_handler.dart b/frontend/app_flowy/packages/appflowy_editor/lib/src/service/internal_key_event_handlers/copy_paste_handler.dart index 6d35dddb8c..0121b474d0 100644 --- a/frontend/app_flowy/packages/appflowy_editor/lib/src/service/internal_key_event_handlers/copy_paste_handler.dart +++ b/frontend/app_flowy/packages/appflowy_editor/lib/src/service/internal_key_event_handlers/copy_paste_handler.dart @@ -25,7 +25,7 @@ Selection _computeSelectionAfterPasteMultipleNodes( } void _handleCopy(EditorState editorState) async { - final selection = editorState.cursorSelection?.normalize; + final selection = editorState.cursorSelection?.normalized; if (selection == null || selection.isCollapsed) { return; } @@ -65,7 +65,7 @@ void _handleCopy(EditorState editorState) async { } void _pasteHTML(EditorState editorState, String html) { - final selection = editorState.cursorSelection?.normalize; + final selection = editorState.cursorSelection?.normalized; if (selection == null) { return; } @@ -234,7 +234,7 @@ Delta _lineContentToDelta(String lineContent) { } void _handlePastePlainText(EditorState editorState, String plainText) { - final selection = editorState.cursorSelection?.normalize; + final selection = editorState.cursorSelection?.normalized; if (selection == null) { return; } @@ -300,7 +300,7 @@ void _handleCut(EditorState editorState) { } void _deleteSelectedContent(EditorState editorState) { - final selection = editorState.cursorSelection?.normalize; + final selection = editorState.cursorSelection?.normalized; if (selection == null || selection.isCollapsed) { return; } diff --git a/frontend/app_flowy/packages/appflowy_editor/lib/src/service/internal_key_event_handlers/number_list_helper.dart b/frontend/app_flowy/packages/appflowy_editor/lib/src/service/internal_key_event_handlers/number_list_helper.dart index 0c2a3ab9e2..6bb51bce31 100644 --- a/frontend/app_flowy/packages/appflowy_editor/lib/src/service/internal_key_event_handlers/number_list_helper.dart +++ b/frontend/app_flowy/packages/appflowy_editor/lib/src/service/internal_key_event_handlers/number_list_helper.dart @@ -1,4 +1,4 @@ -import 'package:appflowy_editor/src/document/selection.dart'; +import 'package:appflowy_editor/src/core/location/selection.dart'; import 'package:appflowy_editor/src/editor_state.dart'; import 'package:appflowy_editor/src/document/built_in_attribute_keys.dart'; import 'package:appflowy_editor/src/operation/transaction_builder.dart'; diff --git a/frontend/app_flowy/packages/appflowy_editor/lib/src/service/internal_key_event_handlers/select_all_handler.dart b/frontend/app_flowy/packages/appflowy_editor/lib/src/service/internal_key_event_handlers/select_all_handler.dart index e11deb188b..800877b435 100644 --- a/frontend/app_flowy/packages/appflowy_editor/lib/src/service/internal_key_event_handlers/select_all_handler.dart +++ b/frontend/app_flowy/packages/appflowy_editor/lib/src/service/internal_key_event_handlers/select_all_handler.dart @@ -1,6 +1,6 @@ import 'package:appflowy_editor/src/core/document/node.dart'; -import 'package:appflowy_editor/src/core/selection/position.dart'; -import 'package:appflowy_editor/src/document/selection.dart'; +import 'package:appflowy_editor/src/core/location/position.dart'; +import 'package:appflowy_editor/src/core/location/selection.dart'; import 'package:appflowy_editor/src/service/shortcut_event/shortcut_event_handler.dart'; import 'package:flutter/material.dart'; diff --git a/frontend/app_flowy/packages/appflowy_editor/lib/src/service/internal_key_event_handlers/whitespace_handler.dart b/frontend/app_flowy/packages/appflowy_editor/lib/src/service/internal_key_event_handlers/whitespace_handler.dart index 917831cc3b..de6f4d946c 100644 --- a/frontend/app_flowy/packages/appflowy_editor/lib/src/service/internal_key_event_handlers/whitespace_handler.dart +++ b/frontend/app_flowy/packages/appflowy_editor/lib/src/service/internal_key_event_handlers/whitespace_handler.dart @@ -3,8 +3,8 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:appflowy_editor/src/document/built_in_attribute_keys.dart'; import 'package:appflowy_editor/src/core/document/node.dart'; -import 'package:appflowy_editor/src/core/selection/position.dart'; -import 'package:appflowy_editor/src/document/selection.dart'; +import 'package:appflowy_editor/src/core/location/position.dart'; +import 'package:appflowy_editor/src/core/location/selection.dart'; import 'package:appflowy_editor/src/editor_state.dart'; import 'package:appflowy_editor/src/operation/transaction_builder.dart'; import './number_list_helper.dart'; diff --git a/frontend/app_flowy/packages/appflowy_editor/lib/src/service/selection_service.dart b/frontend/app_flowy/packages/appflowy_editor/lib/src/service/selection_service.dart index 3badb2de2f..ed0bc369a5 100644 --- a/frontend/app_flowy/packages/appflowy_editor/lib/src/service/selection_service.dart +++ b/frontend/app_flowy/packages/appflowy_editor/lib/src/service/selection_service.dart @@ -4,8 +4,8 @@ import 'package:flutter/material.dart'; import 'package:appflowy_editor/src/core/document/node.dart'; import 'package:appflowy_editor/src/core/document/node_iterator.dart'; import 'package:appflowy_editor/src/core/document/path.dart'; -import 'package:appflowy_editor/src/core/selection/position.dart'; -import 'package:appflowy_editor/src/document/selection.dart'; +import 'package:appflowy_editor/src/core/location/position.dart'; +import 'package:appflowy_editor/src/core/location/selection.dart'; import 'package:appflowy_editor/src/editor_state.dart'; import 'package:appflowy_editor/src/extensions/node_extensions.dart'; import 'package:appflowy_editor/src/extensions/object_extensions.dart'; @@ -366,7 +366,7 @@ class _AppFlowySelectionState extends State final backwardNodes = selection.isBackward ? nodes : nodes.reversed.toList(growable: false); - final normalizedSelection = selection.normalize; + final normalizedSelection = selection.normalized; assert(normalizedSelection.isBackward); Log.selection.debug('update selection areas, $normalizedSelection'); @@ -378,7 +378,7 @@ class _AppFlowySelectionState extends State continue; } - var newSelection = normalizedSelection.copy(); + var newSelection = normalizedSelection.copyWith(); /// In the case of multiple selections, /// we need to return a new selection for each selected node individually. diff --git a/frontend/app_flowy/packages/appflowy_editor/lib/src/undo_manager.dart b/frontend/app_flowy/packages/appflowy_editor/lib/src/undo_manager.dart index 737076e930..bfc90e27b2 100644 --- a/frontend/app_flowy/packages/appflowy_editor/lib/src/undo_manager.dart +++ b/frontend/app_flowy/packages/appflowy_editor/lib/src/undo_manager.dart @@ -1,6 +1,6 @@ import 'dart:collection'; -import 'package:appflowy_editor/src/document/selection.dart'; +import 'package:appflowy_editor/src/core/location/selection.dart'; import 'package:appflowy_editor/src/infra/log.dart'; import 'package:appflowy_editor/src/operation/operation.dart'; import 'package:appflowy_editor/src/operation/transaction_builder.dart'; diff --git a/frontend/app_flowy/packages/appflowy_editor/test/core/selection/position_test.dart b/frontend/app_flowy/packages/appflowy_editor/test/core/location/position_test.dart similarity index 100% rename from frontend/app_flowy/packages/appflowy_editor/test/core/selection/position_test.dart rename to frontend/app_flowy/packages/appflowy_editor/test/core/location/position_test.dart diff --git a/frontend/app_flowy/packages/appflowy_editor/test/core/location/selection_test.dart b/frontend/app_flowy/packages/appflowy_editor/test/core/location/selection_test.dart new file mode 100644 index 0000000000..4361ffcf67 --- /dev/null +++ b/frontend/app_flowy/packages/appflowy_editor/test/core/location/selection_test.dart @@ -0,0 +1,77 @@ +import 'package:appflowy_editor/appflowy_editor.dart'; +import 'package:flutter_test/flutter_test.dart'; + +void main() async { + group('selection.dart', () { + test('test selection equality', () { + final position = Position(path: [0, 1, 2], offset: 3); + final selectionA = Selection(start: position, end: position); + final selectionB = Selection.collapsed(position); + expect(selectionA, selectionB); + expect(selectionA.hashCode, selectionB.hashCode); + + final newPosition = Position(path: [1, 2, 3], offset: 4); + + final selectionC = selectionA.copyWith(start: newPosition); + expect(selectionC.start, newPosition); + expect(selectionC.end, position); + expect(selectionC.isCollapsed, false); + + final selectionD = selectionA.copyWith(end: newPosition); + expect(selectionD.start, position); + expect(selectionD.end, newPosition); + expect(selectionD.isCollapsed, false); + + final selectionE = Selection.single(path: [0, 1, 2], startOffset: 3); + expect(selectionE, selectionA); + expect(selectionE.isSingle, true); + expect(selectionE.isCollapsed, true); + }); + + test('test selection direction', () { + final start = Position(path: [0, 1, 2], offset: 3); + final end = Position(path: [1, 2, 3], offset: 3); + final backwardSelection = Selection(start: start, end: end); + expect(backwardSelection.isBackward, true); + final forwardSelection = Selection(start: end, end: start); + expect(forwardSelection.isForward, true); + + expect(backwardSelection.reversed, forwardSelection); + expect(forwardSelection.normalized, backwardSelection); + + expect(backwardSelection.startIndex, 3); + expect(backwardSelection.endIndex, 3); + }); + + test('test selection collapsed', () { + final start = Position(path: [0, 1, 2], offset: 3); + final end = Position(path: [1, 2, 3], offset: 3); + final selection = Selection(start: start, end: end); + final collapsedAtStart = selection.collapse(atStart: true); + expect(collapsedAtStart.isCollapsed, true); + expect(collapsedAtStart.start, start); + expect(collapsedAtStart.end, start); + + final collapsedAtEnd = selection.collapse(atStart: false); + expect(collapsedAtEnd.isCollapsed, true); + expect(collapsedAtEnd.start, end); + expect(collapsedAtEnd.end, end); + }); + + test('test selection toJson', () { + final start = Position(path: [0, 1, 2], offset: 3); + final end = Position(path: [1, 2, 3], offset: 3); + final selection = Selection(start: start, end: end); + expect(selection.toJson(), { + 'start': { + 'path': [0, 1, 2], + 'offset': 3 + }, + 'end': { + 'path': [1, 2, 3], + 'offset': 3 + } + }); + }); + }); +} diff --git a/frontend/app_flowy/packages/appflowy_editor/test/legacy/flowy_editor_test.dart b/frontend/app_flowy/packages/appflowy_editor/test/legacy/flowy_editor_test.dart index 8fd6e71b87..aba15f02c7 100644 --- a/frontend/app_flowy/packages/appflowy_editor/test/legacy/flowy_editor_test.dart +++ b/frontend/app_flowy/packages/appflowy_editor/test/legacy/flowy_editor_test.dart @@ -1,6 +1,6 @@ import 'package:appflowy_editor/src/core/document/path.dart'; -import 'package:appflowy_editor/src/core/selection/position.dart'; -import 'package:appflowy_editor/src/document/selection.dart'; +import 'package:appflowy_editor/src/core/location/position.dart'; +import 'package:appflowy_editor/src/core/location/selection.dart'; import 'package:flutter_test/flutter_test.dart'; void main() {