Flutter Engine
FlutterTextInputPlugin.mm File Reference
#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterTextInputPlugin.h"
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#include "flutter/fml/platform/darwin/string_range_sanitization.h"

Go to the source code of this file.

Classes

class  FlutterSecureTextInputView
 

Functions

static UIKeyboardType ToUIKeyboardType (NSDictionary *type)
 
static UITextAutocapitalizationType ToUITextAutoCapitalizationType (NSDictionary *type)
 
static UIReturnKeyType ToUIReturnKeyType (NSString *inputType)
 
static UITextContentType ToUITextContentType (NSArray< NSString *> *hints)
 
static NSString * autofillIdFromDictionary (NSDictionary *dictionary)
 
typedef NS_ENUM (NSInteger, FlutterAutofillType)
 
static BOOL isFieldPasswordRelated (NSDictionary *configuration)
 
static FlutterAutofillType autofillTypeOf (NSDictionary *configuration)
 

Variables

static const char _kTextAffinityDownstream [] = "TextAffinity.downstream"
 
static const char _kTextAffinityUpstream [] = "TextAffinity.upstream"
 
const CGRect kInvalidFirstRect = {{-1, -1}, {9999, 9999}}
 
static NSString *const kSecureTextEntry = @"@"obscureText"
 
static NSString *const kKeyboardType = @"@"inputType"
 
static NSString *const kKeyboardAppearance = @"@"keyboardAppearance"
 
static NSString *const kInputAction = @"@"inputAction"
 
static NSString *const kSmartDashesType = @"@"smartDashesType"
 
static NSString *const kSmartQuotesType = @"@"smartQuotesType"
 
static NSString *const kAssociatedAutofillFields = @"@"fields"
 
static NSString *const kAutofillProperties = @"@"autofill"
 
static NSString *const kAutofillId = @"@"uniqueIdentifier"
 
static NSString *const kAutofillEditingValue = @"@"editingValue"
 
static NSString *const kAutofillHints = @"@"hints"
 
static NSString *const kAutocorrectionType = @"@"autocorrect"
 
const char * _selectionAffinity
 
FlutterTextRange_selectedTextRange
 
CGRect _cachedFirstRect
 

Function Documentation

◆ autofillIdFromDictionary()

static NSString* autofillIdFromDictionary ( NSDictionary *  dictionary)
static

Definition at line 242 of file FlutterTextInputPlugin.mm.

References kAutofillId, kAutofillProperties, and kSecureTextEntry.

Referenced by FlutterTextInputPlugin::handleMethodCall:result:, and isFieldPasswordRelated().

242  {
243  NSDictionary* autofill = dictionary[kAutofillProperties];
244  if (autofill) {
245  return autofill[kAutofillId];
246  }
247 
248  // When autofill is nil, the field may still need an autofill id
249  // if the field is for password.
250  return [dictionary[kSecureTextEntry] boolValue] ? @"password" : nil;
251 }
static NSString *const kSecureTextEntry
static NSString *const kAutofillId
static NSString *const kAutofillProperties

◆ autofillTypeOf()

static FlutterAutofillType autofillTypeOf ( NSDictionary *  configuration)
static

Definition at line 302 of file FlutterTextInputPlugin.mm.

References isFieldPasswordRelated(), kAssociatedAutofillFields, kAutofillHints, kAutofillProperties, and ToUITextContentType().

Referenced by FlutterTextInputPlugin::handleMethodCall:result:.

302  {
303  for (NSDictionary* field in configuration[kAssociatedAutofillFields]) {
304  if (isFieldPasswordRelated(field)) {
305  return FlutterAutofillTypePassword;
306  }
307  }
308 
309  if (isFieldPasswordRelated(configuration)) {
310  return FlutterAutofillTypePassword;
311  }
312 
313  if (@available(iOS 10.0, *)) {
314  NSDictionary* autofill = configuration[kAutofillProperties];
315  UITextContentType contentType = ToUITextContentType(autofill[kAutofillHints]);
316  return [contentType isEqualToString:@""] ? FlutterAutofillTypeNone : FlutterAutofillTypeRegular;
317  }
318 
319  return FlutterAutofillTypeNone;
320 }
static BOOL isFieldPasswordRelated(NSDictionary *configuration)
static NSString *const kAssociatedAutofillFields
static NSString *const kAutofillProperties
static NSString *const kAutofillHints
static UITextContentType ToUITextContentType(NSArray< NSString *> *hints)

