| 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, |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 } |
| OLD | NEW |