diff --git a/lib/src/widgets/controller.dart b/lib/src/widgets/controller.dart index d47dce72..bb092646 100644 --- a/lib/src/widgets/controller.dart +++ b/lib/src/widgets/controller.dart @@ -11,6 +11,7 @@ import '../models/quill_delta.dart'; import '../utils/diff_delta.dart'; typedef ReplaceTextCallback = bool Function(int index, int len, Object? data); +typedef DeleteCallback = void Function(int cursorPosition, bool forward); class QuillController extends ChangeNotifier { QuillController({ @@ -18,6 +19,7 @@ class QuillController extends ChangeNotifier { required TextSelection selection, bool keepStyleOnNewLine = false, this.onReplaceText, + this.onDelete, }) : _selection = selection, _keepStyleOnNewLine = keepStyleOnNewLine; @@ -39,10 +41,13 @@ class QuillController extends ChangeNotifier { TextSelection get selection => _selection; TextSelection _selection; - /// Manual [replaceText] handler + /// Custom [replaceText] handler /// Return false to ignore the event ReplaceTextCallback? onReplaceText; + /// Custom delete handler + DeleteCallback? onDelete; + /// Store any styles attribute that got toggled by the tap of a button /// and that has not been applied yet. /// It gets reset after each format action within the [document]. @@ -186,6 +191,12 @@ class QuillController extends ChangeNotifier { ignoreFocusOnTextChange = false; } + /// Called in two cases: + /// forward == false && textBefore.isEmpty + /// forward == true && textAfter.isEmpty + void handleDelete(int cursorPosition, bool forward) => + onDelete?.call(cursorPosition, forward); + void formatText(int index, int len, Attribute? attribute) { if (len == 0 && attribute!.isInline && diff --git a/lib/src/widgets/raw_editor/raw_editor_state_keyboard_mixin.dart b/lib/src/widgets/raw_editor/raw_editor_state_keyboard_mixin.dart index db860248..72fd5dc2 100644 --- a/lib/src/widgets/raw_editor/raw_editor_state_keyboard_mixin.dart +++ b/lib/src/widgets/raw_editor/raw_editor_state_keyboard_mixin.dart @@ -153,12 +153,16 @@ mixin RawEditorStateKeyboardMixin on EditorState { final newSelection = TextSelection.collapsed(offset: cursorPosition); final newText = textBefore + textAfter; final size = plainText.length - newText.length; - widget.controller.replaceText( - cursorPosition, - size, - '', - newSelection, - ); + if (size == 0) { + widget.controller.handleDelete(cursorPosition, forward); + } else { + widget.controller.replaceText( + cursorPosition, + size, + '', + newSelection, + ); + } } TextSelection _jumpToBeginOrEndOfWord(