◆ isFieldPasswordRelated()

static BOOL isFieldPasswordRelated ( NSDictionary *  configuration)
static

Definition at line 274 of file FlutterTextInputPlugin.mm.

References autofillIdFromDictionary(), kAutofillHints, kAutofillProperties, kSecureTextEntry, and ToUITextContentType().

Referenced by autofillTypeOf().

274  {
275  if (@available(iOS 10.0, *)) {
276  BOOL isSecureTextEntry = [configuration[kSecureTextEntry] boolValue];
277  if (isSecureTextEntry)
278  return YES;
279 
280  if (!autofillIdFromDictionary(configuration)) {
281  return NO;
282  }
283  NSDictionary* autofill = configuration[kAutofillProperties];
284  UITextContentType contentType = ToUITextContentType(autofill[kAutofillHints]);
285 
286  if (@available(iOS 11.0, *)) {
287  if ([contentType isEqualToString:UITextContentTypePassword] ||
288  [contentType isEqualToString:UITextContentTypeUsername]) {
289  return YES;
290  }
291  }
292 
293  if (@available(iOS 12.0, *)) {
294  if ([contentType isEqualToString:UITextContentTypeNewPassword]) {
295  return YES;
296  }
297  }
298  }
299  return NO;
300 }
static NSString *const kSecureTextEntry
static NSString *const kAutofillProperties
static NSString * autofillIdFromDictionary(NSDictionary *dictionary)
static NSString *const kAutofillHints
static UITextContentType ToUITextContentType(NSArray< NSString *> *hints)

◆ NS_ENUM()

typedef NS_ENUM ( NSInteger  ,
FlutterAutofillType   
)

Definition at line 265 of file FlutterTextInputPlugin.mm.

265  {
266  // The field does not have autofillable content. Additionally if
267  // the field is currently in the autofill context, it will be
268  // removed from the context without triggering autofill save.
269  FlutterAutofillTypeNone,
270  FlutterAutofillTypeRegular,
271  FlutterAutofillTypePassword,
272 };

◆ ToUIKeyboardType()

static UIKeyboardType ToUIKeyboardType ( NSDictionary *  type)
static

Definition at line 42 of file FlutterTextInputPlugin.mm.

42  {
43  NSString* inputType = type[@"name"];
44  if ([inputType isEqualToString:@"TextInputType.address"])
45  return UIKeyboardTypeDefault;
46  if ([inputType isEqualToString:@"TextInputType.datetime"])
47  return UIKeyboardTypeNumbersAndPunctuation;
48  if ([inputType isEqualToString:@"TextInputType.emailAddress"])
49  return UIKeyboardTypeEmailAddress;
50  if ([inputType isEqualToString:@"TextInputType.multiline"])
51  return UIKeyboardTypeDefault;
52  if ([inputType isEqualToString:@"TextInputType.name"])
53  return UIKeyboardTypeNamePhonePad;
54  if ([inputType isEqualToString:@"TextInputType.number"]) {
55  if ([type[@"signed"] boolValue])
56  return UIKeyboardTypeNumbersAndPunctuation;
57  if ([type[@"decimal"] boolValue])
58  return UIKeyboardTypeDecimalPad;
59  return UIKeyboardTypeNumberPad;
60  }
61  if ([inputType isEqualToString:@"TextInputType.phone"])
62  return UIKeyboardTypePhonePad;
63  if ([inputType isEqualToString:@"TextInputType.text"])
64  return UIKeyboardTypeDefault;
65  if ([inputType isEqualToString:@"TextInputType.url"])
66  return UIKeyboardTypeURL;
67  return UIKeyboardTypeDefault;
68 }

◆ ToUIReturnKeyType()

static UIReturnKeyType ToUIReturnKeyType ( NSString *  inputType)
static

Definition at line 82 of file FlutterTextInputPlugin.mm.

