Index: components/autofill/core/browser/autofill_profile.cc |
diff --git a/components/autofill/core/browser/autofill_profile.cc b/components/autofill/core/browser/autofill_profile.cc |
index e786bb3305950e8cf6ae7ce3fa9c35fc909686fc..36da9682ef93e1d79e769a2b201685f52c88a107 100644 |
--- a/components/autofill/core/browser/autofill_profile.cc |
+++ b/components/autofill/core/browser/autofill_profile.cc |
@@ -196,17 +196,12 @@ class FindByPhone { |
const std::string& app_locale) |
: phone_(phone), |
country_code_(country_code), |
- app_locale_(app_locale) { |
- } |
+ app_locale_(app_locale) {} |
bool operator()(const base::string16& phone) { |
return i18n::PhoneNumbersMatch(phone, phone_, country_code_, app_locale_); |
} |
- bool operator()(const base::string16* phone) { |
- return i18n::PhoneNumbersMatch(*phone, phone_, country_code_, app_locale_); |
- } |
- |
private: |
base::string16 phone_; |
std::string country_code_; |
@@ -214,13 +209,18 @@ class FindByPhone { |
}; |
// Functor used to check for case-insensitive equality of two strings. |
-struct CaseInsensitiveStringEquals |
- : public std::binary_function<base::string16, base::string16, bool> |
-{ |
- bool operator()(const base::string16& x, const base::string16& y) const { |
- return |
- x.size() == y.size() && StringToLowerASCII(x) == StringToLowerASCII(y); |
+struct CaseInsensitiveStringEquals { |
+ public: |
+ CaseInsensitiveStringEquals(const base::string16& other) |
+ : other_(other) {} |
+ |
+ bool operator()(const base::string16& x) const { |
+ return x.size() == other_.size() && |
+ StringToLowerASCII(x) == StringToLowerASCII(other_); |
} |
+ |
+ private: |
+ const base::string16& other_; |
}; |
} // namespace |
@@ -434,7 +434,8 @@ int AutofillProfile::Compare(const AutofillProfile& profile) const { |
return comparison; |
} |
- const ServerFieldType multi_value_types[] = { NAME_FIRST, |
+ const ServerFieldType multi_value_types[] = { NAME_FULL, |
+ NAME_FIRST, |
NAME_MIDDLE, |
NAME_LAST, |
EMAIL_ADDRESS, |
@@ -518,7 +519,8 @@ bool AutofillProfile::IsSubsetOf(const AutofillProfile& profile, |
} |
void AutofillProfile::OverwriteOrAppendNames( |
- const std::vector<NameInfo>& names) { |
+ const std::vector<NameInfo>& names, |
+ const std::string& app_locale) { |
std::vector<NameInfo> results(name_); |
for (std::vector<NameInfo>::const_iterator it = names.begin(); |
it != names.end(); |
@@ -528,14 +530,20 @@ void AutofillProfile::OverwriteOrAppendNames( |
for (size_t index = 0; index < name_.size(); ++index) { |
NameInfo current_name = name_[index]; |
- if (current_name.EqualsIgnoreCase(imported_name)) { |
+ if (current_name.ParsedNamesAreEqual(imported_name)) { |
+ if (current_name.GetRawInfo(NAME_FULL).empty()) { |
+ current_name.SetRawInfo(NAME_FULL, |
+ imported_name.GetRawInfo(NAME_FULL)); |
+ } |
+ |
should_append_imported_name = false; |
break; |
} |
- base::string16 full_name = current_name.GetRawInfo(NAME_FULL); |
+ AutofillType type = AutofillType(NAME_FULL); |
+ base::string16 full_name = current_name.GetInfo(type, app_locale); |
if (StringToLowerASCII(full_name) == |
- StringToLowerASCII(imported_name.GetRawInfo(NAME_FULL))) { |
+ StringToLowerASCII(imported_name.GetInfo(type, app_locale))) { |
// The imported name has the same full name string as one of the |
// existing names for this profile. Because full names are |
// _heuristically_ parsed into {first, middle, last} name components, |
@@ -545,13 +553,13 @@ void AutofillProfile::OverwriteOrAppendNames( |
// parse, as this more likely represents the correct, user-input parse |
// of the name. |
NameInfo heuristically_parsed_name; |
- heuristically_parsed_name.SetRawInfo(NAME_FULL, full_name); |
- if (imported_name.EqualsIgnoreCase(heuristically_parsed_name)) { |
+ heuristically_parsed_name.SetInfo(type, full_name, app_locale); |
+ if (imported_name.ParsedNamesAreEqual(heuristically_parsed_name)) { |
should_append_imported_name = false; |
break; |
} |
- if (current_name.EqualsIgnoreCase(heuristically_parsed_name)) { |
+ if (current_name.ParsedNamesAreEqual(heuristically_parsed_name)) { |
results[index] = imported_name; |
should_append_imported_name = false; |
break; |
@@ -589,44 +597,59 @@ void AutofillProfile::OverwriteWithOrAddTo(const AutofillProfile& profile, |
for (ServerFieldTypeSet::const_iterator iter = field_types.begin(); |
iter != field_types.end(); ++iter) { |
- if (AutofillProfile::SupportsMultiValue(*iter)) { |
- std::vector<base::string16> new_values; |
- profile.GetRawMultiInfo(*iter, &new_values); |
- std::vector<base::string16> existing_values; |
- GetRawMultiInfo(*iter, &existing_values); |
- |
- // GetMultiInfo always returns at least one element, even if the profile |
- // has no data stored for this field type. |
- if (existing_values.size() == 1 && existing_values.front().empty()) |
- existing_values.clear(); |
- |
- FieldTypeGroup group = AutofillType(*iter).group(); |
- for (std::vector<base::string16>::iterator value_iter = |
- new_values.begin(); |
- value_iter != new_values.end(); ++value_iter) { |
- // Don't add duplicates. |
- if (group == PHONE_HOME) { |
- AddPhoneIfUnique(*value_iter, app_locale, &existing_values); |
- } else { |
- std::vector<base::string16>::const_iterator existing_iter = |
- std::find_if( |
- existing_values.begin(), existing_values.end(), |
- std::bind1st(CaseInsensitiveStringEquals(), *value_iter)); |
- if (existing_iter == existing_values.end()) |
- existing_values.insert(existing_values.end(), *value_iter); |
- } |
- } |
- if (group == NAME) |
- OverwriteOrAppendNames(profile.name_); |
- else |
- SetRawMultiInfo(*iter, existing_values); |
- } else { |
+ FieldTypeGroup group = AutofillType(*iter).group(); |
+ // Special case names. |
+ if (group == NAME) { |
+ OverwriteOrAppendNames(profile.name_, app_locale); |
+ continue; |
+ } |
+ |
+ // Single value field --- overwrite. |
+ if (!AutofillProfile::SupportsMultiValue(*iter)) { |
base::string16 new_value = profile.GetRawInfo(*iter); |
if (StringToLowerASCII(GetRawInfo(*iter)) != |
StringToLowerASCII(new_value)) { |
SetRawInfo(*iter, new_value); |
} |
+ continue; |
+ } |
+ |
+ // Multi value field --- overwrite/append. |
+ std::vector<base::string16> new_values; |
+ profile.GetRawMultiInfo(*iter, &new_values); |
+ std::vector<base::string16> existing_values; |
+ GetRawMultiInfo(*iter, &existing_values); |
+ |
+ // GetMultiInfo always returns at least one element, even if the profile |
+ // has no data stored for this field type. |
+ if (existing_values.size() == 1 && existing_values.front().empty()) |
+ existing_values.clear(); |
+ |
+ for (std::vector<base::string16>::iterator value_iter = |
+ new_values.begin(); |
+ value_iter != new_values.end(); ++value_iter) { |
+ // Don't add duplicates. Most types get case insensitive matching. |
+ std::vector<base::string16>::const_iterator existing_iter; |
+ |
+ if (group == PHONE_HOME) { |
+ // Phones allow "fuzzy" matching, so "1-800-FLOWERS", "18003569377", |
+ // "(800)356-9377" and "356-9377" are considered the same. |
+ std::string country_code = |
+ base::UTF16ToASCII(GetRawInfo(ADDRESS_HOME_COUNTRY)); |
+ existing_iter = |
+ std::find_if(existing_values.begin(), existing_values.end(), |
+ FindByPhone(*value_iter, country_code, app_locale)); |
+ } else { |
+ existing_iter = |
+ std::find_if(existing_values.begin(), existing_values.end(), |
+ CaseInsensitiveStringEquals(*value_iter)); |
+ } |
+ |
+ if (existing_iter == existing_values.end()) |
+ existing_values.insert(existing_values.end(), *value_iter); |
} |
+ |
+ SetRawMultiInfo(*iter, existing_values); |
} |
} |
@@ -643,10 +666,11 @@ bool AutofillProfile::SupportsMultiValue(ServerFieldType type) { |
// static |
void AutofillProfile::CreateDifferentiatingLabels( |
const std::vector<AutofillProfile*>& profiles, |
+ const std::string& app_locale, |
std::vector<base::string16>* labels) { |
const size_t kMinimalFieldsShown = 2; |
CreateInferredLabels(profiles, NULL, UNKNOWN_TYPE, kMinimalFieldsShown, |
- labels); |
+ app_locale, labels); |
DCHECK_EQ(profiles.size(), labels->size()); |
} |
@@ -656,6 +680,7 @@ void AutofillProfile::CreateInferredLabels( |
const std::vector<ServerFieldType>* suggested_fields, |
ServerFieldType excluded_field, |
size_t minimal_fields_shown, |
+ const std::string& app_locale, |
std::vector<base::string16>* labels) { |
std::vector<ServerFieldType> fields_to_use; |
GetFieldsForDistinguishingProfiles(suggested_fields, excluded_field, |
@@ -668,7 +693,8 @@ void AutofillProfile::CreateInferredLabels( |
for (size_t i = 0; i < profiles.size(); ++i) { |
base::string16 label = |
profiles[i]->ConstructInferredLabel(fields_to_use, |
- minimal_fields_shown); |
+ minimal_fields_shown, |
+ app_locale); |
labels_to_profiles[label].push_back(i); |
} |
@@ -685,7 +711,7 @@ void AutofillProfile::CreateInferredLabels( |
// We have more than one profile with the same label, so add |
// differentiating fields. |
CreateInferredLabelsHelper(profiles, it->second, fields_to_use, |
- minimal_fields_shown, labels); |
+ minimal_fields_shown, app_locale, labels); |
} |
} |
} |
@@ -719,25 +745,10 @@ void AutofillProfile::GetMultiInfoImpl( |
} |
} |
-void AutofillProfile::AddPhoneIfUnique( |
- const base::string16& phone, |
- const std::string& app_locale, |
- std::vector<base::string16>* existing_phones) { |
- DCHECK(existing_phones); |
- // Phones allow "fuzzy" matching, so "1-800-FLOWERS", "18003569377", |
- // "(800)356-9377" and "356-9377" are considered the same. |
- std::string country_code = |
- base::UTF16ToASCII(GetRawInfo(ADDRESS_HOME_COUNTRY)); |
- if (std::find_if(existing_phones->begin(), existing_phones->end(), |
- FindByPhone(phone, country_code, app_locale)) == |
- existing_phones->end()) { |
- existing_phones->push_back(phone); |
- } |
-} |
- |
base::string16 AutofillProfile::ConstructInferredLabel( |
const std::vector<ServerFieldType>& included_fields, |
- size_t num_fields_to_use) const { |
+ size_t num_fields_to_use, |
+ const std::string& app_locale) const { |
const base::string16 separator = |
l10n_util::GetStringUTF16(IDS_AUTOFILL_ADDRESS_SUMMARY_SEPARATOR); |
@@ -747,7 +758,7 @@ base::string16 AutofillProfile::ConstructInferredLabel( |
included_fields.begin(); |
it != included_fields.end() && num_fields_used < num_fields_to_use; |
++it) { |
- base::string16 field = GetRawInfo(*it); |
+ base::string16 field = GetInfo(AutofillType(*it), app_locale); |
if (field.empty()) |
continue; |
@@ -772,6 +783,7 @@ void AutofillProfile::CreateInferredLabelsHelper( |
const std::list<size_t>& indices, |
const std::vector<ServerFieldType>& fields, |
size_t num_fields_to_include, |
+ const std::string& app_locale, |
std::vector<base::string16>* labels) { |
// For efficiency, we first construct a map of fields to their text values and |
// each value's frequency. |
@@ -785,7 +797,8 @@ void AutofillProfile::CreateInferredLabelsHelper( |
for (std::list<size_t>::const_iterator it = indices.begin(); |
it != indices.end(); ++it) { |
const AutofillProfile* profile = profiles[*it]; |
- base::string16 field_text = profile->GetRawInfo(*field); |
+ base::string16 field_text = |
+ profile->GetInfo(AutofillType(*field), app_locale); |
// If this label is not already in the map, add it with frequency 0. |
if (!field_text_frequencies.count(field_text)) |
@@ -812,7 +825,8 @@ void AutofillProfile::CreateInferredLabelsHelper( |
for (std::vector<ServerFieldType>::const_iterator field = fields.begin(); |
field != fields.end(); ++field) { |
// Skip over empty fields. |
- base::string16 field_text = profile->GetRawInfo(*field); |
+ base::string16 field_text = |
+ profile->GetInfo(AutofillType(*field), app_locale); |
if (field_text.empty()) |
continue; |
@@ -837,8 +851,8 @@ void AutofillProfile::CreateInferredLabelsHelper( |
break; |
} |
- (*labels)[*it] = |
- profile->ConstructInferredLabel(label_fields, label_fields.size()); |
+ (*labels)[*it] = profile->ConstructInferredLabel( |
+ label_fields, label_fields.size(), app_locale); |
} |
} |