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. | |
Mathieu
2016/06/10 14:10:57
nit: mention that there is no directionality
Roger McFarlane (Chromium)
2016/06/10 16:19:44
Done.
| |
43 bool AreMergeable(const AutofillProfile& p1, const AutofillProfile& p2) const; | |
44 | |
45 protected: | |
46 // Returns the set of unique tokens in |s|. Note that the string data backing | |
47 // |s| is expected to have a lifetime which exceeds the call to UniqueTokens. | |
48 static std::set<base::StringPiece16> UniqueTokens(base::StringPiece16 s); | |
49 | |
50 // Returns true if all of the tokens in |s1| are in |s2| or vice versa. | |
51 static bool HaveSameTokens(base::StringPiece16 s1, base::StringPiece16 s2); | |
52 | |
53 // Generate the set of full/initial variants for |name|. For example, given | |
54 // "jean francois" (the normalized for comparison form of "Jean-François") | |
55 // this function returns the set: | |
56 // | |
57 // { "", "f", "francois, | |
58 // "j", "j f", "j francois", | |
59 // "jean", "jean f", "jean francois" } | |
60 // | |
61 // Note: Expects that |name| is already normalized for comparison. | |
62 static std::set<base::string16> GetNameVariants(const base::string16& name); | |
63 | |
64 // Returns true if |full_name_2| is a variant of |full_name_1|. | |
65 // | |
66 // This function generates all variations of |full_name_1| and returns true if | |
67 // one of these variants is equal to |full_name_2|. For example, this function | |
68 // will return true if |full_name_2| is "john q public" and |full_name_1| is | |
69 // "john quincy public" because |full_name_2| can be derived from | |
70 // |full_name_1| by using the middle initial. Note that the reverse is not | |
71 // true, "john quincy public" is not a name variant of "john q public". | |
72 // | |
73 // Note: Expects that |full_name| is already normalized for comparison. | |
74 bool IsNameVariantOf(const base::string16& full_name_1, | |
75 const base::string16& full_name_2) const; | |
76 | |
77 // Returns true if |p1| and |p2| have names which are equivalent for the | |
78 // purposes of merging the two profiles. This means one of the names is | |
79 // empty, the names are the same, or one name is a variation of the other. | |
80 // The name comparison is insensitive to case, punctuation and diacritics. | |
81 // | |
82 // Note that this method does not provide any guidance on actually merging | |
83 // the names. | |
84 bool HaveMergeableNames(const AutofillProfile& p1, | |
85 const AutofillProfile& p2) const; | |
86 | |
87 // Returns true if |p1| and |p2| have email addresses which are equivalent for | |
88 // the purposes of merging the two profiles. This means one of the email | |
89 // addresses is empty, or the email addresses are the same (modulo case). | |
90 // | |
91 // Note that this method does not provide any guidance on actually merging | |
92 // the email addresses. | |
93 bool HaveMergeableEmailAddresses(const AutofillProfile& p1, | |
94 const AutofillProfile& p2) const; | |
95 | |
96 // Returns true if |p1| and |p2| have company names which are equivalent for | |
97 // the purposes of merging the two profiles. This means one of the company | |
98 // names is empty, or the normalized company names are the same (modulo case). | |
99 // | |
100 // Note that this method does not provide any guidance on actually merging | |
101 // the company names. | |
102 bool HaveMergeableCompanyNames(const AutofillProfile& p1, | |
103 const AutofillProfile& p2) const; | |
104 | |
105 // Returns true if |p1| and |p2| have phone numbers which are equivalent for | |
106 // the purposes of merging the two profiles. This means one of the phone | |
107 // numbers is empty, or the phone numbers match modulo formatting | |
108 // differences or missing information. For example, if the phone numbers are | |
109 // the same but one has an extension, country code, or area code and the other | |
110 // does not. | |
111 // | |
112 // Note that this method does not provide any guidance on actually merging | |
113 // the company names. | |
114 bool HaveMergeablePhoneNumbers(const AutofillProfile& p1, | |
115 const AutofillProfile& p2) const; | |
116 | |
117 // Returns true if |p1| and |p2| have addresses which are equivalent for the | |
118 // purposes of merging the two profiles. This means one of the addresses is | |
119 // empty, or the addresses are a match. A number of normalization and | |
120 // comparison heuristics are employed to determine if the addresses match. | |
121 // | |
122 // Note that this method does not provide any guidance on actually merging | |
123 // the email addresses. | |
124 bool HaveMergeableAddresses(const AutofillProfile& p1, | |
125 const AutofillProfile& p2) const; | |
126 | |
127 private: | |
128 l10n::CaseInsensitiveCompare case_insensitive_compare_; | |
129 std::unique_ptr<icu::Transliterator> transliterator_; | |
130 const std::string app_locale_; | |
131 | |
132 DISALLOW_COPY_AND_ASSIGN(AutofillProfileComparator); | |
133 }; | |
134 | |
135 } // namespace autofill | |
136 | |
137 #endif // COMPONENTS_AUTOFILL_CORE_BROWSER_AUTOFILL_PROFILE_COMPARATOR_H_ | |
OLD | NEW |