82  {
83  // Where did the term "unspecified" come from? iOS has a "default" and Android
84  // has "unspecified." These 2 terms seem to mean the same thing but we need
85  // to pick just one. "unspecified" was chosen because "default" is often a
86  // reserved word in languages with switch statements (dart, java, etc).
87  if ([inputType isEqualToString:@"TextInputAction.unspecified"])
88  return UIReturnKeyDefault;
89 
90  if ([inputType isEqualToString:@"TextInputAction.done"])
91  return UIReturnKeyDone;
92 
93  if ([inputType isEqualToString:@"TextInputAction.go"])
94  return UIReturnKeyGo;
95 
96  if ([inputType isEqualToString:@"TextInputAction.send"])
97  return UIReturnKeySend;
98 
99  if ([inputType isEqualToString:@"TextInputAction.search"])
100  return UIReturnKeySearch;
101 
102  if ([inputType isEqualToString:@"TextInputAction.next"])
103  return UIReturnKeyNext;
104 
105  if (@available(iOS 9.0, *))
106  if ([inputType isEqualToString:@"TextInputAction.continueAction"])
107  return UIReturnKeyContinue;
108 
109  if ([inputType isEqualToString:@"TextInputAction.join"])
110  return UIReturnKeyJoin;
111 
112  if ([inputType isEqualToString:@"TextInputAction.route"])
113  return UIReturnKeyRoute;
114 
115  if ([inputType isEqualToString:@"TextInputAction.emergencyCall"])
116  return UIReturnKeyEmergencyCall;
117 
118  if ([inputType isEqualToString:@"TextInputAction.newline"])
119  return UIReturnKeyDefault;
120 
121  // Present default key if bad input type is given.
122  return UIReturnKeyDefault;
123 }

◆ ToUITextAutoCapitalizationType()

static UITextAutocapitalizationType ToUITextAutoCapitalizationType ( NSDictionary *  type)
static

Definition at line 70 of file FlutterTextInputPlugin.mm.

70  {
71  NSString* textCapitalization = type[@"textCapitalization"];
72  if ([textCapitalization isEqualToString:@"TextCapitalization.characters"]) {
73  return UITextAutocapitalizationTypeAllCharacters;
74  } else if ([textCapitalization isEqualToString:@"TextCapitalization.sentences"]) {
75  return UITextAutocapitalizationTypeSentences;
76  } else if ([textCapitalization isEqualToString:@"TextCapitalization.words"]) {
77  return UITextAutocapitalizationTypeWords;
78  }
79  return UITextAutocapitalizationTypeNone;
80 }

◆ ToUITextContentType()

static UITextContentType ToUITextContentType ( NSArray< NSString *> *  hints)
static

Definition at line 125 of file FlutterTextInputPlugin.mm.

Referenced by autofillTypeOf(), and isFieldPasswordRelated().

125  {
126  if (hints == nil || hints.count == 0) {
127  return @"";
128  }
129 
130  NSString* hint = hints[0];
131  if (@available(iOS 10.0, *)) {
132  if ([hint isEqualToString:@"addressCityAndState"]) {
133  return UITextContentTypeAddressCityAndState;
134  }
135 
136  if ([hint isEqualToString:@"addressState"]) {
137  return UITextContentTypeAddressState;
138  }
139 
140  if ([hint isEqualToString:@"addressCity"]) {
141  return UITextContentTypeAddressCity;
142  }
143 
144  if ([hint isEqualToString:@"sublocality"]) {
145  return UITextContentTypeSublocality;
146  }
147 
148  if ([hint isEqualToString:@"streetAddressLine1"]) {
149  return UITextContentTypeStreetAddressLine1;
150  }
151 
152  if ([hint isEqualToString:@"streetAddressLine2"]) {
153  return UITextContentTypeStreetAddressLine2;
154  }
155 
156  if ([hint isEqualToString:@"countryName"]) {
157  return UITextContentTypeCountryName;
158  }
159 
160  if ([hint isEqualToString:@"fullStreetAddress"]) {
161  return UITextContentTypeFullStreetAddress;
162  }
163 
164  if ([hint isEqualToString:@"postalCode"]) {
165  return UITextContentTypePostalCode;
166  }
167 
168  if ([hint isEqualToString:@"location"]) {
169  return UITextContentTypeLocation;
170  }
171 
172  if ([hint isEqualToString:@"creditCardNumber"]) {
173  return UITextContentTypeCreditCardNumber;
174  }
175 
176  if ([hint isEqualToString:@"email"]) {
177  return UITextContentTypeEmailAddress;
178  }
179 
180  if ([hint isEqualToString:@"jobTitle"]) {
181  return UITextContentTypeJobTitle;
182  }
183 
184  if ([hint isEqualToString:@"givenName"]) {
185  return UITextContentTypeGivenName;
186  }
187 
188  if ([hint isEqualToString:@"middleName"]) {
189  return UITextContentTypeMiddleName;
190  }
191 
192  if ([hint isEqualToString:@"familyName"]) {
193  return UITextContentTypeFamilyName;
194  }
195 
196  if ([hint isEqualToString:@"name"]) {
197  return UITextContentTypeName;
198  }
199 
200  if ([hint isEqualToString:@"namePrefix"]) {
201  return UITextContentTypeNamePrefix;
202  }
203 
204  if ([hint isEqualToString:@"nameSuffix"]) {
205  return UITextContentTypeNameSuffix;
206  }
207 
208  if ([hint isEqualToString:@"nickname"]) {
209  return UITextContentTypeNickname;
210  }
211 
212  if ([hint isEqualToString:@"organizationName"]) {
213  return UITextContentTypeOrganizationName;
214  }
215 
216  if ([hint isEqualToString:@"telephoneNumber"]) {
217  return UITextContentTypeTelephoneNumber;
218  }
219  }
220 
221  if (@available(iOS 11.0, *)) {
222  if ([hint isEqualToString:@"password"]) {
223  return UITextContentTypePassword;
224  }
225  }
226 
227  if (@available(iOS 12.0, *)) {
228  if ([hint isEqualToString:@"oneTimeCode"]) {
229  return UITextContentTypeOneTimeCode;
230  }
231 
232  if ([hint isEqualToString:@"newPassword"]) {
233  return UITextContentTypeNewPassword;
234  }
235  }
236 
237  return hints[0];
238 }

