Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(42)

Side by Side Diff: components/autofill/core/browser/autofill_profile.cc

Issue 2041413004: Add an AutofillProfileComparator class. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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.h" 5 #include "components/autofill/core/browser/autofill_profile.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <functional> 8 #include <functional>
9 #include <map> 9 #include <map>
10 #include <memory> 10 #include <memory>
11 #include <ostream> 11 #include <ostream>
12 #include <set> 12 #include <set>
13 13
14 #include "base/guid.h" 14 #include "base/guid.h"
15 #include "base/i18n/case_conversion.h" 15 #include "base/i18n/case_conversion.h"
16 #include "base/i18n/char_iterator.h" 16 #include "base/i18n/char_iterator.h"
17 #include "base/logging.h" 17 #include "base/logging.h"
18 #include "base/macros.h" 18 #include "base/macros.h"
19 #include "base/metrics/histogram_macros.h" 19 #include "base/metrics/histogram_macros.h"
20 #include "base/sha1.h" 20 #include "base/sha1.h"
21 #include "base/strings/string_util.h" 21 #include "base/strings/string_util.h"
22 #include "base/strings/utf_string_conversion_utils.h" 22 #include "base/strings/utf_string_conversion_utils.h"
23 #include "base/strings/utf_string_conversions.h" 23 #include "base/strings/utf_string_conversions.h"
24 #include "components/autofill/core/browser/address.h" 24 #include "components/autofill/core/browser/address.h"
25 #include "components/autofill/core/browser/address_i18n.h" 25 #include "components/autofill/core/browser/address_i18n.h"
26 #include "components/autofill/core/browser/autofill_country.h" 26 #include "components/autofill/core/browser/autofill_country.h"
27 #include "components/autofill/core/browser/autofill_field.h" 27 #include "components/autofill/core/browser/autofill_field.h"
28 #include "components/autofill/core/browser/autofill_metrics.h" 28 #include "components/autofill/core/browser/autofill_metrics.h"
29 #include "components/autofill/core/browser/autofill_profile_comparator.h"
29 #include "components/autofill/core/browser/autofill_type.h" 30 #include "components/autofill/core/browser/autofill_type.h"
30 #include "components/autofill/core/browser/contact_info.h" 31 #include "components/autofill/core/browser/contact_info.h"
31 #include "components/autofill/core/browser/phone_number.h" 32 #include "components/autofill/core/browser/phone_number.h"
32 #include "components/autofill/core/browser/phone_number_i18n.h" 33 #include "components/autofill/core/browser/phone_number_i18n.h"
33 #include "components/autofill/core/browser/state_names.h" 34 #include "components/autofill/core/browser/state_names.h"
34 #include "components/autofill/core/browser/validation.h" 35 #include "components/autofill/core/browser/validation.h"
35 #include "components/autofill/core/common/autofill_l10n_util.h" 36 #include "components/autofill/core/common/autofill_l10n_util.h"
36 #include "components/autofill/core/common/form_field_data.h" 37 #include "components/autofill/core/common/form_field_data.h"
37 #include "grit/components_strings.h" 38 #include "grit/components_strings.h"
38 #include "third_party/icu/source/common/unicode/uchar.h" 39 #include "third_party/icu/source/common/unicode/uchar.h"
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after
211 collapsed_set.insert(PHONE_HOME_WHOLE_NUMBER); 212 collapsed_set.insert(PHONE_HOME_WHOLE_NUMBER);
212 break; 213 break;
213 214
214 default: 215 default:
215 collapsed_set.insert(it); 216 collapsed_set.insert(it);
216 } 217 }
217 } 218 }
218 std::swap(*type_set, collapsed_set); 219 std::swap(*type_set, collapsed_set);
219 } 220 }
220 221
221 base::string16 NormalizeForComparison(const base::string16& text) {
222 using icu::UnicodeString;
223 using icu::Transliterator;
224
225 // Use ICU transliteration to remove diacritics and fold case.
226 // See http://userguide.icu-project.org/transforms/general
227 UErrorCode status = U_ZERO_ERROR;
228 std::unique_ptr<Transliterator> transliterator(Transliterator::createInstance(
229 "NFD; [:Nonspacing Mark:] Remove; Lower; NFC", UTRANS_FORWARD, status));
230 if (U_FAILURE(status) || transliterator == nullptr) {
231 LOG(ERROR) << "Failed to create ICU Transliterator: "
232 << u_errorName(status);
233 return text;
234 }
235
236 UnicodeString value = UnicodeString(text.data(), text.length());
237 transliterator->transliterate(value);
238
239 return base::string16(value.getBuffer(), value.length());
240 }
241
242 } // namespace 222 } // namespace
243 223
244 AutofillProfile::AutofillProfile(const std::string& guid, 224 AutofillProfile::AutofillProfile(const std::string& guid,
245 const std::string& origin) 225 const std::string& origin)
246 : AutofillDataModel(guid, origin), 226 : AutofillDataModel(guid, origin),
247 record_type_(LOCAL_PROFILE), 227 record_type_(LOCAL_PROFILE),
248 phone_number_(this) { 228 phone_number_(this) {
249 } 229 }
250 230
251 AutofillProfile::AutofillProfile(RecordType type, const std::string& server_id) 231 AutofillProfile::AutofillProfile(RecordType type, const std::string& server_id)
(...skipping 536 matching lines...) Expand 10 before | Expand all | Expand 10 after
788 768
789 void AutofillProfile::RecordAndLogUse() { 769 void AutofillProfile::RecordAndLogUse() {
790 UMA_HISTOGRAM_COUNTS_1000("Autofill.DaysSinceLastUse.Profile", 770 UMA_HISTOGRAM_COUNTS_1000("Autofill.DaysSinceLastUse.Profile",
791 (base::Time::Now() - use_date()).InDays()); 771 (base::Time::Now() - use_date()).InDays());
792 RecordUse(); 772 RecordUse();
793 } 773 }
794 774
795 // static 775 // static
796 base::string16 AutofillProfile::CanonicalizeProfileString( 776 base::string16 AutofillProfile::CanonicalizeProfileString(
797 const base::string16& str) { 777 const base::string16& str) {
798 base::string16 ret; 778 // The locale doesn't matter for general string canonicalization.
799 ret.reserve(str.size()); 779 AutofillProfileComparator comparator("en-US");
800 780 return comparator.NormalizeForComparison(str);
801 // This algorithm is not designed to be perfect, we could get arbitrarily
802 // fancy here trying to canonicalize address lines. Instead, this is designed
803 // to handle common cases for all types of data (addresses and names) without
804 // the need of domain-specific logic.
805 //
806 // 1. Convert punctuation to spaces and normalize all whitespace to spaces.
807 // This will convert "Mid-Island Plz." -> "Mid Island Plz " (the trailing
808 // space will be trimmed off outside of the end of the loop).
809 //
810 // 2. Collapse consecutive punctuation/whitespace characters to a single
811 // space. We pretend the string has already started with whitespace in
812 // order to trim leading spaces.
813 //
814 // 3. Remove diacritics (accents and other non-spacing marks) and perform
815 // case folding to lower-case.
816
817 bool previous_was_whitespace = true;
818 for (base::i18n::UTF16CharIterator iter(&str); !iter.end(); iter.Advance()) {
819 switch (u_charType(iter.get())) {
820 // Punctuation
821 case U_DASH_PUNCTUATION:
822 case U_START_PUNCTUATION:
823 case U_END_PUNCTUATION:
824 case U_CONNECTOR_PUNCTUATION:
825 case U_OTHER_PUNCTUATION:
826 // Whitespace
827 case U_CONTROL_CHAR: // To escape the '\n' character.
828 case U_SPACE_SEPARATOR:
829 case U_LINE_SEPARATOR:
830 case U_PARAGRAPH_SEPARATOR:
831 if (!previous_was_whitespace) {
832 ret.push_back(' ');
833 previous_was_whitespace = true;
834 }
835 break;
836
837 default:
838 previous_was_whitespace = false;
839 base::WriteUnicodeCharacter(iter.get(), &ret);
840 break;
841 }
842 }
843
844 // Trim off trailing whitespace if we left one.
845 if (previous_was_whitespace && !ret.empty())
846 ret.resize(ret.size() - 1);
847
848 // Remove diacritics and perform case folding.
849 return NormalizeForComparison(ret);
850 }
851
852 // static
853 bool AutofillProfile::AreProfileStringsSimilar(const base::string16& a,
854 const base::string16& b) {
855 return CanonicalizeProfileString(a) == CanonicalizeProfileString(b);
856 } 781 }
857 782
858 void AutofillProfile::GetSupportedTypes( 783 void AutofillProfile::GetSupportedTypes(
859 ServerFieldTypeSet* supported_types) const { 784 ServerFieldTypeSet* supported_types) const {
860 FormGroupList info = FormGroups(); 785 FormGroupList info = FormGroups();
861 for (const auto& it : info) { 786 for (const auto& it : info) {
862 it->GetSupportedTypes(supported_types); 787 it->GetSupportedTypes(supported_types);
863 } 788 }
864 } 789 }
865 790
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after
1084 << " " << UTF16ToUTF8(profile.GetRawInfo(ADDRESS_HOME_CITY)) << " " 1009 << " " << UTF16ToUTF8(profile.GetRawInfo(ADDRESS_HOME_CITY)) << " "
1085 << UTF16ToUTF8(profile.GetRawInfo(ADDRESS_HOME_STATE)) << " " 1010 << UTF16ToUTF8(profile.GetRawInfo(ADDRESS_HOME_STATE)) << " "
1086 << UTF16ToUTF8(profile.GetRawInfo(ADDRESS_HOME_ZIP)) << " " 1011 << UTF16ToUTF8(profile.GetRawInfo(ADDRESS_HOME_ZIP)) << " "
1087 << UTF16ToUTF8(profile.GetRawInfo(ADDRESS_HOME_SORTING_CODE)) << " " 1012 << UTF16ToUTF8(profile.GetRawInfo(ADDRESS_HOME_SORTING_CODE)) << " "
1088 << UTF16ToUTF8(profile.GetRawInfo(ADDRESS_HOME_COUNTRY)) << " " 1013 << UTF16ToUTF8(profile.GetRawInfo(ADDRESS_HOME_COUNTRY)) << " "
1089 << profile.language_code() << " " 1014 << profile.language_code() << " "
1090 << UTF16ToUTF8(profile.GetRawInfo(PHONE_HOME_WHOLE_NUMBER)); 1015 << UTF16ToUTF8(profile.GetRawInfo(PHONE_HOME_WHOLE_NUMBER));
1091 } 1016 }
1092 1017
1093 } // namespace autofill 1018 } // namespace autofill
OLDNEW
« no previous file with comments | « components/autofill/core/browser/autofill_profile.h ('k') | components/autofill/core/browser/autofill_profile_comparator.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698