Skip to content

Commit 6ddee44

Browse files
authored
[Web] Properly report inverted selection (flutter#44806)
Fixes flutter#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
1 parent a983489 commit 6ddee44

File tree

3 files changed

+42
-14
lines changed

3 files changed

+42
-14
lines changed

lib/web_ui/lib/src/engine/dom.dart

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2068,6 +2068,10 @@ extension DomHTMLTextAreaElementExtension on DomHTMLTextAreaElement {
20682068
external set _name(JSString value);
20692069
set name(String value) => _name = value.toJS;
20702070

2071+
@JS('selectionDirection')
2072+
external JSString? get _selectionDirection;
2073+
String? get selectionDirection => _selectionDirection?.toDart;
2074+
20712075
@JS('selectionStart')
20722076
external JSNumber? get _selectionStart;
20732077
double? get selectionStart => _selectionStart?.toDartDouble;
@@ -2704,6 +2708,10 @@ extension DomHTMLInputElementExtension on DomHTMLInputElement {
27042708
external set _autocomplete(JSString value);
27052709
set autocomplete(String value) => _autocomplete = value.toJS;
27062710

2711+
@JS('selectionDirection')
2712+
external JSString? get _selectionDirection;
2713+
String? get selectionDirection => _selectionDirection?.toDart;
2714+
27072715
@JS('selectionStart')
27082716
external JSNumber? get _selectionStart;
27092717
double? get selectionStart => _selectionStart?.toDartDouble;

lib/web_ui/lib/src/engine/text_editing/text_editing.dart

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -770,17 +770,31 @@ class EditingState {
770770
factory EditingState.fromDomElement(DomHTMLElement? domElement) {
771771
if (domInstanceOfString(domElement, 'HTMLInputElement')) {
772772
final DomHTMLInputElement element = domElement! as DomHTMLInputElement;
773-
return EditingState(
774-
text: element.value,
775-
baseOffset: element.selectionStart?.toInt(),
776-
extentOffset: element.selectionEnd?.toInt());
773+
if (element.selectionDirection == 'backward') {
774+
return EditingState(
775+
text: element.value,
776+
baseOffset: element.selectionEnd?.toInt(),
777+
extentOffset: element.selectionStart?.toInt());
778+
} else {
779+
return EditingState(
780+
text: element.value,
781+
baseOffset: element.selectionStart?.toInt(),
782+
extentOffset: element.selectionEnd?.toInt());
783+
}
777784
} else if (domInstanceOfString(domElement, 'HTMLTextAreaElement')) {
778785
final DomHTMLTextAreaElement element = domElement! as
779786
DomHTMLTextAreaElement;
780-
return EditingState(
781-
text: element.value,
782-
baseOffset: element.selectionStart?.toInt(),
783-
extentOffset: element.selectionEnd?.toInt());
787+
if (element.selectionDirection == 'backward') {
788+
return EditingState(
789+
text: element.value,
790+
baseOffset: element.selectionEnd?.toInt(),
791+
extentOffset: element.selectionStart?.toInt());
792+
} else {
793+
return EditingState(
794+
text: element.value,
795+
baseOffset: element.selectionStart?.toInt(),
796+
extentOffset: element.selectionEnd?.toInt());
797+
}
784798
} else {
785799
throw UnsupportedError('Initialized with unsupported input type');
786800
}

lib/web_ui/test/engine/text_editing_test.dart

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2726,14 +2726,17 @@ Future<void> testMain() async {
27262726
final DomHTMLInputElement input =
27272727
defaultTextEditingRoot.querySelector('input')! as DomHTMLInputElement;
27282728
input.value = 'Test';
2729-
input.selectionStart = 1;
2730-
input.selectionEnd = 2;
27312729

2730+
input.setSelectionRange(1, 2);
27322731
editingState = EditingState.fromDomElement(input);
2733-
27342732
expect(editingState.text, 'Test');
27352733
expect(editingState.baseOffset, 1);
27362734
expect(editingState.extentOffset, 2);
2735+
2736+
input.setSelectionRange(1, 2, 'backward');
2737+
editingState = EditingState.fromDomElement(input);
2738+
expect(editingState.baseOffset, 2);
2739+
expect(editingState.extentOffset, 1);
27372740
});
27382741

27392742
test('Get Editing State from text area element', () {
@@ -2747,14 +2750,17 @@ Future<void> testMain() async {
27472750
final DomHTMLTextAreaElement input =
27482751
defaultTextEditingRoot.querySelector('textarea')! as DomHTMLTextAreaElement;
27492752
input.value = 'Test';
2750-
input.selectionStart = 1;
2751-
input.selectionEnd = 2;
27522753

2754+
input.setSelectionRange(1, 2);
27532755
editingState = EditingState.fromDomElement(input);
2754-
27552756
expect(editingState.text, 'Test');
27562757
expect(editingState.baseOffset, 1);
27572758
expect(editingState.extentOffset, 2);
2759+
2760+
input.setSelectionRange(1, 2, 'backward');
2761+
editingState = EditingState.fromDomElement(input);
2762+
expect(editingState.baseOffset, 2);
2763+
expect(editingState.extentOffset, 1);
27582764
});
27592765

27602766
group('comparing editing states', () {

0 commit comments

Comments
 (0)