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

Commit cef8bce

Browse files
[Web Text Input] ensure the input element is put in the DOM on desktop safari (#30885)
1 parent 7002447 commit cef8bce

File tree

2 files changed

+41
-3
lines changed

2 files changed

+41
-3
lines changed

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

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -782,9 +782,10 @@ class SafariDesktopTextEditingStrategy extends DefaultTextEditingStrategy {
782782
// On Safari Desktop, when a form is focused, it opens an autofill menu
783783
// immediately.
784784
// Flutter framework sends `setEditableSizeAndTransform` for informing
785-
// the engine about the location of the text field. This call will
786-
// arrive after `show` call. Therefore form is placed, when
787-
// `setEditableSizeAndTransform` method is called and focus called on the
785+
// the engine about the location of the text field. This call may arrive
786+
// after the first `show` call, depending on the text input widget's
787+
// implementation. Therefore form is placed, when
788+
// `setEditableSizeAndTransform` method is called and focus called on the
788789
// form only after placing it to the correct position and only once after
789790
// that. Calling focus multiple times causes flickering.
790791
focusedFormElement!.focus();
@@ -800,6 +801,9 @@ class SafariDesktopTextEditingStrategy extends DefaultTextEditingStrategy {
800801

801802
@override
802803
void initializeElementPlacement() {
804+
if (geometry != null) {
805+
placeElement();
806+
}
803807
activeDomElement.focus();
804808
}
805809
}

lib/web_ui/test/text_editing_test.dart

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -551,6 +551,40 @@ void testMain() {
551551
expect(spy.messages, isEmpty);
552552
});
553553

554+
test('setClient, setEditingState, setSizeAndTransform, show - input element is put into the DOM', () {
555+
editingStrategy = SafariDesktopTextEditingStrategy(textEditing!);
556+
textEditing!.debugTextEditingStrategyOverride = editingStrategy;
557+
final MethodCall setClient = MethodCall(
558+
'TextInput.setClient', <dynamic>[123, flutterSinglelineConfig]);
559+
sendFrameworkMessage(codec.encodeMethodCall(setClient));
560+
561+
const MethodCall setEditingState =
562+
MethodCall('TextInput.setEditingState', <String, dynamic>{
563+
'text': 'abcd',
564+
'selectionBase': 2,
565+
'selectionExtent': 3,
566+
});
567+
sendFrameworkMessage(codec.encodeMethodCall(setEditingState));
568+
569+
// Editing shouldn't have started yet.
570+
expect(document.activeElement, document.body);
571+
572+
// The "setSizeAndTransform" message has to be here before we call
573+
// checkInputEditingState, since on some platforms (e.g. Desktop Safari)
574+
// we don't put the input element into the DOM until we get its correct
575+
// dimensions from the framework.
576+
final MethodCall setSizeAndTransform =
577+
configureSetSizeAndTransformMethodCall(150, 50,
578+
Matrix4.translationValues(10.0, 20.0, 30.0).storage.toList());
579+
sendFrameworkMessage(codec.encodeMethodCall(setSizeAndTransform));
580+
581+
const MethodCall show = MethodCall('TextInput.show');
582+
sendFrameworkMessage(codec.encodeMethodCall(show));
583+
584+
expect(defaultTextEditingRoot.activeElement,
585+
textEditing!.strategy.domElement);
586+
});
587+
554588
test('setClient, setEditingState, show, updateConfig, clearClient', () {
555589
final MethodCall setClient = MethodCall('TextInput.setClient', <dynamic>[
556590
123,

0 commit comments

Comments
 (0)