| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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/core/browser/autofill_profile_comparator.h" | 5 #include "components/autofill/core/browser/autofill_profile_comparator.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include "base/i18n/case_conversion.h" | 10 #include "base/i18n/case_conversion.h" |
| (...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 269 if (!full_name_candidate->full.empty()) { | 269 if (!full_name_candidate->full.empty()) { |
| 270 info->SetRawInfo(NAME_FULL, full_name_candidate->full); | 270 info->SetRawInfo(NAME_FULL, full_name_candidate->full); |
| 271 } | 271 } |
| 272 info->SetRawInfo(NAME_FIRST, name_parts_candidate->given); | 272 info->SetRawInfo(NAME_FIRST, name_parts_candidate->given); |
| 273 info->SetRawInfo(NAME_LAST, name_parts_candidate->surname); | 273 info->SetRawInfo(NAME_LAST, name_parts_candidate->surname); |
| 274 } | 274 } |
| 275 | 275 |
| 276 return true; | 276 return true; |
| 277 } | 277 } |
| 278 | 278 |
| 279 bool AutofillProfileComparator::IsNameVariantOf( |
| 280 const base::string16& full_name_1, |
| 281 const base::string16& full_name_2) const { |
| 282 data_util::NameParts name_1_parts = data_util::SplitName(full_name_1); |
| 283 |
| 284 // Build the variants of full_name_1`s given, middle and family names. |
| 285 // |
| 286 // TODO(rogerm): Figure out whether or not we should break apart a compound |
| 287 // family name into variants (crbug/619051) |
| 288 const std::set<base::string16> given_name_variants = |
| 289 GetNamePartVariants(name_1_parts.given); |
| 290 const std::set<base::string16> middle_name_variants = |
| 291 GetNamePartVariants(name_1_parts.middle); |
| 292 base::StringPiece16 family_name = name_1_parts.family; |
| 293 |
| 294 // Iterate over all full name variants of profile 2 and see if any of them |
| 295 // match the full name from profile 1. |
| 296 for (const auto& given_name : given_name_variants) { |
| 297 for (const auto& middle_name : middle_name_variants) { |
| 298 base::string16 candidate = base::CollapseWhitespace( |
| 299 base::JoinString({given_name, middle_name, family_name}, kSpace), |
| 300 true); |
| 301 if (candidate == full_name_2) |
| 302 return true; |
| 303 } |
| 304 } |
| 305 |
| 306 // Also check if the name is just composed of the user's initials. For |
| 307 // example, "thomas jefferson miller" could be composed as "tj miller". |
| 308 if (!name_1_parts.given.empty() && !name_1_parts.middle.empty()) { |
| 309 base::string16 initials; |
| 310 initials.push_back(name_1_parts.given[0]); |
| 311 initials.push_back(name_1_parts.middle[0]); |
| 312 base::string16 candidate = base::CollapseWhitespace( |
| 313 base::JoinString({initials, family_name}, kSpace), true); |
| 314 if (candidate == full_name_2) |
| 315 return true; |
| 316 } |
| 317 |
| 318 // There was no match found. |
| 319 return false; |
| 320 } |
| 321 |
| 279 bool AutofillProfileComparator::MergeEmailAddresses( | 322 bool AutofillProfileComparator::MergeEmailAddresses( |
| 280 const AutofillProfile& p1, | 323 const AutofillProfile& p1, |
| 281 const AutofillProfile& p2, | 324 const AutofillProfile& p2, |
| 282 EmailInfo* email_info) const { | 325 EmailInfo* email_info) const { |
| 283 DCHECK(HaveMergeableEmailAddresses(p1, p2)); | 326 DCHECK(HaveMergeableEmailAddresses(p1, p2)); |
| 284 | 327 |
| 285 const AutofillType kEmailAddress(EMAIL_ADDRESS); | 328 const AutofillType kEmailAddress(EMAIL_ADDRESS); |
| 286 const base::string16& e1 = p1.GetInfo(kEmailAddress, app_locale_); | 329 const base::string16& e1 = p1.GetInfo(kEmailAddress, app_locale_); |
| 287 const base::string16& e2 = p2.GetInfo(kEmailAddress, app_locale_); | 330 const base::string16& e2 = p2.GetInfo(kEmailAddress, app_locale_); |
| 288 const base::string16* best = nullptr; | 331 const base::string16* best = nullptr; |
| (...skipping 411 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 700 if (sub_name.empty()) | 743 if (sub_name.empty()) |
| 701 continue; | 744 continue; |
| 702 initials.push_back(sub_name[0]); | 745 initials.push_back(sub_name[0]); |
| 703 } | 746 } |
| 704 variants.insert(initials); | 747 variants.insert(initials); |
| 705 | 748 |
| 706 // And, we're done. | 749 // And, we're done. |
| 707 return variants; | 750 return variants; |
| 708 } | 751 } |
| 709 | 752 |
| 710 bool AutofillProfileComparator::IsNameVariantOf( | |
| 711 const base::string16& full_name_1, | |
| 712 const base::string16& full_name_2) const { | |
| 713 data_util::NameParts name_1_parts = data_util::SplitName(full_name_1); | |
| 714 | |
| 715 // Build the variants of full_name_1`s given, middle and family names. | |
| 716 // | |
| 717 // TODO(rogerm): Figure out whether or not we should break apart a compound | |
| 718 // family name into variants (crbug/619051) | |
| 719 const std::set<base::string16> given_name_variants = | |
| 720 GetNamePartVariants(name_1_parts.given); | |
| 721 const std::set<base::string16> middle_name_variants = | |
| 722 GetNamePartVariants(name_1_parts.middle); | |
| 723 base::StringPiece16 family_name = name_1_parts.family; | |
| 724 | |
| 725 // Iterate over all full name variants of profile 2 and see if any of them | |
| 726 // match the full name from profile 1. | |
| 727 for (const auto& given_name : given_name_variants) { | |
| 728 for (const auto& middle_name : middle_name_variants) { | |
| 729 base::string16 candidate = base::CollapseWhitespace( | |
| 730 base::JoinString({given_name, middle_name, family_name}, kSpace), | |
| 731 true); | |
| 732 if (candidate == full_name_2) | |
| 733 return true; | |
| 734 } | |
| 735 } | |
| 736 | |
| 737 // Also check if the name is just composed of the user's initials. For | |
| 738 // example, "thomas jefferson miller" could be composed as "tj miller". | |
| 739 if (!name_1_parts.given.empty() && !name_1_parts.middle.empty()) { | |
| 740 base::string16 initials; | |
| 741 initials.push_back(name_1_parts.given[0]); | |
| 742 initials.push_back(name_1_parts.middle[0]); | |
| 743 base::string16 candidate = base::CollapseWhitespace( | |
| 744 base::JoinString({initials, family_name}, kSpace), true); | |
| 745 if (candidate == full_name_2) | |
| 746 return true; | |
| 747 } | |
| 748 | |
| 749 // There was no match found. | |
| 750 return false; | |
| 751 } | |
| 752 | |
| 753 bool AutofillProfileComparator::HaveMergeableNames( | 753 bool AutofillProfileComparator::HaveMergeableNames( |
| 754 const AutofillProfile& p1, | 754 const AutofillProfile& p1, |
| 755 const AutofillProfile& p2) const { | 755 const AutofillProfile& p2) const { |
| 756 base::string16 full_name_1 = | 756 base::string16 full_name_1 = |
| 757 NormalizeForComparison(p1.GetInfo(AutofillType(NAME_FULL), app_locale_)); | 757 NormalizeForComparison(p1.GetInfo(AutofillType(NAME_FULL), app_locale_)); |
| 758 base::string16 full_name_2 = | 758 base::string16 full_name_2 = |
| 759 NormalizeForComparison(p2.GetInfo(AutofillType(NAME_FULL), app_locale_)); | 759 NormalizeForComparison(p2.GetInfo(AutofillType(NAME_FULL), app_locale_)); |
| 760 | 760 |
| 761 if (full_name_1.empty() || full_name_2.empty() || | 761 if (full_name_1.empty() || full_name_2.empty() || |
| 762 full_name_1 == full_name_2) { | 762 full_name_1 == full_name_2) { |
| (...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 950 const base::string16& address2 = rewriter.Rewrite(NormalizeForComparison( | 950 const base::string16& address2 = rewriter.Rewrite(NormalizeForComparison( |
| 951 p2.GetInfo(AutofillType(ADDRESS_HOME_STREET_ADDRESS), app_locale_))); | 951 p2.GetInfo(AutofillType(ADDRESS_HOME_STREET_ADDRESS), app_locale_))); |
| 952 if (CompareTokens(address1, address2) == DIFFERENT_TOKENS) { | 952 if (CompareTokens(address1, address2) == DIFFERENT_TOKENS) { |
| 953 return false; | 953 return false; |
| 954 } | 954 } |
| 955 | 955 |
| 956 return true; | 956 return true; |
| 957 } | 957 } |
| 958 | 958 |
| 959 } // namespace autofill | 959 } // namespace autofill |
| OLD | NEW |