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