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 |