OLD | NEW |
(Empty) | |
| 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 |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_AUTOFILL_PROFILE_COMPARATOR_H_ |
| 6 #define COMPONENTS_AUTOFILL_CORE_BROWSER_AUTOFILL_PROFILE_COMPARATOR_H_ |
| 7 |
| 8 #include <memory> |
| 9 #include <set> |
| 10 |
| 11 #include "base/strings/string16.h" |
| 12 #include "base/strings/string_piece.h" |
| 13 #include "components/autofill/core/browser/autofill_profile.h" |
| 14 #include "components/autofill/core/common/autofill_l10n_util.h" |
| 15 #include "third_party/icu/source/i18n/unicode/translit.h" |
| 16 |
| 17 namespace autofill { |
| 18 |
| 19 // A utility class to assist in the comparison of AutofillProfile data. |
| 20 class AutofillProfileComparator { |
| 21 public: |
| 22 explicit AutofillProfileComparator(const base::StringPiece& app_locale); |
| 23 ~AutofillProfileComparator(); |
| 24 |
| 25 enum WhitespaceSpec { RETAIN_WHITESPACE, DISCARD_WHITESPACE }; |
| 26 |
| 27 // Returns a copy of |text| with uppercase converted to lowercase and |
| 28 // diacritics removed. |
| 29 // |
| 30 // If |whitespace_spec| is RETAIN_WHITESPACE, punctuation is converted to |
| 31 // spaces, and extraneous whitespace is trimmed and collapsed. For example, |
| 32 // "Jean- François" becomes "jean francois". |
| 33 // |
| 34 // If |whitespace_spec| is DISCARD_WHITESPACE, punctuation and whitespace are |
| 35 // discarded. For example, +1 (234) 567-8900 becomes 12345678900. |
| 36 base::string16 NormalizeForComparison( |
| 37 base::StringPiece16 text, |
| 38 WhitespaceSpec whitespace_spec = RETAIN_WHITESPACE) const; |
| 39 |
| 40 // Returns true if |p1| and |p2| are viable merge candidates. This means that |
| 41 // their names, addresses, email addreses, company names, and phone numbers |
| 42 // are all pairwise equivalent or mergeable. |
| 43 // |
| 44 // Note that mergeability is non-directional; merging two profiles will likely |
| 45 // incorporate data from both profiles. |
| 46 bool AreMergeable(const AutofillProfile& p1, const AutofillProfile& p2) const; |
| 47 |
| 48 protected: |
| 49 // Returns the set of unique tokens in |s|. Note that the string data backing |
| 50 // |s| is expected to have a lifetime which exceeds the call to UniqueTokens. |
| 51 static std::set<base::StringPiece16> UniqueTokens(base::StringPiece16 s); |
| 52 |
| 53 // Returns true if all of the tokens in |s1| are in |s2| or vice versa. |
| 54 static bool HaveSameTokens(base::StringPiece16 s1, base::StringPiece16 s2); |
| 55 |
| 56 // Generate the set of full/initial variants for |name_part|, where |
| 57 // |name_part| is the user's first or middle name. For example, given "jean |
| 58 // francois" (the normalized for comparison form of "Jean-François") this |
| 59 // function returns the set: |
| 60 // |
| 61 // { "", "f", "francois, |
| 62 // "j", "j f", "j francois", |
| 63 // "jean", "jean f", "jean francois", "jf" } |
| 64 // |
| 65 // Note: Expects that |name| is already normalized for comparison. |
| 66 static std::set<base::string16> GetNamePartVariants( |
| 67 const base::string16& name_part); |
| 68 |
| 69 // Returns true if |full_name_2| is a variant of |full_name_1|. |
| 70 // |
| 71 // This function generates all variations of |full_name_1| and returns true if |
| 72 // one of these variants is equal to |full_name_2|. For example, this function |
| 73 // will return true if |full_name_2| is "john q public" and |full_name_1| is |
| 74 // "john quincy public" because |full_name_2| can be derived from |
| 75 // |full_name_1| by using the middle initial. Note that the reverse is not |
| 76 // true, "john quincy public" is not a name variant of "john q public". |
| 77 // |
| 78 // Note: Expects that |full_name| is already normalized for comparison. |
| 79 bool IsNameVariantOf(const base::string16& full_name_1, |
| 80 const base::string16& full_name_2) const; |
| 81 |
| 82 // Returns true if |p1| and |p2| have names which are equivalent for the |
| 83 // purposes of merging the two profiles. This means one of the names is |
| 84 // empty, the names are the same, or one name is a variation of the other. |
| 85 // The name comparison is insensitive to case, punctuation and diacritics. |
| 86 // |
| 87 // Note that this method does not provide any guidance on actually merging |
| 88 // the names. |
| 89 bool HaveMergeableNames(const AutofillProfile& p1, |
| 90 const AutofillProfile& p2) const; |
| 91 |
| 92 // Returns true if |p1| and |p2| have email addresses which are equivalent for |
| 93 // the purposes of merging the two profiles. This means one of the email |
| 94 // addresses is empty, or the email addresses are the same (modulo case). |
| 95 // |
| 96 // Note that this method does not provide any guidance on actually merging |
| 97 // the email addresses. |
| 98 bool HaveMergeableEmailAddresses(const AutofillProfile& p1, |
| 99 const AutofillProfile& p2) const; |
| 100 |
| 101 // Returns true if |p1| and |p2| have company names which are equivalent for |
| 102 // the purposes of merging the two profiles. This means one of the company |
| 103 // names is empty, or the normalized company names are the same (modulo case). |
| 104 // |
| 105 // Note that this method does not provide any guidance on actually merging |
| 106 // the company names. |
| 107 bool HaveMergeableCompanyNames(const AutofillProfile& p1, |
| 108 const AutofillProfile& p2) const; |
| 109 |
| 110 // Returns true if |p1| and |p2| have phone numbers which are equivalent for |
| 111 // the purposes of merging the two profiles. This means one of the phone |
| 112 // numbers is empty, or the phone numbers match modulo formatting |
| 113 // differences or missing information. For example, if the phone numbers are |
| 114 // the same but one has an extension, country code, or area code and the other |
| 115 // does not. |
| 116 // |
| 117 // Note that this method does not provide any guidance on actually merging |
| 118 // the company names. |
| 119 bool HaveMergeablePhoneNumbers(const AutofillProfile& p1, |
| 120 const AutofillProfile& p2) const; |
| 121 |
| 122 // Returns true if |p1| and |p2| have addresses which are equivalent for the |
| 123 // purposes of merging the two profiles. This means one of the addresses is |
| 124 // empty, or the addresses are a match. A number of normalization and |
| 125 // comparison heuristics are employed to determine if the addresses match. |
| 126 // |
| 127 // Note that this method does not provide any guidance on actually merging |
| 128 // the email addresses. |
| 129 bool HaveMergeableAddresses(const AutofillProfile& p1, |
| 130 const AutofillProfile& p2) const; |
| 131 |
| 132 private: |
| 133 l10n::CaseInsensitiveCompare case_insensitive_compare_; |
| 134 std::unique_ptr<icu::Transliterator> transliterator_; |
| 135 const std::string app_locale_; |
| 136 |
| 137 DISALLOW_COPY_AND_ASSIGN(AutofillProfileComparator); |
| 138 }; |
| 139 |
| 140 } // namespace autofill |
| 141 |
| 142 #endif // COMPONENTS_AUTOFILL_CORE_BROWSER_AUTOFILL_PROFILE_COMPARATOR_H_ |
OLD | NEW |