mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
[web] denull some of text_editing.dart (#166595)
According to
485d6b8ae3/packages/flutter/lib/src/services/text_input.dart (L1086),
the framework never sends null values for any of the fields. So there's
no need for the engine to do all the null handling.
---------
Co-authored-by: Mouad Debbar <mouad.debbar@gmail.com>
This commit is contained in:
parent
fa8f0f2988
commit
c790bb111a
@ -1480,7 +1480,7 @@ extension type DomHTMLTextAreaElement._(JSObject _) implements DomHTMLElement {
|
||||
external double? get selectionEnd;
|
||||
external set selectionStart(double? value);
|
||||
external set selectionEnd(double? value);
|
||||
external String? get value;
|
||||
external String get value;
|
||||
|
||||
@JS('setSelectionRange')
|
||||
external void _setSelectionRange(int start, int end, [String direction]);
|
||||
@ -1855,7 +1855,7 @@ extension type DomHTMLInputElement._(JSObject _) implements DomHTMLElement {
|
||||
external String? type;
|
||||
external set max(String? value);
|
||||
external set min(String value);
|
||||
external String? value;
|
||||
external String value;
|
||||
external bool? disabled;
|
||||
external String placeholder;
|
||||
external String? name;
|
||||
|
||||
@ -41,7 +41,7 @@ class SemanticIncrementable extends SemanticRole {
|
||||
return;
|
||||
}
|
||||
_pendingResync = true;
|
||||
final int newInputValue = int.parse(_element.value!);
|
||||
final int newInputValue = int.parse(_element.value);
|
||||
if (newInputValue > _currentSurrogateValue) {
|
||||
_currentSurrogateValue += 1;
|
||||
EnginePlatformDispatcher.instance.invokeOnSemanticsAction(
|
||||
|
||||
@ -74,11 +74,11 @@ mixin CompositionAwareMixin {
|
||||
}
|
||||
|
||||
EditingState determineCompositionState(EditingState editingState) {
|
||||
if (editingState.extentOffset == null || composingText == null || editingState.text == null) {
|
||||
if (composingText == null) {
|
||||
return editingState;
|
||||
}
|
||||
|
||||
final int composingBase = editingState.extentOffset! - composingText!.length;
|
||||
final int composingBase = editingState.extentOffset - composingText!.length;
|
||||
|
||||
if (composingBase < 0) {
|
||||
return editingState;
|
||||
|
||||
@ -617,24 +617,22 @@ class TextEditingDeltaState {
|
||||
// If the deletion is forward, [deltaStart] is set to the new editing state baseOffset
|
||||
// and [deltaEnd] is set to [deltaStart] incremented by the length of the deletion.
|
||||
final int deletedLength =
|
||||
newTextEditingDeltaState.oldText.length - newEditingState.text!.length;
|
||||
newTextEditingDeltaState.oldText.length - newEditingState.text.length;
|
||||
final bool backwardDeletion = newEditingState.baseOffset != lastEditingState?.baseOffset;
|
||||
if (backwardDeletion) {
|
||||
newTextEditingDeltaState.deltaStart = newTextEditingDeltaState.deltaEnd - deletedLength;
|
||||
} else {
|
||||
// Forward deletion
|
||||
newTextEditingDeltaState.deltaStart = newEditingState.baseOffset!;
|
||||
newTextEditingDeltaState.deltaStart = newEditingState.baseOffset;
|
||||
newTextEditingDeltaState.deltaEnd = newTextEditingDeltaState.deltaStart + deletedLength;
|
||||
}
|
||||
} else if (isTextBeingChangedAtActiveSelection) {
|
||||
final bool isPreviousSelectionInverted =
|
||||
lastEditingState!.baseOffset! > lastEditingState.extentOffset!;
|
||||
lastEditingState!.baseOffset > lastEditingState.extentOffset;
|
||||
// When a selection of text is replaced by a copy/paste operation we set the starting range
|
||||
// of the delta to be the beginning of the selection of the previous editing state.
|
||||
newTextEditingDeltaState.deltaStart =
|
||||
isPreviousSelectionInverted
|
||||
? lastEditingState.extentOffset!
|
||||
: lastEditingState.baseOffset!;
|
||||
isPreviousSelectionInverted ? lastEditingState.extentOffset : lastEditingState.baseOffset;
|
||||
}
|
||||
|
||||
// If we are composing then set the delta range to the composing region we
|
||||
@ -673,7 +671,7 @@ class TextEditingDeltaState {
|
||||
newTextEditingDeltaState.deltaText,
|
||||
replacementRange,
|
||||
);
|
||||
final bool isDeltaVerified = textAfterDelta == newEditingState.text!;
|
||||
final bool isDeltaVerified = textAfterDelta == newEditingState.text;
|
||||
|
||||
if (!isDeltaVerified) {
|
||||
// 1. Find all matches for deltaText.
|
||||
@ -681,7 +679,7 @@ class TextEditingDeltaState {
|
||||
// new editing state's text value.
|
||||
final bool isPeriodInsertion = newTextEditingDeltaState.deltaText.contains('.');
|
||||
final RegExp deltaTextPattern = RegExp(RegExp.escape(newTextEditingDeltaState.deltaText));
|
||||
for (final Match match in deltaTextPattern.allMatches(newEditingState.text!)) {
|
||||
for (final Match match in deltaTextPattern.allMatches(newEditingState.text)) {
|
||||
String textAfterMatch;
|
||||
int actualEnd;
|
||||
final bool isMatchWithinOldTextBounds =
|
||||
@ -702,7 +700,7 @@ class TextEditingDeltaState {
|
||||
);
|
||||
}
|
||||
|
||||
if (textAfterMatch == newEditingState.text!) {
|
||||
if (textAfterMatch == newEditingState.text) {
|
||||
newTextEditingDeltaState.deltaStart = match.start;
|
||||
newTextEditingDeltaState.deltaEnd = actualEnd;
|
||||
break;
|
||||
@ -789,15 +787,15 @@ class TextEditingDeltaState {
|
||||
/// The current text and selection state of a text field.
|
||||
class EditingState {
|
||||
EditingState({
|
||||
this.text,
|
||||
int? baseOffset,
|
||||
int? extentOffset,
|
||||
required this.text,
|
||||
required int baseOffset,
|
||||
required int extentOffset,
|
||||
this.composingBaseOffset = -1,
|
||||
this.composingExtentOffset = -1,
|
||||
}) : // Don't allow negative numbers.
|
||||
baseOffset = math.max(0, baseOffset ?? 0),
|
||||
baseOffset = math.max(0, baseOffset),
|
||||
// Don't allow negative numbers.
|
||||
extentOffset = math.max(0, extentOffset ?? 0);
|
||||
extentOffset = math.max(0, extentOffset);
|
||||
|
||||
/// Creates an [EditingState] instance using values from an editing state Map
|
||||
/// coming from Flutter.
|
||||
@ -819,20 +817,18 @@ class EditingState {
|
||||
/// -1, if so 0 assigned to the [baseOffset] and [extentOffset]. -1 is not a
|
||||
/// valid selection range for input DOM elements.
|
||||
factory EditingState.fromFrameworkMessage(Map<String, dynamic> flutterEditingState) {
|
||||
final String? text = flutterEditingState.tryString('text');
|
||||
|
||||
final String text = flutterEditingState.readString('text');
|
||||
final int selectionBase = flutterEditingState.readInt('selectionBase');
|
||||
final int selectionExtent = flutterEditingState.readInt('selectionExtent');
|
||||
|
||||
final int? composingBase = flutterEditingState.tryInt('composingBase');
|
||||
final int? composingExtent = flutterEditingState.tryInt('composingExtent');
|
||||
final int composingBase = flutterEditingState.readInt('composingBase');
|
||||
final int composingExtent = flutterEditingState.readInt('composingExtent');
|
||||
|
||||
return EditingState(
|
||||
text: text,
|
||||
baseOffset: selectionBase,
|
||||
extentOffset: selectionExtent,
|
||||
composingBaseOffset: composingBase ?? -1,
|
||||
composingExtentOffset: composingExtent ?? -1,
|
||||
composingBaseOffset: composingBase,
|
||||
composingExtentOffset: composingExtent,
|
||||
);
|
||||
}
|
||||
|
||||
@ -841,35 +837,39 @@ class EditingState {
|
||||
///
|
||||
/// [domElement] can be a [InputElement] or a [TextAreaElement] depending on
|
||||
/// the [InputType] of the text field.
|
||||
factory EditingState.fromDomElement(DomHTMLElement? domElement) {
|
||||
if (domElement != null && domElement.isA<DomHTMLInputElement>()) {
|
||||
final DomHTMLInputElement element = domElement as DomHTMLInputElement;
|
||||
factory EditingState.fromDomElement(DomHTMLElement domElement) {
|
||||
if (domElement.isA<DomHTMLInputElement>()) {
|
||||
final element = domElement as DomHTMLInputElement;
|
||||
final selectionEnd = element.selectionEnd?.toInt() ?? 0;
|
||||
final selectionStart = element.selectionStart?.toInt() ?? 0;
|
||||
if (element.selectionDirection == 'backward') {
|
||||
return EditingState(
|
||||
text: element.value,
|
||||
baseOffset: element.selectionEnd?.toInt(),
|
||||
extentOffset: element.selectionStart?.toInt(),
|
||||
baseOffset: selectionEnd,
|
||||
extentOffset: selectionStart,
|
||||
);
|
||||
} else {
|
||||
return EditingState(
|
||||
text: element.value,
|
||||
baseOffset: element.selectionStart?.toInt(),
|
||||
extentOffset: element.selectionEnd?.toInt(),
|
||||
baseOffset: selectionStart,
|
||||
extentOffset: selectionEnd,
|
||||
);
|
||||
}
|
||||
} else if (domElement != null && domElement.isA<DomHTMLTextAreaElement>()) {
|
||||
final DomHTMLTextAreaElement element = domElement as DomHTMLTextAreaElement;
|
||||
} else if (domElement.isA<DomHTMLTextAreaElement>()) {
|
||||
final element = domElement as DomHTMLTextAreaElement;
|
||||
final selectionEnd = element.selectionEnd?.toInt() ?? 0;
|
||||
final selectionStart = element.selectionStart?.toInt() ?? 0;
|
||||
if (element.selectionDirection == 'backward') {
|
||||
return EditingState(
|
||||
text: element.value,
|
||||
baseOffset: element.selectionEnd?.toInt(),
|
||||
extentOffset: element.selectionStart?.toInt(),
|
||||
baseOffset: selectionEnd,
|
||||
extentOffset: selectionStart,
|
||||
);
|
||||
} else {
|
||||
return EditingState(
|
||||
text: element.value,
|
||||
baseOffset: element.selectionStart?.toInt(),
|
||||
extentOffset: element.selectionEnd?.toInt(),
|
||||
baseOffset: selectionStart,
|
||||
extentOffset: selectionEnd,
|
||||
);
|
||||
}
|
||||
} else {
|
||||
@ -878,9 +878,9 @@ class EditingState {
|
||||
}
|
||||
|
||||
// Pick the smallest selection index for base.
|
||||
int get minOffset => math.min(baseOffset ?? 0, extentOffset ?? 0);
|
||||
int get minOffset => math.min(baseOffset, extentOffset);
|
||||
// Pick the greatest selection index for extent.
|
||||
int get maxOffset => math.max(baseOffset ?? 0, extentOffset ?? 0);
|
||||
int get maxOffset => math.max(baseOffset, extentOffset);
|
||||
|
||||
EditingState copyWith({
|
||||
String? text,
|
||||
@ -910,13 +910,13 @@ class EditingState {
|
||||
};
|
||||
|
||||
/// The current text being edited.
|
||||
final String? text;
|
||||
final String text;
|
||||
|
||||
/// The offset at which the text selection originates.
|
||||
final int? baseOffset;
|
||||
final int baseOffset;
|
||||
|
||||
/// The offset at which the text selection terminates.
|
||||
final int? extentOffset;
|
||||
final int extentOffset;
|
||||
|
||||
/// The offset at which [CompositionAwareMixin.composingText] begins, if any.
|
||||
final int composingBaseOffset;
|
||||
@ -925,7 +925,7 @@ class EditingState {
|
||||
final int composingExtentOffset;
|
||||
|
||||
/// Whether the current editing state is valid or not.
|
||||
bool get isValid => baseOffset! >= 0 && extentOffset! >= 0;
|
||||
bool get isValid => baseOffset >= 0 && extentOffset >= 0;
|
||||
|
||||
@override
|
||||
int get hashCode =>
|
||||
@ -1275,7 +1275,7 @@ abstract class DefaultTextEditingStrategy
|
||||
|
||||
TextEditingDeltaState? _editingDeltaState;
|
||||
TextEditingDeltaState get editingDeltaState {
|
||||
_editingDeltaState ??= TextEditingDeltaState(oldText: lastEditingState!.text!);
|
||||
_editingDeltaState ??= TextEditingDeltaState(oldText: lastEditingState!.text);
|
||||
return _editingDeltaState!;
|
||||
}
|
||||
|
||||
@ -1516,9 +1516,9 @@ abstract class DefaultTextEditingStrategy
|
||||
|
||||
if (inputType != null) {
|
||||
final bool isSelectionInverted =
|
||||
lastEditingState!.baseOffset! > lastEditingState!.extentOffset!;
|
||||
lastEditingState!.baseOffset > lastEditingState!.extentOffset;
|
||||
final int deltaOffset =
|
||||
isSelectionInverted ? lastEditingState!.baseOffset! : lastEditingState!.extentOffset!;
|
||||
isSelectionInverted ? lastEditingState!.baseOffset : lastEditingState!.extentOffset;
|
||||
if (inputType.contains('delete')) {
|
||||
// The deltaStart is set in handleChange because there is where we get access
|
||||
// to the new selection baseOffset which is our new deltaStart.
|
||||
|
||||
@ -114,7 +114,11 @@ Future<void> testMain() async {
|
||||
|
||||
group('determine composition state', () {
|
||||
test('should return editing state if extentOffset is null', () {
|
||||
final EditingState editingState = EditingState(text: 'Test');
|
||||
final EditingState editingState = EditingState(
|
||||
text: 'Test',
|
||||
baseOffset: 0,
|
||||
extentOffset: 0,
|
||||
);
|
||||
|
||||
final _MockWithCompositionAwareMixin mockWithCompositionAwareMixin =
|
||||
_MockWithCompositionAwareMixin();
|
||||
@ -137,7 +141,7 @@ Future<void> testMain() async {
|
||||
});
|
||||
|
||||
test('should return editing state if text is null', () {
|
||||
final EditingState editingState = EditingState(baseOffset: 0, extentOffset: 0);
|
||||
final EditingState editingState = EditingState(text: '', baseOffset: 0, extentOffset: 0);
|
||||
|
||||
final _MockWithCompositionAwareMixin mockWithCompositionAwareMixin =
|
||||
_MockWithCompositionAwareMixin();
|
||||
|
||||
@ -283,6 +283,8 @@ void testMain() {
|
||||
'text': 'updated',
|
||||
'selectionBase': 2,
|
||||
'selectionExtent': 3,
|
||||
'composingBase': -1,
|
||||
'composingExtent': -1,
|
||||
});
|
||||
sendFrameworkMessage(codec.encodeMethodCall(setEditingState), testTextEditing);
|
||||
|
||||
@ -351,7 +353,7 @@ void testMain() {
|
||||
expect(owner().semanticsHost.ownerDocument?.activeElement, domDocument.body);
|
||||
|
||||
// The input will have focus after editing state is set and semantics updated.
|
||||
strategy.setEditingState(EditingState(text: 'foo'));
|
||||
strategy.setEditingState(EditingState(text: 'foo', baseOffset: 0, extentOffset: 0));
|
||||
|
||||
// NOTE: at this point some browsers, e.g. some versions of Safari will
|
||||
// have set the focus on the editing element as a result of setting
|
||||
|
||||
@ -813,6 +813,8 @@ Future<void> testMain() async {
|
||||
'text': 'abcd',
|
||||
'selectionBase': 2,
|
||||
'selectionExtent': 3,
|
||||
'composingBase': -1,
|
||||
'composingExtent': -1,
|
||||
});
|
||||
sendFrameworkMessage(codec.encodeMethodCall(setEditingState));
|
||||
|
||||
@ -844,6 +846,8 @@ Future<void> testMain() async {
|
||||
'text': 'abcd',
|
||||
'selectionBase': 2,
|
||||
'selectionExtent': 3,
|
||||
'composingBase': -1,
|
||||
'composingExtent': -1,
|
||||
});
|
||||
sendFrameworkMessage(codec.encodeMethodCall(setEditingState));
|
||||
|
||||
@ -914,7 +918,13 @@ Future<void> testMain() async {
|
||||
|
||||
const MethodCall setEditingState = MethodCall(
|
||||
'TextInput.setEditingState',
|
||||
<String, dynamic>{'text': 'abcd', 'selectionBase': 2, 'selectionExtent': 3},
|
||||
<String, dynamic>{
|
||||
'text': 'abcd',
|
||||
'selectionBase': 2,
|
||||
'selectionExtent': 3,
|
||||
'composingBase': -1,
|
||||
'composingExtent': -1,
|
||||
},
|
||||
);
|
||||
sendFrameworkMessage(codec.encodeMethodCall(setEditingState));
|
||||
|
||||
@ -937,6 +947,8 @@ Future<void> testMain() async {
|
||||
'text': 'abcd',
|
||||
'selectionBase': 2,
|
||||
'selectionExtent': 3,
|
||||
'composingBase': -1,
|
||||
'composingExtent': -1,
|
||||
});
|
||||
sendFrameworkMessage(codec.encodeMethodCall(setEditingState));
|
||||
|
||||
@ -973,6 +985,8 @@ Future<void> testMain() async {
|
||||
'text': 'abcd',
|
||||
'selectionBase': 2,
|
||||
'selectionExtent': 3,
|
||||
'composingBase': -1,
|
||||
'composingExtent': -1,
|
||||
});
|
||||
sendFrameworkMessage(codec.encodeMethodCall(setEditingState));
|
||||
|
||||
@ -1026,6 +1040,8 @@ Future<void> testMain() async {
|
||||
'text': 'abcd',
|
||||
'selectionBase': 2,
|
||||
'selectionExtent': 3,
|
||||
'composingBase': -1,
|
||||
'composingExtent': -1,
|
||||
});
|
||||
sendFrameworkMessage(codec.encodeMethodCall(setEditingState));
|
||||
|
||||
@ -1071,7 +1087,13 @@ Future<void> testMain() async {
|
||||
|
||||
const MethodCall setEditingState = MethodCall(
|
||||
'TextInput.setEditingState',
|
||||
<String, dynamic>{'text': 'abcd', 'selectionBase': 2, 'selectionExtent': 3},
|
||||
<String, dynamic>{
|
||||
'text': 'abcd',
|
||||
'selectionBase': 2,
|
||||
'selectionExtent': 3,
|
||||
'composingBase': -1,
|
||||
'composingExtent': -1,
|
||||
},
|
||||
);
|
||||
sendFrameworkMessage(codec.encodeMethodCall(setEditingState));
|
||||
|
||||
@ -1124,6 +1146,8 @@ Future<void> testMain() async {
|
||||
'text': 'abcd',
|
||||
'selectionBase': 2,
|
||||
'selectionExtent': 3,
|
||||
'composingBase': -1,
|
||||
'composingExtent': -1,
|
||||
});
|
||||
sendFrameworkMessage(codec.encodeMethodCall(setEditingState));
|
||||
|
||||
@ -1177,6 +1201,8 @@ Future<void> testMain() async {
|
||||
'text': 'abcd',
|
||||
'selectionBase': 2,
|
||||
'selectionExtent': 3,
|
||||
'composingBase': -1,
|
||||
'composingExtent': -1,
|
||||
});
|
||||
sendFrameworkMessage(codec.encodeMethodCall(setEditingState1));
|
||||
|
||||
@ -1229,6 +1255,8 @@ Future<void> testMain() async {
|
||||
'text': 'abcd',
|
||||
'selectionBase': 2,
|
||||
'selectionExtent': 3,
|
||||
'composingBase': -1,
|
||||
'composingExtent': -1,
|
||||
});
|
||||
sendFrameworkMessage(codec.encodeMethodCall(setEditingState1));
|
||||
|
||||
@ -1281,6 +1309,8 @@ Future<void> testMain() async {
|
||||
'text': 'abcd',
|
||||
'selectionBase': 2,
|
||||
'selectionExtent': 3,
|
||||
'composingBase': -1,
|
||||
'composingExtent': -1,
|
||||
});
|
||||
sendFrameworkMessage(codec.encodeMethodCall(setEditingState1));
|
||||
|
||||
@ -1340,6 +1370,8 @@ Future<void> testMain() async {
|
||||
'text': 'abcd',
|
||||
'selectionBase': 2,
|
||||
'selectionExtent': 3,
|
||||
'composingBase': -1,
|
||||
'composingExtent': -1,
|
||||
});
|
||||
final MethodCall setSizeAndTransform = configureSetSizeAndTransformMethodCall(
|
||||
150,
|
||||
@ -1386,6 +1418,8 @@ Future<void> testMain() async {
|
||||
'text': 'abcd',
|
||||
'selectionBase': 2,
|
||||
'selectionExtent': 3,
|
||||
'composingBase': -1,
|
||||
'composingExtent': -1,
|
||||
});
|
||||
sendFrameworkMessage(codec.encodeMethodCall(setEditingState));
|
||||
|
||||
@ -1443,6 +1477,8 @@ Future<void> testMain() async {
|
||||
'text': 'abcd',
|
||||
'selectionBase': 2,
|
||||
'selectionExtent': 3,
|
||||
'composingBase': -1,
|
||||
'composingExtent': -1,
|
||||
});
|
||||
sendFrameworkMessage(codec.encodeMethodCall(setEditingState1));
|
||||
|
||||
@ -1464,6 +1500,8 @@ Future<void> testMain() async {
|
||||
'text': 'xyz',
|
||||
'selectionBase': 0,
|
||||
'selectionExtent': 2,
|
||||
'composingBase': -1,
|
||||
'composingExtent': -1,
|
||||
});
|
||||
sendFrameworkMessage(codec.encodeMethodCall(setEditingState2));
|
||||
|
||||
@ -1494,6 +1532,8 @@ Future<void> testMain() async {
|
||||
'text': 'abcd',
|
||||
'selectionBase': 2,
|
||||
'selectionExtent': 3,
|
||||
'composingBase': -1,
|
||||
'composingExtent': -1,
|
||||
});
|
||||
sendFrameworkMessage(codec.encodeMethodCall(setEditingState1));
|
||||
|
||||
@ -1546,6 +1586,8 @@ Future<void> testMain() async {
|
||||
'text': 'abcd',
|
||||
'selectionBase': 2,
|
||||
'selectionExtent': 3,
|
||||
'composingBase': -1,
|
||||
'composingExtent': -1,
|
||||
});
|
||||
sendFrameworkMessage(codec.encodeMethodCall(setEditingState1));
|
||||
|
||||
@ -1619,6 +1661,8 @@ Future<void> testMain() async {
|
||||
'text': 'abcd',
|
||||
'selectionBase': 2,
|
||||
'selectionExtent': 3,
|
||||
'composingBase': -1,
|
||||
'composingExtent': -1,
|
||||
});
|
||||
sendFrameworkMessage(codec.encodeMethodCall(setEditingState1));
|
||||
|
||||
@ -1667,6 +1711,8 @@ Future<void> testMain() async {
|
||||
'text': '',
|
||||
'selectionBase': 0,
|
||||
'selectionExtent': 0,
|
||||
'composingBase': -1,
|
||||
'composingExtent': -1,
|
||||
});
|
||||
sendFrameworkMessage(codec.encodeMethodCall(setEditingState1));
|
||||
|
||||
@ -1703,6 +1749,8 @@ Future<void> testMain() async {
|
||||
'text': '',
|
||||
'selectionBase': 0,
|
||||
'selectionExtent': 0,
|
||||
'composingBase': -1,
|
||||
'composingExtent': -1,
|
||||
});
|
||||
sendFrameworkMessage(codec.encodeMethodCall(setEditingState1));
|
||||
|
||||
@ -1736,6 +1784,8 @@ Future<void> testMain() async {
|
||||
'text': '',
|
||||
'selectionBase': 0,
|
||||
'selectionExtent': 0,
|
||||
'composingBase': -1,
|
||||
'composingExtent': -1,
|
||||
});
|
||||
sendFrameworkMessage(codec.encodeMethodCall(setEditingState1));
|
||||
|
||||
@ -1774,7 +1824,13 @@ Future<void> testMain() async {
|
||||
|
||||
const MethodCall setEditingState = MethodCall(
|
||||
'TextInput.setEditingState',
|
||||
<String, dynamic>{'text': 'abcd', 'selectionBase': 2, 'selectionExtent': 3},
|
||||
<String, dynamic>{
|
||||
'text': 'abcd',
|
||||
'selectionBase': 2,
|
||||
'selectionExtent': 3,
|
||||
'composingBase': -1,
|
||||
'composingExtent': -1,
|
||||
},
|
||||
);
|
||||
sendFrameworkMessage(codec.encodeMethodCall(setEditingState));
|
||||
|
||||
@ -1835,7 +1891,13 @@ Future<void> testMain() async {
|
||||
|
||||
const MethodCall setEditingState = MethodCall(
|
||||
'TextInput.setEditingState',
|
||||
<String, dynamic>{'text': 'abcd', 'selectionBase': 2, 'selectionExtent': 3},
|
||||
<String, dynamic>{
|
||||
'text': 'abcd',
|
||||
'selectionBase': 2,
|
||||
'selectionExtent': 3,
|
||||
'composingBase': -1,
|
||||
'composingExtent': -1,
|
||||
},
|
||||
);
|
||||
sendFrameworkMessage(codec.encodeMethodCall(setEditingState));
|
||||
|
||||
@ -1903,7 +1965,13 @@ Future<void> testMain() async {
|
||||
|
||||
const MethodCall setEditingState = MethodCall(
|
||||
'TextInput.setEditingState',
|
||||
<String, dynamic>{'text': 'abcd', 'selectionBase': 2, 'selectionExtent': 3},
|
||||
<String, dynamic>{
|
||||
'text': 'abcd',
|
||||
'selectionBase': 2,
|
||||
'selectionExtent': 3,
|
||||
'composingBase': -1,
|
||||
'composingExtent': -1,
|
||||
},
|
||||
);
|
||||
sendFrameworkMessage(codec.encodeMethodCall(setEditingState));
|
||||
|
||||
@ -1965,6 +2033,8 @@ Future<void> testMain() async {
|
||||
'text': 'xyz',
|
||||
'selectionBase': 1,
|
||||
'selectionExtent': 2,
|
||||
'composingBase': -1,
|
||||
'composingExtent': -1,
|
||||
});
|
||||
sendFrameworkMessage(codec.encodeMethodCall(setEditingState1));
|
||||
|
||||
@ -1989,6 +2059,8 @@ Future<void> testMain() async {
|
||||
'text': 'xyz',
|
||||
'selectionBase': -1,
|
||||
'selectionExtent': -1,
|
||||
'composingBase': -1,
|
||||
'composingExtent': -1,
|
||||
});
|
||||
sendFrameworkMessage(codec.encodeMethodCall(setEditingState2));
|
||||
|
||||
@ -2009,6 +2081,8 @@ Future<void> testMain() async {
|
||||
'text': 'abcd',
|
||||
'selectionBase': 2,
|
||||
'selectionExtent': 3,
|
||||
'composingBase': -1,
|
||||
'composingExtent': -1,
|
||||
});
|
||||
sendFrameworkMessage(codec.encodeMethodCall(setEditingState));
|
||||
|
||||
@ -2072,6 +2146,8 @@ Future<void> testMain() async {
|
||||
'text': '',
|
||||
'selectionBase': -1,
|
||||
'selectionExtent': -1,
|
||||
'composingBase': -1,
|
||||
'composingExtent': -1,
|
||||
});
|
||||
sendFrameworkMessage(codec.encodeMethodCall(setEditingState));
|
||||
|
||||
@ -2129,6 +2205,8 @@ Future<void> testMain() async {
|
||||
'text': 'Hello world',
|
||||
'selectionBase': 9,
|
||||
'selectionExtent': 3,
|
||||
'composingBase': -1,
|
||||
'composingExtent': -1,
|
||||
});
|
||||
sendFrameworkMessage(codec.encodeMethodCall(setEditingState));
|
||||
|
||||
@ -2194,6 +2272,8 @@ Future<void> testMain() async {
|
||||
'text': 'Hello world',
|
||||
'selectionBase': 9,
|
||||
'selectionExtent': 3,
|
||||
'composingBase': -1,
|
||||
'composingExtent': -1,
|
||||
});
|
||||
sendFrameworkMessage(codec.encodeMethodCall(setEditingState));
|
||||
|
||||
@ -2275,6 +2355,8 @@ Future<void> testMain() async {
|
||||
'text': 'abcd',
|
||||
'selectionBase': 2,
|
||||
'selectionExtent': 3,
|
||||
'composingBase': -1,
|
||||
'composingExtent': -1,
|
||||
});
|
||||
sendFrameworkMessage(codec.encodeMethodCall(setEditingState1));
|
||||
|
||||
@ -2369,8 +2451,8 @@ Future<void> testMain() async {
|
||||
'text': 'foo\nbar',
|
||||
'selectionBase': 2,
|
||||
'selectionExtent': 3,
|
||||
'composingBase': null,
|
||||
'composingExtent': null,
|
||||
'composingBase': -1,
|
||||
'composingExtent': -1,
|
||||
});
|
||||
sendFrameworkMessage(codec.encodeMethodCall(setEditingState));
|
||||
checkTextAreaEditingState(textarea, 'foo\nbar', 2, 3);
|
||||
@ -2598,8 +2680,8 @@ Future<void> testMain() async {
|
||||
'text': '1\n2\n3\n4\n',
|
||||
'selectionBase': 8,
|
||||
'selectionExtent': 8,
|
||||
'composingBase': null,
|
||||
'composingExtent': null,
|
||||
'composingBase': -1,
|
||||
'composingExtent': -1,
|
||||
});
|
||||
sendFrameworkMessage(codec.encodeMethodCall(setEditingState));
|
||||
checkTextAreaEditingState(textarea, '1\n2\n3\n4\n', 8, 8);
|
||||
@ -3292,18 +3374,24 @@ Future<void> testMain() async {
|
||||
|
||||
test('Fix flipped base and extent offsets', () {
|
||||
expect(
|
||||
EditingState(baseOffset: 10, extentOffset: 4),
|
||||
EditingState(baseOffset: 4, extentOffset: 10),
|
||||
EditingState(text: '', baseOffset: 10, extentOffset: 4),
|
||||
EditingState(text: '', baseOffset: 4, extentOffset: 10),
|
||||
);
|
||||
|
||||
expect(
|
||||
EditingState.fromFrameworkMessage(<String, dynamic>{
|
||||
'text': '',
|
||||
'selectionBase': 10,
|
||||
'selectionExtent': 4,
|
||||
'composingBase': -1,
|
||||
'composingExtent': -1,
|
||||
}),
|
||||
EditingState.fromFrameworkMessage(<String, dynamic>{
|
||||
'text': '',
|
||||
'selectionBase': 4,
|
||||
'selectionExtent': 10,
|
||||
'composingBase': -1,
|
||||
'composingExtent': -1,
|
||||
}),
|
||||
);
|
||||
});
|
||||
@ -3311,7 +3399,13 @@ Future<void> testMain() async {
|
||||
test('Sets default composing offsets if none given', () {
|
||||
final EditingState editingState = EditingState(text: 'Test', baseOffset: 2, extentOffset: 4);
|
||||
final EditingState editingStateFromFrameworkMsg = EditingState.fromFrameworkMessage(
|
||||
<String, dynamic>{'selectionBase': 10, 'selectionExtent': 4},
|
||||
<String, dynamic>{
|
||||
'text': '',
|
||||
'selectionBase': 10,
|
||||
'selectionExtent': 4,
|
||||
'composingBase': -1,
|
||||
'composingExtent': -1,
|
||||
},
|
||||
);
|
||||
|
||||
expect(editingState.composingBaseOffset, -1);
|
||||
@ -3322,8 +3416,16 @@ Future<void> testMain() async {
|
||||
});
|
||||
|
||||
test('Correctly identifies min and max offsets', () {
|
||||
final EditingState flippedEditingState = EditingState(baseOffset: 10, extentOffset: 4);
|
||||
final EditingState normalEditingState = EditingState(baseOffset: 2, extentOffset: 6);
|
||||
final EditingState flippedEditingState = EditingState(
|
||||
text: '',
|
||||
baseOffset: 10,
|
||||
extentOffset: 4,
|
||||
);
|
||||
final EditingState normalEditingState = EditingState(
|
||||
text: '',
|
||||
baseOffset: 2,
|
||||
extentOffset: 6,
|
||||
);
|
||||
|
||||
expect(flippedEditingState.minOffset, 4);
|
||||
expect(flippedEditingState.maxOffset, 10);
|
||||
@ -3435,8 +3537,16 @@ Future<void> testMain() async {
|
||||
});
|
||||
|
||||
test('Takes flipped base and extent offsets into account', () {
|
||||
final EditingState flippedEditingState = EditingState(baseOffset: 10, extentOffset: 4);
|
||||
final EditingState normalEditingState = EditingState(baseOffset: 4, extentOffset: 10);
|
||||
final EditingState flippedEditingState = EditingState(
|
||||
text: '',
|
||||
baseOffset: 10,
|
||||
extentOffset: 4,
|
||||
);
|
||||
final EditingState normalEditingState = EditingState(
|
||||
text: '',
|
||||
baseOffset: 4,
|
||||
extentOffset: 10,
|
||||
);
|
||||
|
||||
expect(normalEditingState, flippedEditingState);
|
||||
|
||||
@ -3445,14 +3555,23 @@ Future<void> testMain() async {
|
||||
|
||||
test('takes composition range into account', () {
|
||||
final EditingState editingState1 = EditingState(
|
||||
text: '',
|
||||
baseOffset: 0,
|
||||
extentOffset: 0,
|
||||
composingBaseOffset: 1,
|
||||
composingExtentOffset: 2,
|
||||
);
|
||||
final EditingState editingState2 = EditingState(
|
||||
text: '',
|
||||
baseOffset: 0,
|
||||
extentOffset: 0,
|
||||
composingBaseOffset: 1,
|
||||
composingExtentOffset: 2,
|
||||
);
|
||||
final EditingState editingState3 = EditingState(
|
||||
text: '',
|
||||
baseOffset: 0,
|
||||
extentOffset: 0,
|
||||
composingBaseOffset: 4,
|
||||
composingExtentOffset: 8,
|
||||
);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user