Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions lib/web_ui/lib/src/engine/text_editing/text_editing.dart
Original file line number Diff line number Diff line change
Expand Up @@ -782,9 +782,10 @@ class SafariDesktopTextEditingStrategy extends DefaultTextEditingStrategy {
// On Safari Desktop, when a form is focused, it opens an autofill menu
// immediately.
// Flutter framework sends `setEditableSizeAndTransform` for informing
// the engine about the location of the text field. This call will
// arrive after `show` call. Therefore form is placed, when
// `setEditableSizeAndTransform` method is called and focus called on the
// the engine about the location of the text field. This call may arrive
// after the first `show` call, depending on the text input widget's
// implementation. Therefore form is placed, when
// `setEditableSizeAndTransform` method is called and focus called on the
// form only after placing it to the correct position and only once after
// that. Calling focus multiple times causes flickering.
focusedFormElement!.focus();
Expand All @@ -800,6 +801,9 @@ class SafariDesktopTextEditingStrategy extends DefaultTextEditingStrategy {

@override
void initializeElementPlacement() {
if (geometry != null) {
placeElement();
}
activeDomElement.focus();
}
}
Expand Down
34 changes: 34 additions & 0 deletions lib/web_ui/test/text_editing_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -551,6 +551,40 @@ void testMain() {
expect(spy.messages, isEmpty);
});

test('setClient, setEditingState, setSizeAndTransform, show - input element is put into the DOM', () {
editingStrategy = SafariDesktopTextEditingStrategy(textEditing!);
textEditing!.debugTextEditingStrategyOverride = editingStrategy;
final MethodCall setClient = MethodCall(
'TextInput.setClient', <dynamic>[123, flutterSinglelineConfig]);
sendFrameworkMessage(codec.encodeMethodCall(setClient));

const MethodCall setEditingState =
MethodCall('TextInput.setEditingState', <String, dynamic>{
'text': 'abcd',
'selectionBase': 2,
'selectionExtent': 3,
});
sendFrameworkMessage(codec.encodeMethodCall(setEditingState));

// Editing shouldn't have started yet.
expect(document.activeElement, document.body);

// The "setSizeAndTransform" message has to be here before we call
// checkInputEditingState, since on some platforms (e.g. Desktop Safari)
// we don't put the input element into the DOM until we get its correct
// dimensions from the framework.
final MethodCall setSizeAndTransform =
configureSetSizeAndTransformMethodCall(150, 50,
Matrix4.translationValues(10.0, 20.0, 30.0).storage.toList());
sendFrameworkMessage(codec.encodeMethodCall(setSizeAndTransform));

const MethodCall show = MethodCall('TextInput.show');
sendFrameworkMessage(codec.encodeMethodCall(show));

expect(defaultTextEditingRoot.activeElement,
textEditing!.strategy.domElement);
});

test('setClient, setEditingState, show, updateConfig, clearClient', () {
final MethodCall setClient = MethodCall('TextInput.setClient', <dynamic>[
123,
Expand Down