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

Commit 040581d

Browse files
fix tests
1 parent 6c6aa9e commit 040581d

File tree

4 files changed

+101
-53
lines changed

4 files changed

+101
-53
lines changed

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

Lines changed: 14 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -161,16 +161,16 @@ class EngineAutofillForm {
161161
/// in a `TextInputConfiguration`. Not having this field indicates autofill
162162
/// is explicitly disabled on the text field by the developer.
163163
///
164-
/// The `fields` argument corresponds to the "filds" field in a
164+
/// The `fields` argument corresponds to the "fields" field in a
165165
/// `TextInputConfiguration`.
166166
///
167167
/// Returns null if the input field is not within an autofill group.
168168
static EngineAutofillForm? fromFrameworkMessage(
169169
Map<String, dynamic>? focusedElementAutofill,
170170
List<dynamic>? fields,
171171
) {
172-
// Autofill value is null if the developer explicitly disables it on the
173-
// input field.
172+
// Autofill value will be null if the developer explicitly disables it on
173+
// the input field.
174174
if (focusedElementAutofill == null) {
175175
return null;
176176
}
@@ -413,20 +413,19 @@ class AutofillInfo {
413413
}
414414
if (domElement is html.InputElement) {
415415
final html.InputElement element = domElement;
416-
element.name = autofillHint;
417416
if (placeholder != null) {
418417
element.placeholder = placeholder;
419418
}
420-
element.autocomplete = autofillHint ?? 'on';
421-
if (autofillHint == null) {
422-
return;
423-
}
424-
element.id = autofillHint;
425-
if (autofillHint.contains('password')) {
426-
element.type = 'password';
427-
} else {
428-
element.type = 'text';
419+
if (autofillHint != null) {
420+
element.name = autofillHint;
421+
element.id = autofillHint;
422+
if (autofillHint.contains('password')) {
423+
element.type = 'password';
424+
} else {
425+
element.type = 'text';
426+
}
429427
}
428+
element.autocomplete = autofillHint ?? 'on';
430429
} else if (domElement is html.TextAreaElement) {
431430
if (placeholder != null) {
432431
domElement.placeholder = placeholder;
@@ -800,13 +799,7 @@ class SafariDesktopTextEditingStrategy extends DefaultTextEditingStrategy {
800799

801800
@override
802801
void initializeElementPlacement() {
803-
if (geometry != null) {
804-
placeElement();
805-
} else {
806-
// If the geometry infomation is not yet available, the input element
807-
// probably hasn't been added to the DOM yet.
808-
activeDomElement.focus();
809-
}
802+
activeDomElement.focus();
810803
}
811804
}
812805

@@ -900,9 +893,9 @@ abstract class DefaultTextEditingStrategy implements TextEditingStrategy {
900893
_appendedToForm = false;
901894
}
902895

903-
isEnabled = true;
904896
initializeElementPlacement();
905897

898+
isEnabled = true;
906899
this.onChange = onChange;
907900
this.onAction = onAction;
908901
}

lib/web_ui/test/text_editing_test.dart

Lines changed: 79 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -476,14 +476,18 @@ void testMain() {
476476
// Editing shouldn't have started yet.
477477
expect(document.activeElement, document.body);
478478

479+
const MethodCall show = MethodCall('TextInput.show');
480+
sendFrameworkMessage(codec.encodeMethodCall(show));
481+
482+
// The "setSizeAndTransform" message has to be here before we call
483+
// checkInputEditingState, since on some platforms (e.g. Desktop Safari)
484+
// we don't put the input element on DOM until we get its correct
485+
// dimensions from the framework.
479486
final MethodCall setSizeAndTransform =
480487
configureSetSizeAndTransformMethodCall(150, 50,
481488
Matrix4.translationValues(10.0, 20.0, 30.0).storage.toList());
482489
sendFrameworkMessage(codec.encodeMethodCall(setSizeAndTransform));
483490

484-
const MethodCall show = MethodCall('TextInput.show');
485-
sendFrameworkMessage(codec.encodeMethodCall(show));
486-
487491
checkInputEditingState(textEditing!.strategy.domElement, '', 0, 0);
488492

489493
const MethodCall setEditingState =
@@ -523,14 +527,18 @@ void testMain() {
523527
// Editing shouldn't have started yet.
524528
expect(document.activeElement, document.body);
525529

530+
const MethodCall show = MethodCall('TextInput.show');
531+
sendFrameworkMessage(codec.encodeMethodCall(show));
532+
533+
// The "setSizeAndTransform" message has to be here before we call
534+
// checkInputEditingState, since on some platforms (e.g. Desktop Safari)
535+
// we don't put the input element on DOM until we get its correct
536+
// dimensions from the framework.
526537
final MethodCall setSizeAndTransform =
527538
configureSetSizeAndTransformMethodCall(150, 50,
528539
Matrix4.translationValues(10.0, 20.0, 30.0).storage.toList());
529540
sendFrameworkMessage(codec.encodeMethodCall(setSizeAndTransform));
530541

531-
const MethodCall show = MethodCall('TextInput.show');
532-
sendFrameworkMessage(codec.encodeMethodCall(show));
533-
534542
checkInputEditingState(
535543
textEditing!.strategy.domElement, 'abcd', 2, 3);
536544

@@ -601,14 +609,18 @@ void testMain() {
601609
// Editing shouldn't have started yet.
602610
expect(defaultTextEditingRoot.activeElement, null);
603611

612+
const MethodCall show = MethodCall('TextInput.show');
613+
sendFrameworkMessage(codec.encodeMethodCall(show));
614+
615+
// The "setSizeAndTransform" message has to be here before we call
616+
// checkInputEditingState, since on some platforms (e.g. Desktop Safari)
617+
// we don't put the input element on DOM until we get its correct
618+
// dimensions from the framework.
604619
final MethodCall setSizeAndTransform =
605620
configureSetSizeAndTransformMethodCall(150, 50,
606621
Matrix4.translationValues(10.0, 20.0, 30.0).storage.toList());
607622
sendFrameworkMessage(codec.encodeMethodCall(setSizeAndTransform));
608623

609-
const MethodCall show = MethodCall('TextInput.show');
610-
sendFrameworkMessage(codec.encodeMethodCall(show));
611-
612624
checkInputEditingState(
613625
textEditing!.strategy.domElement, 'abcd', 2, 3);
614626
expect(textEditing!.isEditing, isTrue);
@@ -643,14 +655,18 @@ void testMain() {
643655
// Editing shouldn't have started yet.
644656
expect(defaultTextEditingRoot.activeElement, null);
645657

658+
const MethodCall show = MethodCall('TextInput.show');
659+
sendFrameworkMessage(codec.encodeMethodCall(show));
660+
661+
// The "setSizeAndTransform" message has to be here before we call
662+
// checkInputEditingState, since on some platforms (e.g. Desktop Safari)
663+
// we don't put the input element on DOM until we get its correct
664+
// dimensions from the framework.
646665
final MethodCall setSizeAndTransform =
647666
configureSetSizeAndTransformMethodCall(150, 50,
648667
Matrix4.translationValues(10.0, 20.0, 30.0).storage.toList());
649668
sendFrameworkMessage(codec.encodeMethodCall(setSizeAndTransform));
650669

651-
const MethodCall show = MethodCall('TextInput.show');
652-
sendFrameworkMessage(codec.encodeMethodCall(show));
653-
654670
checkInputEditingState(
655671
textEditing!.strategy.domElement, 'abcd', 2, 3);
656672

@@ -860,14 +876,18 @@ void testMain() {
860876
// Editing shouldn't have started yet.
861877
expect(document.activeElement, document.body);
862878

879+
const MethodCall show = MethodCall('TextInput.show');
880+
sendFrameworkMessage(codec.encodeMethodCall(show));
881+
882+
// The "setSizeAndTransform" message has to be here before we call
883+
// checkInputEditingState, since on some platforms (e.g. Desktop Safari)
884+
// we don't put the input element on DOM until we get its correct
885+
// dimensions from the framework.
863886
final MethodCall setSizeAndTransform =
864887
configureSetSizeAndTransformMethodCall(150, 50,
865888
Matrix4.translationValues(10.0, 20.0, 30.0).storage.toList());
866889
sendFrameworkMessage(codec.encodeMethodCall(setSizeAndTransform));
867890

868-
const MethodCall show = MethodCall('TextInput.show');
869-
sendFrameworkMessage(codec.encodeMethodCall(show));
870-
871891
checkInputEditingState(
872892
textEditing!.strategy.domElement, 'abcd', 2, 3);
873893

@@ -898,14 +918,18 @@ void testMain() {
898918
});
899919
sendFrameworkMessage(codec.encodeMethodCall(setEditingState1));
900920

921+
const MethodCall show = MethodCall('TextInput.show');
922+
sendFrameworkMessage(codec.encodeMethodCall(show));
923+
924+
// The "setSizeAndTransform" message has to be here before we call
925+
// checkInputEditingState, since on some platforms (e.g. Desktop Safari)
926+
// we don't put the input element on DOM until we get its correct
927+
// dimensions from the framework.
901928
final MethodCall setSizeAndTransform =
902929
configureSetSizeAndTransformMethodCall(150, 50,
903930
Matrix4.translationValues(10.0, 20.0, 30.0).storage.toList());
904931
sendFrameworkMessage(codec.encodeMethodCall(setSizeAndTransform));
905932

906-
const MethodCall show = MethodCall('TextInput.show');
907-
sendFrameworkMessage(codec.encodeMethodCall(show));
908-
909933
const MethodCall setEditingState2 =
910934
MethodCall('TextInput.setEditingState', <String, dynamic>{
911935
'text': 'xyz',
@@ -946,6 +970,10 @@ void testMain() {
946970
const MethodCall show = MethodCall('TextInput.show');
947971
sendFrameworkMessage(codec.encodeMethodCall(show));
948972

973+
// The "setSizeAndTransform" message has to be here before we call
974+
// checkInputEditingState, since on some platforms (e.g. Desktop Safari)
975+
// we don't put the input element on DOM until we get its correct
976+
// dimensions from the framework.
949977
final MethodCall setSizeAndTransform =
950978
configureSetSizeAndTransformMethodCall(150, 50,
951979
Matrix4.translationValues(10.0, 20.0, 30.0).storage.toList());
@@ -987,14 +1015,18 @@ void testMain() {
9871015
});
9881016
sendFrameworkMessage(codec.encodeMethodCall(setEditingState1));
9891017

1018+
const MethodCall show = MethodCall('TextInput.show');
1019+
sendFrameworkMessage(codec.encodeMethodCall(show));
1020+
1021+
// The "setSizeAndTransform" message has to be here before we call
1022+
// checkInputEditingState, since on some platforms (e.g. Desktop Safari)
1023+
// we don't put the input element on DOM until we get its correct
1024+
// dimensions from the framework.
9901025
final MethodCall setSizeAndTransform =
9911026
configureSetSizeAndTransformMethodCall(10, 10,
9921027
Matrix4.translationValues(10.0, 10.0, 10.0).storage.toList());
9931028
sendFrameworkMessage(codec.encodeMethodCall(setSizeAndTransform));
9941029

995-
const MethodCall show = MethodCall('TextInput.show');
996-
sendFrameworkMessage(codec.encodeMethodCall(show));
997-
9981030
final InputElement inputElement =
9991031
textEditing!.strategy.domElement! as InputElement;
10001032
expect(inputElement.value, 'abcd');
@@ -1061,6 +1093,10 @@ void testMain() {
10611093
const MethodCall show = MethodCall('TextInput.show');
10621094
sendFrameworkMessage(codec.encodeMethodCall(show));
10631095

1096+
// The "setSizeAndTransform" message has to be here before we call
1097+
// checkInputEditingState, since on some platforms (e.g. Desktop Safari)
1098+
// we don't put the input element on DOM until we get its correct
1099+
// dimensions from the framework.
10641100
final MethodCall setSizeAndTransform =
10651101
configureSetSizeAndTransformMethodCall(150, 50,
10661102
Matrix4.translationValues(10.0, 20.0, 30.0).storage.toList());
@@ -1218,6 +1254,10 @@ void testMain() {
12181254
const MethodCall show = MethodCall('TextInput.show');
12191255
sendFrameworkMessage(codec.encodeMethodCall(show));
12201256

1257+
// The "setSizeAndTransform" message has to be here before we call
1258+
// checkInputEditingState, since on some platforms (e.g. Desktop Safari)
1259+
// we don't put the input element on DOM until we get its correct
1260+
// dimensions from the framework.
12211261
final MethodCall setSizeAndTransform =
12221262
configureSetSizeAndTransformMethodCall(
12231263
150,
@@ -1360,14 +1400,18 @@ void testMain() {
13601400
});
13611401
sendFrameworkMessage(codec.encodeMethodCall(setEditingState1));
13621402

1403+
const MethodCall show = MethodCall('TextInput.show');
1404+
sendFrameworkMessage(codec.encodeMethodCall(show));
1405+
1406+
// The "setSizeAndTransform" message has to be here before we call
1407+
// checkInputEditingState, since on some platforms (e.g. Desktop Safari)
1408+
// we don't put the input element on DOM until we get its correct
1409+
// dimensions from the framework.
13631410
final MethodCall setSizeAndTransform =
13641411
configureSetSizeAndTransformMethodCall(150, 50,
13651412
Matrix4.translationValues(10.0, 20.0, 30.0).storage.toList());
13661413
sendFrameworkMessage(codec.encodeMethodCall(setSizeAndTransform));
13671414

1368-
const MethodCall show = MethodCall('TextInput.show');
1369-
sendFrameworkMessage(codec.encodeMethodCall(show));
1370-
13711415
// Check if the selection range is correct.
13721416
checkInputEditingState(
13731417
textEditing!.strategy.domElement, 'xyz', 1, 2);
@@ -1478,6 +1522,10 @@ void testMain() {
14781522
const MethodCall show = MethodCall('TextInput.show');
14791523
sendFrameworkMessage(codec.encodeMethodCall(show));
14801524

1525+
// The "setSizeAndTransform" message has to be here before we call
1526+
// checkInputEditingState, since on some platforms (e.g. Desktop Safari)
1527+
// we don't put the input element on DOM until we get its correct
1528+
// dimensions from the framework.
14811529
final MethodCall setSizeAndTransform =
14821530
configureSetSizeAndTransformMethodCall(150, 50,
14831531
Matrix4.translationValues(10.0, 20.0, 30.0).storage.toList());
@@ -1533,14 +1581,18 @@ void testMain() {
15331581
// Editing shouldn't have started yet.
15341582
expect(defaultTextEditingRoot.activeElement, null);
15351583

1584+
const MethodCall show = MethodCall('TextInput.show');
1585+
sendFrameworkMessage(codec.encodeMethodCall(show));
1586+
1587+
// The "setSizeAndTransform" message has to be here before we call
1588+
// checkInputEditingState, since on some platforms (e.g. Desktop Safari)
1589+
// we don't put the input element on DOM until we get its correct
1590+
// dimensions from the framework.
15361591
final MethodCall setSizeAndTransform =
15371592
configureSetSizeAndTransformMethodCall(150, 50,
15381593
Matrix4.translationValues(10.0, 20.0, 30.0).storage.toList());
15391594
sendFrameworkMessage(codec.encodeMethodCall(setSizeAndTransform));
15401595

1541-
const MethodCall show = MethodCall('TextInput.show');
1542-
sendFrameworkMessage(codec.encodeMethodCall(show));
1543-
15441596
final TextAreaElement textarea = textEditing!.strategy.domElement! as TextAreaElement;
15451597
checkTextAreaEditingState(textarea, '', 0, 0);
15461598

shell/platform/darwin/ios/framework/Source/FlutterTextInputPlugin.mm

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -324,10 +324,10 @@ static UITextContentType ToUITextContentType(NSArray<NSString*>* hints) {
324324
// have an autofill type of FlutterAutofillTypeRegular.
325325
//
326326
// The text input plugin creates a new UIView for every FlutterAutofillTypeNone
327-
// text field. The UIView is released and not reused since the software keyboard
328-
// may use the identity of a UIView to distinguish different views and provides
329-
// the same predictive text suggestions or restore the composing region if a
330-
// UIView is reused for a different flutter text field.
327+
// text field. The UIView instance is never reused for other flutter text fields
328+
// since the software keyboard often uses the identity of a UIView to distinguish
329+
// different views and provides the same predictive text suggestions or restore
330+
// the composing region if a UIView is reused for a different flutter text field.
331331
//
332332
// The text input plugin creates a new "autofill context" if the text field has
333333
// the type of FlutterAutofillTypePassword, to represent the AutofillGroup of
@@ -389,7 +389,8 @@ static FlutterAutofillType autofillTypeOf(NSDictionary* configuration) {
389389
if (@available(iOS 10.0, *)) {
390390
NSDictionary* autofill = configuration[kAutofillProperties];
391391
UITextContentType contentType = ToUITextContentType(autofill[kAutofillHints]);
392-
return [contentType isEqualToString:@""] ? FlutterAutofillTypeNone : FlutterAutofillTypeRegular;
392+
return !autofill || [contentType isEqualToString:@""] ? FlutterAutofillTypeNone
393+
: FlutterAutofillTypeRegular;
393394
}
394395

395396
return FlutterAutofillTypeNone;

shell/platform/darwin/ios/framework/Source/FlutterTextInputPluginTest.mm

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -646,6 +646,8 @@ - (void)testDisablingAutofillOnInputClient {
646646
- (void)testAutofillEnabledByDefault {
647647
NSDictionary* config = self.mutableTemplateCopy;
648648
[config setValue:@"NO" forKey:@"obscureText"];
649+
[config setValue:@{@"uniqueIdentifier" : @"field1", @"editingValue" : @{@"text" : @""}}
650+
forKey:@"autofill"];
649651

650652
[self setClientId:123 configuration:config];
651653

0 commit comments

Comments
 (0)