| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 "chrome/browser/autofill/autofill_profile.h" | 5 #include "chrome/browser/autofill/autofill_profile.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <set> | 8 #include <set> |
| 9 | 9 |
| 10 #include "base/stl_util-inl.h" | 10 #include "base/stl_util-inl.h" |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 141 (*it)->GetPossibleFieldTypes(text, possible_types); | 141 (*it)->GetPossibleFieldTypes(text, possible_types); |
| 142 } | 142 } |
| 143 | 143 |
| 144 void AutofillProfile::GetAvailableFieldTypes( | 144 void AutofillProfile::GetAvailableFieldTypes( |
| 145 FieldTypeSet* available_types) const { | 145 FieldTypeSet* available_types) const { |
| 146 FormGroupList info = info_list(); | 146 FormGroupList info = info_list(); |
| 147 for (FormGroupList::const_iterator it = info.begin(); it != info.end(); ++it) | 147 for (FormGroupList::const_iterator it = info.begin(); it != info.end(); ++it) |
| 148 (*it)->GetAvailableFieldTypes(available_types); | 148 (*it)->GetAvailableFieldTypes(available_types); |
| 149 } | 149 } |
| 150 | 150 |
| 151 string16 AutofillProfile::GetFieldText(const AutofillType& type) const { | 151 string16 AutofillProfile::GetFieldText(AutofillFieldType type) const { |
| 152 AutofillType return_type( | 152 AutofillFieldType return_type = AutofillType::GetEquivalentFieldType(type); |
| 153 AutofillType::GetEquivalentFieldType(type.field_type())); | |
| 154 | 153 |
| 155 FormGroupMap info = info_map(); | 154 FormGroupMap info = info_map(); |
| 156 FormGroupMap::const_iterator it = info.find(return_type.group()); | 155 FormGroupMap::const_iterator it = |
| 156 info.find(AutofillType(return_type).group()); |
| 157 if (it == info.end()) | 157 if (it == info.end()) |
| 158 return string16(); | 158 return string16(); |
| 159 | 159 |
| 160 return it->second->GetFieldText(return_type); | 160 return it->second->GetFieldText(return_type); |
| 161 } | 161 } |
| 162 | 162 |
| 163 void AutofillProfile::FindInfoMatches( | 163 void AutofillProfile::FindInfoMatches( |
| 164 const AutofillType& type, | 164 AutofillFieldType type, |
| 165 const string16& value, | 165 const string16& value, |
| 166 std::vector<string16>* matched_text) const { | 166 std::vector<string16>* matched_text) const { |
| 167 if (matched_text == NULL) { | 167 if (matched_text == NULL) { |
| 168 DLOG(ERROR) << "NULL matched text passed in"; | 168 DLOG(ERROR) << "NULL matched text passed in"; |
| 169 return; | 169 return; |
| 170 } | 170 } |
| 171 | 171 |
| 172 string16 clean_info = StringToLowerASCII(CollapseWhitespace(value, false)); | 172 string16 clean_info = StringToLowerASCII(CollapseWhitespace(value, false)); |
| 173 | 173 |
| 174 // If the field_type is unknown, then match against all field types. | 174 // If the field_type is unknown, then match against all field types. |
| 175 if (type.field_type() == UNKNOWN_TYPE) { | 175 if (type == UNKNOWN_TYPE) { |
| 176 FormGroupList info = info_list(); | 176 FormGroupList info = info_list(); |
| 177 for (FormGroupList::const_iterator it = info.begin(); | 177 for (FormGroupList::const_iterator it = info.begin(); |
| 178 it != info.end(); ++it) | 178 it != info.end(); ++it) |
| 179 (*it)->FindInfoMatches(type, clean_info, matched_text); | 179 (*it)->FindInfoMatches(type, clean_info, matched_text); |
| 180 } else { | 180 } else { |
| 181 FormGroupMap info = info_map(); | 181 FormGroupMap info = info_map(); |
| 182 FormGroupMap::const_iterator it = info.find(type.group()); | 182 FormGroupMap::const_iterator it = info.find(AutofillType(type).group()); |
| 183 if (it != info.end()) | 183 if (it != info.end()) |
| 184 it->second->FindInfoMatches(type, clean_info, matched_text); | 184 it->second->FindInfoMatches(type, clean_info, matched_text); |
| 185 } | 185 } |
| 186 } | 186 } |
| 187 | 187 |
| 188 void AutofillProfile::SetInfo(const AutofillType& type, const string16& value) { | 188 void AutofillProfile::SetInfo(AutofillFieldType type, const string16& value) { |
| 189 MutableFormGroupMap info = mutable_info_map(); | 189 MutableFormGroupMap info = mutable_info_map(); |
| 190 MutableFormGroupMap::iterator it = info.find(type.group()); | 190 MutableFormGroupMap::iterator it = info.find(AutofillType(type).group()); |
| 191 if (it != info.end()) | 191 if (it != info.end()) |
| 192 it->second->SetInfo(type, CollapseWhitespace(value, false)); | 192 it->second->SetInfo(type, CollapseWhitespace(value, false)); |
| 193 } | 193 } |
| 194 | 194 |
| 195 const string16 AutofillProfile::Label() const { | 195 const string16 AutofillProfile::Label() const { |
| 196 return label_; | 196 return label_; |
| 197 } | 197 } |
| 198 | 198 |
| 199 const std::string AutofillProfile::CountryCode() const { | 199 const std::string AutofillProfile::CountryCode() const { |
| 200 return address_.country_code(); | 200 return address_.country_code(); |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 284 ADDRESS_HOME_LINE1, | 284 ADDRESS_HOME_LINE1, |
| 285 ADDRESS_HOME_LINE2, | 285 ADDRESS_HOME_LINE2, |
| 286 ADDRESS_HOME_CITY, | 286 ADDRESS_HOME_CITY, |
| 287 ADDRESS_HOME_STATE, | 287 ADDRESS_HOME_STATE, |
| 288 ADDRESS_HOME_ZIP, | 288 ADDRESS_HOME_ZIP, |
| 289 ADDRESS_HOME_COUNTRY, | 289 ADDRESS_HOME_COUNTRY, |
| 290 PHONE_HOME_NUMBER, | 290 PHONE_HOME_NUMBER, |
| 291 PHONE_FAX_NUMBER }; | 291 PHONE_FAX_NUMBER }; |
| 292 | 292 |
| 293 for (size_t index = 0; index < arraysize(types); ++index) { | 293 for (size_t index = 0; index < arraysize(types); ++index) { |
| 294 int comparison = GetFieldText(AutofillType(types[index])).compare( | 294 int comparison = GetFieldText(types[index]).compare( |
| 295 profile.GetFieldText(AutofillType(types[index]))); | 295 profile.GetFieldText(types[index])); |
| 296 if (comparison != 0) | 296 if (comparison != 0) |
| 297 return comparison; | 297 return comparison; |
| 298 } | 298 } |
| 299 | 299 |
| 300 return 0; | 300 return 0; |
| 301 } | 301 } |
| 302 | 302 |
| 303 bool AutofillProfile::operator==(const AutofillProfile& profile) const { | 303 bool AutofillProfile::operator==(const AutofillProfile& profile) const { |
| 304 return guid_ == profile.guid_ && Compare(profile) == 0; | 304 return guid_ == profile.guid_ && Compare(profile) == 0; |
| 305 } | 305 } |
| 306 | 306 |
| 307 bool AutofillProfile::operator!=(const AutofillProfile& profile) const { | 307 bool AutofillProfile::operator!=(const AutofillProfile& profile) const { |
| 308 return !operator==(profile); | 308 return !operator==(profile); |
| 309 } | 309 } |
| 310 | 310 |
| 311 const string16 AutofillProfile::PrimaryValue() const { | 311 const string16 AutofillProfile::PrimaryValue() const { |
| 312 return GetFieldText(AutofillType(NAME_FULL)) + | 312 return GetFieldText(NAME_FULL) + |
| 313 GetFieldText(AutofillType(ADDRESS_HOME_LINE1)) + | 313 GetFieldText(ADDRESS_HOME_LINE1) + |
| 314 GetFieldText(AutofillType(ADDRESS_HOME_LINE2)) + | 314 GetFieldText(ADDRESS_HOME_LINE2) + |
| 315 GetFieldText(AutofillType(EMAIL_ADDRESS)); | 315 GetFieldText(EMAIL_ADDRESS); |
| 316 } | 316 } |
| 317 | 317 |
| 318 string16 AutofillProfile::ConstructInferredLabel( | 318 string16 AutofillProfile::ConstructInferredLabel( |
| 319 const std::vector<AutofillFieldType>& included_fields, | 319 const std::vector<AutofillFieldType>& included_fields, |
| 320 size_t num_fields_to_use) const { | 320 size_t num_fields_to_use) const { |
| 321 const string16 separator = | 321 const string16 separator = |
| 322 l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_ADDRESS_SUMMARY_SEPARATOR); | 322 l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_ADDRESS_SUMMARY_SEPARATOR); |
| 323 | 323 |
| 324 string16 label; | 324 string16 label; |
| 325 size_t num_fields_used = 0; | 325 size_t num_fields_used = 0; |
| 326 for (std::vector<AutofillFieldType>::const_iterator it = | 326 for (std::vector<AutofillFieldType>::const_iterator it = |
| 327 included_fields.begin(); | 327 included_fields.begin(); |
| 328 it != included_fields.end() && num_fields_used < num_fields_to_use; | 328 it != included_fields.end() && num_fields_used < num_fields_to_use; |
| 329 ++it) { | 329 ++it) { |
| 330 string16 field = GetFieldText(AutofillType(*it)); | 330 string16 field = GetFieldText(*it); |
| 331 if (field.empty()) | 331 if (field.empty()) |
| 332 continue; | 332 continue; |
| 333 | 333 |
| 334 if (!label.empty()) | 334 if (!label.empty()) |
| 335 label.append(separator); | 335 label.append(separator); |
| 336 | 336 |
| 337 // Fax number has special format, to indicate that this is a fax number. | 337 // Fax number has special format, to indicate that this is a fax number. |
| 338 if (*it == PHONE_FAX_WHOLE_NUMBER) { | 338 if (*it == PHONE_FAX_WHOLE_NUMBER) { |
| 339 field = l10n_util::GetStringFUTF16( | 339 field = l10n_util::GetStringFUTF16( |
| 340 IDS_AUTOFILL_DIALOG_ADDRESS_SUMMARY_FAX_FORMAT, field); | 340 IDS_AUTOFILL_DIALOG_ADDRESS_SUMMARY_FAX_FORMAT, field); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 357 std::map<AutofillFieldType, | 357 std::map<AutofillFieldType, |
| 358 std::map<string16, size_t> > field_text_frequencies_by_field; | 358 std::map<string16, size_t> > field_text_frequencies_by_field; |
| 359 for (std::vector<AutofillFieldType>::const_iterator field = fields.begin(); | 359 for (std::vector<AutofillFieldType>::const_iterator field = fields.begin(); |
| 360 field != fields.end(); ++field) { | 360 field != fields.end(); ++field) { |
| 361 std::map<string16, size_t>& field_text_frequencies = | 361 std::map<string16, size_t>& field_text_frequencies = |
| 362 field_text_frequencies_by_field[*field]; | 362 field_text_frequencies_by_field[*field]; |
| 363 | 363 |
| 364 for (std::list<size_t>::const_iterator it = indices.begin(); | 364 for (std::list<size_t>::const_iterator it = indices.begin(); |
| 365 it != indices.end(); ++it) { | 365 it != indices.end(); ++it) { |
| 366 const AutofillProfile* profile = profiles[*it]; | 366 const AutofillProfile* profile = profiles[*it]; |
| 367 string16 field_text = profile->GetFieldText(AutofillType(*field)); | 367 string16 field_text = profile->GetFieldText(*field); |
| 368 | 368 |
| 369 // If this label is not already in the map, add it with frequency 0. | 369 // If this label is not already in the map, add it with frequency 0. |
| 370 if (!field_text_frequencies.count(field_text)) | 370 if (!field_text_frequencies.count(field_text)) |
| 371 field_text_frequencies[field_text] = 0; | 371 field_text_frequencies[field_text] = 0; |
| 372 | 372 |
| 373 // Now, increment the frequency for this label. | 373 // Now, increment the frequency for this label. |
| 374 ++field_text_frequencies[field_text]; | 374 ++field_text_frequencies[field_text]; |
| 375 } | 375 } |
| 376 } | 376 } |
| 377 | 377 |
| 378 // Now comes the meat of the algorithm. For each profile, we scan the list of | 378 // Now comes the meat of the algorithm. For each profile, we scan the list of |
| 379 // fields to use, looking for two things: | 379 // fields to use, looking for two things: |
| 380 // 1. A (non-empty) field that differentiates the profile from all others | 380 // 1. A (non-empty) field that differentiates the profile from all others |
| 381 // 2. At least |num_fields_to_include| non-empty fields | 381 // 2. At least |num_fields_to_include| non-empty fields |
| 382 // Before we've satisfied condition (2), we include all fields, even ones that | 382 // Before we've satisfied condition (2), we include all fields, even ones that |
| 383 // are identical across all the profiles. Once we've satisfied condition (2), | 383 // are identical across all the profiles. Once we've satisfied condition (2), |
| 384 // we only include fields that that have at last two distinct values. | 384 // we only include fields that that have at last two distinct values. |
| 385 for (std::list<size_t>::const_iterator it = indices.begin(); | 385 for (std::list<size_t>::const_iterator it = indices.begin(); |
| 386 it != indices.end(); ++it) { | 386 it != indices.end(); ++it) { |
| 387 const AutofillProfile* profile = profiles[*it]; | 387 const AutofillProfile* profile = profiles[*it]; |
| 388 | 388 |
| 389 std::vector<AutofillFieldType> label_fields; | 389 std::vector<AutofillFieldType> label_fields; |
| 390 bool found_differentiating_field = false; | 390 bool found_differentiating_field = false; |
| 391 for (std::vector<AutofillFieldType>::const_iterator field = fields.begin(); | 391 for (std::vector<AutofillFieldType>::const_iterator field = fields.begin(); |
| 392 field != fields.end(); ++field) { | 392 field != fields.end(); ++field) { |
| 393 // Skip over empty fields. | 393 // Skip over empty fields. |
| 394 string16 field_text = profile->GetFieldText(AutofillType(*field)); | 394 string16 field_text = profile->GetFieldText(*field); |
| 395 if (field_text.empty()) | 395 if (field_text.empty()) |
| 396 continue; | 396 continue; |
| 397 | 397 |
| 398 std::map<string16, size_t>& field_text_frequencies = | 398 std::map<string16, size_t>& field_text_frequencies = |
| 399 field_text_frequencies_by_field[*field]; | 399 field_text_frequencies_by_field[*field]; |
| 400 found_differentiating_field |= | 400 found_differentiating_field |= |
| 401 !field_text_frequencies.count(string16()) && | 401 !field_text_frequencies.count(string16()) && |
| 402 (field_text_frequencies[field_text] == 1); | 402 (field_text_frequencies[field_text] == 1); |
| 403 | 403 |
| 404 // Once we've found enough non-empty fields, skip over any remaining | 404 // Once we've found enough non-empty fields, skip over any remaining |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 454 return m; | 454 return m; |
| 455 } | 455 } |
| 456 | 456 |
| 457 // So we can compare AutofillProfiles with EXPECT_EQ(). | 457 // So we can compare AutofillProfiles with EXPECT_EQ(). |
| 458 std::ostream& operator<<(std::ostream& os, const AutofillProfile& profile) { | 458 std::ostream& operator<<(std::ostream& os, const AutofillProfile& profile) { |
| 459 return os | 459 return os |
| 460 << UTF16ToUTF8(profile.Label()) | 460 << UTF16ToUTF8(profile.Label()) |
| 461 << " " | 461 << " " |
| 462 << profile.guid() | 462 << profile.guid() |
| 463 << " " | 463 << " " |
| 464 << UTF16ToUTF8(profile.GetFieldText(AutofillType(NAME_FIRST))) | 464 << UTF16ToUTF8(profile.GetFieldText(NAME_FIRST)) |
| 465 << " " | 465 << " " |
| 466 << UTF16ToUTF8(profile.GetFieldText(AutofillType(NAME_MIDDLE))) | 466 << UTF16ToUTF8(profile.GetFieldText(NAME_MIDDLE)) |
| 467 << " " | 467 << " " |
| 468 << UTF16ToUTF8(profile.GetFieldText(AutofillType(NAME_LAST))) | 468 << UTF16ToUTF8(profile.GetFieldText(NAME_LAST)) |
| 469 << " " | 469 << " " |
| 470 << UTF16ToUTF8(profile.GetFieldText(AutofillType(EMAIL_ADDRESS))) | 470 << UTF16ToUTF8(profile.GetFieldText(EMAIL_ADDRESS)) |
| 471 << " " | 471 << " " |
| 472 << UTF16ToUTF8(profile.GetFieldText(AutofillType(COMPANY_NAME))) | 472 << UTF16ToUTF8(profile.GetFieldText(COMPANY_NAME)) |
| 473 << " " | 473 << " " |
| 474 << UTF16ToUTF8(profile.GetFieldText(AutofillType(ADDRESS_HOME_LINE1))) | 474 << UTF16ToUTF8(profile.GetFieldText(ADDRESS_HOME_LINE1)) |
| 475 << " " | 475 << " " |
| 476 << UTF16ToUTF8(profile.GetFieldText(AutofillType(ADDRESS_HOME_LINE2))) | 476 << UTF16ToUTF8(profile.GetFieldText(ADDRESS_HOME_LINE2)) |
| 477 << " " | 477 << " " |
| 478 << UTF16ToUTF8(profile.GetFieldText(AutofillType(ADDRESS_HOME_CITY))) | 478 << UTF16ToUTF8(profile.GetFieldText(ADDRESS_HOME_CITY)) |
| 479 << " " | 479 << " " |
| 480 << UTF16ToUTF8(profile.GetFieldText(AutofillType(ADDRESS_HOME_STATE))) | 480 << UTF16ToUTF8(profile.GetFieldText(ADDRESS_HOME_STATE)) |
| 481 << " " | 481 << " " |
| 482 << UTF16ToUTF8(profile.GetFieldText(AutofillType(ADDRESS_HOME_ZIP))) | 482 << UTF16ToUTF8(profile.GetFieldText(ADDRESS_HOME_ZIP)) |
| 483 << " " | 483 << " " |
| 484 << UTF16ToUTF8(profile.GetFieldText(AutofillType(ADDRESS_HOME_COUNTRY))) | 484 << UTF16ToUTF8(profile.GetFieldText(ADDRESS_HOME_COUNTRY)) |
| 485 << " " | 485 << " " |
| 486 << UTF16ToUTF8(profile.GetFieldText(AutofillType( | 486 << UTF16ToUTF8(profile.GetFieldText(PHONE_HOME_WHOLE_NUMBER)) |
| 487 PHONE_HOME_WHOLE_NUMBER))) | |
| 488 << " " | 487 << " " |
| 489 << UTF16ToUTF8(profile.GetFieldText(AutofillType( | 488 << UTF16ToUTF8(profile.GetFieldText(PHONE_FAX_WHOLE_NUMBER)); |
| 490 PHONE_FAX_WHOLE_NUMBER))); | |
| 491 } | 489 } |
| OLD | NEW |