Variable Documentation

◆ _cachedFirstRect

CGRect _cachedFirstRect

Definition at line 435 of file FlutterTextInputPlugin.mm.

◆ _kTextAffinityDownstream

const char _kTextAffinityDownstream[] = "TextAffinity.downstream"
static

Definition at line 12 of file FlutterTextInputPlugin.mm.

◆ _kTextAffinityUpstream

const char _kTextAffinityUpstream[] = "TextAffinity.upstream"
static

Definition at line 13 of file FlutterTextInputPlugin.mm.

◆ _selectedTextRange

FlutterTextRange* _selectedTextRange

Definition at line 434 of file FlutterTextInputPlugin.mm.

◆ _selectionAffinity

const char* _selectionAffinity
Initial value:
{
int _textInputClient

Definition at line 431 of file FlutterTextInputPlugin.mm.

◆ kAssociatedAutofillFields

NSString* const kAssociatedAutofillFields = @"@"fields"
static

◆ kAutocorrectionType

NSString* const kAutocorrectionType = @"@"autocorrect"
static

Definition at line 38 of file FlutterTextInputPlugin.mm.

◆ kAutofillEditingValue

NSString* const kAutofillEditingValue = @"@"editingValue"
static

Definition at line 35 of file FlutterTextInputPlugin.mm.

◆ kAutofillHints

NSString* const kAutofillHints = @"@"hints"
static

Definition at line 36 of file FlutterTextInputPlugin.mm.

Referenced by autofillTypeOf(), and isFieldPasswordRelated().

◆ kAutofillId

NSString* const kAutofillId = @"@"uniqueIdentifier"
static

Definition at line 34 of file FlutterTextInputPlugin.mm.

Referenced by autofillIdFromDictionary().

◆ kAutofillProperties

NSString* const kAutofillProperties = @"@"autofill"
static

◆ kInputAction

NSString* const kInputAction = @"@"inputAction"
static

Definition at line 25 of file FlutterTextInputPlugin.mm.

◆ kInvalidFirstRect

const CGRect kInvalidFirstRect = {{-1, -1}, {9999, 9999}}

◆ kKeyboardAppearance

NSString* const kKeyboardAppearance = @"@"keyboardAppearance"
static

Definition at line 24 of file FlutterTextInputPlugin.mm.

◆ kKeyboardType

NSString* const kKeyboardType = @"@"inputType"
static

Definition at line 23 of file FlutterTextInputPlugin.mm.

◆ kSecureTextEntry

NSString* const kSecureTextEntry = @"@"obscureText"
static

Definition at line 22 of file FlutterTextInputPlugin.mm.

Referenced by autofillIdFromDictionary(), and isFieldPasswordRelated().

◆ kSmartDashesType

NSString* const kSmartDashesType = @"@"smartDashesType"
static

Definition at line 27 of file FlutterTextInputPlugin.mm.

◆ kSmartQuotesType

NSString* const kSmartQuotesType = @"@"smartQuotesType"
static

Definition at line 28 of file FlutterTextInputPlugin.mm.