Unverified Commit ee8131b4 authored by Gary Qian's avatar Gary Qian Committed by GitHub

Reland formatter changes (#52765)

parent ee845255
...@@ -1230,6 +1230,9 @@ class EditableTextState extends State<EditableText> with AutomaticKeepAliveClien ...@@ -1230,6 +1230,9 @@ class EditableTextState extends State<EditableText> with AutomaticKeepAliveClien
// _lastFormattedUnmodifiedTextEditingValue tracks the last value // _lastFormattedUnmodifiedTextEditingValue tracks the last value
// that the formatter ran on and is used to prevent double-formatting. // that the formatter ran on and is used to prevent double-formatting.
TextEditingValue _lastFormattedUnmodifiedTextEditingValue; TextEditingValue _lastFormattedUnmodifiedTextEditingValue;
// _lastFormattedValue tracks the last post-format value, so that it can be
// reused without rerunning the formatter when the input value is repeated.
TextEditingValue _lastFormattedValue;
// _receivedRemoteTextEditingValue is the direct value last passed in // _receivedRemoteTextEditingValue is the direct value last passed in
// updateEditingValue. This value does not get updated with the formatted // updateEditingValue. This value does not get updated with the formatted
// version. // version.
...@@ -1660,15 +1663,30 @@ class EditableTextState extends State<EditableText> with AutomaticKeepAliveClien ...@@ -1660,15 +1663,30 @@ class EditableTextState extends State<EditableText> with AutomaticKeepAliveClien
// Check if the new value is the same as the current local value, or is the same // Check if the new value is the same as the current local value, or is the same
// as the post-formatting value of the previous pass. // as the post-formatting value of the previous pass.
final bool textChanged = _value?.text != value?.text; final bool textChanged = _value?.text != value?.text;
final bool isRepeat = value?.text == _lastFormattedUnmodifiedTextEditingValue?.text; final bool isRepeatText = value?.text == _lastFormattedUnmodifiedTextEditingValue?.text;
if (textChanged && !isRepeat && widget.inputFormatters != null && widget.inputFormatters.isNotEmpty) { final bool isRepeatSelection = value?.selection == _lastFormattedUnmodifiedTextEditingValue?.selection;
for (final TextInputFormatter formatter in widget.inputFormatters) final bool isRepeatComposing = value?.composing == _lastFormattedUnmodifiedTextEditingValue?.composing;
// Only format when the text has changed and there are available formatters.
if (!isRepeatText && textChanged && widget.inputFormatters != null && widget.inputFormatters.isNotEmpty) {
for (final TextInputFormatter formatter in widget.inputFormatters) {
value = formatter.formatEditUpdate(_value, value); value = formatter.formatEditUpdate(_value, value);
}
// Always pass the text through the whitespace directionality formatter to
// maintain expected behavior with carets on trailing whitespace.
value = _whitespaceFormatter.formatEditUpdate(_value, value);
_lastFormattedValue = value;
}
// If the text, selection, or composing region has changed, we should update the
// locally stored TextEditingValue to the new one.
if (!isRepeatText || !isRepeatSelection || !isRepeatComposing) {
_value = value; _value = value;
_updateRemoteEditingValueIfNeeded(); } else if (textChanged && _lastFormattedValue != null) {
} else { _value = _lastFormattedValue;
_value = value;
} }
// Always attempt to send the value. If the value has changed, then it will send,
// otherwise, it will short-circuit.
_updateRemoteEditingValueIfNeeded();
if (textChanged && widget.onChanged != null) if (textChanged && widget.onChanged != null)
widget.onChanged(value.text); widget.onChanged(value.text);
_lastFormattedUnmodifiedTextEditingValue = _receivedRemoteTextEditingValue; _lastFormattedUnmodifiedTextEditingValue = _receivedRemoteTextEditingValue;
...@@ -2207,14 +2225,22 @@ class _WhitespaceDirectionalityFormatter extends TextInputFormatter { ...@@ -2207,14 +2225,22 @@ class _WhitespaceDirectionalityFormatter extends TextInputFormatter {
// We add/subtract from these as we insert/remove markers. // We add/subtract from these as we insert/remove markers.
int selectionBase = newValue.selection.baseOffset; int selectionBase = newValue.selection.baseOffset;
int selectionExtent = newValue.selection.extentOffset; int selectionExtent = newValue.selection.extentOffset;
int composingStart = newValue.composing.start;
int composingEnd = newValue.composing.end;
void addToSelection() { void addToLength() {
selectionBase += outputCodepoints.length <= selectionBase ? 1 : 0; selectionBase += outputCodepoints.length <= selectionBase ? 1 : 0;
selectionExtent += outputCodepoints.length <= selectionExtent ? 1 : 0; selectionExtent += outputCodepoints.length <= selectionExtent ? 1 : 0;
composingStart += outputCodepoints.length <= composingStart ? 1 : 0;
composingEnd += outputCodepoints.length <= composingEnd ? 1 : 0;
} }
void subtractFromSelection() { void subtractFromLength() {
selectionBase -= outputCodepoints.length < selectionBase ? 1 : 0; selectionBase -= outputCodepoints.length < selectionBase ? 1 : 0;
selectionExtent -= outputCodepoints.length < selectionExtent ? 1 : 0; selectionExtent -= outputCodepoints.length < selectionExtent ? 1 : 0;
composingStart -= outputCodepoints.length < composingStart ? 1 : 0;
composingEnd -= outputCodepoints.length < composingEnd ? 1 : 0;
} }
bool previousWasWhitespace = false; bool previousWasWhitespace = false;
...@@ -2230,11 +2256,11 @@ class _WhitespaceDirectionalityFormatter extends TextInputFormatter { ...@@ -2230,11 +2256,11 @@ class _WhitespaceDirectionalityFormatter extends TextInputFormatter {
// If we already added directionality for this run of whitespace, // If we already added directionality for this run of whitespace,
// "shift" the marker added to the end of the whitespace run. // "shift" the marker added to the end of the whitespace run.
if (previousWasWhitespace) { if (previousWasWhitespace) {
subtractFromSelection(); subtractFromLength();
outputCodepoints.removeLast(); outputCodepoints.removeLast();
} }
outputCodepoints.add(codepoint); outputCodepoints.add(codepoint);
addToSelection(); addToLength();
outputCodepoints.add(_previousNonWhitespaceDirection == TextDirection.rtl ? _rlm : _lrm); outputCodepoints.add(_previousNonWhitespaceDirection == TextDirection.rtl ? _rlm : _lrm);
previousWasWhitespace = true; previousWasWhitespace = true;
...@@ -2243,7 +2269,7 @@ class _WhitespaceDirectionalityFormatter extends TextInputFormatter { ...@@ -2243,7 +2269,7 @@ class _WhitespaceDirectionalityFormatter extends TextInputFormatter {
// Handle pre-existing directionality markers. Use pre-existing marker // Handle pre-existing directionality markers. Use pre-existing marker
// instead of the one we add. // instead of the one we add.
if (previousWasWhitespace) { if (previousWasWhitespace) {
subtractFromSelection(); subtractFromLength();
outputCodepoints.removeLast(); outputCodepoints.removeLast();
} }
outputCodepoints.add(codepoint); outputCodepoints.add(codepoint);
...@@ -2256,7 +2282,7 @@ class _WhitespaceDirectionalityFormatter extends TextInputFormatter { ...@@ -2256,7 +2282,7 @@ class _WhitespaceDirectionalityFormatter extends TextInputFormatter {
if (!previousWasDirectionalityMarker && if (!previousWasDirectionalityMarker &&
previousWasWhitespace && previousWasWhitespace &&
getDirection(codepoint) == _previousNonWhitespaceDirection) { getDirection(codepoint) == _previousNonWhitespaceDirection) {
subtractFromSelection(); subtractFromLength();
outputCodepoints.removeLast(); outputCodepoints.removeLast();
} }
// Normal character, track its codepoint add it to the string. // Normal character, track its codepoint add it to the string.
...@@ -2276,6 +2302,7 @@ class _WhitespaceDirectionalityFormatter extends TextInputFormatter { ...@@ -2276,6 +2302,7 @@ class _WhitespaceDirectionalityFormatter extends TextInputFormatter {
affinity: newValue.selection.affinity, affinity: newValue.selection.affinity,
isDirectional: newValue.selection.isDirectional isDirectional: newValue.selection.isDirectional
), ),
composing: TextRange(start: composingStart, end: composingEnd),
); );
} }
return newValue; return newValue;
......
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