Unverified Commit af9a409e authored by Pedro Massango's avatar Pedro Massango Committed by GitHub

Prevent WhitelistingTextInputFormatter to return a empty string if the current...

Prevent WhitelistingTextInputFormatter to return a empty string if the current value does not satisfy the formatter (#57264)
parent fed18fc4
......@@ -107,10 +107,11 @@ class BlacklistingTextInputFormatter extends TextInputFormatter {
@override
TextEditingValue formatEditUpdate(
TextEditingValue oldValue, // unused.
TextEditingValue oldValue,
TextEditingValue newValue,
) {
return _selectionAwareTextManipulation(
oldValue,
newValue,
(String substring) {
return substring.replaceAll(blacklistedPattern, replacementString);
......@@ -239,10 +240,11 @@ class WhitelistingTextInputFormatter extends TextInputFormatter {
@override
TextEditingValue formatEditUpdate(
TextEditingValue oldValue, // unused.
TextEditingValue oldValue,
TextEditingValue newValue,
) {
return _selectionAwareTextManipulation(
oldValue,
newValue,
(String substring) {
return whitelistedPattern
......@@ -259,6 +261,7 @@ class WhitelistingTextInputFormatter extends TextInputFormatter {
}
TextEditingValue _selectionAwareTextManipulation(
TextEditingValue oldValue,
TextEditingValue value,
String substringManipulation(String substring),
) {
......@@ -268,6 +271,19 @@ TextEditingValue _selectionAwareTextManipulation(
TextSelection manipulatedSelection;
if (selectionStartIndex < 0 || selectionEndIndex < 0) {
manipulatedText = substringManipulation(value.text);
} else if (value.selection.isCollapsed) { // Non-selection text manipulation
int cursorPosition = value.selection.baseOffset;
manipulatedText = substringManipulation(value.text);
// We only return the old valid value if the current value is not empty and
// if manipulation fails.
if (value.text.isNotEmpty && manipulatedText.isEmpty) {
manipulatedText = oldValue.text;
// We decrease cursorPosition by one because
// user entered a invalid character.
cursorPosition -= 1;
}
// Move the caret to its previous position.
manipulatedSelection = TextSelection.collapsed(offset: cursorPosition);
} else {
final String beforeSelection = substringManipulation(
value.text.substring(0, selectionStartIndex)
......
......@@ -84,4 +84,55 @@ void main() {
});
});
});
group('WhitelistingTextInputFormatter', () {
test('should return the old value if new value contains non-white-listed character', () {
const TextEditingValue oldValue = TextEditingValue(text: '12345');
const TextEditingValue newValue = TextEditingValue(text: '12345@');
final WhitelistingTextInputFormatter formatter = WhitelistingTextInputFormatter.digitsOnly;
final TextEditingValue formatted = formatter.formatEditUpdate(oldValue, newValue);
// assert that we are passing digits only at the first time
expect(oldValue.text, equals('12345'));
// The new value is always the oldValue plus a non-digit character (user press @)
expect(newValue.text, equals('12345@'));
// we expect that the formatted value returns the oldValue only since the newValue does not
// satisfy the formatter condition (wich is, in this case digitsOnly)
expect(formatted.text, equals('12345'));
});
test('should move the cursor to the right position', () {
TextEditingValue collapsedValue(String text, int offset) =>
TextEditingValue(
text: text,
selection: TextSelection.collapsed(offset: offset),
);
TextEditingValue oldValue = collapsedValue('123', 0);
TextEditingValue newValue = collapsedValue('123456', 6);
final WhitelistingTextInputFormatter formatter =
WhitelistingTextInputFormatter.digitsOnly;
TextEditingValue formatted = formatter.formatEditUpdate(oldValue,
newValue);
// assert that we are passing digits only at the first time
expect(oldValue.text, equals('123'));
// assert that we are passing digits only at the second time
expect(newValue.text, equals('123456'));
// assert that cursor is at the end of the text
expect(formatted.selection.baseOffset, equals(6));
// move cursor at the middle of the text and then add the number 9.
oldValue = newValue.copyWith(
selection: const TextSelection.collapsed(offset: 4));
newValue = oldValue.copyWith(text: '1239456');
formatted = formatter.formatEditUpdate(oldValue, newValue);
// cursor must be now at fourth position (right after the number 9)
expect(formatted.selection.baseOffset, equals(4));
});
});
}
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