Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(905)

Side by Side Diff: chrome/browser/autofill/select_control_handler.cc

Issue 6484022: Autofill i18n: Set postal code and state field labels based on the selected country. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Properly merged with ToT Created 9 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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 17 matching lines...) Expand all
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) {
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,
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();
165 std::string app_locale = AutoFillCountry::ApplicationLocale();
439 166
440 string16 abbrev, full; 167 for (std::vector<string16>::const_iterator iter =
441 if (value.size() < 4U) { 168 field->option_strings().begin();
442 abbrev = value; 169 iter != field->option_strings().end();
443 full = Country::FullName(value); 170 ++iter) {
444 } else { 171 // Canonicalize each <option> value to a country code, and compare to the
445 abbrev = Country::Abbreviation(value); 172 // target country code.
446 full = value; 173 if (country_code == AutoFillCountry::GetCountryCode(*iter, app_locale)) {
174 field->set_value(*iter);
175 return true;
176 }
447 } 177 }
448 178
449 // Try the abbreviation name first. 179 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 } 180 }
458 181
459 bool FillExpirationMonthSelectControl(const string16& value, 182 bool FillExpirationMonthSelectControl(const string16& value,
460 webkit_glue::FormField* field) { 183 webkit_glue::FormField* field) {
461 if (value.empty())
462 return false;
463
464 if (SetSelectControlValue(value, field))
465 return true;
466
467 int index = 0; 184 int index = 0;
468 if (!base::StringToInt(value, &index) || 185 if (!base::StringToInt(value, &index) ||
469 index <= 0 || 186 index <= 0 ||
470 static_cast<size_t>(index) >= arraysize(kMonthsFull)) 187 static_cast<size_t>(index) >= arraysize(kMonthsFull))
471 return false; 188 return false;
472 189
473 bool filled = 190 bool filled =
474 SetSelectControlValue(ASCIIToUTF16(kMonthsAbbreviated[index]), field) || 191 SetSelectControlValue(ASCIIToUTF16(kMonthsAbbreviated[index]), field) ||
475 SetSelectControlValue(ASCIIToUTF16(kMonthsFull[index]), field) || 192 SetSelectControlValue(ASCIIToUTF16(kMonthsFull[index]), field) ||
476 SetSelectControlValue(ASCIIToUTF16(kMonthsNumeric[index]), field); 193 SetSelectControlValue(ASCIIToUTF16(kMonthsNumeric[index]), field);
477 return filled; 194 return filled;
478 } 195 }
479 196
480 } // namespace 197 } // namespace
481 198
482 namespace autofill { 199 namespace autofill {
483 200
484 void FillSelectControl(const FormGroup& form_group, 201 void FillSelectControl(const FormGroup& form_group,
485 AutoFillType type, 202 AutoFillType type,
486 webkit_glue::FormField* field) { 203 webkit_glue::FormField* field) {
487 DCHECK(field); 204 DCHECK(field);
488 DCHECK_EQ(field->form_control_type(), ASCIIToUTF16("select-one")); 205 DCHECK_EQ(field->form_control_type(), ASCIIToUTF16("select-one"));
489 206
207 string16 field_text = form_group.GetFieldText(type);
208 if (field_text.empty())
209 return;
210
490 string16 value; 211 string16 value;
491 string16 field_text = form_group.GetFieldText(type);
492 for (size_t i = 0; i < field->option_strings().size(); ++i) { 212 for (size_t i = 0; i < field->option_strings().size(); ++i) {
493 if (field_text == field->option_strings()[i]) { 213 if (field_text == field->option_strings()[i]) {
494 // An exact match, use it. 214 // An exact match, use it.
495 value = field_text; 215 value = field_text;
496 break; 216 break;
497 } 217 }
498 218
499 if (StringToLowerASCII(field->option_strings()[i]) == 219 if (StringToLowerASCII(field->option_strings()[i]) ==
500 StringToLowerASCII(field_text)) { 220 StringToLowerASCII(field_text)) {
501 // A match, but not in the same case. Save it in case an exact match is 221 // A match, but not in the same case. Save it in case an exact match is
502 // not found. 222 // not found.
503 value = field->option_strings()[i]; 223 value = field->option_strings()[i];
504 } 224 }
505 } 225 }
506 226
507 if (!value.empty()) { 227 if (!value.empty()) {
508 field->set_value(value); 228 field->set_value(value);
509 return; 229 return;
510 } 230 }
511 231
512 if (type.field_type() == ADDRESS_HOME_STATE || 232 if (type.field_type() == ADDRESS_HOME_STATE ||
513 type.field_type() == ADDRESS_BILLING_STATE) { 233 type.field_type() == ADDRESS_BILLING_STATE) {
514 FillStateSelectControl(field_text, field); 234 FillStateSelectControl(field_text, field);
515 } else if (type.field_type() == ADDRESS_HOME_COUNTRY || 235 } else if (type.field_type() == ADDRESS_HOME_COUNTRY ||
516 type.field_type() == ADDRESS_BILLING_COUNTRY) { 236 type.field_type() == ADDRESS_BILLING_COUNTRY) {
517 FillCountrySelectControl(field_text, field); 237 FillCountrySelectControl(form_group, field);
518 } else if (type.field_type() == CREDIT_CARD_EXP_MONTH) { 238 } else if (type.field_type() == CREDIT_CARD_EXP_MONTH) {
519 FillExpirationMonthSelectControl(field_text, field); 239 FillExpirationMonthSelectControl(field_text, field);
520 } 240 }
521 241
522 return; 242 return;
523 } 243 }
524 244
525 } // namespace autofill 245 } // namespace autofill
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698