|
|
|
@ -233,7 +233,6 @@ class RawEditorState extends EditorState |
|
|
|
|
AutomaticKeepAliveClientMixin<RawEditor>, |
|
|
|
|
WidgetsBindingObserver, |
|
|
|
|
TickerProviderStateMixin<RawEditor>, |
|
|
|
|
TextEditingActionTarget, |
|
|
|
|
RawEditorStateTextInputClientMixin, |
|
|
|
|
RawEditorStateSelectionDelegateMixin { |
|
|
|
|
final GlobalKey _editorKey = GlobalKey(); |
|
|
|
@ -256,7 +255,6 @@ class RawEditorState extends EditorState |
|
|
|
|
|
|
|
|
|
// Focus |
|
|
|
|
bool _didAutoFocus = false; |
|
|
|
|
FocusAttachment? _focusAttachment; |
|
|
|
|
bool get _hasFocus => widget.focusNode.hasFocus; |
|
|
|
|
|
|
|
|
|
// Theme |
|
|
|
@ -280,7 +278,6 @@ class RawEditorState extends EditorState |
|
|
|
|
@override |
|
|
|
|
Widget build(BuildContext context) { |
|
|
|
|
assert(debugCheckHasMediaQuery(context)); |
|
|
|
|
_focusAttachment!.reparent(); |
|
|
|
|
super.build(context); |
|
|
|
|
|
|
|
|
|
var _doc = widget.controller.document; |
|
|
|
@ -575,7 +572,7 @@ class RawEditorState extends EditorState |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
_focusAttachment = widget.focusNode.attach(context); |
|
|
|
|
// Focus |
|
|
|
|
widget.focusNode.addListener(_handleFocusChanged); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -619,8 +616,6 @@ class RawEditorState extends EditorState |
|
|
|
|
|
|
|
|
|
if (widget.focusNode != oldWidget.focusNode) { |
|
|
|
|
oldWidget.focusNode.removeListener(_handleFocusChanged); |
|
|
|
|
_focusAttachment?.detach(); |
|
|
|
|
_focusAttachment = widget.focusNode.attach(context); |
|
|
|
|
widget.focusNode.addListener(_handleFocusChanged); |
|
|
|
|
updateKeepAlive(); |
|
|
|
|
} |
|
|
|
@ -658,7 +653,6 @@ class RawEditorState extends EditorState |
|
|
|
|
_selectionOverlay = null; |
|
|
|
|
widget.controller.removeListener(_didChangeTextEditingValue); |
|
|
|
|
widget.focusNode.removeListener(_handleFocusChanged); |
|
|
|
|
_focusAttachment!.detach(); |
|
|
|
|
_cursorCont.dispose(); |
|
|
|
|
_clipboardStatus |
|
|
|
|
..removeListener(_onChangedClipboardStatus) |
|
|
|
@ -835,8 +829,15 @@ class RawEditorState extends EditorState |
|
|
|
|
/// This property is typically used to notify the renderer of input gestures. |
|
|
|
|
@override |
|
|
|
|
RenderEditor get renderEditor => |
|
|
|
|
_editorKey.currentContext?.findRenderObject() as RenderEditor; |
|
|
|
|
_editorKey.currentContext!.findRenderObject() as RenderEditor; |
|
|
|
|
|
|
|
|
|
/// Express interest in interacting with the keyboard. |
|
|
|
|
/// |
|
|
|
|
/// If this control is already attached to the keyboard, this function will |
|
|
|
|
/// request that the keyboard become visible. Otherwise, this function will |
|
|
|
|
/// ask the focus system that it become focused. If successful in acquiring |
|
|
|
|
/// focus, the control will then attach to the keyboard and request that the |
|
|
|
|
/// keyboard become visible. |
|
|
|
|
@override |
|
|
|
|
void requestKeyboard() { |
|
|
|
|
if (_hasFocus) { |
|
|
|
@ -847,24 +848,6 @@ class RawEditorState extends EditorState |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@override |
|
|
|
|
void setTextEditingValue( |
|
|
|
|
TextEditingValue value, SelectionChangedCause cause) { |
|
|
|
|
if (value == textEditingValue) { |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
textEditingValue = value; |
|
|
|
|
userUpdateTextEditingValue(value, cause); |
|
|
|
|
|
|
|
|
|
// keyboard and text input force a selection completion |
|
|
|
|
_handleSelectionCompleted(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@override |
|
|
|
|
void debugAssertLayoutUpToDate() { |
|
|
|
|
renderEditor.debugAssertLayoutUpToDate(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/// Shows the selection toolbar at the location of the current cursor. |
|
|
|
|
/// |
|
|
|
|
/// Returns `false` if a toolbar couldn't be shown, such as when the toolbar |
|
|
|
@ -892,8 +875,19 @@ class RawEditorState extends EditorState |
|
|
|
|
widget.controller.copiedImageUrl = null; |
|
|
|
|
_pastePlainText = widget.controller.getPlainText(); |
|
|
|
|
_pasteStyle = widget.controller.getAllIndividualSelectionStyles(); |
|
|
|
|
|
|
|
|
|
// Copied straight from EditableTextState |
|
|
|
|
super.copySelection(cause); |
|
|
|
|
void _copySelection(SelectionChangedCause cause) { |
|
|
|
|
final selection = textEditingValue.selection; |
|
|
|
|
final text = textEditingValue.text; |
|
|
|
|
if (selection.isCollapsed || !selection.isValid) { |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
Clipboard.setData(ClipboardData(text: selection.textInside(text))); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
_copySelection(cause); |
|
|
|
|
|
|
|
|
|
if (cause == SelectionChangedCause.toolbar) { |
|
|
|
|
bringIntoView(textEditingValue.selection.extent); |
|
|
|
|
hideToolbar(false); |
|
|
|
@ -919,7 +913,30 @@ class RawEditorState extends EditorState |
|
|
|
|
_pasteStyle = widget.controller.getAllIndividualSelectionStyles(); |
|
|
|
|
|
|
|
|
|
// Copied straight from EditableTextState |
|
|
|
|
super.cutSelection(cause); |
|
|
|
|
void _cutSelection(SelectionChangedCause cause) { |
|
|
|
|
final selection = textEditingValue.selection; |
|
|
|
|
if (widget.readOnly || !selection.isValid) { |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
final text = textEditingValue.text; |
|
|
|
|
if (selection.isCollapsed) { |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
Clipboard.setData(ClipboardData(text: selection.textInside(text))); |
|
|
|
|
userUpdateTextEditingValue( |
|
|
|
|
TextEditingValue( |
|
|
|
|
text: selection.textBefore(text) + selection.textAfter(text), |
|
|
|
|
selection: TextSelection.collapsed( |
|
|
|
|
offset: math.min(selection.start, selection.end), |
|
|
|
|
affinity: selection.affinity, |
|
|
|
|
), |
|
|
|
|
), |
|
|
|
|
cause, |
|
|
|
|
); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
_cutSelection(cause); |
|
|
|
|
|
|
|
|
|
if (cause == SelectionChangedCause.toolbar) { |
|
|
|
|
bringIntoView(textEditingValue.selection.extent); |
|
|
|
|
hideToolbar(); |
|
|
|
@ -946,7 +963,37 @@ class RawEditorState extends EditorState |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Copied straight from EditableTextState |
|
|
|
|
super.pasteText(cause); // ignore: unawaited_futures |
|
|
|
|
Future<void> pasteText(SelectionChangedCause cause) async { |
|
|
|
|
final selection = textEditingValue.selection; |
|
|
|
|
if (widget.readOnly || !selection.isValid) { |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
final text = textEditingValue.text; |
|
|
|
|
if (!selection.isValid) { |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
// Snapshot the input before using `await`. |
|
|
|
|
// See https://github.com/flutter/flutter/issues/11427 |
|
|
|
|
final data = await Clipboard.getData(Clipboard.kTextPlain); |
|
|
|
|
if (data == null) { |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
userUpdateTextEditingValue( |
|
|
|
|
TextEditingValue( |
|
|
|
|
text: selection.textBefore(text) + |
|
|
|
|
data.text! + |
|
|
|
|
selection.textAfter(text), |
|
|
|
|
selection: TextSelection.collapsed( |
|
|
|
|
offset: |
|
|
|
|
math.min(selection.start, selection.end) + data.text!.length, |
|
|
|
|
affinity: selection.affinity, |
|
|
|
|
), |
|
|
|
|
), |
|
|
|
|
cause, |
|
|
|
|
); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
pasteText(cause); // ignore: unawaited_futures |
|
|
|
|
|
|
|
|
|
if (cause == SelectionChangedCause.toolbar) { |
|
|
|
|
bringIntoView(textEditingValue.selection.extent); |
|
|
|
@ -954,10 +1001,31 @@ class RawEditorState extends EditorState |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void _setSelection(TextSelection nextSelection, SelectionChangedCause cause) { |
|
|
|
|
if (nextSelection == textEditingValue.selection) { |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
userUpdateTextEditingValue( |
|
|
|
|
textEditingValue.copyWith(selection: nextSelection), |
|
|
|
|
cause, |
|
|
|
|
); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@override |
|
|
|
|
void selectAll(SelectionChangedCause cause) { |
|
|
|
|
// Copied straight from EditableTextState |
|
|
|
|
super.selectAll(cause); |
|
|
|
|
void _selectAll(SelectionChangedCause cause) { |
|
|
|
|
_setSelection( |
|
|
|
|
textEditingValue.selection.copyWith( |
|
|
|
|
baseOffset: 0, |
|
|
|
|
extentOffset: textEditingValue.text.length, |
|
|
|
|
), |
|
|
|
|
cause, |
|
|
|
|
); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
_selectAll(cause); |
|
|
|
|
|
|
|
|
|
if (cause == SelectionChangedCause.toolbar) { |
|
|
|
|
bringIntoView(textEditingValue.selection.extent); |
|
|
|
|
} |
|
|
|
@ -966,18 +1034,6 @@ class RawEditorState extends EditorState |
|
|
|
|
@override |
|
|
|
|
bool get wantKeepAlive => widget.focusNode.hasFocus; |
|
|
|
|
|
|
|
|
|
@override |
|
|
|
|
bool get obscureText => false; |
|
|
|
|
|
|
|
|
|
@override |
|
|
|
|
bool get selectionEnabled => widget.enableInteractiveSelection; |
|
|
|
|
|
|
|
|
|
@override |
|
|
|
|
bool get readOnly => widget.readOnly; |
|
|
|
|
|
|
|
|
|
@override |
|
|
|
|
TextLayoutMetrics get textLayoutMetrics => renderEditor; |
|
|
|
|
|
|
|
|
|
@override |
|
|
|
|
AnimationController get floatingCursorResetController => |
|
|
|
|
_floatingCursorResetController; |
|
|
|
|