Chromium Code Reviews| 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 |