[web_ui] Fixing invalid state bug for text editing (#12698)

* Fixing invalid state bug for text editing. Flutter Framework was sending editing state selection base and extent as -1. Since -1 is an invalid value for a dom element selection it was not applied to the last editing state. Now if the base or offset is sent as negative value, web engine will set 0 to the selection range.

* Addressing PR comments.
This commit is contained in:
Nurhan Turgut 2019-09-30 12:31:17 -07:00 committed by GitHub
parent 463762b817
commit bfcafbec2b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 55 additions and 4 deletions

View File

@ -61,10 +61,20 @@ class EditingState {
/// "composingExtent": -1
/// }
/// ```
EditingState.fromFlutter(Map<String, dynamic> flutterEditingState)
: text = flutterEditingState['text'],
baseOffset = flutterEditingState['selectionBase'],
extentOffset = flutterEditingState['selectionExtent'];
///
/// Flutter Framework can send the [selectionBase] and [selectionExtent] as
/// -1, if so 0 assigned to the [baseOffset] and [extentOffset]. -1 is not a
/// valid selection range for input DOM elements.
factory EditingState.fromFlutter(Map<String, dynamic> flutterEditingState) {
final int selectionBase = flutterEditingState['selectionBase'];
final int selectionExtent = flutterEditingState['selectionExtent'];
final String text = flutterEditingState['text'];
return EditingState(
text: text,
baseOffset: math.max(0, selectionBase),
extentOffset: math.max(0, selectionExtent));
}
/// Creates an [EditingState] instance using values from the editing element
/// in the DOM.

View File

@ -549,6 +549,47 @@ void main() {
expect(spy.messages, isEmpty);
});
test(
'negative base offset and selection extent values in editing state is handled',
() {
final MethodCall setClient = MethodCall(
'TextInput.setClient', <dynamic>[123, flutterSinglelineConfig]);
textEditing.handleTextInput(codec.encodeMethodCall(setClient));
const MethodCall setEditingState1 =
MethodCall('TextInput.setEditingState', <String, dynamic>{
'text': 'xyz',
'selectionBase': 1,
'selectionExtent': 2,
});
textEditing.handleTextInput(codec.encodeMethodCall(setEditingState1));
const MethodCall show = MethodCall('TextInput.show');
textEditing.handleTextInput(codec.encodeMethodCall(show));
// Check if the selection range is correct.
checkInputEditingState(
textEditing.editingElement.domElement, 'xyz', 1, 2);
const MethodCall setEditingState2 =
MethodCall('TextInput.setEditingState', <String, dynamic>{
'text': 'xyz',
'selectionBase': -1,
'selectionExtent': -1,
});
textEditing.handleTextInput(codec.encodeMethodCall(setEditingState2));
// The negative offset values are applied to the dom element as 0.
checkInputEditingState(
textEditing.editingElement.domElement, 'xyz', 0, 0);
const MethodCall clearClient = MethodCall('TextInput.clearClient');
textEditing.handleTextInput(codec.encodeMethodCall(clearClient));
// Confirm that [HybridTextEditing] didn't send any messages.
expect(spy.messages, isEmpty);
});
test('Syncs the editing state back to Flutter', () {
final MethodCall setClient = MethodCall(
'TextInput.setClient', <dynamic>[123, flutterSinglelineConfig]);