mirror of
https://github.com/bggRGjQaUbCoE/PiliPlus.git
synced 2026-07-03 15:50:18 +08:00
@@ -2,7 +2,7 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// ignore_for_file: uri_does_not_exist_in_doc_import
|
||||
// ignore_for_file: prefer_initializing_formals, uri_does_not_exist_in_doc_import
|
||||
|
||||
/// @docImport 'package:flutter/cupertino.dart';
|
||||
/// @docImport 'package:flutter/material.dart';
|
||||
@@ -394,7 +394,7 @@ class _DiscreteKeyFrameSimulation extends Simulation {
|
||||
/// ### Customizing User Input Accessibility Announcements
|
||||
///
|
||||
/// To customize user input accessibility announcements triggered by text
|
||||
/// changes, use [SemanticsService.announce] to make the desired
|
||||
/// changes, use [SemanticsService.sendAnnouncement] to make the desired
|
||||
/// accessibility announcement.
|
||||
///
|
||||
/// On iOS, the on-screen keyboard may announce the most recent input
|
||||
@@ -525,6 +525,7 @@ class EditableText extends StatefulWidget {
|
||||
this.spellCheckConfiguration,
|
||||
this.magnifierConfiguration = TextMagnifierConfiguration.disabled,
|
||||
this.hintLocales,
|
||||
this.enableInlinePrediction,
|
||||
}) : assert(obscuringCharacter.length == 1),
|
||||
autocorrect =
|
||||
autocorrect ?? _inferAutocorrect(autofillHints: autofillHints),
|
||||
@@ -1683,6 +1684,9 @@ class EditableText extends StatefulWidget {
|
||||
/// {@macro flutter.services.TextInputConfiguration.hintLocales}
|
||||
final List<Locale>? hintLocales;
|
||||
|
||||
/// {@macro flutter.services.TextInputConfiguration.enableInlinePrediction}
|
||||
final bool? enableInlinePrediction;
|
||||
|
||||
/// The default value for [selectionHeightStyle].
|
||||
///
|
||||
/// On web platforms, this defaults to [ui.BoxHeightStyle.max].
|
||||
@@ -2159,6 +2163,13 @@ class EditableText extends StatefulWidget {
|
||||
defaultValue: true,
|
||||
),
|
||||
)
|
||||
..add(
|
||||
DiagnosticsProperty<bool?>(
|
||||
'enableInlinePrediction',
|
||||
enableInlinePrediction,
|
||||
defaultValue: null,
|
||||
),
|
||||
)
|
||||
..add(
|
||||
DiagnosticsProperty<bool>(
|
||||
'enableInteractiveSelection',
|
||||
@@ -2494,7 +2505,9 @@ class EditableTextState extends State<EditableText>
|
||||
final String text =
|
||||
widget.controller.getSelectionText(selection) ??
|
||||
selection.textInside(textEditingValue.text);
|
||||
Clipboard.setData(ClipboardData(text: text));
|
||||
Clipboard.setData(
|
||||
ClipboardData(text: text),
|
||||
).catchError(_reportClipboardError('while copying selection to clipboard'));
|
||||
if (cause == SelectionChangedCause.toolbar) {
|
||||
bringIntoView(textEditingValue.selection.extent);
|
||||
hideToolbar(false);
|
||||
@@ -2536,7 +2549,9 @@ class EditableTextState extends State<EditableText>
|
||||
final String text =
|
||||
widget.controller.getSelectionText(selection) ??
|
||||
selection.textInside(textEditingValue.text);
|
||||
Clipboard.setData(ClipboardData(text: text));
|
||||
Clipboard.setData(
|
||||
ClipboardData(text: text),
|
||||
).catchError(_reportClipboardError('while cutting selection to clipboard'));
|
||||
_replaceText(ReplaceTextIntent(textEditingValue, '', selection, cause));
|
||||
if (cause == SelectionChangedCause.toolbar) {
|
||||
// Schedule a call to bringIntoView() after renderEditable updates.
|
||||
@@ -2550,6 +2565,19 @@ class EditableTextState extends State<EditableText>
|
||||
clipboardStatus.update();
|
||||
}
|
||||
|
||||
void Function(Object, StackTrace) _reportClipboardError(String context) {
|
||||
return (Object exception, StackTrace stack) {
|
||||
FlutterError.reportError(
|
||||
FlutterErrorDetails(
|
||||
exception: exception,
|
||||
stack: stack,
|
||||
library: 'widgets library',
|
||||
context: ErrorDescription(context),
|
||||
),
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
bool get _allowPaste {
|
||||
return !widget.readOnly && textEditingValue.selection.isValid;
|
||||
}
|
||||
@@ -2616,6 +2644,21 @@ class EditableTextState extends State<EditableText>
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _pasteTextWithReporting(SelectionChangedCause cause) async {
|
||||
try {
|
||||
await pasteText(cause);
|
||||
} catch (error, stack) {
|
||||
FlutterError.reportError(
|
||||
FlutterErrorDetails(
|
||||
exception: error,
|
||||
stack: stack,
|
||||
library: 'widgets',
|
||||
context: ErrorDescription('while pasting text to EditableText'),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// Select the entire text value.
|
||||
@override
|
||||
void selectAll(SelectionChangedCause cause) {
|
||||
@@ -2723,7 +2766,19 @@ class EditableTextState extends State<EditableText>
|
||||
return;
|
||||
}
|
||||
if (_hasInputConnection) {
|
||||
LiveText.startLiveTextInput();
|
||||
LiveText.startLiveTextInput().then(
|
||||
(_) {},
|
||||
onError: (Object error, StackTrace stack) {
|
||||
FlutterError.reportError(
|
||||
FlutterErrorDetails(
|
||||
exception: error,
|
||||
stack: stack,
|
||||
library: 'widgets library',
|
||||
context: ErrorDescription('while starting Live Text input'),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
if (cause == SelectionChangedCause.toolbar) {
|
||||
hideToolbar();
|
||||
@@ -2846,8 +2901,8 @@ class EditableTextState extends State<EditableText>
|
||||
),
|
||||
if (toolbarOptions.paste && pasteEnabled)
|
||||
ContextMenuButtonItem(
|
||||
onPressed: () {
|
||||
pasteText(SelectionChangedCause.toolbar);
|
||||
onPressed: () async {
|
||||
await _pasteTextWithReporting(SelectionChangedCause.toolbar);
|
||||
},
|
||||
type: ContextMenuButtonType.paste,
|
||||
),
|
||||
@@ -2972,7 +3027,7 @@ class EditableTextState extends State<EditableText>
|
||||
? () => cutSelection(SelectionChangedCause.toolbar)
|
||||
: null,
|
||||
onPaste: pasteEnabled
|
||||
? () => pasteText(SelectionChangedCause.toolbar)
|
||||
? () => _pasteTextWithReporting(SelectionChangedCause.toolbar)
|
||||
: null,
|
||||
onSelectAll: selectAllEnabled
|
||||
? () => selectAll(SelectionChangedCause.toolbar)
|
||||
@@ -3118,6 +3173,14 @@ class EditableTextState extends State<EditableText>
|
||||
_effectiveAutofillClient.textInputConfiguration,
|
||||
);
|
||||
}
|
||||
// The style may have changed due to dependency changes
|
||||
// (e.g. MediaQuery.boldTextOf, MediaQuery.textScalerOf, etc.).
|
||||
SchedulerBinding.instance.addPostFrameCallback((Duration _) {
|
||||
if (!mounted || !_hasInputConnection) {
|
||||
return;
|
||||
}
|
||||
_textInputConnection!.updateStyle(_getTextInputStyle(context));
|
||||
}, debugLabel: 'EditableText.updateStyle');
|
||||
}
|
||||
|
||||
if (defaultTargetPlatform != TargetPlatform.iOS &&
|
||||
@@ -3217,7 +3280,13 @@ class EditableTextState extends State<EditableText>
|
||||
}
|
||||
|
||||
if (kIsWeb && _hasInputConnection) {
|
||||
if (oldWidget.readOnly != widget.readOnly) {
|
||||
final obscureTextChanged = oldWidget.obscureText != widget.obscureText;
|
||||
if (obscureTextChanged || oldWidget.keyboardType != widget.keyboardType) {
|
||||
if (obscureTextChanged) {
|
||||
// When obscureText is toggled, we should reset its state to prevent the last character from being visible between state changes.
|
||||
_obscureShowCharTicksPending = 0;
|
||||
_obscureLatestCharIndex = null;
|
||||
}
|
||||
_textInputConnection!.updateConfig(
|
||||
_effectiveAutofillClient.textInputConfiguration,
|
||||
);
|
||||
@@ -3240,13 +3309,14 @@ class EditableTextState extends State<EditableText>
|
||||
? widget.style.merge(const TextStyle(fontWeight: FontWeight.bold))
|
||||
: widget.style;
|
||||
if (_hasInputConnection) {
|
||||
_textInputConnection!.setStyle(
|
||||
fontFamily: _style.fontFamily,
|
||||
fontSize: _style.fontSize,
|
||||
fontWeight: _style.fontWeight,
|
||||
textDirection: _textDirection,
|
||||
textAlign: widget.textAlign,
|
||||
);
|
||||
// Schedule the style update after layout to ensure preferredLineHeight
|
||||
// is computed with the new style.
|
||||
SchedulerBinding.instance.addPostFrameCallback((Duration _) {
|
||||
if (!mounted || !_hasInputConnection) {
|
||||
return;
|
||||
}
|
||||
_textInputConnection!.updateStyle(_getTextInputStyle(context));
|
||||
}, debugLabel: 'EditableText.updateStyle');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3272,6 +3342,27 @@ class EditableTextState extends State<EditableText>
|
||||
}
|
||||
}
|
||||
|
||||
TextInputStyle _getTextInputStyle(BuildContext context) {
|
||||
final double? letterSpacingOverride =
|
||||
MediaQuery.maybeLetterSpacingOverrideOf(context);
|
||||
final double? wordSpacingOverride = MediaQuery.maybeWordSpacingOverrideOf(
|
||||
context,
|
||||
);
|
||||
|
||||
return TextInputStyle(
|
||||
fontFamily: _style.fontFamily,
|
||||
fontSize: _style.fontSize,
|
||||
fontWeight: _style.fontWeight,
|
||||
textDirection: _textDirection,
|
||||
textAlign: widget.textAlign,
|
||||
letterSpacing: letterSpacingOverride ?? _style.letterSpacing,
|
||||
wordSpacing: wordSpacingOverride ?? _style.wordSpacing,
|
||||
// preferredLineHeight already includes lineHeightScaleFactor from
|
||||
// _OverridingTextStyleTextSpanUtils.applyTextSpacingOverrides.
|
||||
lineHeight: renderEditable.preferredLineHeight,
|
||||
);
|
||||
}
|
||||
|
||||
@protected
|
||||
@override
|
||||
void dispose() {
|
||||
@@ -3902,13 +3993,7 @@ class EditableTextState extends State<EditableText>
|
||||
_updateSizeAndTransform();
|
||||
_schedulePeriodicPostFrameCallbacks();
|
||||
_textInputConnection!
|
||||
..setStyle(
|
||||
fontFamily: _style.fontFamily,
|
||||
fontSize: _style.fontSize,
|
||||
fontWeight: _style.fontWeight,
|
||||
textDirection: _textDirection,
|
||||
textAlign: widget.textAlign,
|
||||
)
|
||||
..updateStyle(_getTextInputStyle(context))
|
||||
..setEditingState(localValue)
|
||||
..show();
|
||||
if (_needsAutofill) {
|
||||
@@ -3974,13 +4059,7 @@ class EditableTextState extends State<EditableText>
|
||||
|
||||
newConnection
|
||||
..show()
|
||||
..setStyle(
|
||||
fontFamily: _style.fontFamily,
|
||||
fontSize: _style.fontSize,
|
||||
fontWeight: _style.fontWeight,
|
||||
textDirection: _textDirection,
|
||||
textAlign: widget.textAlign,
|
||||
)
|
||||
..updateStyle(_getTextInputStyle(context))
|
||||
..setEditingState(_value);
|
||||
_lastKnownRemoteTextEditingValue = _value;
|
||||
}
|
||||
@@ -3996,6 +4075,15 @@ class EditableTextState extends State<EditableText>
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
bool onFocusReceived() {
|
||||
if (mounted && !_hasFocus && widget.focusNode.canRequestFocus) {
|
||||
widget.focusNode.requestFocus();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@override
|
||||
void connectionClosed() {
|
||||
if (_hasInputConnection) {
|
||||
@@ -5248,6 +5336,7 @@ class EditableTextState extends State<EditableText>
|
||||
? const <String>[]
|
||||
: widget.contentInsertionConfiguration!.allowedMimeTypes,
|
||||
hintLocales: widget.hintLocales,
|
||||
enableInlinePrediction: widget.enableInlinePrediction,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -5300,9 +5389,9 @@ class EditableTextState extends State<EditableText>
|
||||
: pasteEnabled &&
|
||||
(widget.selectionControls?.canPaste(this) ?? false)) &&
|
||||
(clipboardStatus.value == ClipboardStatus.pasteable)
|
||||
? () {
|
||||
controls?.handlePaste(this);
|
||||
pasteText(SelectionChangedCause.toolbar);
|
||||
? () async {
|
||||
await controls?.handlePaste(this);
|
||||
await _pasteTextWithReporting(SelectionChangedCause.toolbar);
|
||||
}
|
||||
: null;
|
||||
}
|
||||
@@ -5529,70 +5618,6 @@ class EditableTextState extends State<EditableText>
|
||||
_scrollController.jumpTo(destination);
|
||||
}
|
||||
|
||||
/// Extend the selection down by page if the `forward` parameter is true, or
|
||||
/// up by page otherwise.
|
||||
void _extendSelectionByPage(ExtendSelectionByPageIntent intent) {
|
||||
if (widget.maxLines == 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
final TextSelection nextSelection;
|
||||
final Rect extentRect = renderEditable.getLocalRectForCaret(
|
||||
_value.selection.extent,
|
||||
);
|
||||
final state = _scrollableKey.currentState as ScrollableState?;
|
||||
final double increment = ScrollAction.getDirectionalIncrement(
|
||||
state!,
|
||||
ScrollIntent(
|
||||
direction: intent.forward ? AxisDirection.down : AxisDirection.up,
|
||||
type: ScrollIncrementType.page,
|
||||
),
|
||||
);
|
||||
final ScrollPosition position = _scrollController.position;
|
||||
if (intent.forward) {
|
||||
if (_value.selection.extentOffset >= _value.text.length) {
|
||||
return;
|
||||
}
|
||||
final nextExtentOffset = Offset(
|
||||
extentRect.left,
|
||||
extentRect.top + increment,
|
||||
);
|
||||
final double height =
|
||||
position.maxScrollExtent + renderEditable.size.height;
|
||||
final TextPosition nextExtent =
|
||||
nextExtentOffset.dy + position.pixels >= height
|
||||
? TextPosition(offset: _value.text.length)
|
||||
: renderEditable.getPositionForPoint(
|
||||
renderEditable.localToGlobal(nextExtentOffset),
|
||||
);
|
||||
nextSelection = _value.selection.copyWith(
|
||||
extentOffset: nextExtent.offset,
|
||||
);
|
||||
} else {
|
||||
if (_value.selection.extentOffset <= 0) {
|
||||
return;
|
||||
}
|
||||
final nextExtentOffset = Offset(
|
||||
extentRect.left,
|
||||
extentRect.top + increment,
|
||||
);
|
||||
final TextPosition nextExtent = nextExtentOffset.dy + position.pixels <= 0
|
||||
? const TextPosition(offset: 0)
|
||||
: renderEditable.getPositionForPoint(
|
||||
renderEditable.localToGlobal(nextExtentOffset),
|
||||
);
|
||||
nextSelection = _value.selection.copyWith(
|
||||
extentOffset: nextExtent.offset,
|
||||
);
|
||||
}
|
||||
|
||||
bringIntoView(nextSelection.extent);
|
||||
userUpdateTextEditingValue(
|
||||
_value.copyWith(selection: nextSelection),
|
||||
SelectionChangedCause.keyboard,
|
||||
);
|
||||
}
|
||||
|
||||
void _updateSelection(UpdateSelectionIntent intent) {
|
||||
assert(
|
||||
intent.newSelection.start <= intent.currentTextEditingValue.text.length,
|
||||
@@ -5730,11 +5755,6 @@ class EditableTextState extends State<EditableText>
|
||||
ignoreNonCollapsedSelection: false,
|
||||
),
|
||||
),
|
||||
ExtendSelectionByPageIntent: _makeOverridable(
|
||||
CallbackAction<ExtendSelectionByPageIntent>(
|
||||
onInvoke: _extendSelectionByPage,
|
||||
),
|
||||
),
|
||||
ExtendSelectionToNextWordBoundaryIntent: _makeOverridable(
|
||||
_UpdateTextSelectionAction<ExtendSelectionToNextWordBoundaryIntent>(
|
||||
this,
|
||||
@@ -6953,7 +6973,7 @@ class _PasteSelectionAction extends ContextAction<PasteTextIntent> {
|
||||
return;
|
||||
}
|
||||
|
||||
state.pasteText(intent.cause);
|
||||
state._pasteTextWithReporting(intent.cause);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user