Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Added autofill functionality #16227

Closed
Closed
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
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,8 @@ public static Configuration fromJson(@NonNull JSONObject json) throws JSONExcept
TextCapitalization.fromValue(json.getString("textCapitalization")),
InputType.fromJson(json.getJSONObject("inputType")),
inputAction,
json.isNull("actionLabel") ? null : json.getString("actionLabel")
json.isNull("actionLabel") ? null : json.getString("actionLabel"),
json.isNull("textContentType") ? null : TextContentType.fromJson(json.getJSONObject("textContentType"))
);
}

Expand Down Expand Up @@ -328,6 +329,8 @@ private static Integer inputActionFromTextInputAction(@NonNull String inputActio
public final Integer inputAction;
@Nullable
public final String actionLabel;
@Nullable
public final TextContentType textContentType;

public Configuration(
boolean obscureText,
Expand All @@ -336,7 +339,8 @@ public Configuration(
@NonNull TextCapitalization textCapitalization,
@NonNull InputType inputType,
@Nullable Integer inputAction,
@Nullable String actionLabel
@Nullable String actionLabel,
@Nullable TextContentType textContentType
) {
this.obscureText = obscureText;
this.autocorrect = autocorrect;
Expand All @@ -345,6 +349,7 @@ public Configuration(
this.inputType = inputType;
this.inputAction = inputAction;
this.actionLabel = actionLabel;
this.textContentType = textContentType;
}
}

Expand Down Expand Up @@ -406,6 +411,23 @@ static TextInputType fromValue(@NonNull String encodedName) throws NoSuchFieldEx
}
}

/**
* Types of text content for auto-fill functionality
*/
public static class TextContentType {
@NonNull
public static TextContentType fromJson(@NonNull JSONObject json) throws JSONException, NoSuchFieldException {
return new TextContentType(json.getString("rawValue"));
}

@NonNull
public final String rawValue;

public TextContentType(@NonNull String rawValue) {
this.rawValue = rawValue;
}
}

/**
* Text capitalization schemes.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,12 @@ public InputConnection createInputConnection(View view, EditorInfo outAttrs) {
outAttrs.actionId = enterAction;
}
outAttrs.imeOptions |= enterAction;

String autofillHintValue = configuration.textContentType.rawValue;
if (autofillHintValue != null) {
String[] autofillHints = {autofillHintValue};
view.setAutofillHints(autofillHints);
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unsure if this is the correct view to set the auto fill hints on.

}

InputConnectionAdaptor connection = new InputConnectionAdaptor(
view,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,75 @@ static UITextAutocapitalizationType ToUITextAutoCapitalizationType(NSDictionary*
return UITextAutocapitalizationTypeNone;
}

static UITextContentType ToUITextContentType(NSDictionary* type) API_AVAILABLE(ios(10.0)) {
NSDictionary* contentTypeDictionary = type[@"textContentType"];
NSString* contentType = contentTypeDictionary[@"name"];

if ([contentType isEqualToString:@"TextContentType.personName"])
return UITextContentTypeName;
else if ([contentType isEqualToString:@"TextContentType.personNamePrefix"])
return UITextContentTypeNamePrefix;
else if ([contentType isEqualToString:@"TextContentType.personGivenName"])
return UITextContentTypeGivenName;
else if ([contentType isEqualToString:@"TextContentType.personMiddleName"])
return UITextContentTypeMiddleName;
else if ([contentType isEqualToString:@"TextContentType.personFamilyName"])
return UITextContentTypeFamilyName;
else if ([contentType isEqualToString:@"TextContentType.personNameSuffix"])
return UITextContentTypeNameSuffix;
else if ([contentType isEqualToString:@"TextContentType.postalAddress"])
return UITextContentTypeFullStreetAddress;
else if ([contentType isEqualToString:@"TextContentType.streetAddress"])
return UITextContentTypeStreetAddressLine1;
else if ([contentType isEqualToString:@"TextContentType.extendedAddress"])
return UITextContentTypeStreetAddressLine2;
else if ([contentType isEqualToString:@"TextContentType.addressLocality"])
return UITextContentTypeAddressCity;
else if ([contentType isEqualToString:@"TextContentType.addressRegion"])
return UITextContentTypeAddressState;
else if ([contentType isEqualToString:@"TextContentType.addressCountry"])
return UITextContentTypeCountryName;
else if ([contentType isEqualToString:@"TextContentType.postalCode"])
return UITextContentTypePostalCode;
else if ([contentType isEqualToString:@"TextContentType.phoneNumber"])
return UITextContentTypeTelephoneNumber;
else if ([contentType isEqualToString:@"TextContentType.emailAddress"])
return UITextContentTypeEmailAddress;
else if ([contentType isEqualToString:@"TextContentType.url"])
return UITextContentTypeURL;
else if ([contentType isEqualToString:@"TextContentType.creditCardNumber"])
return UITextContentTypeCreditCardNumber;
else if ([contentType isEqualToString:@"TextContentType.username"]) {
if (@available(iOS 11.0, *)) {
return UITextContentTypeUsername;
} else {
return nil;
}
} else if ([contentType isEqualToString:@"TextContentType.password"]) {
if (@available(iOS 11.0, *)) {
return UITextContentTypePassword;
} else {
return nil;
}
} else if ([contentType isEqualToString:@"TextContentType.newPassword"]) {
if (@available(iOS 12.0, *)) {
return UITextContentTypeNewPassword;
} else {
return nil;
}
} else if ([contentType isEqualToString:@"TextContentType.smsOTPCode"]) {
if (@available(iOS 12.0, *)) {
return UITextContentTypeOneTimeCode;
} else {
return nil;
}
}

// If we don't have a known match, try and cast it from the raw value
NSString* rawValue = contentTypeDictionary[@"rawValue"];
return (UITextContentType)rawValue;
}

static UIReturnKeyType ToUIReturnKeyType(NSString* inputType) {
// Where did the term "unspecified" come from? iOS has a "default" and Android
// has "unspecified." These 2 terms seem to mean the same thing but we need
Expand Down Expand Up @@ -154,6 +223,7 @@ @interface FlutterTextInputView : UIView <UITextInput>
@property(nonatomic) UITextAutocapitalizationType autocapitalizationType;
@property(nonatomic) UITextAutocorrectionType autocorrectionType;
@property(nonatomic) UITextSpellCheckingType spellCheckingType;
@property(nonatomic, copy) UITextContentType textContentType API_AVAILABLE(ios(10.0));
@property(nonatomic) BOOL enablesReturnKeyAutomatically;
@property(nonatomic) UIKeyboardAppearance keyboardAppearance;
@property(nonatomic) UIKeyboardType keyboardType;
Expand Down Expand Up @@ -195,6 +265,7 @@ - (instancetype)init {
_keyboardType = UIKeyboardTypeDefault;
_returnKeyType = UIReturnKeyDone;
_secureTextEntry = NO;
_textContentType = nil;
if (@available(iOS 11.0, *)) {
_smartQuotesType = UITextSmartQuotesTypeYes;
_smartDashesType = UITextSmartDashesTypeYes;
Expand Down Expand Up @@ -793,6 +864,9 @@ - (void)setTextInputClient:(int)client withConfiguration:(NSDictionary*)configur
_activeView.autocorrectionType = autocorrect && ![autocorrect boolValue]
? UITextAutocorrectionTypeNo
: UITextAutocorrectionTypeDefault;
if (@available(iOS 10.0, *)) {
_activeView.textContentType = ToUITextContentType(configuration);
}
[_activeView setTextInputClient:client];
[_activeView reloadInputViews];
}
Expand Down