inset_services/autofill.rs
1//! Flutter counterpart: `services/autofill.dart`.
2//!
3//! `AutofillConfiguration` lives in `inset-embedder` (re-exported from
4//! `text_input.rs`) because `View` names `TextInputConfiguration`.
5
6use inset_foundation::{App, Handle, HandleId};
7
8use crate::text_input::{
9 AnyTextInputClient, TextEditingValue, TextInput, TextInputConfiguration, TextInputConnection,
10};
11
12/// A collection of commonly used autofill hint strings on different platforms.
13///
14/// Each hint is pre-defined on at least one supported platform. See their
15/// documentation for their availability on each platform, and the platform
16/// values each autofill hint corresponds to.
17pub struct AutofillHints;
18
19impl AutofillHints {
20 /// The input field expects an address locality (city/town).
21 ///
22 /// This hint will be translated to the below values on different platforms:
23 ///
24 /// * Android: [AUTOFILL_HINT_POSTAL_ADDRESS_LOCALITY](https://developer.android.com/reference/androidx/autofill/HintConstants#AUTOFILL_HINT_POSTAL_ADDRESS_LOCALITY).
25 /// * iOS: [addressCity](https://developer.apple.com/documentation/uikit/uitextcontenttype).
26 /// * Otherwise, the hint string will be used as-is.
27 pub const ADDRESS_CITY: &str = "addressCity";
28
29 /// The input field expects a city name combined with a state name.
30 ///
31 /// This hint will be translated to the below values on different platforms:
32 ///
33 /// * iOS: [addressCityAndState](https://developer.apple.com/documentation/uikit/uitextcontenttype).
34 /// * Otherwise, the hint string will be used as-is.
35 pub const ADDRESS_CITY_AND_STATE: &str = "addressCityAndState";
36
37 /// The input field expects a region/state.
38 ///
39 /// This hint will be translated to the below values on different platforms:
40 ///
41 /// * Android: [AUTOFILL_HINT_POSTAL_ADDRESS_REGION](https://developer.android.com/reference/androidx/autofill/HintConstants#AUTOFILL_HINT_POSTAL_ADDRESS_REGION).
42 /// * iOS: [addressState](https://developer.apple.com/documentation/uikit/uitextcontenttype).
43 /// * Otherwise, the hint string will be used as-is.
44 pub const ADDRESS_STATE: &str = "addressState";
45
46 /// The input field expects a person's full birth date.
47 ///
48 /// This hint will be translated to the below values on different platforms:
49 ///
50 /// * Android: [AUTOFILL_HINT_BIRTH_DATE_FULL](https://developer.android.com/reference/androidx/autofill/HintConstants#AUTOFILL_HINT_BIRTH_DATE_FULL).
51 /// * web: ["bday"](https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#autofilling-form-controls:-the-autocomplete-attribute).
52 /// * Otherwise, the hint string will be used as-is.
53 pub const BIRTHDAY: &str = "birthday";
54
55 /// The input field expects a person's birth day(of the month).
56 ///
57 /// This hint will be translated to the below values on different platforms:
58 ///
59 /// * Android: [AUTOFILL_HINT_BIRTH_DATE_DAY](https://developer.android.com/reference/androidx/autofill/HintConstants#AUTOFILL_HINT_BIRTH_DATE_DAY).
60 /// * web: ["bday-day"](https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#autofilling-form-controls:-the-autocomplete-attribute).
61 /// * Otherwise, the hint string will be used as-is.
62 pub const BIRTHDAY_DAY: &str = "birthdayDay";
63
64 /// The input field expects a person's birth month.
65 ///
66 /// This hint will be translated to the below values on different platforms:
67 ///
68 /// * Android: [AUTOFILL_HINT_BIRTH_DATE_MONTH](https://developer.android.com/reference/androidx/autofill/HintConstants#AUTOFILL_HINT_BIRTH_DATE_MONTH).
69 /// * web: ["bday-month"](https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#autofilling-form-controls:-the-autocomplete-attribute).
70 /// * Otherwise, the hint string will be used as-is.
71 pub const BIRTHDAY_MONTH: &str = "birthdayMonth";
72
73 /// The input field expects a person's birth year.
74 ///
75 /// This hint will be translated to the below values on different platforms:
76 ///
77 /// * Android: [AUTOFILL_HINT_BIRTH_DATE_YEAR](https://developer.android.com/reference/androidx/autofill/HintConstants#AUTOFILL_HINT_BIRTH_DATE_YEAR).
78 /// * web: ["bday-year"](https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#autofilling-form-controls:-the-autocomplete-attribute).
79 /// * Otherwise, the hint string will be used as-is.
80 pub const BIRTHDAY_YEAR: &str = "birthdayYear";
81
82 /// The input field expects an
83 /// [ISO 3166-1-alpha-2](https://www.iso.org/standard/63545.html) country code.
84 ///
85 /// This hint will be translated to the below values on different platforms:
86 ///
87 /// * web: ["country"](https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#autofilling-form-controls:-the-autocomplete-attribute).
88 /// * Otherwise, the hint string will be used as-is.
89 pub const COUNTRY_CODE: &str = "countryCode";
90
91 /// The input field expects a country name.
92 ///
93 /// This hint will be translated to the below values on different platforms:
94 ///
95 /// * Android: [AUTOFILL_HINT_POSTAL_ADDRESS_COUNTRY](https://developer.android.com/reference/androidx/autofill/HintConstants#AUTOFILL_HINT_POSTAL_ADDRESS_COUNTRY).
96 /// * iOS: [countryName](https://developer.apple.com/documentation/uikit/uitextcontenttype).
97 /// * web: ["country-name"](https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#autofilling-form-controls:-the-autocomplete-attribute).
98 /// * Otherwise, the hint string will be used as-is.
99 pub const COUNTRY_NAME: &str = "countryName";
100
101 /// The input field expects a credit card expiration date.
102 ///
103 /// This hint will be translated to the below values on different platforms:
104 ///
105 /// * Android: [AUTOFILL_HINT_CREDIT_CARD_NUMBER](https://developer.android.com/reference/androidx/autofill/HintConstants#AUTOFILL_HINT_CREDIT_CARD_NUMBER).
106 /// * web: ["cc-exp"](https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#autofilling-form-controls:-the-autocomplete-attribute).
107 /// * Otherwise, the hint string will be used as-is.
108 pub const CREDIT_CARD_EXPIRATION_DATE: &str = "creditCardExpirationDate";
109
110 /// The input field expects a credit card expiration day.
111 ///
112 /// This hint will be translated to the below values on different platforms:
113 ///
114 /// * Android: [AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_DAY](https://developer.android.com/reference/androidx/autofill/HintConstants#AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_DAY).
115 /// * Otherwise, the hint string will be used as-is.
116 pub const CREDIT_CARD_EXPIRATION_DAY: &str = "creditCardExpirationDay";
117
118 /// The input field expects a credit card expiration month.
119 ///
120 /// This hint will be translated to the below values on different platforms:
121 ///
122 /// * Android: [AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_MONTH](https://developer.android.com/reference/androidx/autofill/HintConstants#AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_MONTH).
123 /// * web: ["cc-exp-month"](https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#autofilling-form-controls:-the-autocomplete-attribute).
124 /// * Otherwise, the hint string will be used as-is.
125 pub const CREDIT_CARD_EXPIRATION_MONTH: &str = "creditCardExpirationMonth";
126
127 /// The input field expects a credit card expiration year.
128 ///
129 /// This hint will be translated to the below values on different platforms:
130 ///
131 /// * Android: [AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_YEAR](https://developer.android.com/reference/androidx/autofill/HintConstants#AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_YEAR).
132 /// * web: ["cc-exp-year"](https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#autofilling-form-controls:-the-autocomplete-attribute).
133 /// * Otherwise, the hint string will be used as-is.
134 pub const CREDIT_CARD_EXPIRATION_YEAR: &str = "creditCardExpirationYear";
135
136 /// The input field expects the holder's last/family name as given on a credit
137 /// card.
138 ///
139 /// This hint will be translated to the below values on different platforms:
140 ///
141 /// * web: ["cc-family-name"](https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#autofilling-form-controls:-the-autocomplete-attribute).
142 /// * Otherwise, the hint string will be used as-is.
143 pub const CREDIT_CARD_FAMILY_NAME: &str = "creditCardFamilyName";
144
145 /// The input field expects the holder's first/given name as given on a credit
146 /// card.
147 ///
148 /// This hint will be translated to the below values on different platforms:
149 ///
150 /// * web: ["cc-given-name"](https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#autofilling-form-controls:-the-autocomplete-attribute).
151 /// * Otherwise, the hint string will be used as-is.
152 pub const CREDIT_CARD_GIVEN_NAME: &str = "creditCardGivenName";
153
154 /// The input field expects the holder's middle name as given on a credit
155 /// card.
156 ///
157 /// This hint will be translated to the below values on different platforms:
158 ///
159 /// * web: ["cc-additional-name"](https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#autofilling-form-controls:-the-autocomplete-attribute).
160 /// * Otherwise, the hint string will be used as-is.
161 pub const CREDIT_CARD_MIDDLE_NAME: &str = "creditCardMiddleName";
162
163 /// The input field expects the holder's full name as given on a credit card.
164 ///
165 /// This hint will be translated to the below values on different platforms:
166 ///
167 /// * web: ["cc-name"](https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#autofilling-form-controls:-the-autocomplete-attribute).
168 /// * Otherwise, the hint string will be used as-is.
169 pub const CREDIT_CARD_NAME: &str = "creditCardName";
170
171 /// The input field expects a credit card number.
172 ///
173 /// This hint will be translated to the below values on different platforms:
174 ///
175 /// * Android: [AUTOFILL_HINT_CREDIT_CARD_NUMBER](https://developer.android.com/reference/androidx/autofill/HintConstants#AUTOFILL_HINT_CREDIT_CARD_NUMBER).
176 /// * iOS: [creditCardNumber](https://developer.apple.com/documentation/uikit/uitextcontenttype).
177 /// * web: ["cc-number"](https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#autofilling-form-controls:-the-autocomplete-attribute).
178 /// * Otherwise, the hint string will be used as-is.
179 pub const CREDIT_CARD_NUMBER: &str = "creditCardNumber";
180
181 /// The input field expects a credit card security code.
182 ///
183 /// This hint will be translated to the below values on different platforms:
184 ///
185 /// * Android: [AUTOFILL_HINT_CREDIT_CARD_SECURITY_CODE](https://developer.android.com/reference/androidx/autofill/HintConstants#AUTOFILL_HINT_CREDIT_CARD_SECURITY_CODE).
186 /// * web: ["cc-csc"](https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#autofilling-form-controls:-the-autocomplete-attribute).
187 /// * Otherwise, the hint string will be used as-is.
188 pub const CREDIT_CARD_SECURITY_CODE: &str = "creditCardSecurityCode";
189
190 /// The input field expects the type of a credit card, for example "Visa".
191 ///
192 /// This hint will be translated to the below values on different platforms:
193 ///
194 /// * web: ["cc-type"](https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#autofilling-form-controls:-the-autocomplete-attribute).
195 /// * Otherwise, the hint string will be used as-is.
196 pub const CREDIT_CARD_TYPE: &str = "creditCardType";
197
198 /// The input field expects an email address.
199 ///
200 /// This hint will be translated to the below values on different platforms:
201 ///
202 /// * Android: [AUTOFILL_HINT_EMAIL_ADDRESS](https://developer.android.com/reference/androidx/autofill/HintConstants#AUTOFILL_HINT_EMAIL_ADDRESS).
203 /// * iOS: [emailAddress](https://developer.apple.com/documentation/uikit/uitextcontenttype).
204 /// * web: ["email"](https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#autofilling-form-controls:-the-autocomplete-attribute).
205 /// * Otherwise, the hint string will be used as-is.
206 pub const EMAIL: &str = "email";
207
208 /// The input field expects a person's last/family name.
209 ///
210 /// This hint will be translated to the below values on different platforms:
211 ///
212 /// * Android: [AUTOFILL_HINT_PERSON_NAME_FAMILY](https://developer.android.com/reference/androidx/autofill/HintConstants#AUTOFILL_HINT_PERSON_NAME_FAMILY).
213 /// * iOS: [familyName](https://developer.apple.com/documentation/uikit/uitextcontenttype).
214 /// * web: ["family-name"](https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#autofilling-form-controls:-the-autocomplete-attribute).
215 /// * Otherwise, the hint string will be used as-is.
216 pub const FAMILY_NAME: &str = "familyName";
217
218 /// The input field expects a street address that fully identifies a location.
219 ///
220 /// This hint will be translated to the below values on different platforms:
221 ///
222 /// * Android: [AUTOFILL_HINT_POSTAL_ADDRESS_STREET_ADDRESS](https://developer.android.com/reference/androidx/autofill/HintConstants#AUTOFILL_HINT_POSTAL_ADDRESS_STREET_ADDRESS).
223 /// * iOS: [fullStreetAddress](https://developer.apple.com/documentation/uikit/uitextcontenttype).
224 /// * web: ["street-address"](https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#autofilling-form-controls:-the-autocomplete-attribute).
225 /// * Otherwise, the hint string will be used as-is.
226 pub const FULL_STREET_ADDRESS: &str = "fullStreetAddress";
227
228 /// The input field expects a gender.
229 ///
230 /// This hint will be translated to the below values on different platforms:
231 ///
232 /// * Android: [AUTOFILL_HINT_GENDER](https://developer.android.com/reference/androidx/autofill/HintConstants#AUTOFILL_HINT_GENDER).
233 /// * web: ["sex"](https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#autofilling-form-controls:-the-autocomplete-attribute).
234 /// * Otherwise, the hint string will be used as-is.
235 pub const GENDER: &str = "gender";
236
237 /// The input field expects a person's first/given name.
238 ///
239 /// This hint will be translated to the below values on different platforms:
240 ///
241 /// * Android: [AUTOFILL_HINT_PERSON_NAME_GIVEN](https://developer.android.com/reference/androidx/autofill/HintConstants#AUTOFILL_HINT_PERSON_NAME_GIVEN).
242 /// * iOS: [givenName](https://developer.apple.com/documentation/uikit/uitextcontenttype).
243 /// * web: ["given-name"](https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#autofilling-form-controls:-the-autocomplete-attribute).
244 /// * Otherwise, the hint string will be used as-is.
245 pub const GIVEN_NAME: &str = "givenName";
246
247 /// The input field expects a URL representing an instant messaging protocol
248 /// endpoint.
249 ///
250 /// This hint will be translated to the below values on different platforms:
251 ///
252 /// * web: ["impp"](https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#autofilling-form-controls:-the-autocomplete-attribute).
253 /// * Otherwise, the hint string will be used as-is.
254 pub const IMPP: &str = "impp";
255
256 /// The input field expects a job title.
257 ///
258 /// This hint will be translated to the below values on different platforms:
259 ///
260 /// * iOS: [jobTitle](https://developer.apple.com/documentation/uikit/uitextcontenttype).
261 /// * web: ["organization-title"](https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#autofilling-form-controls:-the-autocomplete-attribute).
262 /// * Otherwise, the hint string will be used as-is.
263 pub const JOB_TITLE: &str = "jobTitle";
264
265 /// The input field expects the preferred language of the user.
266 ///
267 /// This hint will be translated to the below values on different platforms:
268 ///
269 /// * web: ["language"](https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#autofilling-form-controls:-the-autocomplete-attribute).
270 /// * Otherwise, the hint string will be used as-is.
271 pub const LANGUAGE: &str = "language";
272
273 /// The input field expects a location, such as a point of interest, an
274 /// address,or another way to identify a location.
275 ///
276 /// This hint will be translated to the below values on different platforms:
277 ///
278 /// * iOS: [location](https://developer.apple.com/documentation/uikit/uitextcontenttype).
279 /// * Otherwise, the hint string will be used as-is.
280 pub const LOCATION: &str = "location";
281
282 /// The input field expects a person's middle initial.
283 ///
284 /// This hint will be translated to the below values on different platforms:
285 ///
286 /// * Android: [AUTOFILL_HINT_PERSON_NAME_MIDDLE_INITIAL](https://developer.android.com/reference/androidx/autofill/HintConstants#AUTOFILL_HINT_PERSON_NAME_MIDDLE_INITIAL).
287 /// * Otherwise, the hint string will be used as-is.
288 pub const MIDDLE_INITIAL: &str = "middleInitial";
289
290 /// The input field expects a person's middle name.
291 ///
292 /// This hint will be translated to the below values on different platforms:
293 ///
294 /// * Android: [AUTOFILL_HINT_PERSON_NAME_MIDDLE](https://developer.android.com/reference/androidx/autofill/HintConstants#AUTOFILL_HINT_PERSON_NAME_MIDDLE).
295 /// * iOS: [middleName](https://developer.apple.com/documentation/uikit/uitextcontenttype).
296 /// * web: ["additional-name"](https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#autofilling-form-controls:-the-autocomplete-attribute).
297 /// * Otherwise, the hint string will be used as-is.
298 pub const MIDDLE_NAME: &str = "middleName";
299
300 /// The input field expects a person's full name.
301 ///
302 /// This hint will be translated to the below values on different platforms:
303 ///
304 /// * Android: [AUTOFILL_HINT_PERSON_NAME](https://developer.android.com/reference/androidx/autofill/HintConstants#AUTOFILL_HINT_PERSON_NAME).
305 /// * iOS: [name](https://developer.apple.com/documentation/uikit/uitextcontenttype).
306 /// * web: ["name"](https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#autofilling-form-controls:-the-autocomplete-attribute).
307 /// * Otherwise, the hint string will be used as-is.
308 pub const NAME: &str = "name";
309
310 /// The input field expects a person's name prefix or title, such as "Dr.".
311 ///
312 /// This hint will be translated to the below values on different platforms:
313 ///
314 /// * Android: [AUTOFILL_HINT_PERSON_NAME_PREFIX](https://developer.android.com/reference/androidx/autofill/HintConstants#AUTOFILL_HINT_PERSON_NAME_PREFIX).
315 /// * iOS: [namePrefix](https://developer.apple.com/documentation/uikit/uitextcontenttype).
316 /// * web: ["honorific-prefix"](https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#autofilling-form-controls:-the-autocomplete-attribute).
317 /// * Otherwise, the hint string will be used as-is.
318 pub const NAME_PREFIX: &str = "namePrefix";
319
320 /// The input field expects a person's name suffix, such as "Jr.".
321 ///
322 /// This hint will be translated to the below values on different platforms:
323 ///
324 /// * Android: [AUTOFILL_HINT_PERSON_NAME_SUFFIX](https://developer.android.com/reference/androidx/autofill/HintConstants#AUTOFILL_HINT_PERSON_NAME_SUFFIX).
325 /// * iOS: [nameSuffix](https://developer.apple.com/documentation/uikit/uitextcontenttype).
326 /// * web: ["honorific-suffix"](https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#autofilling-form-controls:-the-autocomplete-attribute).
327 /// * Otherwise, the hint string will be used as-is.
328 pub const NAME_SUFFIX: &str = "nameSuffix";
329
330 /// The input field expects a newly created password for save/update.
331 ///
332 /// This hint will be translated to the below values on different platforms:
333 ///
334 /// * Android: [AUTOFILL_HINT_NEW_PASSWORD](https://developer.android.com/reference/androidx/autofill/HintConstants#AUTOFILL_HINT_NEW_PASSWORD).
335 /// * iOS: [newPassword](https://developer.apple.com/documentation/uikit/uitextcontenttype).
336 /// * web: ["new-password"](https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#autofilling-form-controls:-the-autocomplete-attribute).
337 /// * Otherwise, the hint string will be used as-is.
338 pub const NEW_PASSWORD: &str = "newPassword";
339
340 /// The input field expects a newly created username for save/update.
341 ///
342 /// This hint will be translated to the below values on different platforms:
343 ///
344 /// * Android: [AUTOFILL_HINT_NEW_USERNAME](https://developer.android.com/reference/androidx/autofill/HintConstants#AUTOFILL_HINT_NEW_USERNAME).
345 /// * Otherwise, the hint string will be used as-is.
346 pub const NEW_USERNAME: &str = "newUsername";
347
348 /// The input field expects a nickname.
349 ///
350 /// This hint will be translated to the below values on different platforms:
351 ///
352 /// * iOS: [nickname](https://developer.apple.com/documentation/uikit/uitextcontenttype).
353 /// * web: ["nickname"](https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#autofilling-form-controls:-the-autocomplete-attribute).
354 /// * Otherwise, the hint string will be used as-is.
355 pub const NICKNAME: &str = "nickname";
356
357 /// The input field expects a SMS one-time code.
358 ///
359 /// This hint will be translated to the below values on different platforms:
360 ///
361 /// * Android: [AUTOFILL_HINT_SMS_OTP](https://developer.android.com/reference/androidx/autofill/HintConstants#AUTOFILL_HINT_SMS_OTP).
362 /// * iOS: [oneTimeCode](https://developer.apple.com/documentation/uikit/uitextcontenttype).
363 /// * web: ["one-time-code"](https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#autofilling-form-controls:-the-autocomplete-attribute).
364 /// * Otherwise, the hint string will be used as-is.
365 pub const ONE_TIME_CODE: &str = "oneTimeCode";
366
367 /// The input field expects an email one-time code.
368 ///
369 /// This hint will be translated to the below values on different platforms:
370 ///
371 /// * Android: [AUTOFILL_HINT_EMAIL_OTP](https://developer.android.com/reference/androidx/autofill/HintConstants#AUTOFILL_HINT_EMAIL_OTP).
372 /// * Otherwise, the hint string will be used as-is.
373 pub const EMAIL_OTP_CODE: &str = "emailOTPCode";
374
375 /// The input field expects an organization name corresponding to the person,
376 /// address, or contact information in the other fields associated with this
377 /// field.
378 ///
379 /// This hint will be translated to the below values on different platforms:
380 ///
381 /// * iOS: [organizationName](https://developer.apple.com/documentation/uikit/uitextcontenttype).
382 /// * web: ["organization"](https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#autofilling-form-controls:-the-autocomplete-attribute).
383 /// * Otherwise, the hint string will be used as-is.
384 pub const ORGANIZATION_NAME: &str = "organizationName";
385
386 /// The input field expects a password.
387 ///
388 /// This hint will be translated to the below values on different platforms:
389 ///
390 /// * Android: [AUTOFILL_HINT_PASSWORD](https://developer.android.com/reference/androidx/autofill/HintConstants#AUTOFILL_HINT_PASSWORD).
391 /// * iOS: [password](https://developer.apple.com/documentation/uikit/uitextcontenttype).
392 /// * web: ["current-password"](https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#autofilling-form-controls:-the-autocomplete-attribute).
393 /// * Otherwise, the hint string will be used as-is.
394 pub const PASSWORD: &str = "password";
395
396 /// The input field expects a photograph, icon, or other image corresponding
397 /// to the company, person, address, or contact information in the other
398 /// fields associated with this field.
399 ///
400 /// This hint will be translated to the below values on different platforms:
401 ///
402 /// * web: ["photo"](https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#autofilling-form-controls:-the-autocomplete-attribute).
403 /// * Otherwise, the hint string will be used as-is.
404 pub const PHOTO: &str = "photo";
405
406 /// The input field expects a postal address.
407 ///
408 /// This hint will be translated to the below values on different platforms:
409 ///
410 /// * Android: [AUTOFILL_HINT_POSTAL_ADDRESS](https://developer.android.com/reference/androidx/autofill/HintConstants#AUTOFILL_HINT_POSTAL_ADDRESS).
411 /// * Otherwise, the hint string will be used as-is.
412 pub const POSTAL_ADDRESS: &str = "postalAddress";
413
414 /// The input field expects an auxiliary address details.
415 ///
416 /// This hint will be translated to the below values on different platforms:
417 ///
418 /// * Android: [AUTOFILL_HINT_POSTAL_ADDRESS_EXTENDED_ADDRESS](https://developer.android.com/reference/androidx/autofill/HintConstants#AUTOFILL_HINT_POSTAL_ADDRESS_EXTENDED_ADDRESS).
419 /// * Otherwise, the hint string will be used as-is.
420 pub const POSTAL_ADDRESS_EXTENDED: &str = "postalAddressExtended";
421
422 /// The input field expects an extended ZIP/POSTAL code.
423 ///
424 /// This hint will be translated to the below values on different platforms:
425 ///
426 /// * Android: [AUTOFILL_HINT_POSTAL_ADDRESS_EXTENDED_POSTAL_CODE](https://developer.android.com/reference/androidx/autofill/HintConstants#AUTOFILL_HINT_POSTAL_ADDRESS_EXTENDED_POSTAL_CODE).
427 /// * Otherwise, the hint string will be used as-is.
428 pub const POSTAL_ADDRESS_EXTENDED_POSTAL_CODE: &str = "postalAddressExtendedPostalCode";
429
430 /// The input field expects a postal code.
431 ///
432 /// This hint will be translated to the below values on different platforms:
433 ///
434 /// * Android: [AUTOFILL_HINT_POSTAL_CODE](https://developer.android.com/reference/androidx/autofill/HintConstants#AUTOFILL_HINT_POSTAL_CODE).
435 /// * iOS: [postalCode](https://developer.apple.com/documentation/uikit/uitextcontenttype).
436 /// * web: ["postal-code"](https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#autofilling-form-controls:-the-autocomplete-attribute).
437 /// * Otherwise, the hint string will be used as-is.
438 pub const POSTAL_CODE: &str = "postalCode";
439
440 /// The first administrative level in the address. This is typically the
441 /// province in which the address is located. In the United States, this would
442 /// be the state. In Switzerland, the canton. In the United Kingdom, the post
443 /// town.
444 ///
445 /// This hint will be translated to the below values on different platforms:
446 ///
447 /// * web: ["address-level1"](https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#autofilling-form-controls:-the-autocomplete-attribute).
448 /// * Otherwise, the hint string will be used as-is.
449 pub const STREET_ADDRESS_LEVEL1: &str = "streetAddressLevel1";
450
451 /// The second administrative level, in addresses with at least two of them.
452 /// In countries with two administrative levels, this would typically be the
453 /// city, town, village, or other locality in which the address is located.
454 ///
455 /// This hint will be translated to the below values on different platforms:
456 ///
457 /// * web: ["address-level2"](https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#autofilling-form-controls:-the-autocomplete-attribute).
458 /// * Otherwise, the hint string will be used as-is.
459 pub const STREET_ADDRESS_LEVEL2: &str = "streetAddressLevel2";
460
461 /// The third administrative level, in addresses with at least three
462 /// administrative levels.
463 ///
464 /// This hint will be translated to the below values on different platforms:
465 ///
466 /// * web: ["address-level3"](https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#autofilling-form-controls:-the-autocomplete-attribute).
467 /// * Otherwise, the hint string will be used as-is.
468 pub const STREET_ADDRESS_LEVEL3: &str = "streetAddressLevel3";
469
470 /// The finest-grained administrative level, in addresses which have four
471 /// levels.
472 ///
473 /// This hint will be translated to the below values on different platforms:
474 ///
475 /// * web: ["address-level4"](https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#autofilling-form-controls:-the-autocomplete-attribute).
476 /// * Otherwise, the hint string will be used as-is.
477 pub const STREET_ADDRESS_LEVEL4: &str = "streetAddressLevel4";
478
479 /// The input field expects the first line of a street address.
480 ///
481 /// This hint will be translated to the below values on different platforms:
482 ///
483 /// * iOS: [streetAddressLine1](https://developer.apple.com/documentation/uikit/uitextcontenttype).
484 /// * web: ["address-line1"](https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#autofilling-form-controls:-the-autocomplete-attribute).
485 /// * Otherwise, the hint string will be used as-is.
486 pub const STREET_ADDRESS_LINE1: &str = "streetAddressLine1";
487
488 /// The input field expects the second line of a street address.
489 ///
490 /// This hint will be translated to the below values on different platforms:
491 ///
492 /// * iOS: [streetAddressLine2](https://developer.apple.com/documentation/uikit/uitextcontenttype).
493 /// As of iOS 14.2 this hint does not trigger autofill.
494 /// * web: ["address-line2"](https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#autofilling-form-controls:-the-autocomplete-attribute).
495 /// * Otherwise, the hint string will be used as-is.
496 pub const STREET_ADDRESS_LINE2: &str = "streetAddressLine2";
497
498 /// The input field expects the third line of a street address.
499 ///
500 /// This hint will be translated to the below values on different platforms:
501 ///
502 /// * web: ["address-line3"](https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#autofilling-form-controls:-the-autocomplete-attribute).
503 /// * Otherwise, the hint string will be used as-is.
504 pub const STREET_ADDRESS_LINE3: &str = "streetAddressLine3";
505
506 /// The input field expects a sublocality.
507 ///
508 /// This hint will be translated to the below values on different platforms:
509 ///
510 /// * iOS: [sublocality](https://developer.apple.com/documentation/uikit/uitextcontenttype).
511 /// * Otherwise, the hint string will be used as-is.
512 pub const SUBLOCALITY: &str = "sublocality";
513
514 /// The input field expects a telephone number.
515 ///
516 /// This hint will be translated to the below values on different platforms:
517 ///
518 /// * Android: [AUTOFILL_HINT_PHONE_NUMBER](https://developer.android.com/reference/androidx/autofill/HintConstants#AUTOFILL_HINT_PHONE_NUMBER).
519 /// * iOS: [telephoneNumber](https://developer.apple.com/documentation/uikit/uitextcontenttype).
520 /// * web: ["tel"](https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#autofilling-form-controls:-the-autocomplete-attribute).
521 /// * Otherwise, the hint string will be used as-is.
522 pub const TELEPHONE_NUMBER: &str = "telephoneNumber";
523
524 /// The input field expects a phone number's area code, with a country
525 /// -internal prefix applied if applicable.
526 ///
527 /// This hint will be translated to the below values on different platforms:
528 ///
529 /// * web: ["tel-area-code"](https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#autofilling-form-controls:-the-autocomplete-attribute).
530 /// * Otherwise, the hint string will be used as-is.
531 pub const TELEPHONE_NUMBER_AREA_CODE: &str = "telephoneNumberAreaCode";
532
533 /// The input field expects a phone number's country code.
534 ///
535 /// This hint will be translated to the below values on different platforms:
536 ///
537 /// * Android: [AUTOFILL_HINT_PHONE_COUNTRY_CODE](https://developer.android.com/reference/androidx/autofill/HintConstants#AUTOFILL_HINT_PHONE_COUNTRY_CODE).
538 /// * web: ["tel-country-code"](https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#autofilling-form-controls:-the-autocomplete-attribute).
539 /// * Otherwise, the hint string will be used as-is.
540 pub const TELEPHONE_NUMBER_COUNTRY_CODE: &str = "telephoneNumberCountryCode";
541
542 /// The input field expects the current device's phone number, usually for
543 /// Sign Up / OTP flows.
544 ///
545 /// This hint will be translated to the below values on different platforms:
546 ///
547 /// * Android: [AUTOFILL_HINT_PHONE_NUMBER_DEVICE](https://developer.android.com/reference/androidx/autofill/HintConstants#AUTOFILL_HINT_PHONE_NUMBER_DEVICE).
548 /// * Otherwise, the hint string will be used as-is.
549 pub const TELEPHONE_NUMBER_DEVICE: &str = "telephoneNumberDevice";
550
551 /// The input field expects a phone number's internal extension code.
552 ///
553 /// This hint will be translated to the below values on different platforms:
554 ///
555 /// * web: ["tel-extension"](https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#autofilling-form-controls:-the-autocomplete-attribute).
556 /// * Otherwise, the hint string will be used as-is.
557 pub const TELEPHONE_NUMBER_EXTENSION: &str = "telephoneNumberExtension";
558
559 /// The input field expects a phone number without the country code and area
560 /// code components.
561 ///
562 /// This hint will be translated to the below values on different platforms:
563 ///
564 /// * web: ["tel-local"](https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#autofilling-form-controls:-the-autocomplete-attribute).
565 /// * Otherwise, the hint string will be used as-is.
566 pub const TELEPHONE_NUMBER_LOCAL: &str = "telephoneNumberLocal";
567
568 /// The input field expects the first part of the component of the telephone
569 /// number that follows the area code, when that component is split into two
570 /// components.
571 ///
572 /// This hint will be translated to the below values on different platforms:
573 ///
574 /// * web: ["tel-local-prefix"](https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#autofilling-form-controls:-the-autocomplete-attribute).
575 /// * Otherwise, the hint string will be used as-is.
576 pub const TELEPHONE_NUMBER_LOCAL_PREFIX: &str = "telephoneNumberLocalPrefix";
577
578 /// The input field expects the second part of the component of the telephone
579 /// number that follows the area code, when that component is split into two
580 /// components.
581 ///
582 /// This hint will be translated to the below values on different platforms:
583 ///
584 /// * web: ["tel-local-suffix"](https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#autofilling-form-controls:-the-autocomplete-attribute).
585 /// * Otherwise, the hint string will be used as-is.
586 pub const TELEPHONE_NUMBER_LOCAL_SUFFIX: &str = "telephoneNumberLocalSuffix";
587
588 /// The input field expects a phone number without country code.
589 ///
590 /// This hint will be translated to the below values on different platforms:
591 ///
592 /// * Android: [AUTOFILL_HINT_PHONE_NATIONAL](https://developer.android.com/reference/androidx/autofill/HintConstants#AUTOFILL_HINT_PHONE_NATIONAL).
593 /// * web: ["tel-national"](https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#autofilling-form-controls:-the-autocomplete-attribute).
594 /// * Otherwise, the hint string will be used as-is.
595 pub const TELEPHONE_NUMBER_NATIONAL: &str = "telephoneNumberNational";
596
597 /// The amount that the user would like for the transaction (e.g. when
598 /// entering a bid or sale price).
599 ///
600 /// This hint will be translated to the below values on different platforms:
601 ///
602 /// * web: ["transaction-amount"](https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#autofilling-form-controls:-the-autocomplete-attribute).
603 /// * Otherwise, the hint string will be used as-is.
604 pub const TRANSACTION_AMOUNT: &str = "transactionAmount";
605
606 /// The currency that the user would prefer the transaction to use, in [ISO
607 /// 4217 currency code](https://www.iso.org/iso-4217-currency-codes.html).
608 ///
609 /// This hint will be translated to the below values on different platforms:
610 ///
611 /// * web: ["transaction-currency"](https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#autofilling-form-controls:-the-autocomplete-attribute).
612 /// * Otherwise, the hint string will be used as-is.
613 pub const TRANSACTION_CURRENCY: &str = "transactionCurrency";
614
615 /// The input field expects a URL.
616 ///
617 /// This hint will be translated to the below values on different platforms:
618 ///
619 /// * iOS: [URL](https://developer.apple.com/documentation/uikit/uitextcontenttype).
620 /// * web: ["url"](https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#autofilling-form-controls:-the-autocomplete-attribute).
621 /// * Otherwise, the hint string will be used as-is.
622 pub const URL: &str = "url";
623
624 /// The input field expects a username or an account name.
625 ///
626 /// This hint will be translated to the below values on different platforms:
627 ///
628 /// * Android: [AUTOFILL_HINT_USERNAME](https://developer.android.com/reference/androidx/autofill/HintConstants#AUTOFILL_HINT_USERNAME).
629 /// * iOS: [username](https://developer.apple.com/documentation/uikit/uitextcontenttype).
630 /// * web: ["username"](https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#autofilling-form-controls:-the-autocomplete-attribute).
631 /// * Otherwise, the hint string will be used as-is.
632 pub const USERNAME: &str = "username";
633}
634
635/// An object that represents an autofillable input field in the autofill workflow.
636///
637/// An [`AutofillClient`] provides autofill-related information of the input field
638/// it represents to the platform, and consumes autofill inputs from the platform.
639pub trait AutofillClient: Sized + 'static {
640 /// The unique identifier of this [`AutofillClient`].
641 ///
642 /// The identifier must not be changed.
643 fn autofill_id(self: Handle<Self>, app: &App) -> String;
644
645 /// The [`TextInputConfiguration`] that describes this [`AutofillClient`].
646 ///
647 /// In order to participate in autofill, its
648 /// [`TextInputConfiguration::autofill_configuration`] must not be
649 /// [`AutofillConfiguration::DISABLED`](crate::AutofillConfiguration::DISABLED).
650 fn text_input_configuration(self: Handle<Self>, app: &App) -> TextInputConfiguration;
651
652 /// Requests this [`AutofillClient`] update its [`TextEditingValue`] to the given
653 /// value.
654 fn autofill(self: Handle<Self>, app: &mut App, new_editing_value: TextEditingValue);
655
656 /// This client as the erased [`AnyAutofillClient`].
657 fn as_autofill_client(self: Handle<Self>) -> AnyAutofillClient {
658 AnyAutofillClient {
659 id: self.id(),
660 vtable: const { &AutofillClientVTable::of::<Self>() },
661 }
662 }
663}
664
665struct AutofillClientVTable {
666 autofill_id: fn(&App, HandleId) -> String,
667 text_input_configuration: fn(&App, HandleId) -> TextInputConfiguration,
668 autofill: fn(&mut App, HandleId, TextEditingValue),
669}
670
671fn resolve<T: 'static>(id: HandleId) -> Handle<T> {
672 Handle::from_id(id)
673}
674
675impl AutofillClientVTable {
676 const fn of<C: AutofillClient>() -> AutofillClientVTable {
677 AutofillClientVTable {
678 autofill_id: |app, id| C::autofill_id(resolve(id), app),
679 text_input_configuration: |app, id| C::text_input_configuration(resolve(id), app),
680 autofill: |app, id, value| C::autofill(resolve(id), app, value),
681 }
682 }
683}
684
685/// Erased [`AutofillClient`]: one identity and a static vtable.
686#[derive(Clone, Copy)]
687pub struct AnyAutofillClient {
688 id: HandleId,
689 vtable: &'static AutofillClientVTable,
690}
691
692impl AnyAutofillClient {
693 pub fn autofill_id(self, app: &App) -> String {
694 (self.vtable.autofill_id)(app, self.id)
695 }
696
697 pub fn text_input_configuration(self, app: &App) -> TextInputConfiguration {
698 (self.vtable.text_input_configuration)(app, self.id)
699 }
700
701 pub fn autofill(self, app: &mut App, new_editing_value: TextEditingValue) {
702 (self.vtable.autofill)(app, self.id, new_editing_value);
703 }
704}
705
706impl PartialEq for AnyAutofillClient {
707 fn eq(&self, other: &AnyAutofillClient) -> bool {
708 self.id == other.id
709 }
710}
711
712impl Eq for AnyAutofillClient {}
713
714/// An ordered group within which [`AutofillClient`]s are logically connected.
715///
716/// [`AutofillClient`]s within the same [`AutofillScope`] are isolated from other
717/// input fields during autofill. That is, when an autofillable `TextInputClient`
718/// gains focus, only the [`AutofillClient`]s within the same [`AutofillScope`] will
719/// be visible to the autofill service, in the same order as they appear in
720/// [`AutofillScope::autofill_clients`].
721///
722/// [`AutofillScope`] also allows `TextInput` to redirect autofill values from the
723/// platform to the [`AutofillClient`] with the given identifier, by calling
724/// [`AutofillScope::get_autofill_client`].
725///
726/// An [`AutofillClient`] that's not tied to any [`AutofillScope`] will only
727/// participate in autofill if the autofill is directly triggered by its own
728/// `TextInputClient`.
729pub trait AutofillScope: Sized + 'static {
730 /// Gets the [`AutofillClient`] associated with the given `autofill_id`, in
731 /// this [`AutofillScope`].
732 ///
733 /// Returns [`None`] if there's no matching [`AutofillClient`].
734 fn get_autofill_client(
735 self: Handle<Self>,
736 app: &App,
737 autofill_id: &str,
738 ) -> Option<AnyAutofillClient>;
739
740 /// The collection of [`AutofillClient`]s currently tied to this [`AutofillScope`].
741 ///
742 /// Every [`AutofillClient`] in this list must have autofill enabled (i.e. its
743 /// [`AutofillClient::text_input_configuration`] must have a non-disabled
744 /// [`crate::AutofillConfiguration`].)
745 fn autofill_clients(self: Handle<Self>, app: &App) -> Vec<AnyAutofillClient>;
746
747 /// Allows a `TextInputClient` to attach to this scope. This method should be
748 /// called in lieu of [`TextInput::attach`], when the `TextInputClient` wishes to
749 /// participate in autofill.
750 ///
751 /// Flutter `AutofillScopeMixin.attach`.
752 fn attach(
753 self: Handle<Self>,
754 app: &mut App,
755 trigger: AnyTextInputClient,
756 configuration: TextInputConfiguration,
757 ) -> Handle<TextInputConnection> {
758 debug_assert!(
759 !self.autofill_clients(app).iter().any(|client| {
760 !client
761 .text_input_configuration(app)
762 .autofill_configuration
763 .enabled
764 }),
765 "Every client in AutofillScope.autofillClients must enable autofill"
766 );
767 TextInput::attach(app, trigger, configuration)
768 }
769}
770
771/// A partial implementation of [`AutofillScope`].
772///
773/// The mixin provides a default implementation for [`AutofillScope::attach`].
774pub trait AutofillScopeMixin: AutofillScope {}
775
776impl<T: AutofillScope> AutofillScopeMixin for T {}
777
778#[cfg(test)]
779mod tests {
780 use inset_foundation::AppCell;
781
782 use super::*;
783 use crate::text_input::TextInputClient;
784
785 #[test]
786 fn hint_strings_match_dart() {
787 assert_eq!(AutofillHints::EMAIL, "email");
788 assert_eq!(AutofillHints::ONE_TIME_CODE, "oneTimeCode");
789 assert_eq!(AutofillHints::EMAIL_OTP_CODE, "emailOTPCode");
790 }
791
792 #[derive(Default)]
793 struct RecordingField {
794 autofill_id: String,
795 value: TextEditingValue,
796 filled: Option<TextEditingValue>,
797 }
798
799 impl AutofillClient for RecordingField {
800 fn autofill_id(self: Handle<Self>, app: &App) -> String {
801 app.get(self).autofill_id.clone()
802 }
803
804 fn text_input_configuration(self: Handle<Self>, app: &App) -> TextInputConfiguration {
805 TextInputConfiguration::builder()
806 .autofill_configuration(crate::AutofillConfiguration::new(
807 app.get(self).autofill_id.clone(),
808 vec![AutofillHints::EMAIL.to_owned()],
809 app.get(self).value.clone(),
810 ))
811 .build()
812 }
813
814 fn autofill(self: Handle<Self>, app: &mut App, new_editing_value: TextEditingValue) {
815 app.get_mut(self).filled = Some(new_editing_value);
816 }
817 }
818
819 impl TextInputClient for RecordingField {
820 fn current_text_editing_value(self: Handle<Self>, app: &App) -> Option<TextEditingValue> {
821 Some(app.get(self).value.clone())
822 }
823
824 fn update_editing_value(self: Handle<Self>, app: &mut App, value: TextEditingValue) {
825 app.get_mut(self).value = value;
826 }
827
828 fn perform_action(self: Handle<Self>, _app: &mut App, _action: crate::TextInputAction) {}
829
830 fn connection_closed(self: Handle<Self>, _app: &mut App) {}
831 }
832
833 struct RecordingScope {
834 clients: Vec<AnyAutofillClient>,
835 }
836
837 impl AutofillScope for RecordingScope {
838 fn get_autofill_client(
839 self: Handle<Self>,
840 app: &App,
841 autofill_id: &str,
842 ) -> Option<AnyAutofillClient> {
843 self.autofill_clients(app)
844 .into_iter()
845 .find(|client| client.autofill_id(app) == autofill_id)
846 }
847
848 fn autofill_clients(self: Handle<Self>, app: &App) -> Vec<AnyAutofillClient> {
849 app.get(self).clients.clone()
850 }
851 }
852
853 #[test]
854 fn scope_attach_uses_text_input_attach() {
855 let cell = AppCell::new();
856 let mut app = cell.borrow_mut();
857 let field = app.create(RecordingField {
858 autofill_id: "email".into(),
859 ..RecordingField::default()
860 });
861 let scope = app.create(RecordingScope {
862 clients: vec![field.as_autofill_client()],
863 });
864 let configuration = field.text_input_configuration(&app);
865 let connection = scope.attach(&mut app, field.as_text_input_client(), configuration);
866 assert!(connection.attached(&mut app));
867 assert_eq!(
868 scope
869 .get_autofill_client(&app, "email")
870 .map(|c| c.autofill_id(&app)),
871 Some("email".into())
872 );
873 field
874 .as_autofill_client()
875 .autofill(&mut app, TextEditingValue::new().text("user@example.com"));
876 assert_eq!(
877 app.get(field).filled.as_ref().map(|v| v.text.as_str()),
878 Some("user@example.com")
879 );
880 }
881}