[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:
Yegor 2025-04-28 09:25:03 -07:00 committed by GitHub
parent fa8f0f2988
commit c790bb111a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 192 additions and 67 deletions

View File

@ -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;

View File

@ -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(

View File

@ -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;

View File

@ -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.

View File

@ -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();

View File

@ -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

View File

@ -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,
);