Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 8 additions & 11 deletions packages/flutter/lib/src/widgets/editable_text.dart
Original file line number Diff line number Diff line change
Expand Up @@ -218,9 +218,9 @@ class TextEditingController extends ValueNotifier<TextEditingValue> {
/// actions, not during the build, layout, or paint phases.
///
/// This property can be set from a listener added to this
/// [TextEditingController]; however, one should not also set [selection]
/// [TextEditingController]; **however, one should not also set [selection]
/// in a separate statement. To change both the [text] and the [selection]
/// change the controller's [value].
/// change the controller's [value].**
set text(String newText) {
value = value.copyWith(
text: newText,
Expand Down Expand Up @@ -285,16 +285,13 @@ class TextEditingController extends ValueNotifier<TextEditingValue> {
/// in a separate statement. To change both the [text] and the [selection]
/// change the controller's [value].
///
/// If the new selection is of non-zero length, or is outside the composing
/// range, the composing range is cleared.
/// If the new selection is outside the composing range, the composing range is
/// cleared.
set selection(TextSelection newSelection) {
if (!isSelectionWithinTextBounds(newSelection)) {
if (!_isSelectionWithinTextBounds(newSelection)) {
throw FlutterError('invalid text selection: $newSelection');
}
final TextRange newComposing =
newSelection.isCollapsed && _isSelectionWithinComposingRange(newSelection)
? value.composing
: TextRange.empty;
final TextRange newComposing = _isSelectionWithinComposingRange(newSelection) ? value.composing : TextRange.empty;
value = value.copyWith(selection: newSelection, composing: newComposing);
}

Expand Down Expand Up @@ -326,7 +323,7 @@ class TextEditingController extends ValueNotifier<TextEditingValue> {
}

/// Check that the [selection] is inside of the bounds of [text].
bool isSelectionWithinTextBounds(TextSelection selection) {
bool _isSelectionWithinTextBounds(TextSelection selection) {
return selection.start <= text.length && selection.end <= text.length;
}

Expand Down Expand Up @@ -3589,7 +3586,7 @@ class EditableTextState extends State<EditableText> with AutomaticKeepAliveClien
// We return early if the selection is not valid. This can happen when the
// text of [EditableText] is updated at the same time as the selection is
// changed by a gesture event.
if (!widget.controller.isSelectionWithinTextBounds(selection)) {
if (!widget.controller._isSelectionWithinTextBounds(selection)) {
return;
}

Expand Down
5 changes: 3 additions & 2 deletions packages/flutter/test/widgets/editable_text_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11185,14 +11185,15 @@ void main() {
));
expect(state.currentTextEditingValue.composing, const TextRange(start: 4, end: 12));

// Setting a selection within the composing range clears the composing range.
// Setting a selection within the composing range doesn't clear the composing range.
state.updateEditingValue(const TextEditingValue(
text: 'foo composing bar',
selection: TextSelection.collapsed(offset: 4),
composing: TextRange(start: 4, end: 12),
));
controller.selection = const TextSelection(baseOffset: 5, extentOffset: 7);
expect(state.currentTextEditingValue.composing, TextRange.empty);
expect(state.currentTextEditingValue.composing, const TextRange(start: 4, end: 12));
expect(state.currentTextEditingValue.selection, const TextSelection(baseOffset: 5, extentOffset: 7));

// Reset the composing range.
state.updateEditingValue(const TextEditingValue(
Expand Down