Unverified Commit 1b62b805 authored by Gary Qian's avatar Gary Qian Committed by GitHub

Handle backspace edgecase in trailing whitespace formatter. (#59379)

parent 807b6025
......@@ -2571,9 +2571,14 @@ class _WhitespaceDirectionalityFormatter extends TextInputFormatter {
composingEnd -= outputCodepoints.length < composingEnd ? 1 : 0;
}
final bool isBackspace = oldValue.text.runes.length - newValue.text.runes.length == 1 &&
isDirectionalityMarker(oldValue.text.runes.last) &&
oldValue.text.substring(0, oldValue.text.length - 1) == newValue.text;
bool previousWasWhitespace = false;
bool previousWasDirectionalityMarker = false;
int previousNonWhitespaceCodepoint;
int index = 0;
for (final int codepoint in newValue.text.runes) {
if (isWhitespace(codepoint)) {
// Only compute the directionality of the non-whitespace
......@@ -2587,9 +2592,15 @@ class _WhitespaceDirectionalityFormatter extends TextInputFormatter {
subtractFromLength();
outputCodepoints.removeLast();
}
outputCodepoints.add(codepoint);
addToLength();
outputCodepoints.add(_previousNonWhitespaceDirection == TextDirection.rtl ? _rlm : _lrm);
// Handle trailing whitespace deleting the directionality char instead of the whitespace.
if (isBackspace && index == newValue.text.runes.length - 1) {
// Do not append the whitespace to the outputCodepoints.
subtractFromLength();
} else {
outputCodepoints.add(codepoint);
addToLength();
outputCodepoints.add(_previousNonWhitespaceDirection == TextDirection.rtl ? _rlm : _lrm);
}
previousWasWhitespace = true;
previousWasDirectionalityMarker = false;
......@@ -2620,6 +2631,7 @@ class _WhitespaceDirectionalityFormatter extends TextInputFormatter {
previousWasWhitespace = false;
previousWasDirectionalityMarker = false;
}
index++;
}
final String formatted = String.fromCharCodes(outputCodepoints);
return TextEditingValue(
......
......@@ -4923,6 +4923,46 @@ void main() {
expect(state.currentTextEditingValue.text, equals('\u{200E}🇧🇼🇧🇷🇮🇴 🇻🇬🇧🇳wahhh!🇧🇬🇧🇫 🇧🇮🇰🇭عَ عَ \u{200F}🇨🇲 🇨🇦🇮🇨 🇨🇻🇧🇶 🇰🇾🇨🇫 🇹🇩🇨🇱 🇨🇳🇨🇽\u{200F}'));
});
testWidgets('Whitespace directionality formatter handles deletion of trailing whitespace', (WidgetTester tester) async {
final TextEditingController controller = TextEditingController(text: 'testText');
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.blue,
controller: controller,
focusNode: focusNode,
maxLines: 1, // Sets text keyboard implicitly.
style: textStyle,
cursorColor: cursorColor,
),
),
),
),
);
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);
// Simulate deleting only the trailing RTL mark.
state.updateEditingValue(const TextEditingValue(text: 'hello \u{200E}الْعَ بِيَّةُ \u{200F}'));
state.updateEditingValue(const TextEditingValue(text: 'hello \u{200E}الْعَ بِيَّةُ '));
// The trailing space should be gone here.
expect(state.currentTextEditingValue.text, equals('hello \u{200E}الْعَ بِيَّةُ'));
});
testWidgets('EditableText changes mouse cursor when hovered', (WidgetTester tester) async {
await tester.pumpWidget(
MediaQuery(
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment