removed onLive search

pull/1379/head
raelsj 2 years ago
parent 787c7a845f
commit bfc00ea11c
  1. 415
      lib/src/widgets/raw_editor.dart

@ -86,8 +86,7 @@ class RawEditor extends StatefulWidget {
this.contentInsertionConfiguration, this.contentInsertionConfiguration,
}) : assert(maxHeight == null || maxHeight > 0, 'maxHeight cannot be null'), }) : assert(maxHeight == null || maxHeight > 0, 'maxHeight cannot be null'),
assert(minHeight == null || minHeight >= 0, 'minHeight cannot be null'), assert(minHeight == null || minHeight >= 0, 'minHeight cannot be null'),
assert(maxHeight == null || minHeight == null || maxHeight >= minHeight, assert(maxHeight == null || minHeight == null || maxHeight >= minHeight, 'maxHeight cannot be null'),
'maxHeight cannot be null'),
showCursor = showCursor ?? true, showCursor = showCursor ?? true,
super(key: key); super(key: key);
@ -337,9 +336,7 @@ class RawEditorState extends EditorState
@override @override
void insertContent(KeyboardInsertedContent content) { void insertContent(KeyboardInsertedContent content) {
assert(widget.contentInsertionConfiguration?.allowedMimeTypes assert(widget.contentInsertionConfiguration?.allowedMimeTypes.contains(content.mimeType) ?? false);
.contains(content.mimeType) ??
false);
widget.contentInsertionConfiguration?.onContentInserted.call(content); widget.contentInsertionConfiguration?.onContentInserted.call(content);
} }
@ -350,17 +347,10 @@ class RawEditorState extends EditorState
List<ContextMenuButtonItem> get contextMenuButtonItems { List<ContextMenuButtonItem> get contextMenuButtonItems {
return EditableText.getEditableButtonItems( return EditableText.getEditableButtonItems(
clipboardStatus: _clipboardStatus.value, clipboardStatus: _clipboardStatus.value,
onLiveTextInput: null, onCopy: copyEnabled ? () => copySelection(SelectionChangedCause.toolbar) : null,
onCopy: copyEnabled onCut: cutEnabled ? () => cutSelection(SelectionChangedCause.toolbar) : null,
? () => copySelection(SelectionChangedCause.toolbar) onPaste: pasteEnabled ? () => pasteText(SelectionChangedCause.toolbar) : null,
: null, onSelectAll: selectAllEnabled ? () => selectAll(SelectionChangedCause.toolbar) : null,
onCut:
cutEnabled ? () => cutSelection(SelectionChangedCause.toolbar) : null,
onPaste:
pasteEnabled ? () => pasteText(SelectionChangedCause.toolbar) : null,
onSelectAll: selectAllEnabled
? () => selectAll(SelectionChangedCause.toolbar)
: null,
); );
} }
@ -402,10 +392,8 @@ class RawEditorState extends EditorState
); );
} }
final startCharacterRect = final startCharacterRect = renderEditor.getLocalRectForCaret(selection.base);
renderEditor.getLocalRectForCaret(selection.base); final endCharacterRect = renderEditor.getLocalRectForCaret(selection.extent);
final endCharacterRect =
renderEditor.getLocalRectForCaret(selection.extent);
return _GlyphHeights( return _GlyphHeights(
startCharacterRect.height, startCharacterRect.height,
endCharacterRect.height, endCharacterRect.height,
@ -434,8 +422,7 @@ class RawEditorState extends EditorState
widget.focusNode.unfocus(); widget.focusNode.unfocus();
break; break;
case ui.PointerDeviceKind.trackpad: case ui.PointerDeviceKind.trackpad:
throw UnimplementedError( throw UnimplementedError('Unexpected pointer down event for trackpad');
'Unexpected pointer down event for trackpad');
} }
break; break;
case TargetPlatform.linux: case TargetPlatform.linux:
@ -454,8 +441,7 @@ class RawEditorState extends EditorState
var _doc = controller.document; var _doc = controller.document;
if (_doc.isEmpty() && widget.placeholder != null) { if (_doc.isEmpty() && widget.placeholder != null) {
final raw = widget.placeholder?.replaceAll(r'"', '\\"'); final raw = widget.placeholder?.replaceAll(r'"', '\\"');
_doc = Document.fromJson(jsonDecode( _doc = Document.fromJson(jsonDecode('[{"attributes":{"placeholder":true},"insert":"$raw\\n"}]'));
'[{"attributes":{"placeholder":true},"insert":"$raw\\n"}]'));
} }
Widget child = CompositedTransformTarget( Widget child = CompositedTransformTarget(
@ -492,8 +478,7 @@ class RawEditorState extends EditorState
/// the scroll view with [BaselineProxy] which mimics the editor's /// the scroll view with [BaselineProxy] which mimics the editor's
/// baseline. /// baseline.
// This implies that the first line has no styles applied to it. // This implies that the first line has no styles applied to it.
final baselinePadding = final baselinePadding = EdgeInsets.only(top: _styles!.paragraph!.verticalSpacing.top);
EdgeInsets.only(top: _styles!.paragraph!.verticalSpacing.top);
child = BaselineProxy( child = BaselineProxy(
textStyle: _styles!.paragraph!.style, textStyle: _styles!.paragraph!.style,
padding: baselinePadding, padding: baselinePadding,
@ -531,9 +516,7 @@ class RawEditorState extends EditorState
final constraints = widget.expands final constraints = widget.expands
? const BoxConstraints.expand() ? const BoxConstraints.expand()
: BoxConstraints( : BoxConstraints(minHeight: widget.minHeight ?? 0.0, maxHeight: widget.maxHeight ?? double.infinity);
minHeight: widget.minHeight ?? 0.0,
maxHeight: widget.maxHeight ?? double.infinity);
final isMacOS = Theme.of(context).platform == TargetPlatform.macOS; final isMacOS = Theme.of(context).platform == TargetPlatform.macOS;
@ -722,8 +705,7 @@ class RawEditorState extends EditorState
} }
KeyEventResult _handleSpaceKey(RawKeyEvent event) { KeyEventResult _handleSpaceKey(RawKeyEvent event) {
final child = final child = controller.document.queryChild(controller.selection.baseOffset);
controller.document.queryChild(controller.selection.baseOffset);
if (child.node == null) { if (child.node == null) {
return KeyEventResult.ignored; return KeyEventResult.ignored;
} }
@ -753,8 +735,7 @@ class RawEditorState extends EditorState
} }
KeyEventResult _handleTabKey(RawKeyEvent event) { KeyEventResult _handleTabKey(RawKeyEvent event) {
final child = final child = controller.document.queryChild(controller.selection.baseOffset);
controller.document.queryChild(controller.selection.baseOffset);
KeyEventResult insertTabCharacter() { KeyEventResult insertTabCharacter() {
controller.replaceText(controller.selection.baseOffset, 0, '\t', null); controller.replaceText(controller.selection.baseOffset, 0, '\t', null);
@ -813,15 +794,13 @@ class RawEditorState extends EditorState
void _moveCursor(int chars) { void _moveCursor(int chars) {
final selection = controller.selection; final selection = controller.selection;
controller.updateSelection( controller.updateSelection(
controller.selection.copyWith( controller.selection
baseOffset: selection.baseOffset + chars, .copyWith(baseOffset: selection.baseOffset + chars, extentOffset: selection.baseOffset + chars),
extentOffset: selection.baseOffset + chars),
ChangeSource.LOCAL); ChangeSource.LOCAL);
} }
void _updateSelectionForKeyPhrase(String phrase, Attribute attribute) { void _updateSelectionForKeyPhrase(String phrase, Attribute attribute) {
controller.replaceText(controller.selection.baseOffset - phrase.length, controller.replaceText(controller.selection.baseOffset - phrase.length, phrase.length, '\n', null);
phrase.length, '\n', null);
_moveCursor(-phrase.length); _moveCursor(-phrase.length);
controller controller
..formatSelection(attribute) ..formatSelection(attribute)
@ -829,8 +808,7 @@ class RawEditorState extends EditorState
..replaceText(controller.selection.baseOffset + 1, 1, '', null); ..replaceText(controller.selection.baseOffset + 1, 1, '', null);
} }
void _handleSelectionChanged( void _handleSelectionChanged(TextSelection selection, SelectionChangedCause cause) {
TextSelection selection, SelectionChangedCause cause) {
final oldSelection = controller.selection; final oldSelection = controller.selection;
controller.updateSelection(selection, ChangeSource.LOCAL); controller.updateSelection(selection, ChangeSource.LOCAL);
@ -872,10 +850,7 @@ class RawEditorState extends EditorState
// Checkbox tapping causes controller.selection to go to offset 0 // Checkbox tapping causes controller.selection to go to offset 0
// Stop toggling those two toolbar buttons // Stop toggling those two toolbar buttons
..toolbarButtonToggler = { ..toolbarButtonToggler = {Attribute.list.key: attribute, Attribute.header.key: Attribute.header};
Attribute.list.key: attribute,
Attribute.header.key: Attribute.header
};
// Go back from offset 0 to current selection // Go back from offset 0 to current selection
SchedulerBinding.instance.addPostFrameCallback((_) { SchedulerBinding.instance.addPostFrameCallback((_) {
@ -908,8 +883,7 @@ class RawEditorState extends EditorState
if (node is Line) { if (node is Line) {
final editableTextLine = _getEditableTextLineFromNode(node, context); final editableTextLine = _getEditableTextLineFromNode(node, context);
result.add(Directionality( result.add(Directionality(textDirection: getDirectionOfNode(node), child: editableTextLine));
textDirection: getDirectionOfNode(node), child: editableTextLine));
} else if (node is Block) { } else if (node is Block) {
final editableTextBlock = EditableTextBlock( final editableTextBlock = EditableTextBlock(
block: node, block: node,
@ -922,9 +896,7 @@ class RawEditorState extends EditorState
styles: _styles, styles: _styles,
enableInteractiveSelection: widget.enableInteractiveSelection, enableInteractiveSelection: widget.enableInteractiveSelection,
hasFocus: _hasFocus, hasFocus: _hasFocus,
contentPadding: attrs.containsKey(Attribute.codeBlock.key) contentPadding: attrs.containsKey(Attribute.codeBlock.key) ? const EdgeInsets.all(16) : null,
? const EdgeInsets.all(16)
: null,
embedBuilder: widget.embedBuilder, embedBuilder: widget.embedBuilder,
linkActionPicker: _linkActionPicker, linkActionPicker: _linkActionPicker,
onLaunchUrl: widget.onLaunchUrl, onLaunchUrl: widget.onLaunchUrl,
@ -935,8 +907,7 @@ class RawEditorState extends EditorState
readOnly: widget.readOnly, readOnly: widget.readOnly,
customStyleBuilder: widget.customStyleBuilder, customStyleBuilder: widget.customStyleBuilder,
customLinkPrefixes: widget.customLinkPrefixes); customLinkPrefixes: widget.customLinkPrefixes);
result.add(Directionality( result.add(Directionality(textDirection: getDirectionOfNode(node), child: editableTextBlock));
textDirection: getDirectionOfNode(node), child: editableTextBlock));
clearIndents = false; clearIndents = false;
} else { } else {
@ -948,8 +919,7 @@ class RawEditorState extends EditorState
return result; return result;
} }
EditableTextLine _getEditableTextLineFromNode( EditableTextLine _getEditableTextLineFromNode(Line node, BuildContext context) {
Line node, BuildContext context) {
final textLine = TextLine( final textLine = TextLine(
line: node, line: node,
textDirection: _textDirection, textDirection: _textDirection,
@ -979,8 +949,7 @@ class RawEditorState extends EditorState
return editableTextLine; return editableTextLine;
} }
VerticalSpacing _getVerticalSpacingForLine( VerticalSpacing _getVerticalSpacingForLine(Line line, DefaultStyles? defaultStyles) {
Line line, DefaultStyles? defaultStyles) {
final attrs = line.style.attributes; final attrs = line.style.attributes;
if (attrs.containsKey(Attribute.header.key)) { if (attrs.containsKey(Attribute.header.key)) {
int level; int level;
@ -1004,8 +973,7 @@ class RawEditorState extends EditorState
return defaultStyles!.paragraph!.verticalSpacing; return defaultStyles!.paragraph!.verticalSpacing;
} }
VerticalSpacing _getVerticalSpacingForBlock( VerticalSpacing _getVerticalSpacingForBlock(Block node, DefaultStyles? defaultStyles) {
Block node, DefaultStyles? defaultStyles) {
final attrs = node.style.attributes; final attrs = node.style.attributes;
if (attrs.containsKey(Attribute.blockQuote.key)) { if (attrs.containsKey(Attribute.blockQuote.key)) {
return defaultStyles!.quote!.verticalSpacing; return defaultStyles!.quote!.verticalSpacing;
@ -1057,8 +1025,7 @@ class RawEditorState extends EditorState
} else { } else {
_keyboardVisibilityController = KeyboardVisibilityController(); _keyboardVisibilityController = KeyboardVisibilityController();
_keyboardVisible = _keyboardVisibilityController!.isVisible; _keyboardVisible = _keyboardVisibilityController!.isVisible;
_keyboardVisibilitySubscription = _keyboardVisibilitySubscription = _keyboardVisibilityController?.onChange.listen((visible) {
_keyboardVisibilityController?.onChange.listen((visible) {
_keyboardVisible = visible; _keyboardVisible = visible;
if (visible) { if (visible) {
_onChangeTextEditingValue(!_hasFocus); _onChangeTextEditingValue(!_hasFocus);
@ -1100,9 +1067,7 @@ class RawEditorState extends EditorState
super.didChangeDependencies(); super.didChangeDependencies();
final parentStyles = QuillStyles.getStyles(context, true); final parentStyles = QuillStyles.getStyles(context, true);
final defaultStyles = DefaultStyles.getInstance(context); final defaultStyles = DefaultStyles.getInstance(context);
_styles = (parentStyles != null) _styles = (parentStyles != null) ? defaultStyles.merge(parentStyles) : defaultStyles;
? defaultStyles.merge(parentStyles)
: defaultStyles;
if (widget.customStyles != null) { if (widget.customStyles != null) {
_styles = _styles!.merge(widget.customStyles!); _styles = _styles!.merge(widget.customStyles!);
@ -1270,9 +1235,8 @@ class RawEditorState extends EditorState
selectionCtrls: widget.selectionCtrls, selectionCtrls: widget.selectionCtrls,
selectionDelegate: this, selectionDelegate: this,
clipboardStatus: _clipboardStatus, clipboardStatus: _clipboardStatus,
contextMenuBuilder: widget.contextMenuBuilder == null contextMenuBuilder:
? null widget.contextMenuBuilder == null ? null : (context) => widget.contextMenuBuilder!(context, this),
: (context) => widget.contextMenuBuilder!(context, this),
); );
_selectionOverlay!.handlesVisible = _shouldShowSelectionHandles(); _selectionOverlay!.handlesVisible = _shouldShowSelectionHandles();
_selectionOverlay!.showHandles(); _selectionOverlay!.showHandles();
@ -1281,8 +1245,7 @@ class RawEditorState extends EditorState
void _handleFocusChanged() { void _handleFocusChanged() {
if (dirty) { if (dirty) {
SchedulerBinding.instance SchedulerBinding.instance.addPostFrameCallback((_) => _handleFocusChanged());
.addPostFrameCallback((_) => _handleFocusChanged());
return; return;
} }
openOrCloseConnection(); openOrCloseConnection();
@ -1333,8 +1296,7 @@ class RawEditorState extends EditorState
} }
final viewport = RenderAbstractViewport.of(renderEditor); final viewport = RenderAbstractViewport.of(renderEditor);
final editorOffset = final editorOffset = renderEditor.localToGlobal(const Offset(0, 0), ancestor: viewport);
renderEditor.localToGlobal(const Offset(0, 0), ancestor: viewport);
final offsetInViewport = _scrollController.offset + editorOffset.dy; final offsetInViewport = _scrollController.offset + editorOffset.dy;
final offset = renderEditor.getOffsetToRevealCursor( final offset = renderEditor.getOffsetToRevealCursor(
@ -1362,8 +1324,7 @@ class RawEditorState extends EditorState
/// ///
/// This property is typically used to notify the renderer of input gestures. /// This property is typically used to notify the renderer of input gestures.
@override @override
RenderEditor get renderEditor => RenderEditor get renderEditor => _editorKey.currentContext!.findRenderObject() as RenderEditor;
_editorKey.currentContext!.findRenderObject() as RenderEditor;
/// Express interest in interacting with the keyboard. /// Express interest in interacting with the keyboard.
/// ///
@ -1424,8 +1385,7 @@ class RawEditorState extends EditorState
void _replaceText(ReplaceTextIntent intent) { void _replaceText(ReplaceTextIntent intent) {
userUpdateTextEditingValue( userUpdateTextEditingValue(
intent.currentTextEditingValue intent.currentTextEditingValue.replaced(intent.replacementRange, intent.replacementText),
.replaced(intent.replacementRange, intent.replacementText),
intent.cause, intent.cause,
); );
} }
@ -1451,8 +1411,7 @@ class RawEditorState extends EditorState
userUpdateTextEditingValue( userUpdateTextEditingValue(
TextEditingValue( TextEditingValue(
text: textEditingValue.text, text: textEditingValue.text,
selection: selection: TextSelection.collapsed(offset: textEditingValue.selection.end),
TextSelection.collapsed(offset: textEditingValue.selection.end),
), ),
SelectionChangedCause.toolbar, SelectionChangedCause.toolbar,
); );
@ -1496,8 +1455,7 @@ class RawEditorState extends EditorState
final copied = controller.copiedImageUrl!; final copied = controller.copiedImageUrl!;
controller.replaceText(index, length, BlockEmbed.image(copied.url), null); controller.replaceText(index, length, BlockEmbed.image(copied.url), null);
if (copied.styleString.isNotEmpty) { if (copied.styleString.isNotEmpty) {
controller.formatText(getEmbedNode(controller, index + 1).offset, 1, controller.formatText(getEmbedNode(controller, index + 1).offset, 1, StyleAttribute(copied.styleString));
StyleAttribute(copied.styleString));
} }
controller.copiedImageUrl = null; controller.copiedImageUrl = null;
await Clipboard.setData(const ClipboardData(text: '')); await Clipboard.setData(const ClipboardData(text: ''));
@ -1512,8 +1470,7 @@ class RawEditorState extends EditorState
// See https://github.com/flutter/flutter/issues/11427 // See https://github.com/flutter/flutter/issues/11427
final text = await Clipboard.getData(Clipboard.kTextPlain); final text = await Clipboard.getData(Clipboard.kTextPlain);
if (text != null) { if (text != null) {
_replaceText( _replaceText(ReplaceTextIntent(textEditingValue, text.text!, selection, cause));
ReplaceTextIntent(textEditingValue, text.text!, selection, cause));
bringIntoView(textEditingValue.selection.extent); bringIntoView(textEditingValue.selection.extent);
@ -1521,8 +1478,7 @@ class RawEditorState extends EditorState
userUpdateTextEditingValue( userUpdateTextEditingValue(
TextEditingValue( TextEditingValue(
text: textEditingValue.text, text: textEditingValue.text,
selection: selection: TextSelection.collapsed(offset: textEditingValue.selection.end),
TextSelection.collapsed(offset: textEditingValue.selection.end),
), ),
cause, cause,
); );
@ -1556,8 +1512,7 @@ class RawEditorState extends EditorState
void selectAll(SelectionChangedCause cause) { void selectAll(SelectionChangedCause cause) {
userUpdateTextEditingValue( userUpdateTextEditingValue(
textEditingValue.copyWith( textEditingValue.copyWith(
selection: TextSelection( selection: TextSelection(baseOffset: 0, extentOffset: textEditingValue.text.length),
baseOffset: 0, extentOffset: textEditingValue.text.length),
), ),
cause, cause,
); );
@ -1571,16 +1526,14 @@ class RawEditorState extends EditorState
bool get wantKeepAlive => widget.focusNode.hasFocus; bool get wantKeepAlive => widget.focusNode.hasFocus;
@override @override
AnimationController get floatingCursorResetController => AnimationController get floatingCursorResetController => _floatingCursorResetController;
_floatingCursorResetController;
late AnimationController _floatingCursorResetController; late AnimationController _floatingCursorResetController;
// --------------------------- Text Editing Actions -------------------------- // --------------------------- Text Editing Actions --------------------------
_TextBoundary _characterBoundary(DirectionalTextEditingIntent intent) { _TextBoundary _characterBoundary(DirectionalTextEditingIntent intent) {
final _TextBoundary atomicTextBoundary = final _TextBoundary atomicTextBoundary = _CharacterBoundary(textEditingValue);
_CharacterBoundary(textEditingValue);
return _CollapsedSelectionBoundary(atomicTextBoundary, intent.forward); return _CollapsedSelectionBoundary(atomicTextBoundary, intent.forward);
} }
@ -1592,12 +1545,11 @@ class RawEditorState extends EditorState
// _textEditingValueforTextLayoutMetrics; // _textEditingValueforTextLayoutMetrics;
atomicTextBoundary = _CharacterBoundary(textEditingValue); atomicTextBoundary = _CharacterBoundary(textEditingValue);
// This isn't enough. Newline characters. // This isn't enough. Newline characters.
boundary = _ExpandedTextBoundary(_WhitespaceBoundary(textEditingValue), boundary =
_WordBoundary(renderEditor, textEditingValue)); _ExpandedTextBoundary(_WhitespaceBoundary(textEditingValue), _WordBoundary(renderEditor, textEditingValue));
final mixedBoundary = intent.forward final mixedBoundary =
? _MixedBoundary(atomicTextBoundary, boundary) intent.forward ? _MixedBoundary(atomicTextBoundary, boundary) : _MixedBoundary(boundary, atomicTextBoundary);
: _MixedBoundary(boundary, atomicTextBoundary);
// Use a _MixedBoundary to make sure we don't leave invalid codepoints in // Use a _MixedBoundary to make sure we don't leave invalid codepoints in
// the field after deletion. // the field after deletion.
return _CollapsedSelectionBoundary(mixedBoundary, intent.forward); return _CollapsedSelectionBoundary(mixedBoundary, intent.forward);
@ -1618,22 +1570,17 @@ class RawEditorState extends EditorState
// since the document boundary is unique and the linebreak boundary is // since the document boundary is unique and the linebreak boundary is
// already caret-location based. // already caret-location based.
return intent.forward return intent.forward
? _MixedBoundary( ? _MixedBoundary(_CollapsedSelectionBoundary(atomicTextBoundary, true), boundary)
_CollapsedSelectionBoundary(atomicTextBoundary, true), boundary) : _MixedBoundary(boundary, _CollapsedSelectionBoundary(atomicTextBoundary, false));
: _MixedBoundary(
boundary, _CollapsedSelectionBoundary(atomicTextBoundary, false));
} }
_TextBoundary _documentBoundary(DirectionalTextEditingIntent intent) => _TextBoundary _documentBoundary(DirectionalTextEditingIntent intent) => _DocumentBoundary(textEditingValue);
_DocumentBoundary(textEditingValue);
Action<T> _makeOverridable<T extends Intent>(Action<T> defaultAction) { Action<T> _makeOverridable<T extends Intent>(Action<T> defaultAction) {
return Action<T>.overridable( return Action<T>.overridable(context: context, defaultAction: defaultAction);
context: context, defaultAction: defaultAction);
} }
late final Action<ReplaceTextIntent> _replaceTextAction = late final Action<ReplaceTextIntent> _replaceTextAction = CallbackAction<ReplaceTextIntent>(onInvoke: _replaceText);
CallbackAction<ReplaceTextIntent>(onInvoke: _replaceText);
void _updateSelection(UpdateSelectionIntent intent) { void _updateSelection(UpdateSelectionIntent intent) {
userUpdateTextEditingValue( userUpdateTextEditingValue(
@ -1645,21 +1592,17 @@ class RawEditorState extends EditorState
late final Action<UpdateSelectionIntent> _updateSelectionAction = late final Action<UpdateSelectionIntent> _updateSelectionAction =
CallbackAction<UpdateSelectionIntent>(onInvoke: _updateSelection); CallbackAction<UpdateSelectionIntent>(onInvoke: _updateSelection);
late final _UpdateTextSelectionToAdjacentLineAction< late final _UpdateTextSelectionToAdjacentLineAction<ExtendSelectionVerticallyToAdjacentLineIntent>
ExtendSelectionVerticallyToAdjacentLineIntent> _adjacentLineAction = _adjacentLineAction =
_UpdateTextSelectionToAdjacentLineAction< _UpdateTextSelectionToAdjacentLineAction<ExtendSelectionVerticallyToAdjacentLineIntent>(this);
ExtendSelectionVerticallyToAdjacentLineIntent>(this);
late final _ToggleTextStyleAction _formatSelectionAction = late final _ToggleTextStyleAction _formatSelectionAction = _ToggleTextStyleAction(this);
_ToggleTextStyleAction(this);
late final _IndentSelectionAction _indentSelectionAction = late final _IndentSelectionAction _indentSelectionAction = _IndentSelectionAction(this);
_IndentSelectionAction(this);
late final _OpenSearchAction _openSearchAction = _OpenSearchAction(this); late final _OpenSearchAction _openSearchAction = _OpenSearchAction(this);
late final _ApplyHeaderAction _applyHeaderAction = _ApplyHeaderAction(this); late final _ApplyHeaderAction _applyHeaderAction = _ApplyHeaderAction(this);
late final _ApplyCheckListAction _applyCheckListAction = late final _ApplyCheckListAction _applyCheckListAction = _ApplyCheckListAction(this);
_ApplyCheckListAction(this);
late final Map<Type, Action<Intent>> _actions = <Type, Action<Intent>>{ late final Map<Type, Action<Intent>> _actions = <Type, Action<Intent>>{
DoNothingAndStopPropagationTextIntent: DoNothingAction(consumesKey: false), DoNothingAndStopPropagationTextIntent: DoNothingAction(consumesKey: false),
@ -1668,43 +1611,33 @@ class RawEditorState extends EditorState
DirectionalFocusIntent: DirectionalFocusAction.forTextField(), DirectionalFocusIntent: DirectionalFocusAction.forTextField(),
// Delete // Delete
DeleteCharacterIntent: _makeOverridable( DeleteCharacterIntent: _makeOverridable(_DeleteTextAction<DeleteCharacterIntent>(this, _characterBoundary)),
_DeleteTextAction<DeleteCharacterIntent>(this, _characterBoundary)), DeleteToNextWordBoundaryIntent:
DeleteToNextWordBoundaryIntent: _makeOverridable( _makeOverridable(_DeleteTextAction<DeleteToNextWordBoundaryIntent>(this, _nextWordBoundary)),
_DeleteTextAction<DeleteToNextWordBoundaryIntent>( DeleteToLineBreakIntent: _makeOverridable(_DeleteTextAction<DeleteToLineBreakIntent>(this, _linebreak)),
this, _nextWordBoundary)),
DeleteToLineBreakIntent: _makeOverridable(
_DeleteTextAction<DeleteToLineBreakIntent>(this, _linebreak)),
// Extend/Move Selection // Extend/Move Selection
ExtendSelectionByCharacterIntent: _makeOverridable( ExtendSelectionByCharacterIntent: _makeOverridable(_UpdateTextSelectionAction<ExtendSelectionByCharacterIntent>(
_UpdateTextSelectionAction<ExtendSelectionByCharacterIntent>(
this, this,
false, false,
_characterBoundary, _characterBoundary,
)), )),
ExtendSelectionToNextWordBoundaryIntent: _makeOverridable( ExtendSelectionToNextWordBoundaryIntent: _makeOverridable(
_UpdateTextSelectionAction<ExtendSelectionToNextWordBoundaryIntent>( _UpdateTextSelectionAction<ExtendSelectionToNextWordBoundaryIntent>(this, true, _nextWordBoundary)),
this, true, _nextWordBoundary)), ExtendSelectionToLineBreakIntent:
ExtendSelectionToLineBreakIntent: _makeOverridable( _makeOverridable(_UpdateTextSelectionAction<ExtendSelectionToLineBreakIntent>(this, true, _linebreak)),
_UpdateTextSelectionAction<ExtendSelectionToLineBreakIntent>( ExtendSelectionVerticallyToAdjacentLineIntent: _makeOverridable(_adjacentLineAction),
this, true, _linebreak)),
ExtendSelectionVerticallyToAdjacentLineIntent:
_makeOverridable(_adjacentLineAction),
ExtendSelectionToDocumentBoundaryIntent: _makeOverridable( ExtendSelectionToDocumentBoundaryIntent: _makeOverridable(
_UpdateTextSelectionAction<ExtendSelectionToDocumentBoundaryIntent>( _UpdateTextSelectionAction<ExtendSelectionToDocumentBoundaryIntent>(this, true, _documentBoundary)),
this, true, _documentBoundary)), ExtendSelectionToNextWordBoundaryOrCaretLocationIntent:
ExtendSelectionToNextWordBoundaryOrCaretLocationIntent: _makeOverridable( _makeOverridable(_ExtendSelectionOrCaretPositionAction(this, _nextWordBoundary)),
_ExtendSelectionOrCaretPositionAction(this, _nextWordBoundary)),
// Copy Paste // Copy Paste
SelectAllTextIntent: _makeOverridable(_SelectAllAction(this)), SelectAllTextIntent: _makeOverridable(_SelectAllAction(this)),
CopySelectionTextIntent: _makeOverridable(_CopySelectionAction(this)), CopySelectionTextIntent: _makeOverridable(_CopySelectionAction(this)),
PasteTextIntent: _makeOverridable(CallbackAction<PasteTextIntent>( PasteTextIntent: _makeOverridable(CallbackAction<PasteTextIntent>(onInvoke: (intent) => pasteText(intent.cause))),
onInvoke: (intent) => pasteText(intent.cause))),
HideSelectionToolbarIntent: HideSelectionToolbarIntent: _makeOverridable(_HideSelectionToolbarAction(this)),
_makeOverridable(_HideSelectionToolbarAction(this)),
UndoTextIntent: _makeOverridable(_UndoKeyboardAction(this)), UndoTextIntent: _makeOverridable(_UndoKeyboardAction(this)),
RedoTextIntent: _makeOverridable(_RedoKeyboardAction(this)), RedoTextIntent: _makeOverridable(_RedoKeyboardAction(this)),
@ -1731,8 +1664,7 @@ class RawEditorState extends EditorState
} }
@override @override
void didChangeInputControl( void didChangeInputControl(TextInputControl? oldControl, TextInputControl? newControl) {
TextInputControl? oldControl, TextInputControl? newControl) {
// TODO: implement didChangeInputControl // TODO: implement didChangeInputControl
} }
@ -1811,8 +1743,7 @@ class _Editor extends MultiChildRenderObjectWidget {
} }
@override @override
void updateRenderObject( void updateRenderObject(BuildContext context, covariant RenderEditor renderObject) {
BuildContext context, covariant RenderEditor renderObject) {
renderObject renderObject
..offset = offset ..offset = offset
..document = document ..document = document
@ -1881,8 +1812,7 @@ class _WhitespaceBoundary extends _TextBoundary {
@override @override
TextPosition getLeadingTextBoundaryAt(TextPosition position) { TextPosition getLeadingTextBoundaryAt(TextPosition position) {
for (var index = position.offset; index >= 0; index -= 1) { for (var index = position.offset; index >= 0; index -= 1) {
if (!TextLayoutMetrics.isWhitespace( if (!TextLayoutMetrics.isWhitespace(textEditingValue.text.codeUnitAt(index))) {
textEditingValue.text.codeUnitAt(index))) {
return TextPosition(offset: index); return TextPosition(offset: index);
} }
} }
@ -1891,11 +1821,8 @@ class _WhitespaceBoundary extends _TextBoundary {
@override @override
TextPosition getTrailingTextBoundaryAt(TextPosition position) { TextPosition getTrailingTextBoundaryAt(TextPosition position) {
for (var index = position.offset; for (var index = position.offset; index < textEditingValue.text.length; index += 1) {
index < textEditingValue.text.length; if (!TextLayoutMetrics.isWhitespace(textEditingValue.text.codeUnitAt(index))) {
index += 1) {
if (!TextLayoutMetrics.isWhitespace(
textEditingValue.text.codeUnitAt(index))) {
return TextPosition(offset: index + 1); return TextPosition(offset: index + 1);
} }
} }
@ -1914,21 +1841,16 @@ class _CharacterBoundary extends _TextBoundary {
@override @override
TextPosition getLeadingTextBoundaryAt(TextPosition position) { TextPosition getLeadingTextBoundaryAt(TextPosition position) {
final int endOffset = final int endOffset = math.min(position.offset + 1, textEditingValue.text.length);
math.min(position.offset + 1, textEditingValue.text.length);
return TextPosition( return TextPosition(
offset: offset: CharacterRange.at(textEditingValue.text, position.offset, endOffset).stringBeforeLength,
CharacterRange.at(textEditingValue.text, position.offset, endOffset)
.stringBeforeLength,
); );
} }
@override @override
TextPosition getTrailingTextBoundaryAt(TextPosition position) { TextPosition getTrailingTextBoundaryAt(TextPosition position) {
final int endOffset = final int endOffset = math.min(position.offset + 1, textEditingValue.text.length);
math.min(position.offset + 1, textEditingValue.text.length); final range = CharacterRange.at(textEditingValue.text, position.offset, endOffset);
final range =
CharacterRange.at(textEditingValue.text, position.offset, endOffset);
return TextPosition( return TextPosition(
offset: textEditingValue.text.length - range.stringAfterLength, offset: textEditingValue.text.length - range.stringAfterLength,
); );
@ -1936,10 +1858,8 @@ class _CharacterBoundary extends _TextBoundary {
@override @override
TextRange getTextBoundaryAt(TextPosition position) { TextRange getTextBoundaryAt(TextPosition position) {
final int endOffset = final int endOffset = math.min(position.offset + 1, textEditingValue.text.length);
math.min(position.offset + 1, textEditingValue.text.length); final range = CharacterRange.at(textEditingValue.text, position.offset, endOffset);
final range =
CharacterRange.at(textEditingValue.text, position.offset, endOffset);
return TextRange( return TextRange(
start: range.stringBeforeLength, start: range.stringBeforeLength,
end: textEditingValue.text.length - range.stringAfterLength, end: textEditingValue.text.length - range.stringAfterLength,
@ -1961,8 +1881,7 @@ class _WordBoundary extends _TextBoundary {
return TextPosition( return TextPosition(
offset: textLayout.getWordBoundary(position).start, offset: textLayout.getWordBoundary(position).start,
// Word boundary seems to always report downstream on many platforms. // Word boundary seems to always report downstream on many platforms.
affinity: affinity: TextAffinity.downstream, // ignore: avoid_redundant_argument_values
TextAffinity.downstream, // ignore: avoid_redundant_argument_values
); );
} }
@ -1971,8 +1890,7 @@ class _WordBoundary extends _TextBoundary {
return TextPosition( return TextPosition(
offset: textLayout.getWordBoundary(position).end, offset: textLayout.getWordBoundary(position).end,
// Word boundary seems to always report downstream on many platforms. // Word boundary seems to always report downstream on many platforms.
affinity: affinity: TextAffinity.downstream, // ignore: avoid_redundant_argument_values
TextAffinity.downstream, // ignore: avoid_redundant_argument_values
); );
} }
} }
@ -2013,8 +1931,7 @@ class _DocumentBoundary extends _TextBoundary {
final TextEditingValue textEditingValue; final TextEditingValue textEditingValue;
@override @override
TextPosition getLeadingTextBoundaryAt(TextPosition position) => TextPosition getLeadingTextBoundaryAt(TextPosition position) => const TextPosition(offset: 0);
const TextPosition(offset: 0);
@override @override
TextPosition getTrailingTextBoundaryAt(TextPosition position) { TextPosition getTrailingTextBoundaryAt(TextPosition position) {
@ -2036,8 +1953,7 @@ class _ExpandedTextBoundary extends _TextBoundary {
@override @override
TextEditingValue get textEditingValue { TextEditingValue get textEditingValue {
assert(innerTextBoundary.textEditingValue == assert(innerTextBoundary.textEditingValue == outerTextBoundary.textEditingValue);
outerTextBoundary.textEditingValue);
return innerTextBoundary.textEditingValue; return innerTextBoundary.textEditingValue;
} }
@ -2076,8 +1992,7 @@ class _CollapsedSelectionBoundary extends _TextBoundary {
? innerTextBoundary.getLeadingTextBoundaryAt(position) ? innerTextBoundary.getLeadingTextBoundaryAt(position)
: position.offset <= 0 : position.offset <= 0
? const TextPosition(offset: 0) ? const TextPosition(offset: 0)
: innerTextBoundary.getLeadingTextBoundaryAt( : innerTextBoundary.getLeadingTextBoundaryAt(TextPosition(offset: position.offset - 1));
TextPosition(offset: position.offset - 1));
} }
@override @override
@ -2086,8 +2001,7 @@ class _CollapsedSelectionBoundary extends _TextBoundary {
? innerTextBoundary.getTrailingTextBoundaryAt(position) ? innerTextBoundary.getTrailingTextBoundaryAt(position)
: position.offset <= 0 : position.offset <= 0
? const TextPosition(offset: 0) ? const TextPosition(offset: 0)
: innerTextBoundary.getTrailingTextBoundaryAt( : innerTextBoundary.getTrailingTextBoundaryAt(TextPosition(offset: position.offset - 1));
TextPosition(offset: position.offset - 1));
} }
} }
@ -2102,8 +2016,7 @@ class _MixedBoundary extends _TextBoundary {
@override @override
TextEditingValue get textEditingValue { TextEditingValue get textEditingValue {
assert(leadingTextBoundary.textEditingValue == assert(leadingTextBoundary.textEditingValue == trailingTextBoundary.textEditingValue);
trailingTextBoundary.textEditingValue);
return leadingTextBoundary.textEditingValue; return leadingTextBoundary.textEditingValue;
} }
@ -2117,8 +2030,7 @@ class _MixedBoundary extends _TextBoundary {
} }
// ------------------------------- Text Actions ------------------------------- // ------------------------------- Text Actions -------------------------------
class _DeleteTextAction<T extends DirectionalTextEditingIntent> class _DeleteTextAction<T extends DirectionalTextEditingIntent> extends ContextAction<T> {
extends ContextAction<T> {
_DeleteTextAction(this.state, this.getTextBoundariesForIntent); _DeleteTextAction(this.state, this.getTextBoundariesForIntent);
final RawEditorState state; final RawEditorState state;
@ -2131,12 +2043,8 @@ class _DeleteTextAction<T extends DirectionalTextEditingIntent>
final _TextBoundary atomicBoundary = _CharacterBoundary(value); final _TextBoundary atomicBoundary = _CharacterBoundary(value);
return TextRange( return TextRange(
start: atomicBoundary start: atomicBoundary.getLeadingTextBoundaryAt(TextPosition(offset: selection.start)).offset,
.getLeadingTextBoundaryAt(TextPosition(offset: selection.start)) end: atomicBoundary.getTrailingTextBoundaryAt(TextPosition(offset: selection.end - 1)).offset,
.offset,
end: atomicBoundary
.getTrailingTextBoundaryAt(TextPosition(offset: selection.end - 1))
.offset,
); );
} }
@ -2148,10 +2056,7 @@ class _DeleteTextAction<T extends DirectionalTextEditingIntent>
if (!selection.isCollapsed) { if (!selection.isCollapsed) {
return Actions.invoke( return Actions.invoke(
context!, context!,
ReplaceTextIntent( ReplaceTextIntent(state.textEditingValue, '', _expandNonCollapsedRange(state.textEditingValue),
state.textEditingValue,
'',
_expandNonCollapsedRange(state.textEditingValue),
SelectionChangedCause.keyboard), SelectionChangedCause.keyboard),
); );
} }
@ -2163,10 +2068,7 @@ class _DeleteTextAction<T extends DirectionalTextEditingIntent>
if (!textBoundary.textEditingValue.selection.isCollapsed) { if (!textBoundary.textEditingValue.selection.isCollapsed) {
return Actions.invoke( return Actions.invoke(
context!, context!,
ReplaceTextIntent( ReplaceTextIntent(state.textEditingValue, '', _expandNonCollapsedRange(textBoundary.textEditingValue),
state.textEditingValue,
'',
_expandNonCollapsedRange(textBoundary.textEditingValue),
SelectionChangedCause.keyboard), SelectionChangedCause.keyboard),
); );
} }
@ -2176,22 +2078,18 @@ class _DeleteTextAction<T extends DirectionalTextEditingIntent>
ReplaceTextIntent( ReplaceTextIntent(
textBoundary.textEditingValue, textBoundary.textEditingValue,
'', '',
textBoundary textBoundary.getTextBoundaryAt(textBoundary.textEditingValue.selection.base),
.getTextBoundaryAt(textBoundary.textEditingValue.selection.base),
SelectionChangedCause.keyboard, SelectionChangedCause.keyboard,
), ),
); );
} }
@override @override
bool get isActionEnabled => bool get isActionEnabled => !state.widget.readOnly && state.textEditingValue.selection.isValid;
!state.widget.readOnly && state.textEditingValue.selection.isValid;
} }
class _UpdateTextSelectionAction<T extends DirectionalCaretMovementIntent> class _UpdateTextSelectionAction<T extends DirectionalCaretMovementIntent> extends ContextAction<T> {
extends ContextAction<T> { _UpdateTextSelectionAction(this.state, this.ignoreNonCollapsedSelection, this.getTextBoundariesForIntent);
_UpdateTextSelectionAction(this.state, this.ignoreNonCollapsedSelection,
this.getTextBoundariesForIntent);
final RawEditorState state; final RawEditorState state;
final bool ignoreNonCollapsedSelection; final bool ignoreNonCollapsedSelection;
@ -2202,8 +2100,7 @@ class _UpdateTextSelectionAction<T extends DirectionalCaretMovementIntent>
final selection = state.textEditingValue.selection; final selection = state.textEditingValue.selection;
assert(selection.isValid); assert(selection.isValid);
final collapseSelection = final collapseSelection = intent.collapseSelection || !state.widget.selectionEnabled;
intent.collapseSelection || !state.widget.selectionEnabled;
// Collapse to the logical start/end. // Collapse to the logical start/end.
TextSelection _collapse(TextSelection selection) { TextSelection _collapse(TextSelection selection) {
assert(selection.isValid); assert(selection.isValid);
@ -2214,13 +2111,10 @@ class _UpdateTextSelectionAction<T extends DirectionalCaretMovementIntent>
); );
} }
if (!selection.isCollapsed && if (!selection.isCollapsed && !ignoreNonCollapsedSelection && collapseSelection) {
!ignoreNonCollapsedSelection &&
collapseSelection) {
return Actions.invoke( return Actions.invoke(
context!, context!,
UpdateSelectionIntent(state.textEditingValue, _collapse(selection), UpdateSelectionIntent(state.textEditingValue, _collapse(selection), SelectionChangedCause.keyboard),
SelectionChangedCause.keyboard),
); );
} }
@ -2229,30 +2123,24 @@ class _UpdateTextSelectionAction<T extends DirectionalCaretMovementIntent>
if (!textBoundarySelection.isValid) { if (!textBoundarySelection.isValid) {
return null; return null;
} }
if (!textBoundarySelection.isCollapsed && if (!textBoundarySelection.isCollapsed && !ignoreNonCollapsedSelection && collapseSelection) {
!ignoreNonCollapsedSelection &&
collapseSelection) {
return Actions.invoke( return Actions.invoke(
context!, context!,
UpdateSelectionIntent(state.textEditingValue, UpdateSelectionIntent(state.textEditingValue, _collapse(textBoundarySelection), SelectionChangedCause.keyboard),
_collapse(textBoundarySelection), SelectionChangedCause.keyboard),
); );
} }
final extent = textBoundarySelection.extent; final extent = textBoundarySelection.extent;
final newExtent = intent.forward final newExtent =
? textBoundary.getTrailingTextBoundaryAt(extent) intent.forward ? textBoundary.getTrailingTextBoundaryAt(extent) : textBoundary.getLeadingTextBoundaryAt(extent);
: textBoundary.getLeadingTextBoundaryAt(extent);
final newSelection = collapseSelection final newSelection =
? TextSelection.fromPosition(newExtent) collapseSelection ? TextSelection.fromPosition(newExtent) : textBoundarySelection.extendTo(newExtent);
: textBoundarySelection.extendTo(newExtent);
// If collapseAtReversal is true and would have an effect, collapse it. // If collapseAtReversal is true and would have an effect, collapse it.
if (!selection.isCollapsed && if (!selection.isCollapsed &&
intent.collapseAtReversal && intent.collapseAtReversal &&
(selection.baseOffset < selection.extentOffset != (selection.baseOffset < selection.extentOffset != newSelection.baseOffset < newSelection.extentOffset)) {
newSelection.baseOffset < newSelection.extentOffset)) {
return Actions.invoke( return Actions.invoke(
context!, context!,
UpdateSelectionIntent( UpdateSelectionIntent(
@ -2265,8 +2153,7 @@ class _UpdateTextSelectionAction<T extends DirectionalCaretMovementIntent>
return Actions.invoke( return Actions.invoke(
context!, context!,
UpdateSelectionIntent(textBoundary.textEditingValue, newSelection, UpdateSelectionIntent(textBoundary.textEditingValue, newSelection, SelectionChangedCause.keyboard),
SelectionChangedCause.keyboard),
); );
} }
@ -2274,19 +2161,16 @@ class _UpdateTextSelectionAction<T extends DirectionalCaretMovementIntent>
bool get isActionEnabled => state.textEditingValue.selection.isValid; bool get isActionEnabled => state.textEditingValue.selection.isValid;
} }
class _ExtendSelectionOrCaretPositionAction extends ContextAction< class _ExtendSelectionOrCaretPositionAction
ExtendSelectionToNextWordBoundaryOrCaretLocationIntent> { extends ContextAction<ExtendSelectionToNextWordBoundaryOrCaretLocationIntent> {
_ExtendSelectionOrCaretPositionAction( _ExtendSelectionOrCaretPositionAction(this.state, this.getTextBoundariesForIntent);
this.state, this.getTextBoundariesForIntent);
final RawEditorState state; final RawEditorState state;
final _TextBoundary Function( final _TextBoundary Function(ExtendSelectionToNextWordBoundaryOrCaretLocationIntent intent)
ExtendSelectionToNextWordBoundaryOrCaretLocationIntent intent)
getTextBoundariesForIntent; getTextBoundariesForIntent;
@override @override
Object? invoke(ExtendSelectionToNextWordBoundaryOrCaretLocationIntent intent, Object? invoke(ExtendSelectionToNextWordBoundaryOrCaretLocationIntent intent, [BuildContext? context]) {
[BuildContext? context]) {
final selection = state.textEditingValue.selection; final selection = state.textEditingValue.selection;
assert(selection.isValid); assert(selection.isValid);
@ -2297,18 +2181,15 @@ class _ExtendSelectionOrCaretPositionAction extends ContextAction<
} }
final extent = textBoundarySelection.extent; final extent = textBoundarySelection.extent;
final newExtent = intent.forward final newExtent =
? textBoundary.getTrailingTextBoundaryAt(extent) intent.forward ? textBoundary.getTrailingTextBoundaryAt(extent) : textBoundary.getLeadingTextBoundaryAt(extent);
: textBoundary.getLeadingTextBoundaryAt(extent);
final newSelection = (newExtent.offset - textBoundarySelection.baseOffset) * final newSelection = (newExtent.offset - textBoundarySelection.baseOffset) *
(textBoundarySelection.extentOffset - (textBoundarySelection.extentOffset - textBoundarySelection.baseOffset) <
textBoundarySelection.baseOffset) <
0 0
? textBoundarySelection.copyWith( ? textBoundarySelection.copyWith(
extentOffset: textBoundarySelection.baseOffset, extentOffset: textBoundarySelection.baseOffset,
affinity: textBoundarySelection.extentOffset > affinity: textBoundarySelection.extentOffset > textBoundarySelection.baseOffset
textBoundarySelection.baseOffset
? TextAffinity.downstream ? TextAffinity.downstream
: TextAffinity.upstream, : TextAffinity.upstream,
) )
@ -2316,18 +2197,15 @@ class _ExtendSelectionOrCaretPositionAction extends ContextAction<
return Actions.invoke( return Actions.invoke(
context!, context!,
UpdateSelectionIntent(textBoundary.textEditingValue, newSelection, UpdateSelectionIntent(textBoundary.textEditingValue, newSelection, SelectionChangedCause.keyboard),
SelectionChangedCause.keyboard),
); );
} }
@override @override
bool get isActionEnabled => bool get isActionEnabled => state.widget.selectionEnabled && state.textEditingValue.selection.isValid;
state.widget.selectionEnabled && state.textEditingValue.selection.isValid;
} }
class _UpdateTextSelectionToAdjacentLineAction< class _UpdateTextSelectionToAdjacentLineAction<T extends DirectionalCaretMovementIntent> extends ContextAction<T> {
T extends DirectionalCaretMovementIntent> extends ContextAction<T> {
_UpdateTextSelectionToAdjacentLineAction(this.state); _UpdateTextSelectionToAdjacentLineAction(this.state);
final RawEditorState state; final RawEditorState state;
@ -2357,32 +2235,25 @@ class _UpdateTextSelectionToAdjacentLineAction<
void invoke(T intent, [BuildContext? context]) { void invoke(T intent, [BuildContext? context]) {
assert(state.textEditingValue.selection.isValid); assert(state.textEditingValue.selection.isValid);
final collapseSelection = final collapseSelection = intent.collapseSelection || !state.widget.selectionEnabled;
intent.collapseSelection || !state.widget.selectionEnabled;
final value = state.textEditingValue; final value = state.textEditingValue;
if (!value.selection.isValid) { if (!value.selection.isValid) {
return; return;
} }
final currentRun = _verticalMovementRun ?? final currentRun =
state.renderEditor _verticalMovementRun ?? state.renderEditor.startVerticalCaretMovement(state.renderEditor.selection.extent);
.startVerticalCaretMovement(state.renderEditor.selection.extent);
final shouldMove = final shouldMove = intent.forward ? currentRun.moveNext() : currentRun.movePrevious();
intent.forward ? currentRun.moveNext() : currentRun.movePrevious();
final newExtent = shouldMove final newExtent = shouldMove
? currentRun.current ? currentRun.current
: (intent.forward : (intent.forward ? TextPosition(offset: state.textEditingValue.text.length) : const TextPosition(offset: 0));
? TextPosition(offset: state.textEditingValue.text.length) final newSelection =
: const TextPosition(offset: 0)); collapseSelection ? TextSelection.fromPosition(newExtent) : value.selection.extendTo(newExtent);
final newSelection = collapseSelection
? TextSelection.fromPosition(newExtent)
: value.selection.extendTo(newExtent);
Actions.invoke( Actions.invoke(
context!, context!,
UpdateSelectionIntent( UpdateSelectionIntent(value, newSelection, SelectionChangedCause.keyboard),
value, newSelection, SelectionChangedCause.keyboard),
); );
if (state.textEditingValue.selection == newSelection) { if (state.textEditingValue.selection == newSelection) {
_verticalMovementRun = currentRun; _verticalMovementRun = currentRun;
@ -2405,8 +2276,7 @@ class _SelectAllAction extends ContextAction<SelectAllTextIntent> {
context!, context!,
UpdateSelectionIntent( UpdateSelectionIntent(
state.textEditingValue, state.textEditingValue,
TextSelection( TextSelection(baseOffset: 0, extentOffset: state.textEditingValue.text.length),
baseOffset: 0, extentOffset: state.textEditingValue.text.length),
intent.cause, intent.cause,
), ),
); );
@ -2431,9 +2301,7 @@ class _CopySelectionAction extends ContextAction<CopySelectionTextIntent> {
} }
@override @override
bool get isActionEnabled => bool get isActionEnabled => state.textEditingValue.selection.isValid && !state.textEditingValue.selection.isCollapsed;
state.textEditingValue.selection.isValid &&
!state.textEditingValue.selection.isCollapsed;
} }
//Intent class for "escape" key to dismiss selection toolbar in Windows platform //Intent class for "escape" key to dismiss selection toolbar in Windows platform
@ -2441,8 +2309,7 @@ class HideSelectionToolbarIntent extends Intent {
const HideSelectionToolbarIntent(); const HideSelectionToolbarIntent();
} }
class _HideSelectionToolbarAction class _HideSelectionToolbarAction extends ContextAction<HideSelectionToolbarIntent> {
extends ContextAction<HideSelectionToolbarIntent> {
_HideSelectionToolbarAction(this.state); _HideSelectionToolbarAction(this.state);
final RawEditorState state; final RawEditorState state;
@ -2513,10 +2380,8 @@ class _ToggleTextStyleAction extends Action<ToggleTextStyleIntent> {
@override @override
void invoke(ToggleTextStyleIntent intent, [BuildContext? context]) { void invoke(ToggleTextStyleIntent intent, [BuildContext? context]) {
final isActive = _isStyleActive( final isActive = _isStyleActive(intent.attribute, state.controller.getSelectionStyle().attributes);
intent.attribute, state.controller.getSelectionStyle().attributes); state.controller.formatSelection(isActive ? Attribute.clone(intent.attribute, null) : intent.attribute);
state.controller.formatSelection(
isActive ? Attribute.clone(intent.attribute, null) : intent.attribute);
} }
@override @override
@ -2579,16 +2444,12 @@ class _ApplyHeaderAction extends Action<ApplyHeaderIntent> {
final RawEditorState state; final RawEditorState state;
Attribute<dynamic> _getHeaderValue() { Attribute<dynamic> _getHeaderValue() {
return state.controller return state.controller.getSelectionStyle().attributes[Attribute.header.key] ?? Attribute.header;
.getSelectionStyle()
.attributes[Attribute.header.key] ??
Attribute.header;
} }
@override @override
void invoke(ApplyHeaderIntent intent, [BuildContext? context]) { void invoke(ApplyHeaderIntent intent, [BuildContext? context]) {
final _attribute = final _attribute = _getHeaderValue() == intent.header ? Attribute.header : intent.header;
_getHeaderValue() == intent.header ? Attribute.header : intent.header;
state.controller.formatSelection(_attribute); state.controller.formatSelection(_attribute);
} }
@ -2620,15 +2481,13 @@ class _ApplyCheckListAction extends Action<ApplyCheckListIntent> {
if (attribute == null) { if (attribute == null) {
return false; return false;
} }
return attribute.value == Attribute.unchecked.value || return attribute.value == Attribute.unchecked.value || attribute.value == Attribute.checked.value;
attribute.value == Attribute.checked.value;
} }
@override @override
void invoke(ApplyCheckListIntent intent, [BuildContext? context]) { void invoke(ApplyCheckListIntent intent, [BuildContext? context]) {
state.controller.formatSelection(_getIsToggled() state.controller
? Attribute.clone(Attribute.unchecked, null) .formatSelection(_getIsToggled() ? Attribute.clone(Attribute.unchecked, null) : Attribute.unchecked);
: Attribute.unchecked);
} }
@override @override

Loading…
Cancel
Save