Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 0d0446a

Browse files
committed
Web - Fix selection jump on Android
1 parent f1c6949 commit 0d0446a

File tree

2 files changed

+61
-2
lines changed

2 files changed

+61
-2
lines changed

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

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1416,9 +1416,12 @@ abstract class DefaultTextEditingStrategy with CompositionAwareMixin implements
14161416

14171417
/// Prevent default behavior for mouse down, up and move.
14181418
///
1419-
/// When normal mouse events are not prevented, in desktop browsers, mouse
1420-
/// selection conflicts with selection sent from the framework, which creates
1419+
/// When normal mouse events are not prevented, mouse selection
1420+
/// conflicts with selection sent from the framework, which creates
14211421
/// flickering during selection by mouse.
1422+
///
1423+
/// On mobile browsers, mouse events are sent after a touch event,
1424+
/// see: https://bugs.chromium.org/p/chromium/issues/detail?id=119216#c11.
14221425
void preventDefaultForMouseEvents() {
14231426
subscriptions.add(
14241427
DomSubscription(activeDomElement, 'mousedown', (_) {
@@ -1576,6 +1579,8 @@ class IOSTextEditingStrategy extends GloballyPositionedTextEditingStrategy {
15761579
owner.sendTextConnectionClosedToFrameworkIfAny();
15771580
}
15781581
}));
1582+
1583+
preventDefaultForMouseEvents();
15791584
}
15801585

15811586
@override

lib/web_ui/test/engine/text_editing_test.dart

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1896,6 +1896,59 @@ Future<void> testMain() async {
18961896
hideKeyboard();
18971897
});
18981898

1899+
test('prevent mouse events on Android', () {
1900+
// Regression test for https://github.com/flutter/flutter/issues/124483.
1901+
debugOperatingSystemOverride = OperatingSystem.android;
1902+
debugBrowserEngineOverride = BrowserEngine.blink;
1903+
1904+
/// During initialization [HybridTextEditing] will pick the correct
1905+
/// text editing strategy for [OperatingSystem.android].
1906+
textEditing = HybridTextEditing();
1907+
1908+
final MethodCall setClient = MethodCall(
1909+
'TextInput.setClient',
1910+
<dynamic>[123, flutterMultilineConfig],
1911+
);
1912+
sendFrameworkMessage(codec.encodeMethodCall(setClient));
1913+
1914+
// Editing shouldn't have started yet.
1915+
expect(defaultTextEditingRoot.ownerDocument?.activeElement, domDocument.body);
1916+
1917+
const MethodCall show = MethodCall('TextInput.show');
1918+
sendFrameworkMessage(codec.encodeMethodCall(show));
1919+
1920+
// The "setSizeAndTransform" message has to be here before we call
1921+
// checkInputEditingState, since on some platforms (e.g. Desktop Safari)
1922+
// we don't put the input element into the DOM until we get its correct
1923+
// dimensions from the framework.
1924+
final List<double> transform = Matrix4.translationValues(10.0, 20.0, 30.0).storage.toList();
1925+
final MethodCall setSizeAndTransform = configureSetSizeAndTransformMethodCall(150, 50, transform);
1926+
sendFrameworkMessage(codec.encodeMethodCall(setSizeAndTransform));
1927+
1928+
final DomHTMLTextAreaElement textarea = textEditing!.strategy.domElement! as DomHTMLTextAreaElement;
1929+
checkTextAreaEditingState(textarea, '', 0, 0);
1930+
1931+
// Can set editing state and preserve new lines.
1932+
const MethodCall setEditingState = MethodCall(
1933+
'TextInput.setEditingState',
1934+
<String, dynamic>{
1935+
'text': '1\n2\n3\n4\n',
1936+
'selectionBase': 8,
1937+
'selectionExtent': 8,
1938+
'composingBase': null,
1939+
'composingExtent': null,
1940+
},
1941+
);
1942+
sendFrameworkMessage(codec.encodeMethodCall(setEditingState));
1943+
checkTextAreaEditingState(textarea, '1\n2\n3\n4\n', 8, 8);
1944+
1945+
// 'mousedown' event should be prevented.
1946+
final bool prevented = !textarea.dispatchEvent(createDomEvent('Event', 'mousedown'));
1947+
expect(prevented, true);
1948+
1949+
hideKeyboard();
1950+
});
1951+
18991952
test('sets correct input type in iOS', () {
19001953
// Test on ios-safari only.
19011954
if (browserEngine == BrowserEngine.webkit &&
@@ -2324,6 +2377,7 @@ Future<void> testMain() async {
23242377
expect(textArea.selectionEnd, 2);
23252378
});
23262379

2380+
23272381
test('Configure input element editing state for a flipped base and extent',
23282382
() {
23292383
final DomHTMLInputElement input =

0 commit comments

Comments
 (0)