mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
[web] Don't show handles when selection change is caused by keyboard (#65127)
This commit is contained in:
parent
389b5b6c3a
commit
0d8de393aa
@ -1643,7 +1643,11 @@ class EditableTextState extends State<EditableText> with AutomaticKeepAliveClien
|
||||
}
|
||||
}
|
||||
|
||||
_formatAndSetValue(value);
|
||||
if (_isSelectionOnlyChange(value)) {
|
||||
_handleSelectionChanged(value.selection, renderEditable, SelectionChangedCause.keyboard);
|
||||
} else {
|
||||
_formatAndSetValue(value);
|
||||
}
|
||||
|
||||
if (_hasInputConnection) {
|
||||
// To keep the cursor from blinking while typing, we want to restart the
|
||||
@ -1653,6 +1657,10 @@ class EditableTextState extends State<EditableText> with AutomaticKeepAliveClien
|
||||
}
|
||||
}
|
||||
|
||||
bool _isSelectionOnlyChange(TextEditingValue value) {
|
||||
return value.text == _value.text && value.composing == _value.composing;
|
||||
}
|
||||
|
||||
@override
|
||||
void performAction(TextInputAction action) {
|
||||
switch (action) {
|
||||
|
||||
@ -7795,6 +7795,48 @@ void main() {
|
||||
},
|
||||
);
|
||||
|
||||
testWidgets('Does not show handles when updated from the web engine', (WidgetTester tester) async {
|
||||
final TextEditingController controller = TextEditingController(
|
||||
text: 'abc def ghi',
|
||||
);
|
||||
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
home: Material(
|
||||
child: TextField(controller: controller),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
// Interact with the text field to establish the input connection.
|
||||
final Offset topLeft = tester.getTopLeft(find.byType(EditableText));
|
||||
final TestGesture gesture = await tester.startGesture(
|
||||
topLeft + const Offset(0.0, 5.0),
|
||||
kind: PointerDeviceKind.mouse,
|
||||
);
|
||||
addTearDown(gesture.removePointer);
|
||||
await tester.pump(const Duration(milliseconds: 50));
|
||||
await gesture.up();
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
final EditableTextState state = tester.state(find.byType(EditableText));
|
||||
expect(state.selectionOverlay.handlesAreVisible, isFalse);
|
||||
expect(controller.selection, const TextSelection.collapsed(offset: 0));
|
||||
|
||||
if (kIsWeb) {
|
||||
tester.testTextInput.updateEditingValue(const TextEditingValue(
|
||||
selection: TextSelection(baseOffset: 2, extentOffset: 7),
|
||||
));
|
||||
// Wait for all the `setState` calls to be flushed.
|
||||
await tester.pumpAndSettle();
|
||||
expect(
|
||||
state.currentTextEditingValue.selection,
|
||||
const TextSelection(baseOffset: 2, extentOffset: 7),
|
||||
);
|
||||
expect(state.selectionOverlay.handlesAreVisible, isFalse);
|
||||
}
|
||||
});
|
||||
|
||||
testWidgets('Tapping selection handles toggles the toolbar', (WidgetTester tester) async {
|
||||
final TextEditingController controller = TextEditingController(
|
||||
text: 'abc def ghi',
|
||||
|
||||
@ -1398,6 +1398,46 @@ void main() {
|
||||
}
|
||||
});
|
||||
|
||||
testWidgets('Read-only fields do not format text', (WidgetTester tester) async {
|
||||
SelectionChangedCause selectionCause;
|
||||
|
||||
final TextEditingController controller =
|
||||
TextEditingController(text: 'Lorem ipsum dolor sit amet');
|
||||
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
home: EditableText(
|
||||
readOnly: true,
|
||||
controller: controller,
|
||||
backgroundCursorColor: Colors.grey,
|
||||
focusNode: focusNode,
|
||||
style: textStyle,
|
||||
cursorColor: cursorColor,
|
||||
selectionControls: materialTextSelectionControls,
|
||||
onSelectionChanged: (TextSelection selection, SelectionChangedCause cause) {
|
||||
selectionCause = cause;
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
// Interact with the field to establish the input connection.
|
||||
final Offset topLeft = tester.getTopLeft(find.byType(EditableText));
|
||||
await tester.tapAt(topLeft + const Offset(0.0, 5.0));
|
||||
await tester.pump();
|
||||
|
||||
expect(tester.testTextInput.hasAnyClients, kIsWeb ? isTrue : isFalse);
|
||||
if (kIsWeb) {
|
||||
tester.testTextInput.updateEditingValue(const TextEditingValue(
|
||||
text: 'Foo bar',
|
||||
selection: TextSelection(baseOffset: 0, extentOffset: 3),
|
||||
));
|
||||
// On web, the only way a text field can be updated from the engine is if
|
||||
// a keyboard is used.
|
||||
expect(selectionCause, SelectionChangedCause.keyboard);
|
||||
}
|
||||
});
|
||||
|
||||
testWidgets('Fires onChanged when text changes via TextSelectionOverlay', (WidgetTester tester) async {
|
||||
String changedValue;
|
||||
final Widget widget = MaterialApp(
|
||||
|
||||
@ -3971,4 +3971,45 @@ void main() {
|
||||
TargetPlatform.windows,
|
||||
}),
|
||||
);
|
||||
|
||||
testWidgets('Does not show handles when updated from the web engine', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(
|
||||
const MaterialApp(
|
||||
home: Material(
|
||||
child: SelectableText('abc def ghi'),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
// Interact with the selectable text to establish the input connection.
|
||||
final Offset topLeft = tester.getTopLeft(find.byType(EditableText));
|
||||
final TestGesture gesture = await tester.startGesture(
|
||||
topLeft + const Offset(0.0, 5.0),
|
||||
kind: PointerDeviceKind.mouse,
|
||||
);
|
||||
addTearDown(gesture.removePointer);
|
||||
await tester.pump(const Duration(milliseconds: 50));
|
||||
await gesture.up();
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
final EditableTextState state = tester.state(find.byType(EditableText));
|
||||
expect(state.selectionOverlay.handlesAreVisible, isFalse);
|
||||
expect(
|
||||
state.currentTextEditingValue.selection,
|
||||
const TextSelection.collapsed(offset: 0),
|
||||
);
|
||||
|
||||
if (kIsWeb) {
|
||||
tester.testTextInput.updateEditingValue(const TextEditingValue(
|
||||
selection: TextSelection(baseOffset: 2, extentOffset: 7),
|
||||
));
|
||||
// Wait for all the `setState` calls to be flushed.
|
||||
await tester.pumpAndSettle();
|
||||
expect(
|
||||
state.currentTextEditingValue.selection,
|
||||
const TextSelection(baseOffset: 2, extentOffset: 7),
|
||||
);
|
||||
expect(state.selectionOverlay.handlesAreVisible, isFalse);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user