Fix requestExistingInputState response (#47472)
This commit is contained in:
parent
cc1c9649c4
commit
93f718b386
@ -753,6 +753,9 @@ abstract class TextInputClient {
|
||||
/// Updates the floating cursor position and state.
|
||||
void updateFloatingCursor(RawFloatingCursorPoint point);
|
||||
|
||||
/// The current state of the [TextEditingValue] held by this client.
|
||||
TextEditingValue get currentTextEditingValue;
|
||||
|
||||
/// Platform notified framework of closed connection.
|
||||
///
|
||||
/// [TextInputClient] should cleanup its connection and finalize editing.
|
||||
@ -1036,7 +1039,6 @@ class TextInput {
|
||||
|
||||
TextInputConnection _currentConnection;
|
||||
TextInputConfiguration _currentConfiguration;
|
||||
TextEditingValue _currentTextEditingValue;
|
||||
|
||||
Future<dynamic> _handleTextInputInvocation(MethodCall methodCall) async {
|
||||
if (_currentConnection == null)
|
||||
@ -1048,9 +1050,9 @@ class TextInput {
|
||||
if (method == 'TextInputClient.requestExistingInputState') {
|
||||
assert(_currentConnection._client != null);
|
||||
_attach(_currentConnection, _currentConfiguration);
|
||||
// This will be null if we've never had a call to [_setEditingState].
|
||||
if (_currentTextEditingValue != null) {
|
||||
_setEditingState(_currentTextEditingValue);
|
||||
final TextEditingValue editingValue = _currentConnection._client.currentTextEditingValue;
|
||||
if (editingValue != null) {
|
||||
_setEditingState(editingValue);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -1110,7 +1112,6 @@ class TextInput {
|
||||
'TextInput.setEditingState',
|
||||
value.toJSON(),
|
||||
);
|
||||
_currentTextEditingValue = value;
|
||||
}
|
||||
|
||||
void _show() {
|
||||
|
@ -1202,6 +1202,9 @@ class EditableTextState extends State<EditableText> with AutomaticKeepAliveClien
|
||||
|
||||
TextEditingValue _lastKnownRemoteTextEditingValue;
|
||||
|
||||
@override
|
||||
TextEditingValue get currentTextEditingValue => _value;
|
||||
|
||||
@override
|
||||
void updateEditingValue(TextEditingValue value) {
|
||||
// Since we still have to support keyboard select, this is the best place
|
||||
|
@ -13,12 +13,10 @@ void main() {
|
||||
|
||||
group('TextInput message channels', () {
|
||||
FakeTextChannel fakeTextChannel;
|
||||
FakeTextInputClient client;
|
||||
|
||||
setUp(() {
|
||||
fakeTextChannel = FakeTextChannel((MethodCall call) async {});
|
||||
TextInput.setChannel(fakeTextChannel);
|
||||
client = FakeTextInputClient();
|
||||
});
|
||||
|
||||
tearDown(() {
|
||||
@ -27,6 +25,26 @@ void main() {
|
||||
});
|
||||
|
||||
test('text input client handler responds to reattach with setClient', () async {
|
||||
final FakeTextInputClient client = FakeTextInputClient(const TextEditingValue(text: 'test1'));
|
||||
TextInput.attach(client, client.configuration);
|
||||
fakeTextChannel.validateOutgoingMethodCalls(<MethodCall>[
|
||||
MethodCall('TextInput.setClient', <dynamic>[1, client.configuration.toJson()]),
|
||||
]);
|
||||
|
||||
fakeTextChannel.incoming(const MethodCall('TextInputClient.requestExistingInputState', null));
|
||||
|
||||
expect(fakeTextChannel.outgoingCalls.length, 3);
|
||||
fakeTextChannel.validateOutgoingMethodCalls(<MethodCall>[
|
||||
// From original attach
|
||||
MethodCall('TextInput.setClient', <dynamic>[1, client.configuration.toJson()]),
|
||||
// From requestExistingInputState
|
||||
MethodCall('TextInput.setClient', <dynamic>[1, client.configuration.toJson()]),
|
||||
MethodCall('TextInput.setEditingState', client.currentTextEditingValue.toJSON()),
|
||||
]);
|
||||
});
|
||||
|
||||
test('text input client handler responds to reattach with setClient (null TextEditingValue)', () async {
|
||||
final FakeTextInputClient client = FakeTextInputClient(null);
|
||||
TextInput.attach(client, client.configuration);
|
||||
fakeTextChannel.validateOutgoingMethodCalls(<MethodCall>[
|
||||
MethodCall('TextInput.setClient', <dynamic>[1, client.configuration.toJson()]),
|
||||
@ -42,33 +60,6 @@ void main() {
|
||||
MethodCall('TextInput.setClient', <dynamic>[1, client.configuration.toJson()]),
|
||||
]);
|
||||
});
|
||||
|
||||
test('text input client handler responds to reattach with setClient and text state', () async {
|
||||
final TextInputConnection connection = TextInput.attach(client, client.configuration);
|
||||
fakeTextChannel.validateOutgoingMethodCalls(<MethodCall>[
|
||||
MethodCall('TextInput.setClient', <dynamic>[1, client.configuration.toJson()]),
|
||||
]);
|
||||
|
||||
const TextEditingValue editingState = TextEditingValue(text: 'foo');
|
||||
connection.setEditingState(editingState);
|
||||
fakeTextChannel.validateOutgoingMethodCalls(<MethodCall>[
|
||||
MethodCall('TextInput.setClient', <dynamic>[1, client.configuration.toJson()]),
|
||||
MethodCall('TextInput.setEditingState', editingState.toJSON()),
|
||||
]);
|
||||
|
||||
fakeTextChannel.incoming(const MethodCall('TextInputClient.requestExistingInputState', null));
|
||||
|
||||
expect(fakeTextChannel.outgoingCalls.length, 4);
|
||||
fakeTextChannel.validateOutgoingMethodCalls(<MethodCall>[
|
||||
// attach
|
||||
MethodCall('TextInput.setClient', <dynamic>[1, client.configuration.toJson()]),
|
||||
// set editing state 1
|
||||
MethodCall('TextInput.setEditingState', editingState.toJSON()),
|
||||
// both from requestExistingInputState
|
||||
MethodCall('TextInput.setClient', <dynamic>[1, client.configuration.toJson()]),
|
||||
MethodCall('TextInput.setEditingState', editingState.toJSON()),
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
group('TextInputConfiguration', () {
|
||||
@ -153,7 +144,7 @@ void main() {
|
||||
|
||||
test('TextInputClient onConnectionClosed method is called', () async {
|
||||
// Assemble a TextInputConnection so we can verify its change in state.
|
||||
final FakeTextInputClient client = FakeTextInputClient();
|
||||
final FakeTextInputClient client = FakeTextInputClient(const TextEditingValue(text: 'test3'));
|
||||
const TextInputConfiguration configuration = TextInputConfiguration();
|
||||
TextInput.attach(client, configuration);
|
||||
|
||||
@ -176,8 +167,13 @@ void main() {
|
||||
}
|
||||
|
||||
class FakeTextInputClient implements TextInputClient {
|
||||
FakeTextInputClient(this.currentTextEditingValue);
|
||||
|
||||
String latestMethodCall = '';
|
||||
|
||||
@override
|
||||
TextEditingValue currentTextEditingValue;
|
||||
|
||||
@override
|
||||
void performAction(TextInputAction action) {
|
||||
latestMethodCall = 'performAction';
|
||||
@ -231,7 +227,6 @@ class FakeTextChannel implements MethodChannel {
|
||||
@override
|
||||
String get name => 'flutter/textinput';
|
||||
|
||||
|
||||
@override
|
||||
void setMethodCallHandler(Future<void> Function(MethodCall call) handler) {
|
||||
incoming = handler;
|
||||
@ -252,7 +247,7 @@ class FakeTextChannel implements MethodChannel {
|
||||
if (outgoingString != expectedString) {
|
||||
print(
|
||||
'Index $i did not match:\n'
|
||||
' actual: ${outgoingCalls[i]}'
|
||||
' actual: ${outgoingCalls[i]}\n'
|
||||
' expected: ${calls[i]}');
|
||||
hasError = true;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user