Unverified Commit d82bca2a authored by Justin McCandless's avatar Justin McCandless Committed by GitHub

Fix selection menu not showing after clear (#37042)

This allows the text selection menu to be shown after deleting all text in a text field.
parent 53a1f225
......@@ -1061,7 +1061,7 @@ class EditableTextState extends State<EditableText> with AutomaticKeepAliveClien
return;
}
if (value.text != _value.text) {
_hideSelectionOverlayIfNeeded();
hideToolbar();
_showCaretOnScreen();
if (widget.obscureText && value.text.length == _value.text.length + 1) {
_obscureShowCharTicksPending = _kObscureShowLatestCharCursorTicks;
......@@ -1300,11 +1300,6 @@ class EditableTextState extends State<EditableText> with AutomaticKeepAliveClien
}
}
void _hideSelectionOverlayIfNeeded() {
_selectionOverlay?.hide();
_selectionOverlay = null;
}
void _updateOrDisposeSelectionOverlayIfNeeded() {
if (_selectionOverlay != null) {
if (_hasFocus) {
......@@ -1323,7 +1318,8 @@ class EditableTextState extends State<EditableText> with AutomaticKeepAliveClien
// EditableWidget, not just changes triggered by user gestures.
requestKeyboard();
_hideSelectionOverlayIfNeeded();
_selectionOverlay?.hide();
_selectionOverlay = null;
if (widget.selectionControls != null) {
_selectionOverlay = TextSelectionOverlay(
......
......@@ -16,7 +16,7 @@ import 'package:flutter/foundation.dart';
import 'editable_text_utils.dart';
import 'semantics_tester.dart';
final TextEditingController controller = TextEditingController();
TextEditingController controller;
final FocusNode focusNode = FocusNode(debugLabel: 'EditableText Node');
final FocusScopeNode focusScopeNode = FocusScopeNode(debugLabel: 'EditableText Scope Node');
const TextStyle textStyle = TextStyle();
......@@ -29,6 +29,12 @@ enum HandlePositionInViewport {
void main() {
setUp(() {
debugResetSemanticsIdCounter();
controller = TextEditingController();
});
tearDown(() {
controller.dispose();
controller = null;
});
// Tests that the desired keyboard action button is requested.
......@@ -528,7 +534,7 @@ void main() {
equals('TextInputAction.done'));
});
testWidgets('can only show toolbar when there is text and a selection', (WidgetTester tester) async {
testWidgets('can show toolbar when there is text and a selection', (WidgetTester tester) async {
await tester.pumpWidget(
MaterialApp(
home: EditableText(
......@@ -545,22 +551,69 @@ void main() {
final EditableTextState state =
tester.state<EditableTextState>(find.byType(EditableText));
// Can't show the toolbar when there's no focus.
expect(state.showToolbar(), false);
await tester.pump();
expect(find.text('PASTE'), findsNothing);
controller.text = 'blah';
// Can show the toolbar when focused even though there's no text.
state.renderEditable.selectWordsInRange(
from: const Offset(0, 0),
cause: SelectionChangedCause.tap,
);
await tester.pump();
expect(state.showToolbar(), false);
expect(state.showToolbar(), true);
await tester.pump();
expect(find.text('PASTE'), findsOneWidget);
// Hide the menu again.
state.hideToolbar();
await tester.pump();
expect(find.text('PASTE'), findsNothing);
// Select something. Doesn't really matter what.
// Can show the menu with text and a selection.
controller.text = 'blah';
await tester.pump();
expect(state.showToolbar(), true);
await tester.pump();
expect(find.text('PASTE'), findsOneWidget);
});
testWidgets('can show the toolbar after clearing all text', (WidgetTester tester) async {
// Regression test for https://github.com/flutter/flutter/issues/35998.
await tester.pumpWidget(
MaterialApp(
home: EditableText(
backgroundCursorColor: Colors.grey,
controller: controller,
focusNode: focusNode,
style: textStyle,
cursorColor: cursorColor,
selectionControls: materialTextSelectionControls,
),
),
);
final EditableTextState state =
tester.state<EditableTextState>(find.byType(EditableText));
// Add text and an empty selection.
controller.text = 'blah';
await tester.pump();
state.renderEditable.selectWordsInRange(
from: const Offset(0, 0),
cause: SelectionChangedCause.tap,
);
await tester.pump();
// Clear the text and selection.
expect(find.text('PASTE'), findsNothing);
state.updateEditingValue(const TextEditingValue(
text: '',
));
await tester.pump();
// Should be able to show the toolbar.
expect(state.showToolbar(), true);
await tester.pump();
expect(find.text('PASTE'), findsOneWidget);
......
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