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

Side by Side Diff: components/autofill/browser/autofill_profile.cc

Issue 13488009: Remove application locale cache in autofill code. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: sync Created 7 years, 8 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) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "components/autofill/browser/autofill_profile.h" 5 #include "components/autofill/browser/autofill_profile.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <functional> 8 #include <functional>
9 #include <map> 9 #include <map>
10 #include <ostream> 10 #include <ostream>
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
179 179
180 default: 180 default:
181 collapsed_set.insert(*iter); 181 collapsed_set.insert(*iter);
182 } 182 }
183 } 183 }
184 std::swap(*type_set, collapsed_set); 184 std::swap(*type_set, collapsed_set);
185 } 185 }
186 186
187 class FindByPhone { 187 class FindByPhone {
188 public: 188 public:
189 FindByPhone(const string16& phone, const std::string& country_code) 189 FindByPhone(const string16& phone,
190 const std::string& country_code,
191 const std::string& app_locale)
190 : phone_(phone), 192 : phone_(phone),
191 country_code_(country_code) { 193 country_code_(country_code),
194 app_locale_(app_locale) {
192 } 195 }
193 196
194 bool operator()(const string16& phone) { 197 bool operator()(const string16& phone) {
195 return autofill_i18n::PhoneNumbersMatch(phone, phone_, country_code_); 198 return autofill_i18n::PhoneNumbersMatch(
199 phone, phone_, country_code_, app_locale_);
196 } 200 }
197 201
198 bool operator()(const string16* phone) { 202 bool operator()(const string16* phone) {
199 return autofill_i18n::PhoneNumbersMatch(*phone, phone_, country_code_); 203 return autofill_i18n::PhoneNumbersMatch(
204 *phone, phone_, country_code_, app_locale_);
200 } 205 }
201 206
202 private: 207 private:
203 string16 phone_; 208 string16 phone_;
204 std::string country_code_; 209 std::string country_code_;
210 std::string app_locale_;
205 }; 211 };
206 212
207 // Functor used to check for case-insensitive equality of two strings. 213 // Functor used to check for case-insensitive equality of two strings.
208 struct CaseInsensitiveStringEquals 214 struct CaseInsensitiveStringEquals
209 : public std::binary_function<string16, string16, bool> 215 : public std::binary_function<string16, string16, bool>
210 { 216 {
211 bool operator()(const string16& x, const string16& y) const { 217 bool operator()(const string16& x, const string16& y) const {
212 return 218 return
213 x.size() == y.size() && StringToLowerASCII(x) == StringToLowerASCII(y); 219 x.size() == y.size() && StringToLowerASCII(x) == StringToLowerASCII(y);
214 } 220 }
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
341 } 347 }
342 348
343 void AutofillProfile::GetMultiInfo(AutofillFieldType type, 349 void AutofillProfile::GetMultiInfo(AutofillFieldType type,
344 const std::string& app_locale, 350 const std::string& app_locale,
345 std::vector<string16>* values) const { 351 std::vector<string16>* values) const {
346 GetMultiInfoImpl(type, app_locale, values); 352 GetMultiInfoImpl(type, app_locale, values);
347 } 353 }
348 354
349 void AutofillProfile::FillFormField(const AutofillField& field, 355 void AutofillProfile::FillFormField(const AutofillField& field,
350 size_t variant, 356 size_t variant,
357 const std::string& app_locale,
351 FormFieldData* field_data) const { 358 FormFieldData* field_data) const {
352 AutofillFieldType type = field.type(); 359 AutofillFieldType type = field.type();
353 DCHECK_NE(AutofillType::CREDIT_CARD, AutofillType(type).group()); 360 DCHECK_NE(AutofillType::CREDIT_CARD, AutofillType(type).group());
354 DCHECK(field_data); 361 DCHECK(field_data);
355 362
356 if (type == PHONE_HOME_NUMBER) { 363 if (type == PHONE_HOME_NUMBER) {
357 FillPhoneNumberField(field, variant, field_data); 364 FillPhoneNumberField(field, variant, app_locale, field_data);
358 } else if (field_data->form_control_type == "select-one") { 365 } else if (field_data->form_control_type == "select-one") {
359 FillSelectControl(type, field_data); 366 FillSelectControl(type, app_locale, field_data);
360 } else { 367 } else {
361 std::vector<string16> values; 368 std::vector<string16> values;
362 GetMultiInfo(type, AutofillCountry::ApplicationLocale(), &values); 369 GetMultiInfo(type, app_locale, &values);
363 if (variant >= values.size()) { 370 if (variant >= values.size()) {
364 // If the variant is unavailable, bail. This case is reachable, for 371 // If the variant is unavailable, bail. This case is reachable, for
365 // example if Sync updates a profile during the filling process. 372 // example if Sync updates a profile during the filling process.
366 return; 373 return;
367 } 374 }
368 375
369 field_data->value = values[variant]; 376 field_data->value = values[variant];
370 } 377 }
371 } 378 }
372 379
373 void AutofillProfile::FillPhoneNumberField(const AutofillField& field, 380 void AutofillProfile::FillPhoneNumberField(const AutofillField& field,
374 size_t variant, 381 size_t variant,
382 const std::string& app_locale,
375 FormFieldData* field_data) const { 383 FormFieldData* field_data) const {
376 std::vector<string16> values; 384 std::vector<string16> values;
377 GetMultiInfo(field.type(), AutofillCountry::ApplicationLocale(), &values); 385 GetMultiInfo(field.type(), app_locale, &values);
378 DCHECK(variant < values.size()); 386 DCHECK(variant < values.size());
379 387
380 // If we are filling a phone number, check to see if the size field 388 // If we are filling a phone number, check to see if the size field
381 // matches the "prefix" or "suffix" sizes and fill accordingly. 389 // matches the "prefix" or "suffix" sizes and fill accordingly.
382 string16 number = values[variant]; 390 string16 number = values[variant];
383 if (number.length() == 391 if (number.length() ==
384 PhoneNumber::kPrefixLength + PhoneNumber::kSuffixLength) { 392 PhoneNumber::kPrefixLength + PhoneNumber::kSuffixLength) {
385 if (field.phone_part() == AutofillField::PHONE_PREFIX || 393 if (field.phone_part() == AutofillField::PHONE_PREFIX ||
386 field_data->max_length == PhoneNumber::kPrefixLength) { 394 field_data->max_length == PhoneNumber::kPrefixLength) {
387 number = number.substr(PhoneNumber::kPrefixOffset, 395 number = number.substr(PhoneNumber::kPrefixOffset,
388 PhoneNumber::kPrefixLength); 396 PhoneNumber::kPrefixLength);
389 } else if (field.phone_part() == AutofillField::PHONE_SUFFIX || 397 } else if (field.phone_part() == AutofillField::PHONE_SUFFIX ||
390 field_data->max_length == PhoneNumber::kSuffixLength) { 398 field_data->max_length == PhoneNumber::kSuffixLength) {
391 number = number.substr(PhoneNumber::kSuffixOffset, 399 number = number.substr(PhoneNumber::kSuffixOffset,
392 PhoneNumber::kSuffixLength); 400 PhoneNumber::kSuffixLength);
393 } 401 }
394 } 402 }
395 403
396 field_data->value = number; 404 field_data->value = number;
397 } 405 }
398 406
399 const string16 AutofillProfile::Label() const { 407 const string16 AutofillProfile::Label() const {
400 return label_; 408 return label_;
401 } 409 }
402 410
403 bool AutofillProfile::IsEmpty() const { 411 bool AutofillProfile::IsEmpty(const std::string& app_locale) const {
404 FieldTypeSet types; 412 FieldTypeSet types;
405 GetNonEmptyTypes(AutofillCountry::ApplicationLocale(), &types); 413 GetNonEmptyTypes(app_locale, &types);
406 return types.empty(); 414 return types.empty();
407 } 415 }
408 416
409 int AutofillProfile::Compare(const AutofillProfile& profile) const { 417 int AutofillProfile::Compare(const AutofillProfile& profile) const {
410 const AutofillFieldType single_value_types[] = { COMPANY_NAME, 418 const AutofillFieldType single_value_types[] = { COMPANY_NAME,
411 ADDRESS_HOME_LINE1, 419 ADDRESS_HOME_LINE1,
412 ADDRESS_HOME_LINE2, 420 ADDRESS_HOME_LINE2,
413 ADDRESS_HOME_CITY, 421 ADDRESS_HOME_CITY,
414 ADDRESS_HOME_STATE, 422 ADDRESS_HOME_STATE,
415 ADDRESS_HOME_ZIP, 423 ADDRESS_HOME_ZIP,
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
452 } 460 }
453 461
454 bool AutofillProfile::operator!=(const AutofillProfile& profile) const { 462 bool AutofillProfile::operator!=(const AutofillProfile& profile) const {
455 return !operator==(profile); 463 return !operator==(profile);
456 } 464 }
457 465
458 const string16 AutofillProfile::PrimaryValue() const { 466 const string16 AutofillProfile::PrimaryValue() const {
459 return GetRawInfo(ADDRESS_HOME_LINE1) + GetRawInfo(ADDRESS_HOME_CITY); 467 return GetRawInfo(ADDRESS_HOME_LINE1) + GetRawInfo(ADDRESS_HOME_CITY);
460 } 468 }
461 469
462 bool AutofillProfile::IsSubsetOf(const AutofillProfile& profile) const { 470 bool AutofillProfile::IsSubsetOf(const AutofillProfile& profile,
471 const std::string& app_locale) const {
463 FieldTypeSet types; 472 FieldTypeSet types;
464 GetNonEmptyTypes(AutofillCountry::ApplicationLocale(), &types); 473 GetNonEmptyTypes(app_locale, &types);
465 474
466 for (FieldTypeSet::const_iterator iter = types.begin(); iter != types.end(); 475 for (FieldTypeSet::const_iterator iter = types.begin(); iter != types.end();
467 ++iter) { 476 ++iter) {
468 if (*iter == NAME_FULL) { 477 if (*iter == NAME_FULL) {
469 // Ignore the compound "full name" field type. We are only interested in 478 // Ignore the compound "full name" field type. We are only interested in
470 // comparing the constituent parts. For example, if |this| has a middle 479 // comparing the constituent parts. For example, if |this| has a middle
471 // name saved, but |profile| lacks one, |profile| could still be a subset 480 // name saved, but |profile| lacks one, |profile| could still be a subset
472 // of |this|. 481 // of |this|.
473 continue; 482 continue;
474 } else if (AutofillType(*iter).group() == AutofillType::PHONE) { 483 } else if (AutofillType(*iter).group() == AutofillType::PHONE) {
475 // Phone numbers should be canonicalized prior to being compared. 484 // Phone numbers should be canonicalized prior to being compared.
476 if (*iter != PHONE_HOME_WHOLE_NUMBER) { 485 if (*iter != PHONE_HOME_WHOLE_NUMBER) {
477 continue; 486 continue;
478 } else if (!autofill_i18n::PhoneNumbersMatch( 487 } else if (!autofill_i18n::PhoneNumbersMatch(
479 GetRawInfo(*iter), 488 GetRawInfo(*iter),
480 profile.GetRawInfo(*iter), 489 profile.GetRawInfo(*iter),
481 UTF16ToASCII(GetRawInfo(ADDRESS_HOME_COUNTRY)))) { 490 UTF16ToASCII(GetRawInfo(ADDRESS_HOME_COUNTRY)),
491 app_locale)) {
482 return false; 492 return false;
483 } 493 }
484 } else if (StringToLowerASCII(GetRawInfo(*iter)) != 494 } else if (StringToLowerASCII(GetRawInfo(*iter)) !=
485 StringToLowerASCII(profile.GetRawInfo(*iter))) { 495 StringToLowerASCII(profile.GetRawInfo(*iter))) {
486 return false; 496 return false;
487 } 497 }
488 } 498 }
489 499
490 return true; 500 return true;
491 } 501 }
492 502
493 void AutofillProfile::OverwriteWithOrAddTo(const AutofillProfile& profile) { 503 void AutofillProfile::OverwriteWithOrAddTo(const AutofillProfile& profile,
504 const std::string& app_locale) {
494 FieldTypeSet field_types; 505 FieldTypeSet field_types;
495 profile.GetNonEmptyTypes(AutofillCountry::ApplicationLocale(), &field_types); 506 profile.GetNonEmptyTypes(app_locale, &field_types);
496 507
497 // Only transfer "full" types (e.g. full name) and not fragments (e.g. 508 // Only transfer "full" types (e.g. full name) and not fragments (e.g.
498 // first name, last name). 509 // first name, last name).
499 CollapseCompoundFieldTypes(&field_types); 510 CollapseCompoundFieldTypes(&field_types);
500 511
501 for (FieldTypeSet::const_iterator iter = field_types.begin(); 512 for (FieldTypeSet::const_iterator iter = field_types.begin();
502 iter != field_types.end(); ++iter) { 513 iter != field_types.end(); ++iter) {
503 if (AutofillProfile::SupportsMultiValue(*iter)) { 514 if (AutofillProfile::SupportsMultiValue(*iter)) {
504 std::vector<string16> new_values; 515 std::vector<string16> new_values;
505 profile.GetRawMultiInfo(*iter, &new_values); 516 profile.GetRawMultiInfo(*iter, &new_values);
506 std::vector<string16> existing_values; 517 std::vector<string16> existing_values;
507 GetRawMultiInfo(*iter, &existing_values); 518 GetRawMultiInfo(*iter, &existing_values);
508 519
509 // GetMultiInfo always returns at least one element, even if the profile 520 // GetMultiInfo always returns at least one element, even if the profile
510 // has no data stored for this field type. 521 // has no data stored for this field type.
511 if (existing_values.size() == 1 && existing_values.front().empty()) 522 if (existing_values.size() == 1 && existing_values.front().empty())
512 existing_values.clear(); 523 existing_values.clear();
513 524
514 FieldTypeGroup group = AutofillType(*iter).group(); 525 FieldTypeGroup group = AutofillType(*iter).group();
515 for (std::vector<string16>::iterator value_iter = new_values.begin(); 526 for (std::vector<string16>::iterator value_iter = new_values.begin();
516 value_iter != new_values.end(); ++value_iter) { 527 value_iter != new_values.end(); ++value_iter) {
517 // Don't add duplicates. 528 // Don't add duplicates.
518 if (group == AutofillType::PHONE) { 529 if (group == AutofillType::PHONE) {
519 AddPhoneIfUnique(*value_iter, &existing_values); 530 AddPhoneIfUnique(*value_iter, app_locale, &existing_values);
520 } else { 531 } else {
521 std::vector<string16>::const_iterator existing_iter = std::find_if( 532 std::vector<string16>::const_iterator existing_iter = std::find_if(
522 existing_values.begin(), existing_values.end(), 533 existing_values.begin(), existing_values.end(),
523 std::bind1st(CaseInsensitiveStringEquals(), *value_iter)); 534 std::bind1st(CaseInsensitiveStringEquals(), *value_iter));
524 if (existing_iter == existing_values.end()) 535 if (existing_iter == existing_values.end())
525 existing_values.insert(existing_values.end(), *value_iter); 536 existing_values.insert(existing_values.end(), *value_iter);
526 } 537 }
527 } 538 }
528 SetRawMultiInfo(*iter, existing_values); 539 SetRawMultiInfo(*iter, existing_values);
529 } else { 540 } else {
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
606 } 617 }
607 } 618 }
608 } 619 }
609 620
610 void AutofillProfile::GetSupportedTypes(FieldTypeSet* supported_types) const { 621 void AutofillProfile::GetSupportedTypes(FieldTypeSet* supported_types) const {
611 FormGroupList info = FormGroups(); 622 FormGroupList info = FormGroups();
612 for (FormGroupList::const_iterator it = info.begin(); it != info.end(); ++it) 623 for (FormGroupList::const_iterator it = info.begin(); it != info.end(); ++it)
613 (*it)->GetSupportedTypes(supported_types); 624 (*it)->GetSupportedTypes(supported_types);
614 } 625 }
615 626
616 bool AutofillProfile::FillCountrySelectControl(FormFieldData* field_data) 627 bool AutofillProfile::FillCountrySelectControl(
617 const { 628 const std::string& app_locale,
629 FormFieldData* field_data) const {
618 std::string country_code = UTF16ToASCII(GetRawInfo(ADDRESS_HOME_COUNTRY)); 630 std::string country_code = UTF16ToASCII(GetRawInfo(ADDRESS_HOME_COUNTRY));
619 std::string app_locale = AutofillCountry::ApplicationLocale();
620 631
621 DCHECK_EQ(field_data->option_values.size(), 632 DCHECK_EQ(field_data->option_values.size(),
622 field_data->option_contents.size()); 633 field_data->option_contents.size());
623 for (size_t i = 0; i < field_data->option_values.size(); ++i) { 634 for (size_t i = 0; i < field_data->option_values.size(); ++i) {
624 // Canonicalize each <option> value to a country code, and compare to the 635 // Canonicalize each <option> value to a country code, and compare to the
625 // target country code. 636 // target country code.
626 string16 value = field_data->option_values[i]; 637 string16 value = field_data->option_values[i];
627 string16 contents = field_data->option_contents[i]; 638 string16 contents = field_data->option_contents[i];
628 if (country_code == AutofillCountry::GetCountryCode(value, app_locale) || 639 if (country_code == AutofillCountry::GetCountryCode(value, app_locale) ||
629 country_code == AutofillCountry::GetCountryCode(contents, app_locale)) { 640 country_code == AutofillCountry::GetCountryCode(contents, app_locale)) {
(...skipping 18 matching lines...) Expand all
648 case AutofillType::PHONE: 659 case AutofillType::PHONE:
649 CopyItemsToValues(type, home_number_, app_locale, values); 660 CopyItemsToValues(type, home_number_, app_locale, values);
650 break; 661 break;
651 default: 662 default:
652 values->resize(1); 663 values->resize(1);
653 (*values)[0] = GetFormGroupInfo(*this, type, app_locale); 664 (*values)[0] = GetFormGroupInfo(*this, type, app_locale);
654 } 665 }
655 } 666 }
656 667
657 void AutofillProfile::AddPhoneIfUnique(const string16& phone, 668 void AutofillProfile::AddPhoneIfUnique(const string16& phone,
669 const std::string& app_locale,
658 std::vector<string16>* existing_phones) { 670 std::vector<string16>* existing_phones) {
659 DCHECK(existing_phones); 671 DCHECK(existing_phones);
660 // Phones allow "fuzzy" matching, so "1-800-FLOWERS", "18003569377", 672 // Phones allow "fuzzy" matching, so "1-800-FLOWERS", "18003569377",
661 // "(800)356-9377" and "356-9377" are considered the same. 673 // "(800)356-9377" and "356-9377" are considered the same.
662 if (std::find_if( 674 std::string country_code = UTF16ToASCII(GetRawInfo(ADDRESS_HOME_COUNTRY));
663 existing_phones->begin(), existing_phones->end(), 675 if (std::find_if(existing_phones->begin(), existing_phones->end(),
664 FindByPhone(phone, UTF16ToASCII(GetRawInfo(ADDRESS_HOME_COUNTRY)))) == 676 FindByPhone(phone, country_code, app_locale)) ==
665 existing_phones->end()) { 677 existing_phones->end()) {
666 existing_phones->push_back(phone); 678 existing_phones->push_back(phone);
667 } 679 }
668 } 680 }
669 681
670 string16 AutofillProfile::ConstructInferredLabel( 682 string16 AutofillProfile::ConstructInferredLabel(
671 const std::vector<AutofillFieldType>& included_fields, 683 const std::vector<AutofillFieldType>& included_fields,
672 size_t num_fields_to_use) const { 684 size_t num_fields_to_use) const {
673 const string16 separator = 685 const string16 separator =
674 l10n_util::GetStringUTF16(IDS_AUTOFILL_ADDRESS_SUMMARY_SEPARATOR); 686 l10n_util::GetStringUTF16(IDS_AUTOFILL_ADDRESS_SUMMARY_SEPARATOR);
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
833 << UTF16ToUTF8(profile.GetRawInfo(ADDRESS_HOME_CITY)) 845 << UTF16ToUTF8(profile.GetRawInfo(ADDRESS_HOME_CITY))
834 << " " 846 << " "
835 << UTF16ToUTF8(profile.GetRawInfo(ADDRESS_HOME_STATE)) 847 << UTF16ToUTF8(profile.GetRawInfo(ADDRESS_HOME_STATE))
836 << " " 848 << " "
837 << UTF16ToUTF8(profile.GetRawInfo(ADDRESS_HOME_ZIP)) 849 << UTF16ToUTF8(profile.GetRawInfo(ADDRESS_HOME_ZIP))
838 << " " 850 << " "
839 << UTF16ToUTF8(profile.GetRawInfo(ADDRESS_HOME_COUNTRY)) 851 << UTF16ToUTF8(profile.GetRawInfo(ADDRESS_HOME_COUNTRY))
840 << " " 852 << " "
841 << UTF16ToUTF8(MultiString(profile, PHONE_HOME_WHOLE_NUMBER)); 853 << UTF16ToUTF8(MultiString(profile, PHONE_HOME_WHOLE_NUMBER));
842 } 854 }
OLDNEW
« no previous file with comments | « components/autofill/browser/autofill_profile.h ('k') | components/autofill/browser/autofill_profile_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698