Un-gate value setting in formatter repeat check logic (#53613)
This commit is contained in:
parent
cb4147cf73
commit
6280b39164
@ -1676,13 +1676,13 @@ class EditableTextState extends State<EditableText> with AutomaticKeepAliveClien
|
|||||||
value = _whitespaceFormatter.formatEditUpdate(_value, value);
|
value = _whitespaceFormatter.formatEditUpdate(_value, value);
|
||||||
_lastFormattedValue = value;
|
_lastFormattedValue = value;
|
||||||
}
|
}
|
||||||
// If the text, selection, or composing region has changed, we should update the
|
|
||||||
// locally stored TextEditingValue to the new one.
|
_value = value;
|
||||||
if (!isRepeatText || !isRepeatSelection || !isRepeatComposing) {
|
// Use the last formatted value when an identical repeat pass is detected.
|
||||||
_value = value;
|
if (isRepeatText && isRepeatSelection && isRepeatComposing && textChanged && _lastFormattedValue != null) {
|
||||||
} else if (textChanged && _lastFormattedValue != null) {
|
|
||||||
_value = _lastFormattedValue;
|
_value = _lastFormattedValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Always attempt to send the value. If the value has changed, then it will send,
|
// Always attempt to send the value. If the value has changed, then it will send,
|
||||||
// otherwise, it will short-circuit.
|
// otherwise, it will short-circuit.
|
||||||
_updateRemoteEditingValueIfNeeded();
|
_updateRemoteEditingValueIfNeeded();
|
||||||
|
@ -4313,6 +4313,49 @@ void main() {
|
|||||||
expect(formatter.log, referenceLog);
|
expect(formatter.log, referenceLog);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Regression test for https://github.com/flutter/flutter/issues/53612
|
||||||
|
testWidgets('formatter logic handles initial repeat edge case', (WidgetTester tester) async {
|
||||||
|
final MockTextFormatter formatter = MockTextFormatter();
|
||||||
|
await tester.pumpWidget(
|
||||||
|
MediaQuery(
|
||||||
|
data: const MediaQueryData(devicePixelRatio: 1.0),
|
||||||
|
child: Directionality(
|
||||||
|
textDirection: TextDirection.ltr,
|
||||||
|
child: FocusScope(
|
||||||
|
node: focusScopeNode,
|
||||||
|
autofocus: true,
|
||||||
|
child: EditableText(
|
||||||
|
backgroundCursorColor: Colors.grey,
|
||||||
|
controller: controller,
|
||||||
|
focusNode: focusNode,
|
||||||
|
maxLines: 1, // Sets text keyboard implicitly.
|
||||||
|
style: textStyle,
|
||||||
|
cursorColor: cursorColor,
|
||||||
|
inputFormatters: <TextInputFormatter>[formatter],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
await tester.tap(find.byType(EditableText));
|
||||||
|
await tester.showKeyboard(find.byType(EditableText));
|
||||||
|
controller.text = '';
|
||||||
|
await tester.idle();
|
||||||
|
|
||||||
|
final EditableTextState state =
|
||||||
|
tester.state<EditableTextState>(find.byType(EditableText));
|
||||||
|
expect(tester.testTextInput.editingState['text'], equals(''));
|
||||||
|
expect(state.wantKeepAlive, true);
|
||||||
|
|
||||||
|
expect(formatter.formatCallCount, 0);
|
||||||
|
state.updateEditingValue(const TextEditingValue(text: ''));
|
||||||
|
state.updateEditingValue(const TextEditingValue(text: '', composing: TextRange(start: 1, end: 2)));
|
||||||
|
state.updateEditingValue(const TextEditingValue(text: '0')); // pass to formatter once to check the values.
|
||||||
|
expect(formatter.lastOldValue.composing, const TextRange(start: 1, end: 2));
|
||||||
|
expect(formatter.lastOldValue.text, '');
|
||||||
|
});
|
||||||
|
|
||||||
testWidgets('Whitespace directionality formatter input Arabic', (WidgetTester tester) async {
|
testWidgets('Whitespace directionality formatter input Arabic', (WidgetTester tester) async {
|
||||||
final TextEditingController controller = TextEditingController(text: 'testText');
|
final TextEditingController controller = TextEditingController(text: 'testText');
|
||||||
await tester.pumpWidget(
|
await tester.pumpWidget(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user