OLD | NEW |
---|---|
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/autofill/select_control_handler.h" | 5 #include "chrome/browser/autofill/select_control_handler.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 | 8 |
9 #include "base/basictypes.h" | 9 #include "base/basictypes.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
11 #include "base/string_number_conversions.h" | 11 #include "base/string_number_conversions.h" |
12 #include "base/string16.h" | 12 #include "base/string16.h" |
13 #include "base/utf_string_conversions.h" | 13 #include "base/utf_string_conversions.h" |
14 #include "chrome/browser/autofill/autofill_country.h" | |
15 #include "chrome/browser/autofill/autofill_profile.h" | |
14 #include "chrome/browser/autofill/form_group.h" | 16 #include "chrome/browser/autofill/form_group.h" |
15 #include "webkit/glue/form_field.h" | 17 #include "webkit/glue/form_field.h" |
16 | 18 |
17 namespace { | 19 namespace { |
18 | 20 |
19 // TODO(jhawkins): Add more states/provinces. See http://crbug.com/45039. | 21 // TODO(jhawkins): Add more states/provinces. See http://crbug.com/45039. |
20 | 22 |
21 class State { | 23 class State { |
22 public: | 24 public: |
23 const char* name; | 25 const char* name; |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
92 return string16(); | 94 return string16(); |
93 } | 95 } |
94 | 96 |
95 string16 State::FullName(const string16& abbreviation) { | 97 string16 State::FullName(const string16& abbreviation) { |
96 for (const State *s = all_states ; s->name ; ++s) | 98 for (const State *s = all_states ; s->name ; ++s) |
97 if (LowerCaseEqualsASCII(abbreviation, s->abbreviation)) | 99 if (LowerCaseEqualsASCII(abbreviation, s->abbreviation)) |
98 return ASCIIToUTF16(s->name); | 100 return ASCIIToUTF16(s->name); |
99 return string16(); | 101 return string16(); |
100 } | 102 } |
101 | 103 |
102 // Holds valid country names, their 2 letter abbreviation, and maps from | |
103 // the former to the latter | |
104 class Country { | |
105 public: | |
106 const char* name; | |
107 const char* abbreviation; | |
108 | |
109 static const Country all_countries[]; | |
110 | |
111 static string16 Abbreviation(const string16 &name); | |
112 static string16 FullName(const string16& abbreviation); | |
113 }; | |
114 | |
115 // A list of all English country names and code elements. ISO 3166. | |
116 const Country Country::all_countries[] = { | |
117 { "united states", "us" }, | |
118 { "afghanistan", "af" }, | |
119 { "aland islands", "ax" }, | |
120 { "albania", "al" }, | |
121 { "algeria", "dz" }, | |
122 { "american samoa", "as" }, | |
123 { "andorra", "ad" }, | |
124 { "angola", "ao" }, | |
125 { "anguilla", "ai" }, | |
126 { "antarctica", "aq" }, | |
127 { "antigua and barbuda", "ag" }, | |
128 { "argentina", "ar" }, | |
129 { "armenia", "am" }, | |
130 { "aruba", "aw" }, | |
131 { "australia", "au" }, | |
132 { "austria", "at" }, | |
133 { "azerbaijan", "az" }, | |
134 { "bahamas", "bs" }, | |
135 { "bahrain", "bh" }, | |
136 { "bangladesh", "bd" }, | |
137 { "barbados", "bb" }, | |
138 { "belarus", "by" }, | |
139 { "belgium", "be" }, | |
140 { "belize", "bz" }, | |
141 { "benin", "bj" }, | |
142 { "bermuda", "bm" }, | |
143 { "bhutan", "bt" }, | |
144 { "bolivia", "bo" }, | |
145 { "bosnia and herzegovina", "ba" }, | |
146 { "botswana", "bw" }, | |
147 { "bouvet island", "bv" }, | |
148 { "brazil", "br" }, | |
149 { "british indian ocean territory", "io" }, | |
150 { "brunei darussalam", "bn" }, | |
151 { "bulgaria", "bg" }, | |
152 { "burkina faso", "bf" }, | |
153 { "burundi", "bi" }, | |
154 { "cambodia", "kh" }, | |
155 { "cameroon", "cm" }, | |
156 { "canada", "ca" }, | |
157 { "cape verde", "cv" }, | |
158 { "cayman islands", "ky" }, | |
159 { "central african republic", "cf" }, | |
160 { "chad", "td" }, | |
161 { "chile", "cl" }, | |
162 { "china", "cn" }, | |
163 { "christmas island", "cx" }, | |
164 { "cocos (keeling) islands", "cc" }, | |
165 { "colombia", "co" }, | |
166 { "comoros", "km" }, | |
167 { "congo", "cg" }, | |
168 { "congo (dem. rep.)", "cd" }, | |
169 { "cook islands", "ck" }, | |
170 { "costa rica", "cr" }, | |
171 { "cote d'ivoire", "ci" }, | |
172 { "croatia", "hr" }, | |
173 { "cuba", "cu" }, | |
174 { "cyprus", "cy" }, | |
175 { "czech republic", "cz" }, | |
176 { "denmark", "dk" }, | |
177 { "djibouti", "dj" }, | |
178 { "dominica", "dm" }, | |
179 { "dominican republic", "do" }, | |
180 { "ecuador", "ec" }, | |
181 { "egypt", "eg" }, | |
182 { "el salvador", "sv" }, | |
183 { "equatorial guinea", "gq" }, | |
184 { "eritrea", "er" }, | |
185 { "estonia", "ee" }, | |
186 { "ethiopia", "et" }, | |
187 { "falkland islands (malvinas)", "fk" }, | |
188 { "faroe islands", "fo" }, | |
189 { "fiji", "fj" }, | |
190 { "finland", "fi" }, | |
191 { "france", "fr" }, | |
192 { "french guiana", "gf" }, | |
193 { "french polynesia", "pf" }, | |
194 { "gabon", "ga" }, | |
195 { "gambia", "gm" }, | |
196 { "georgia", "ge" }, | |
197 { "germany", "de" }, | |
198 { "ghana", "gh" }, | |
199 { "gibraltar", "gi" }, | |
200 { "greece", "gr" }, | |
201 { "greenland", "gl" }, | |
202 { "grenada", "gd" }, | |
203 { "guadeloupe", "gp" }, | |
204 { "guam", "gu" }, | |
205 { "guatemala", "gt" }, | |
206 { "guernsey", "cg" }, | |
207 { "guinea", "gn" }, | |
208 { "guinea-bissau", "gw" }, | |
209 { "guyana", "gy" }, | |
210 { "haiti", "ht" }, | |
211 { "heard island and mcdonald islands", "hm" }, | |
212 { "holy see (vatica city state)", "va" }, | |
213 { "honduras", "hn" }, | |
214 { "hong kong", "hk" }, | |
215 { "hungary", "hu" }, | |
216 { "iceland", "is" }, | |
217 { "india", "in" }, | |
218 { "indonesia", "id" }, | |
219 { "iran", "ir" }, | |
220 { "iraq", "iq" }, | |
221 { "ireland", "ie" }, | |
222 { "isle of man", "im" }, | |
223 { "israel", "il" }, | |
224 { "italy", "it" }, | |
225 { "ivory coast", "ci" }, | |
226 { "jamaica", "jm" }, | |
227 { "japan", "jp" }, | |
228 { "jersey", "je" }, | |
229 { "jordan", "jo" }, | |
230 { "kazakhstan", "kz" }, | |
231 { "kenya", "ke" }, | |
232 { "kiribati", "ki" }, | |
233 { "korea (north)", "kp" }, | |
234 { "korea (south)", "kr" }, | |
235 { "kuwait", "kw" }, | |
236 { "kyrgyzstan", "kg" }, | |
237 { "laos", "la" }, | |
238 { "latvia", "lv" }, | |
239 { "lebanon", "lb" }, | |
240 { "lesotho", "ls" }, | |
241 { "liberia", "lr" }, | |
242 { "libya", "ly" }, | |
243 { "liechtenstein", "li" }, | |
244 { "lithuania", "lt" }, | |
245 { "luxembourg", "lu" }, | |
246 { "macao", "mo" }, | |
247 { "macedonia", "mk" }, | |
248 { "madagascar", "mg" }, | |
249 { "malawi", "mw" }, | |
250 { "malaysia", "my" }, | |
251 { "maldives", "mv" }, | |
252 { "mali", "ml" }, | |
253 { "malta", "mt" }, | |
254 { "marshall islands", "mh" }, | |
255 { "martinique", "mq" }, | |
256 { "mauritania", "mr" }, | |
257 { "mauritius", "mu" }, | |
258 { "mayotte", "yt" }, | |
259 { "mexico", "mx" }, | |
260 { "micronesia", "fm" }, | |
261 { "moldova", "md" }, | |
262 { "monaco", "mc" }, | |
263 { "mongolia", "mn" }, | |
264 { "montserrat", "ms" }, | |
265 { "morocco", "ma" }, | |
266 { "mozambique", "mz" }, | |
267 { "myanmar", "mm" }, | |
268 { "namibia", "na" }, | |
269 { "nepal", "np" }, | |
270 { "netherlands", "nl" }, | |
271 { "netherlands antilles", "an" }, | |
272 { "new caledonia", "nc" }, | |
273 { "new zealand", "nz" }, | |
274 { "nicaragua", "ni" }, | |
275 { "niger", "ne" }, | |
276 { "nigeria", "ng" }, | |
277 { "niue", "nu" }, | |
278 { "norfolk island", "nf" }, | |
279 { "northern mariana islands", "mp" }, | |
280 { "norway", "no" }, | |
281 { "oman", "om" }, | |
282 { "pakistan", "pk" }, | |
283 { "palau", "pw" }, | |
284 { "palestine", "ps" }, | |
285 { "panama", "pa" }, | |
286 { "papua new guinea", "pg" }, | |
287 { "paraguay", "py" }, | |
288 { "peru", "pe" }, | |
289 { "philippines", "ph" }, | |
290 { "pitcairn", "pn" }, | |
291 { "poland", "pl" }, | |
292 { "portugal", "pt" }, | |
293 { "puerto rico", "pr" }, | |
294 { "qatar", "qa" }, | |
295 { "reunion", "re" }, | |
296 { "romania", "ro" }, | |
297 { "russia", "ru" }, | |
298 { "rwanda", "rw" }, | |
299 { "saint helena", "sh" }, | |
300 { "saint kitts and nevis", "kn" }, | |
301 { "saint lucia", "lc" }, | |
302 { "saint pierre and miquelon", "pm" }, | |
303 { "saint vincent and the grenadines", "vc" }, | |
304 { "samoa", "ws" }, | |
305 { "san marino", "sm" }, | |
306 { "sao tome and principe", "st" }, | |
307 { "saudi arabia", "sa" }, | |
308 { "senegal", "sn" }, | |
309 { "serbia and montenegro", "cs" }, | |
310 { "seychelles", "sc" }, | |
311 { "sierra leone", "sl" }, | |
312 { "singapore", "sg" }, | |
313 { "slovakia", "sk" }, | |
314 { "slovenia", "si" }, | |
315 { "solomon islands", "sb" }, | |
316 { "somalia", "so" }, | |
317 { "south africa", "za" }, | |
318 { "south georgia and the south sandwich islands", "gs" }, | |
319 { "spain", "es" }, | |
320 { "sri lanka", "lk" }, | |
321 { "sudan", "sd" }, | |
322 { "suriname", "sr" }, | |
323 { "svalbard and jan mayen", "sj" }, | |
324 { "swaziland", "sz" }, | |
325 { "sweden", "se" }, | |
326 { "switzerland", "ch" }, | |
327 { "syria", "sy" }, | |
328 { "taiwan", "tw" }, | |
329 { "tajikistan", "tj" }, | |
330 { "tanzania", "tz" }, | |
331 { "thailand", "th" }, | |
332 { "timor-leste", "tl" }, | |
333 { "togo", "tg" }, | |
334 { "tokelau", "tk" }, | |
335 { "tonga", "to" }, | |
336 { "trinidad and tobago", "tt" }, | |
337 { "tunisia", "tn" }, | |
338 { "turkey", "tr" }, | |
339 { "turkmenistan", "tm" }, | |
340 { "turks and caicos islands", "tc" }, | |
341 { "tuvalu", "tv" }, | |
342 { "uganda", "ug" }, | |
343 { "ukraine", "ua" }, | |
344 { "united arab emirates", "ae" }, | |
345 { "united kingdom", "gb" }, | |
346 { "u.s. minor outlying islands", "um" }, | |
347 { "uruguay", "uy" }, | |
348 { "uzbekistan", "uz" }, | |
349 { "vanuatu", "vu" }, | |
350 { "venezuela", "ve" }, | |
351 { "vietnam", "vn" }, | |
352 { "virgin islands, british", "vg" }, | |
353 { "virgin islands, u.s.", "vi" }, | |
354 { "wallis and futuna", "wf" }, | |
355 { "western sahara", "eh" }, | |
356 { "yemen", "ye" }, | |
357 { "zambia", "zm" }, | |
358 { "zimbabwe", "zw" }, | |
359 { NULL, NULL } | |
360 }; | |
361 | |
362 string16 Country::Abbreviation(const string16& name) { | |
363 for (const Country *s = all_countries ; s->name ; ++s) | |
364 if (LowerCaseEqualsASCII(name, s->name)) | |
365 return ASCIIToUTF16(s->abbreviation); | |
366 return string16(); | |
367 } | |
368 | |
369 string16 Country::FullName(const string16& abbreviation) { | |
370 for (const Country *s = all_countries ; s->name ; ++s) | |
371 if (LowerCaseEqualsASCII(abbreviation, s->abbreviation)) | |
372 return ASCIIToUTF16(s->name); | |
373 return string16(); | |
374 } | |
375 | |
376 const char* const kMonthsAbbreviated[] = { | 104 const char* const kMonthsAbbreviated[] = { |
377 NULL, // Padding so index 1 = month 1 = January. | 105 NULL, // Padding so index 1 = month 1 = January. |
378 "Jan", "Feb", "Mar", "Apr", "May", "Jun", | 106 "Jan", "Feb", "Mar", "Apr", "May", "Jun", |
379 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", | 107 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", |
380 }; | 108 }; |
381 | 109 |
382 const char* const kMonthsFull[] = { | 110 const char* const kMonthsFull[] = { |
383 NULL, // Padding so index 1 = month 1 = January. | 111 NULL, // Padding so index 1 = month 1 = January. |
384 "January", "February", "March", "April", "May", "June", | 112 "January", "February", "March", "April", "May", "June", |
385 "July", "August", "September", "October", "November", "December", | 113 "July", "August", "September", "October", "November", "December", |
(...skipping 16 matching lines...) Expand all Loading... | |
402 if (value_lowercase == StringToLowerASCII(*iter)) { | 130 if (value_lowercase == StringToLowerASCII(*iter)) { |
403 field->set_value(*iter); | 131 field->set_value(*iter); |
404 return true; | 132 return true; |
405 } | 133 } |
406 } | 134 } |
407 | 135 |
408 return false; | 136 return false; |
409 } | 137 } |
410 | 138 |
411 bool FillStateSelectControl(const string16& value, | 139 bool FillStateSelectControl(const string16& value, |
412 webkit_glue::FormField* field) { | 140 webkit_glue::FormField* field) { |
dhollowa
2011/02/17 00:55:28
A DCHECK(!value.empty()) might be worthwhile here
Ilya Sherman
2011/02/17 23:09:11
Nothing will go wrong if value is empty -- it'll j
| |
413 if (value.empty()) | |
414 return false; | |
415 | |
416 string16 abbrev, full; | 141 string16 abbrev, full; |
417 if (value.size() < 4U) { | 142 if (value.size() < 4U) { |
418 abbrev = value; | 143 abbrev = value; |
419 full = State::FullName(value); | 144 full = State::FullName(value); |
420 } else { | 145 } else { |
421 abbrev = State::Abbreviation(value); | 146 abbrev = State::Abbreviation(value); |
422 full = value; | 147 full = value; |
423 } | 148 } |
424 | 149 |
425 // Try the abbreviation name first. | 150 // Try the abbreviation name first. |
426 if (!abbrev.empty() && SetSelectControlValue(abbrev, field)) | 151 if (!abbrev.empty() && SetSelectControlValue(abbrev, field)) |
427 return true; | 152 return true; |
428 | 153 |
429 if (full.empty()) | 154 if (full.empty()) |
430 return false; | 155 return false; |
431 | 156 |
432 return SetSelectControlValue(full, field); | 157 return SetSelectControlValue(full, field); |
433 } | 158 } |
434 | 159 |
435 bool FillCountrySelectControl(const string16& value, | 160 bool FillCountrySelectControl(const FormGroup& form_group, |
dhollowa
2011/02/17 00:55:28
This looks very much like |SetSelectControlValue|.
Ilya Sherman
2011/02/17 23:09:11
The caller already tries the full country string.
dhollowa
2011/02/17 23:36:47
Makes sense, ya.
On 2011/02/17 23:09:11, Ilya She
| |
436 webkit_glue::FormField* field) { | 161 webkit_glue::FormField* field) { |
437 if (value.empty()) | 162 const AutoFillProfile& profile = |
438 return false; | 163 static_cast<const AutoFillProfile&>(form_group); |
164 std::string country_code = profile.CountryCode(); | |
439 | 165 |
440 string16 abbrev, full; | 166 for (std::vector<string16>::const_iterator iter = |
441 if (value.size() < 4U) { | 167 field->option_strings().begin(); |
442 abbrev = value; | 168 iter != field->option_strings().end(); |
443 full = Country::FullName(value); | 169 ++iter) { |
444 } else { | 170 if (country_code == AutoFillCountry::GetCountryCode(*iter)) { |
445 abbrev = Country::Abbreviation(value); | 171 field->set_value(*iter); |
446 full = value; | 172 return true; |
173 } | |
447 } | 174 } |
448 | 175 |
449 // Try the abbreviation name first. | 176 return false; |
450 if (!abbrev.empty() && SetSelectControlValue(abbrev, field)) | |
451 return true; | |
452 | |
453 if (full.empty()) | |
454 return false; | |
455 | |
456 return SetSelectControlValue(full, field); | |
457 } | 177 } |
458 | 178 |
459 bool FillExpirationMonthSelectControl(const string16& value, | 179 bool FillExpirationMonthSelectControl(const string16& value, |
460 webkit_glue::FormField* field) { | 180 webkit_glue::FormField* field) { |
dhollowa
2011/02/17 00:55:28
A DCHECK(!value.empty()) might be worthwhile here
Ilya Sherman
2011/02/17 23:09:11
An empty value would just trip the "return false;"
dhollowa
2011/02/17 23:36:47
Ok.
On 2011/02/17 23:09:11, Ilya Sherman wrote:
| |
461 if (value.empty()) | |
462 return false; | |
463 | |
464 if (SetSelectControlValue(value, field)) | |
465 return true; | |
466 | |
467 int index = 0; | 181 int index = 0; |
dhollowa
2011/02/17 00:55:28
This no longer tries both the and full month strin
Ilya Sherman
2011/02/17 23:09:11
The caller already tries the full month value.
dhollowa
2011/02/17 23:36:47
Makes sense, ya.
On 2011/02/17 23:09:11, Ilya She
| |
468 if (!base::StringToInt(value, &index) || | 182 if (!base::StringToInt(value, &index) || |
469 index <= 0 || | 183 index <= 0 || |
470 static_cast<size_t>(index) >= arraysize(kMonthsFull)) | 184 static_cast<size_t>(index) >= arraysize(kMonthsFull)) |
471 return false; | 185 return false; |
472 | 186 |
473 bool filled = | 187 bool filled = |
474 SetSelectControlValue(ASCIIToUTF16(kMonthsAbbreviated[index]), field) || | 188 SetSelectControlValue(ASCIIToUTF16(kMonthsAbbreviated[index]), field) || |
475 SetSelectControlValue(ASCIIToUTF16(kMonthsFull[index]), field) || | 189 SetSelectControlValue(ASCIIToUTF16(kMonthsFull[index]), field) || |
476 SetSelectControlValue(ASCIIToUTF16(kMonthsNumeric[index]), field); | 190 SetSelectControlValue(ASCIIToUTF16(kMonthsNumeric[index]), field); |
477 return filled; | 191 return filled; |
478 } | 192 } |
479 | 193 |
480 } // namespace | 194 } // namespace |
481 | 195 |
482 namespace autofill { | 196 namespace autofill { |
483 | 197 |
484 void FillSelectControl(const FormGroup& form_group, | 198 void FillSelectControl(const FormGroup& form_group, |
485 AutoFillType type, | 199 AutoFillType type, |
486 webkit_glue::FormField* field) { | 200 webkit_glue::FormField* field) { |
487 DCHECK(field); | 201 DCHECK(field); |
488 DCHECK(field->form_control_type() == ASCIIToUTF16("select-one")); | 202 DCHECK(field->form_control_type() == ASCIIToUTF16("select-one")); |
489 | 203 |
204 string16 field_text = form_group.GetFieldText(type); | |
205 if (field_text.empty()) | |
206 return; | |
207 | |
490 string16 value; | 208 string16 value; |
491 string16 field_text = form_group.GetFieldText(type); | |
492 for (size_t i = 0; i < field->option_strings().size(); ++i) { | 209 for (size_t i = 0; i < field->option_strings().size(); ++i) { |
493 if (field_text == field->option_strings()[i]) { | 210 if (field_text == field->option_strings()[i]) { |
494 // An exact match, use it. | 211 // An exact match, use it. |
495 value = field_text; | 212 value = field_text; |
496 break; | 213 break; |
497 } | 214 } |
498 | 215 |
499 if (StringToLowerASCII(field->option_strings()[i]) == | 216 if (StringToLowerASCII(field->option_strings()[i]) == |
500 StringToLowerASCII(field_text)) { | 217 StringToLowerASCII(field_text)) { |
501 // A match, but not in the same case. Save it in case an exact match is | 218 // A match, but not in the same case. Save it in case an exact match is |
502 // not found. | 219 // not found. |
503 value = field->option_strings()[i]; | 220 value = field->option_strings()[i]; |
504 } | 221 } |
505 } | 222 } |
506 | 223 |
507 if (!value.empty()) { | 224 if (!value.empty()) { |
508 field->set_value(value); | 225 field->set_value(value); |
509 return; | 226 return; |
510 } | 227 } |
511 | 228 |
512 if (type.field_type() == ADDRESS_HOME_STATE || | 229 if (type.field_type() == ADDRESS_HOME_STATE || |
513 type.field_type() == ADDRESS_BILLING_STATE) { | 230 type.field_type() == ADDRESS_BILLING_STATE) { |
514 FillStateSelectControl(field_text, field); | 231 FillStateSelectControl(field_text, field); |
515 } else if (type.field_type() == ADDRESS_HOME_COUNTRY || | 232 } else if (type.field_type() == ADDRESS_HOME_COUNTRY || |
516 type.field_type() == ADDRESS_BILLING_COUNTRY) { | 233 type.field_type() == ADDRESS_BILLING_COUNTRY) { |
517 FillCountrySelectControl(field_text, field); | 234 FillCountrySelectControl(form_group, field); |
518 } else if (type.field_type() == CREDIT_CARD_EXP_MONTH) { | 235 } else if (type.field_type() == CREDIT_CARD_EXP_MONTH) { |
519 FillExpirationMonthSelectControl(field_text, field); | 236 FillExpirationMonthSelectControl(field_text, field); |
520 } | 237 } |
521 | 238 |
522 return; | 239 return; |
523 } | 240 } |
524 | 241 |
525 } // namespace autofill | 242 } // namespace autofill |
OLD | NEW |