OLD | NEW |
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 Loading... |
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 Loading... |
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, |
(...skipping 13 matching lines...) Expand all Loading... |
401 } | 409 } |
402 | 410 |
403 const std::string AutofillProfile::CountryCode() const { | 411 const std::string AutofillProfile::CountryCode() const { |
404 return address_.country_code(); | 412 return address_.country_code(); |
405 } | 413 } |
406 | 414 |
407 void AutofillProfile::SetCountryCode(const std::string& country_code) { | 415 void AutofillProfile::SetCountryCode(const std::string& country_code) { |
408 address_.set_country_code(country_code); | 416 address_.set_country_code(country_code); |
409 } | 417 } |
410 | 418 |
411 bool AutofillProfile::IsEmpty() const { | 419 bool AutofillProfile::IsEmpty(const std::string& app_locale) const { |
412 FieldTypeSet types; | 420 FieldTypeSet types; |
413 GetNonEmptyTypes(AutofillCountry::ApplicationLocale(), &types); | 421 GetNonEmptyTypes(app_locale, &types); |
414 return types.empty(); | 422 return types.empty(); |
415 } | 423 } |
416 | 424 |
417 int AutofillProfile::Compare(const AutofillProfile& profile) const { | 425 int AutofillProfile::Compare(const AutofillProfile& profile) const { |
418 const AutofillFieldType single_value_types[] = { COMPANY_NAME, | 426 const AutofillFieldType single_value_types[] = { COMPANY_NAME, |
419 ADDRESS_HOME_LINE1, | 427 ADDRESS_HOME_LINE1, |
420 ADDRESS_HOME_LINE2, | 428 ADDRESS_HOME_LINE2, |
421 ADDRESS_HOME_CITY, | 429 ADDRESS_HOME_CITY, |
422 ADDRESS_HOME_STATE, | 430 ADDRESS_HOME_STATE, |
423 ADDRESS_HOME_ZIP, | 431 ADDRESS_HOME_ZIP, |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
460 } | 468 } |
461 | 469 |
462 bool AutofillProfile::operator!=(const AutofillProfile& profile) const { | 470 bool AutofillProfile::operator!=(const AutofillProfile& profile) const { |
463 return !operator==(profile); | 471 return !operator==(profile); |
464 } | 472 } |
465 | 473 |
466 const string16 AutofillProfile::PrimaryValue() const { | 474 const string16 AutofillProfile::PrimaryValue() const { |
467 return GetRawInfo(ADDRESS_HOME_LINE1) + GetRawInfo(ADDRESS_HOME_CITY); | 475 return GetRawInfo(ADDRESS_HOME_LINE1) + GetRawInfo(ADDRESS_HOME_CITY); |
468 } | 476 } |
469 | 477 |
470 bool AutofillProfile::IsSubsetOf(const AutofillProfile& profile) const { | 478 bool AutofillProfile::IsSubsetOf(const AutofillProfile& profile, |
| 479 const std::string& app_locale) const { |
471 FieldTypeSet types; | 480 FieldTypeSet types; |
472 GetNonEmptyTypes(AutofillCountry::ApplicationLocale(), &types); | 481 GetNonEmptyTypes(app_locale, &types); |
473 | 482 |
474 for (FieldTypeSet::const_iterator iter = types.begin(); iter != types.end(); | 483 for (FieldTypeSet::const_iterator iter = types.begin(); iter != types.end(); |
475 ++iter) { | 484 ++iter) { |
476 if (*iter == NAME_FULL) { | 485 if (*iter == NAME_FULL) { |
477 // Ignore the compound "full name" field type. We are only interested in | 486 // Ignore the compound "full name" field type. We are only interested in |
478 // comparing the constituent parts. For example, if |this| has a middle | 487 // comparing the constituent parts. For example, if |this| has a middle |
479 // name saved, but |profile| lacks one, |profile| could still be a subset | 488 // name saved, but |profile| lacks one, |profile| could still be a subset |
480 // of |this|. | 489 // of |this|. |
481 continue; | 490 continue; |
482 } else if (AutofillType(*iter).group() == AutofillType::PHONE) { | 491 } else if (AutofillType(*iter).group() == AutofillType::PHONE) { |
483 // Phone numbers should be canonicalized prior to being compared. | 492 // Phone numbers should be canonicalized prior to being compared. |
484 if (*iter != PHONE_HOME_WHOLE_NUMBER) { | 493 if (*iter != PHONE_HOME_WHOLE_NUMBER) { |
485 continue; | 494 continue; |
486 } else if (!autofill_i18n::PhoneNumbersMatch(GetRawInfo(*iter), | 495 } else if (!autofill_i18n::PhoneNumbersMatch(GetRawInfo(*iter), |
487 profile.GetRawInfo(*iter), | 496 profile.GetRawInfo(*iter), |
488 CountryCode())) { | 497 CountryCode(), |
| 498 app_locale)) { |
489 return false; | 499 return false; |
490 } | 500 } |
491 } else if (StringToLowerASCII(GetRawInfo(*iter)) != | 501 } else if (StringToLowerASCII(GetRawInfo(*iter)) != |
492 StringToLowerASCII(profile.GetRawInfo(*iter))) { | 502 StringToLowerASCII(profile.GetRawInfo(*iter))) { |
493 return false; | 503 return false; |
494 } | 504 } |
495 } | 505 } |
496 | 506 |
497 return true; | 507 return true; |
498 } | 508 } |
499 | 509 |
500 void AutofillProfile::OverwriteWithOrAddTo(const AutofillProfile& profile) { | 510 void AutofillProfile::OverwriteWithOrAddTo(const AutofillProfile& profile, |
| 511 const std::string& app_locale) { |
501 FieldTypeSet field_types; | 512 FieldTypeSet field_types; |
502 profile.GetNonEmptyTypes(AutofillCountry::ApplicationLocale(), &field_types); | 513 profile.GetNonEmptyTypes(app_locale, &field_types); |
503 | 514 |
504 // Only transfer "full" types (e.g. full name) and not fragments (e.g. | 515 // Only transfer "full" types (e.g. full name) and not fragments (e.g. |
505 // first name, last name). | 516 // first name, last name). |
506 CollapseCompoundFieldTypes(&field_types); | 517 CollapseCompoundFieldTypes(&field_types); |
507 | 518 |
508 for (FieldTypeSet::const_iterator iter = field_types.begin(); | 519 for (FieldTypeSet::const_iterator iter = field_types.begin(); |
509 iter != field_types.end(); ++iter) { | 520 iter != field_types.end(); ++iter) { |
510 if (AutofillProfile::SupportsMultiValue(*iter)) { | 521 if (AutofillProfile::SupportsMultiValue(*iter)) { |
511 std::vector<string16> new_values; | 522 std::vector<string16> new_values; |
512 profile.GetRawMultiInfo(*iter, &new_values); | 523 profile.GetRawMultiInfo(*iter, &new_values); |
513 std::vector<string16> existing_values; | 524 std::vector<string16> existing_values; |
514 GetRawMultiInfo(*iter, &existing_values); | 525 GetRawMultiInfo(*iter, &existing_values); |
515 | 526 |
516 // GetMultiInfo always returns at least one element, even if the profile | 527 // GetMultiInfo always returns at least one element, even if the profile |
517 // has no data stored for this field type. | 528 // has no data stored for this field type. |
518 if (existing_values.size() == 1 && existing_values.front().empty()) | 529 if (existing_values.size() == 1 && existing_values.front().empty()) |
519 existing_values.clear(); | 530 existing_values.clear(); |
520 | 531 |
521 FieldTypeGroup group = AutofillType(*iter).group(); | 532 FieldTypeGroup group = AutofillType(*iter).group(); |
522 for (std::vector<string16>::iterator value_iter = new_values.begin(); | 533 for (std::vector<string16>::iterator value_iter = new_values.begin(); |
523 value_iter != new_values.end(); ++value_iter) { | 534 value_iter != new_values.end(); ++value_iter) { |
524 // Don't add duplicates. | 535 // Don't add duplicates. |
525 if (group == AutofillType::PHONE) { | 536 if (group == AutofillType::PHONE) { |
526 AddPhoneIfUnique(*value_iter, &existing_values); | 537 AddPhoneIfUnique(*value_iter, app_locale, &existing_values); |
527 } else { | 538 } else { |
528 std::vector<string16>::const_iterator existing_iter = std::find_if( | 539 std::vector<string16>::const_iterator existing_iter = std::find_if( |
529 existing_values.begin(), existing_values.end(), | 540 existing_values.begin(), existing_values.end(), |
530 std::bind1st(CaseInsensitiveStringEquals(), *value_iter)); | 541 std::bind1st(CaseInsensitiveStringEquals(), *value_iter)); |
531 if (existing_iter == existing_values.end()) | 542 if (existing_iter == existing_values.end()) |
532 existing_values.insert(existing_values.end(), *value_iter); | 543 existing_values.insert(existing_values.end(), *value_iter); |
533 } | 544 } |
534 } | 545 } |
535 SetRawMultiInfo(*iter, existing_values); | 546 SetRawMultiInfo(*iter, existing_values); |
536 } else { | 547 } else { |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
613 } | 624 } |
614 } | 625 } |
615 } | 626 } |
616 | 627 |
617 void AutofillProfile::GetSupportedTypes(FieldTypeSet* supported_types) const { | 628 void AutofillProfile::GetSupportedTypes(FieldTypeSet* supported_types) const { |
618 FormGroupList info = FormGroups(); | 629 FormGroupList info = FormGroups(); |
619 for (FormGroupList::const_iterator it = info.begin(); it != info.end(); ++it) | 630 for (FormGroupList::const_iterator it = info.begin(); it != info.end(); ++it) |
620 (*it)->GetSupportedTypes(supported_types); | 631 (*it)->GetSupportedTypes(supported_types); |
621 } | 632 } |
622 | 633 |
623 bool AutofillProfile::FillCountrySelectControl(FormFieldData* field_data) | 634 bool AutofillProfile::FillCountrySelectControl(const std::string& app_locale, |
| 635 FormFieldData* field_data) |
624 const { | 636 const { |
625 std::string country_code = CountryCode(); | 637 std::string country_code = CountryCode(); |
626 std::string app_locale = AutofillCountry::ApplicationLocale(); | |
627 | 638 |
628 DCHECK_EQ(field_data->option_values.size(), | 639 DCHECK_EQ(field_data->option_values.size(), |
629 field_data->option_contents.size()); | 640 field_data->option_contents.size()); |
630 for (size_t i = 0; i < field_data->option_values.size(); ++i) { | 641 for (size_t i = 0; i < field_data->option_values.size(); ++i) { |
631 // Canonicalize each <option> value to a country code, and compare to the | 642 // Canonicalize each <option> value to a country code, and compare to the |
632 // target country code. | 643 // target country code. |
633 string16 value = field_data->option_values[i]; | 644 string16 value = field_data->option_values[i]; |
634 string16 contents = field_data->option_contents[i]; | 645 string16 contents = field_data->option_contents[i]; |
635 if (country_code == AutofillCountry::GetCountryCode(value, app_locale) || | 646 if (country_code == AutofillCountry::GetCountryCode(value, app_locale) || |
636 country_code == AutofillCountry::GetCountryCode(contents, app_locale)) { | 647 country_code == AutofillCountry::GetCountryCode(contents, app_locale)) { |
(...skipping 18 matching lines...) Expand all Loading... |
655 case AutofillType::PHONE: | 666 case AutofillType::PHONE: |
656 CopyItemsToValues(type, home_number_, app_locale, values); | 667 CopyItemsToValues(type, home_number_, app_locale, values); |
657 break; | 668 break; |
658 default: | 669 default: |
659 values->resize(1); | 670 values->resize(1); |
660 (*values)[0] = GetFormGroupInfo(*this, type, app_locale); | 671 (*values)[0] = GetFormGroupInfo(*this, type, app_locale); |
661 } | 672 } |
662 } | 673 } |
663 | 674 |
664 void AutofillProfile::AddPhoneIfUnique(const string16& phone, | 675 void AutofillProfile::AddPhoneIfUnique(const string16& phone, |
| 676 const std::string& app_locale, |
665 std::vector<string16>* existing_phones) { | 677 std::vector<string16>* existing_phones) { |
666 DCHECK(existing_phones); | 678 DCHECK(existing_phones); |
667 // Phones allow "fuzzy" matching, so "1-800-FLOWERS", "18003569377", | 679 // Phones allow "fuzzy" matching, so "1-800-FLOWERS", "18003569377", |
668 // "(800)356-9377" and "356-9377" are considered the same. | 680 // "(800)356-9377" and "356-9377" are considered the same. |
669 if (std::find_if(existing_phones->begin(), existing_phones->end(), | 681 if (std::find_if(existing_phones->begin(), existing_phones->end(), |
670 FindByPhone(phone, CountryCode())) == | 682 FindByPhone(phone, CountryCode(), app_locale)) == |
671 existing_phones->end()) { | 683 existing_phones->end()) { |
672 existing_phones->push_back(phone); | 684 existing_phones->push_back(phone); |
673 } | 685 } |
674 } | 686 } |
675 | 687 |
676 string16 AutofillProfile::ConstructInferredLabel( | 688 string16 AutofillProfile::ConstructInferredLabel( |
677 const std::vector<AutofillFieldType>& included_fields, | 689 const std::vector<AutofillFieldType>& included_fields, |
678 size_t num_fields_to_use) const { | 690 size_t num_fields_to_use) const { |
679 const string16 separator = | 691 const string16 separator = |
680 l10n_util::GetStringUTF16(IDS_AUTOFILL_ADDRESS_SUMMARY_SEPARATOR); | 692 l10n_util::GetStringUTF16(IDS_AUTOFILL_ADDRESS_SUMMARY_SEPARATOR); |
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
839 << UTF16ToUTF8(profile.GetRawInfo(ADDRESS_HOME_CITY)) | 851 << UTF16ToUTF8(profile.GetRawInfo(ADDRESS_HOME_CITY)) |
840 << " " | 852 << " " |
841 << UTF16ToUTF8(profile.GetRawInfo(ADDRESS_HOME_STATE)) | 853 << UTF16ToUTF8(profile.GetRawInfo(ADDRESS_HOME_STATE)) |
842 << " " | 854 << " " |
843 << UTF16ToUTF8(profile.GetRawInfo(ADDRESS_HOME_ZIP)) | 855 << UTF16ToUTF8(profile.GetRawInfo(ADDRESS_HOME_ZIP)) |
844 << " " | 856 << " " |
845 << UTF16ToUTF8(profile.GetRawInfo(ADDRESS_HOME_COUNTRY)) | 857 << UTF16ToUTF8(profile.GetRawInfo(ADDRESS_HOME_COUNTRY)) |
846 << " " | 858 << " " |
847 << UTF16ToUTF8(MultiString(profile, PHONE_HOME_WHOLE_NUMBER)); | 859 << UTF16ToUTF8(MultiString(profile, PHONE_HOME_WHOLE_NUMBER)); |
848 } | 860 } |
OLD | NEW |