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 <map> | 8 #include <map> |
9 #include <set> | 9 #include <set> |
10 | 10 |
11 #include "base/basictypes.h" | 11 #include "base/basictypes.h" |
12 #include "base/logging.h" | 12 #include "base/logging.h" |
13 #include "base/string_util.h" | 13 #include "base/string_util.h" |
14 #include "base/utf_string_conversions.h" | 14 #include "base/utf_string_conversions.h" |
15 #include "chrome/browser/autofill/address.h" | 15 #include "chrome/browser/autofill/address.h" |
16 #include "chrome/browser/autofill/autofill_type.h" | 16 #include "chrome/browser/autofill/autofill_type.h" |
17 #include "chrome/browser/autofill/contact_info.h" | 17 #include "chrome/browser/autofill/contact_info.h" |
18 #include "chrome/browser/autofill/fax_number.h" | 18 #include "chrome/browser/autofill/phone_number.h" |
19 #include "chrome/browser/autofill/home_phone_number.h" | 19 #include "chrome/browser/autofill/phone_number_i18n.h" |
20 #include "chrome/common/guid.h" | 20 #include "chrome/common/guid.h" |
21 #include "grit/generated_resources.h" | 21 #include "grit/generated_resources.h" |
22 #include "ui/base/l10n/l10n_util.h" | 22 #include "ui/base/l10n/l10n_util.h" |
23 | 23 |
24 namespace { | 24 namespace { |
25 | 25 |
26 // Like |AutofillType::GetEquivalentFieldType()|, but also returns |NAME_FULL| | 26 // Like |AutofillType::GetEquivalentFieldType()|, but also returns |NAME_FULL| |
27 // for first, middle, and last name field types. | 27 // for first, middle, and last name field types. |
28 AutofillFieldType GetEquivalentFieldTypeCollapsingNames( | 28 AutofillFieldType GetEquivalentFieldTypeCollapsingNames( |
29 AutofillFieldType field_type) { | 29 AutofillFieldType field_type) { |
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
171 collapsed_set.insert(*iter); | 171 collapsed_set.insert(*iter); |
172 } | 172 } |
173 } | 173 } |
174 std::swap(*type_set, collapsed_set); | 174 std::swap(*type_set, collapsed_set); |
175 } | 175 } |
176 | 176 |
177 } // namespace | 177 } // namespace |
178 | 178 |
179 AutofillProfile::AutofillProfile(const std::string& guid) | 179 AutofillProfile::AutofillProfile(const std::string& guid) |
180 : guid_(guid), name_(1), email_(1), home_number_(1), fax_number_(1) { | 180 : guid_(guid), name_(1), email_(1), home_number_(1), fax_number_(1) { |
181 // Set the type of the phones - it is set on first SetInfo() call. | |
dhollowa
2011/05/13 18:55:35
Better to use the vector initializer to set the ph
GeorgeY
2011/05/18 17:41:45
Done.
| |
182 home_number_[0].SetInfo(PHONE_HOME_WHOLE_NUMBER, string16()); | |
183 fax_number_[0].SetInfo(PHONE_FAX_WHOLE_NUMBER, string16()); | |
181 } | 184 } |
182 | 185 |
183 AutofillProfile::AutofillProfile() | 186 AutofillProfile::AutofillProfile() |
184 : guid_(guid::GenerateGUID()), | 187 : guid_(guid::GenerateGUID()), |
185 name_(1), | 188 name_(1), |
186 email_(1), | 189 email_(1), |
187 home_number_(1), | 190 home_number_(1), |
188 fax_number_(1) { | 191 fax_number_(1) { |
192 // Set the type of the phones - it is set on first SetInfo() call. | |
dhollowa
2011/05/13 18:55:35
Better to use the vector initializer to set the ph
GeorgeY
2011/05/18 17:41:45
Done.
| |
193 home_number_[0].SetInfo(PHONE_HOME_WHOLE_NUMBER, string16()); | |
194 fax_number_[0].SetInfo(PHONE_FAX_WHOLE_NUMBER, string16()); | |
189 } | 195 } |
190 | 196 |
191 AutofillProfile::AutofillProfile(const AutofillProfile& profile) | 197 AutofillProfile::AutofillProfile(const AutofillProfile& profile) |
192 : FormGroup() { | 198 : FormGroup() { |
193 operator=(profile); | 199 operator=(profile); |
194 } | 200 } |
195 | 201 |
196 AutofillProfile::~AutofillProfile() { | 202 AutofillProfile::~AutofillProfile() { |
197 } | 203 } |
198 | 204 |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
245 void AutofillProfile::SetMultiInfo(AutofillFieldType type, | 251 void AutofillProfile::SetMultiInfo(AutofillFieldType type, |
246 const std::vector<string16>& values) { | 252 const std::vector<string16>& values) { |
247 switch (AutofillType(type).group()) { | 253 switch (AutofillType(type).group()) { |
248 case AutofillType::NAME: | 254 case AutofillType::NAME: |
249 CopyValuesToItems(type, values, &name_); | 255 CopyValuesToItems(type, values, &name_); |
250 break; | 256 break; |
251 case AutofillType::EMAIL: | 257 case AutofillType::EMAIL: |
252 CopyValuesToItems(type, values, &email_); | 258 CopyValuesToItems(type, values, &email_); |
253 break; | 259 break; |
254 case AutofillType::PHONE_HOME: | 260 case AutofillType::PHONE_HOME: |
255 CopyValuesToItems(type, values, &home_number_); | 261 CopyValuesToItems(type, values, &home_number_); |
dhollowa
2011/05/13 18:55:35
Let's keep the initialization logic cohesive withi
GeorgeY
2011/05/18 17:41:45
OK
| |
262 // If it was cleared, set the type. | |
263 if (values.empty()) | |
264 home_number_[0].SetInfo(PHONE_HOME_WHOLE_NUMBER, string16()); | |
256 break; | 265 break; |
257 case AutofillType::PHONE_FAX: | 266 case AutofillType::PHONE_FAX: |
258 CopyValuesToItems(type, values, &fax_number_); | 267 CopyValuesToItems(type, values, &fax_number_); |
268 // If it was cleared, set the type. | |
269 if (values.empty()) | |
270 fax_number_[0].SetInfo(PHONE_FAX_WHOLE_NUMBER, string16()); | |
259 break; | 271 break; |
260 default: | 272 default: |
261 if (values.size() == 1) { | 273 if (values.size() == 1) { |
262 SetInfo(type, values[0]); | 274 SetInfo(type, values[0]); |
263 } else if (values.size() == 0) { | 275 } else if (values.size() == 0) { |
264 SetInfo(type, string16()); | 276 SetInfo(type, string16()); |
265 } else { | 277 } else { |
266 NOTREACHED() | 278 NOTREACHED() |
267 << "Attempt to set multiple values on single-valued field."; | 279 << "Attempt to set multiple values on single-valued field."; |
268 } | 280 } |
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
456 | 468 |
457 bool AutofillProfile::operator!=(const AutofillProfile& profile) const { | 469 bool AutofillProfile::operator!=(const AutofillProfile& profile) const { |
458 return !operator==(profile); | 470 return !operator==(profile); |
459 } | 471 } |
460 | 472 |
461 const string16 AutofillProfile::PrimaryValue() const { | 473 const string16 AutofillProfile::PrimaryValue() const { |
462 return GetInfo(ADDRESS_HOME_LINE1) + | 474 return GetInfo(ADDRESS_HOME_LINE1) + |
463 GetInfo(ADDRESS_HOME_CITY); | 475 GetInfo(ADDRESS_HOME_CITY); |
464 } | 476 } |
465 | 477 |
478 bool AutofillProfile::NormalizePhones() { | |
479 // Successful either if nothing to parse, or everything is parsed correctly. | |
480 bool success = true; | |
481 for (size_t i = 0; i < home_number_.size(); ++i) { | |
482 home_number_[i].set_locale(CountryCode()); | |
483 if (!home_number_[i].NormalizePhone()) | |
484 success = false; | |
485 } | |
486 for (size_t i = 0; i < fax_number_.size(); ++i) { | |
487 fax_number_[i].set_locale(CountryCode()); | |
488 if (!fax_number_[i].NormalizePhone()) | |
489 success = false; | |
490 } | |
491 return success; | |
492 } | |
493 | |
466 void AutofillProfile::OverwriteWithOrAddTo(const AutofillProfile& profile) { | 494 void AutofillProfile::OverwriteWithOrAddTo(const AutofillProfile& profile) { |
467 FieldTypeSet field_types; | 495 FieldTypeSet field_types; |
468 profile.GetNonEmptyTypes(&field_types); | 496 profile.GetNonEmptyTypes(&field_types); |
469 | 497 |
470 // Only transfer "full" types (e.g. full name) and not fragments (e.g. | 498 // Only transfer "full" types (e.g. full name) and not fragments (e.g. |
471 // first name, last name). | 499 // first name, last name). |
472 CollapseCompoundFieldTypes(&field_types); | 500 CollapseCompoundFieldTypes(&field_types); |
473 | 501 |
474 for (FieldTypeSet::const_iterator iter = field_types.begin(); | 502 for (FieldTypeSet::const_iterator iter = field_types.begin(); |
475 iter != field_types.end(); ++iter) { | 503 iter != field_types.end(); ++iter) { |
476 if (AutofillProfile::SupportsMultiValue(*iter)) { | 504 if (AutofillProfile::SupportsMultiValue(*iter)) { |
477 std::vector<string16> new_values; | 505 std::vector<string16> new_values; |
478 profile.GetMultiInfo(*iter, &new_values); | 506 profile.GetMultiInfo(*iter, &new_values); |
479 std::vector<string16> existing_values; | 507 std::vector<string16> existing_values; |
480 GetMultiInfo(*iter, &existing_values); | 508 GetMultiInfo(*iter, &existing_values); |
509 FieldTypeGroup group = AutofillType(*iter).group(); | |
481 for (std::vector<string16>::iterator value_iter = new_values.begin(); | 510 for (std::vector<string16>::iterator value_iter = new_values.begin(); |
482 value_iter != new_values.end(); ++value_iter) { | 511 value_iter != new_values.end(); ++value_iter) { |
483 // Don't add duplicates. | 512 // Don't add duplicates. |
484 if (std::find(existing_values.begin(), existing_values.end(), | 513 if (group == AutofillType::PHONE_HOME || |
dhollowa
2011/05/13 18:55:35
A few things here:
(1) Let's split this logic out
GeorgeY
2011/05/18 17:41:45
Done.
| |
485 *value_iter) == existing_values.end()) { | 514 group == AutofillType::PHONE_FAX) { |
486 existing_values.insert(existing_values.end(), *value_iter); | 515 // Phones allow "fuzzy" matching, so "1-800-FLOWERS", "18003569377", |
516 // "(800)356-9377" and "356-9377" are considered the same. | |
517 std::vector<string16>::const_iterator phone_iter; | |
518 for (phone_iter = existing_values.begin(); | |
519 phone_iter != existing_values.end(); | |
520 ++phone_iter) { | |
521 autofill_i18n::PhoneMatch match = autofill_i18n::ComparePhones( | |
522 *phone_iter, *value_iter, CountryCode()); | |
523 if (match == autofill_i18n::PHONES_EQUAL || | |
524 match == autofill_i18n::PHONES_SUBMATCH) { | |
525 break; | |
526 } | |
527 } | |
528 // Add phone if it does not match any other. | |
529 if (phone_iter == existing_values.end()) | |
530 existing_values.insert(existing_values.end(), *value_iter); | |
531 } else { | |
532 if (std::find(existing_values.begin(), existing_values.end(), | |
533 *value_iter) == existing_values.end()) { | |
534 existing_values.insert(existing_values.end(), *value_iter); | |
535 } | |
487 } | 536 } |
488 } | 537 } |
489 SetMultiInfo(*iter, existing_values); | 538 SetMultiInfo(*iter, existing_values); |
490 } else { | 539 } else { |
491 SetInfo(*iter, profile.GetInfo(*iter)); | 540 SetInfo(*iter, profile.GetInfo(*iter)); |
492 } | 541 } |
493 } | 542 } |
494 } | 543 } |
495 | 544 |
496 string16 AutofillProfile::ConstructInferredLabel( | 545 string16 AutofillProfile::ConstructInferredLabel( |
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
669 << UTF16ToUTF8(profile.GetInfo(ADDRESS_HOME_STATE)) | 718 << UTF16ToUTF8(profile.GetInfo(ADDRESS_HOME_STATE)) |
670 << " " | 719 << " " |
671 << UTF16ToUTF8(profile.GetInfo(ADDRESS_HOME_ZIP)) | 720 << UTF16ToUTF8(profile.GetInfo(ADDRESS_HOME_ZIP)) |
672 << " " | 721 << " " |
673 << UTF16ToUTF8(profile.GetInfo(ADDRESS_HOME_COUNTRY)) | 722 << UTF16ToUTF8(profile.GetInfo(ADDRESS_HOME_COUNTRY)) |
674 << " " | 723 << " " |
675 << UTF16ToUTF8(MultiString(profile, PHONE_HOME_WHOLE_NUMBER)) | 724 << UTF16ToUTF8(MultiString(profile, PHONE_HOME_WHOLE_NUMBER)) |
676 << " " | 725 << " " |
677 << UTF16ToUTF8(MultiString(profile, PHONE_FAX_WHOLE_NUMBER)); | 726 << UTF16ToUTF8(MultiString(profile, PHONE_FAX_WHOLE_NUMBER)); |
678 } | 727 } |
OLD | NEW |