[Web] Properly report inverted selection (flutter/engine#44806)

Fixes https://github.com/flutter/flutter/issues/131906

*List which issues are fixed by this PR. You must list at least one issue.*

*If you had to change anything in the [flutter/tests] repo, include a link to the migration guide as per the [breaking change policy].*

[C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style
This commit is contained in:
Matej Knopp
2023-09-12 03:23:21 +02:00
committed by GitHub
parent d097f5d052
commit e295cca68f
3 changed files with 42 additions and 14 deletions

View File

@@ -2068,6 +2068,10 @@ extension DomHTMLTextAreaElementExtension on DomHTMLTextAreaElement {
external set _name(JSString value);
set name(String value) => _name = value.toJS;
@JS('selectionDirection')
external JSString? get _selectionDirection;
String? get selectionDirection => _selectionDirection?.toDart;
@JS('selectionStart')
external JSNumber? get _selectionStart;
double? get selectionStart => _selectionStart?.toDartDouble;
@@ -2704,6 +2708,10 @@ extension DomHTMLInputElementExtension on DomHTMLInputElement {
external set _autocomplete(JSString value);
set autocomplete(String value) => _autocomplete = value.toJS;
@JS('selectionDirection')
external JSString? get _selectionDirection;
String? get selectionDirection => _selectionDirection?.toDart;
@JS('selectionStart')
external JSNumber? get _selectionStart;
double? get selectionStart => _selectionStart?.toDartDouble;

View File

@@ -770,17 +770,31 @@ class EditingState {
factory EditingState.fromDomElement(DomHTMLElement? domElement) {
if (domInstanceOfString(domElement, 'HTMLInputElement')) {
final DomHTMLInputElement element = domElement! as DomHTMLInputElement;
return EditingState(
text: element.value,
baseOffset: element.selectionStart?.toInt(),
extentOffset: element.selectionEnd?.toInt());
if (element.selectionDirection == 'backward') {
return EditingState(
text: element.value,
baseOffset: element.selectionEnd?.toInt(),
extentOffset: element.selectionStart?.toInt());
} else {
return EditingState(
text: element.value,
baseOffset: element.selectionStart?.toInt(),
extentOffset: element.selectionEnd?.toInt());
}
} else if (domInstanceOfString(domElement, 'HTMLTextAreaElement')) {
final DomHTMLTextAreaElement element = domElement! as
DomHTMLTextAreaElement;
return EditingState(
text: element.value,
baseOffset: element.selectionStart?.toInt(),
extentOffset: element.selectionEnd?.toInt());
if (element.selectionDirection == 'backward') {
return EditingState(
text: element.value,
baseOffset: element.selectionEnd?.toInt(),
extentOffset: element.selectionStart?.toInt());
} else {
return EditingState(
text: element.value,
baseOffset: element.selectionStart?.toInt(),
extentOffset: element.selectionEnd?.toInt());
}
} else {
throw UnsupportedError('Initialized with unsupported input type');
}

View File

@@ -2726,14 +2726,17 @@ Future<void> testMain() async {
final DomHTMLInputElement input =
defaultTextEditingRoot.querySelector('input')! as DomHTMLInputElement;
input.value = 'Test';
input.selectionStart = 1;
input.selectionEnd = 2;
input.setSelectionRange(1, 2);
editingState = EditingState.fromDomElement(input);
expect(editingState.text, 'Test');
expect(editingState.baseOffset, 1);
expect(editingState.extentOffset, 2);
input.setSelectionRange(1, 2, 'backward');
editingState = EditingState.fromDomElement(input);
expect(editingState.baseOffset, 2);
expect(editingState.extentOffset, 1);
});
test('Get Editing State from text area element', () {
@@ -2747,14 +2750,17 @@ Future<void> testMain() async {
final DomHTMLTextAreaElement input =
defaultTextEditingRoot.querySelector('textarea')! as DomHTMLTextAreaElement;
input.value = 'Test';
input.selectionStart = 1;
input.selectionEnd = 2;
input.setSelectionRange(1, 2);
editingState = EditingState.fromDomElement(input);
expect(editingState.text, 'Test');
expect(editingState.baseOffset, 1);
expect(editingState.extentOffset, 2);
input.setSelectionRange(1, 2, 'backward');
editingState = EditingState.fromDomElement(input);
expect(editingState.baseOffset, 2);
expect(editingState.extentOffset, 1);
});
group('comparing editing states', () {