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" |
11 #include "base/i18n/char_iterator.h" | 11 #include "base/i18n/char_iterator.h" |
12 #include "base/i18n/unicodestring.h" | 12 #include "base/i18n/unicodestring.h" |
13 #include "base/strings/string_piece.h" | |
14 #include "base/strings/string_split.h" | 13 #include "base/strings/string_split.h" |
15 #include "base/strings/string_util.h" | 14 #include "base/strings/string_util.h" |
16 #include "base/strings/utf_string_conversion_utils.h" | 15 #include "base/strings/utf_string_conversion_utils.h" |
17 #include "base/strings/utf_string_conversions.h" | 16 #include "base/strings/utf_string_conversions.h" |
18 #include "components/autofill/core/browser/address_rewriter.h" | 17 #include "components/autofill/core/browser/address_rewriter.h" |
19 #include "components/autofill/core/browser/autofill_country.h" | 18 #include "components/autofill/core/browser/autofill_country.h" |
20 #include "components/autofill/core/browser/autofill_data_util.h" | 19 #include "components/autofill/core/browser/autofill_data_util.h" |
21 #include "components/autofill/core/browser/state_names.h" | 20 #include "components/autofill/core/browser/state_names.h" |
22 #include "third_party/libphonenumber/phonenumber_api.h" | 21 #include "third_party/libphonenumber/phonenumber_api.h" |
23 | 22 |
(...skipping 637 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
661 if (!s1.empty()) | 660 if (!s1.empty()) |
662 return s1; | 661 return s1; |
663 return p2.GetInfo(t, app_locale_); | 662 return p2.GetInfo(t, app_locale_); |
664 } | 663 } |
665 | 664 |
666 // static | 665 // static |
667 std::set<base::string16> AutofillProfileComparator::GetNamePartVariants( | 666 std::set<base::string16> AutofillProfileComparator::GetNamePartVariants( |
668 const base::string16& name_part) { | 667 const base::string16& name_part) { |
669 const size_t kMaxSupportedSubNames = 8; | 668 const size_t kMaxSupportedSubNames = 8; |
670 | 669 |
671 std::vector<base::string16> sub_names = base::SplitString( | 670 std::vector<base::StringPiece16> sub_names = base::SplitStringPiece( |
672 name_part, kSpace, base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY); | 671 name_part, kSpace, base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY); |
673 | 672 |
674 // Limit the number of sub-names we support (to constrain memory usage); | 673 // Limit the number of sub-names we support (to constrain memory usage); |
675 if (sub_names.size() > kMaxSupportedSubNames) | 674 if (sub_names.size() > kMaxSupportedSubNames) |
676 return {name_part}; | 675 return {name_part}; |
677 | 676 |
678 // Start with the empty string as a variant. | 677 // Start with the empty string as a variant. |
679 std::set<base::string16> variants = {base::EmptyString16()}; | 678 std::set<base::string16> variants = {base::EmptyString16()}; |
680 | 679 |
681 // For each sub-name, add a variant of all the already existing variants that | 680 // For each sub-name, add a variant of all the already existing variants that |
682 // appends this sub-name and one that appends the initial of this sub-name. | 681 // appends this sub-name and one that appends the initial of this sub-name. |
683 // Duplicates will be discarded when they're added to the variants set. | 682 // Duplicates will be discarded when they're added to the variants set. |
684 for (const base::string16& sub_name : sub_names) { | 683 for (const auto& sub_name : sub_names) { |
685 if (sub_name.empty()) | 684 if (sub_name.empty()) |
686 continue; | 685 continue; |
687 std::vector<base::string16> new_variants; | 686 std::vector<base::string16> new_variants; |
688 for (const base::string16& variant : variants) { | 687 for (const base::string16& variant : variants) { |
689 new_variants.push_back(base::CollapseWhitespace( | 688 new_variants.push_back(base::CollapseWhitespace( |
690 base::JoinString({variant, sub_name}, kSpace), true)); | 689 base::JoinString({variant, sub_name}, kSpace), true)); |
691 new_variants.push_back(base::CollapseWhitespace( | 690 new_variants.push_back(base::CollapseWhitespace( |
692 base::JoinString({variant, sub_name.substr(0, 1)}, kSpace), true)); | 691 base::JoinString({variant, sub_name.substr(0, 1)}, kSpace), true)); |
693 } | 692 } |
694 variants.insert(new_variants.begin(), new_variants.end()); | 693 variants.insert(new_variants.begin(), new_variants.end()); |
695 } | 694 } |
696 | 695 |
697 // As a common case, also add the variant that just concatenates all of the | 696 // As a common case, also add the variant that just concatenates all of the |
698 // initials. | 697 // initials. |
699 base::string16 initials; | 698 base::string16 initials; |
700 for (const base::string16& sub_name : sub_names) { | 699 for (const auto& sub_name : sub_names) { |
701 if (sub_name.empty()) | 700 if (sub_name.empty()) |
702 continue; | 701 continue; |
703 initials.push_back(sub_name[0]); | 702 initials.push_back(sub_name[0]); |
704 } | 703 } |
705 variants.insert(initials); | 704 variants.insert(initials); |
706 | 705 |
707 // And, we're done. | 706 // And, we're done. |
708 return variants; | 707 return variants; |
709 } | 708 } |
710 | 709 |
711 bool AutofillProfileComparator::IsNameVariantOf( | 710 bool AutofillProfileComparator::IsNameVariantOf( |
712 const base::string16& full_name_1, | 711 const base::string16& full_name_1, |
713 const base::string16& full_name_2) const { | 712 const base::string16& full_name_2) const { |
714 data_util::NameParts name_1_parts = data_util::SplitName(full_name_1); | 713 data_util::NameParts name_1_parts = data_util::SplitName(full_name_1); |
715 | 714 |
716 // Build the variants of full_name_1`s given, middle and family names. | 715 // Build the variants of full_name_1`s given, middle and family names. |
717 // | 716 // |
718 // TODO(rogerm): Figure out whether or not we should break apart a compound | 717 // TODO(rogerm): Figure out whether or not we should break apart a compound |
719 // family name into variants (crbug/619051) | 718 // family name into variants (crbug/619051) |
720 const std::set<base::string16> given_name_variants = | 719 const std::set<base::string16> given_name_variants = |
721 GetNamePartVariants(name_1_parts.given); | 720 GetNamePartVariants(name_1_parts.given); |
722 const std::set<base::string16> middle_name_variants = | 721 const std::set<base::string16> middle_name_variants = |
723 GetNamePartVariants(name_1_parts.middle); | 722 GetNamePartVariants(name_1_parts.middle); |
724 const base::string16& family_name = name_1_parts.family; | 723 base::StringPiece16 family_name = name_1_parts.family; |
725 | 724 |
726 // Iterate over all full name variants of profile 2 and see if any of them | 725 // Iterate over all full name variants of profile 2 and see if any of them |
727 // match the full name from profile 1. | 726 // match the full name from profile 1. |
728 for (const base::string16& given_name : given_name_variants) { | 727 for (const auto& given_name : given_name_variants) { |
729 for (const base::string16& middle_name : middle_name_variants) { | 728 for (const auto& middle_name : middle_name_variants) { |
730 base::string16 candidate = base::CollapseWhitespace( | 729 base::string16 candidate = base::CollapseWhitespace( |
731 base::JoinString({given_name, middle_name, family_name}, kSpace), | 730 base::JoinString({given_name, middle_name, family_name}, kSpace), |
732 true); | 731 true); |
733 if (candidate == full_name_2) | 732 if (candidate == full_name_2) |
734 return true; | 733 return true; |
735 } | 734 } |
736 } | 735 } |
737 | 736 |
738 // Also check if the name is just composed of the user's initials. For | 737 // Also check if the name is just composed of the user's initials. For |
739 // example, "thomas jefferson miller" could be composed as "tj miller". | 738 // example, "thomas jefferson miller" could be composed as "tj miller". |
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
951 const base::string16& address2 = rewriter.Rewrite(NormalizeForComparison( | 950 const base::string16& address2 = rewriter.Rewrite(NormalizeForComparison( |
952 p2.GetInfo(AutofillType(ADDRESS_HOME_STREET_ADDRESS), app_locale_))); | 951 p2.GetInfo(AutofillType(ADDRESS_HOME_STREET_ADDRESS), app_locale_))); |
953 if (CompareTokens(address1, address2) == DIFFERENT_TOKENS) { | 952 if (CompareTokens(address1, address2) == DIFFERENT_TOKENS) { |
954 return false; | 953 return false; |
955 } | 954 } |
956 | 955 |
957 return true; | 956 return true; |
958 } | 957 } |
959 | 958 |
960 } // namespace autofill | 959 } // namespace autofill |
OLD | NEW |