| 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 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 110 if (i > 0) | 110 if (i > 0) |
| 111 accumulate += ASCIIToUTF16(" "); | 111 accumulate += ASCIIToUTF16(" "); |
| 112 accumulate += values[i]; | 112 accumulate += values[i]; |
| 113 } | 113 } |
| 114 return accumulate; | 114 return accumulate; |
| 115 } | 115 } |
| 116 | 116 |
| 117 template <class T> | 117 template <class T> |
| 118 void CopyValuesToItems(AutofillFieldType type, | 118 void CopyValuesToItems(AutofillFieldType type, |
| 119 const std::vector<string16>& values, | 119 const std::vector<string16>& values, |
| 120 std::vector<T>* form_group_items) { | 120 std::vector<T>* form_group_items, |
| 121 const T& prototype) { |
| 121 form_group_items->resize(values.size()); | 122 form_group_items->resize(values.size()); |
| 122 for (size_t i = 0; i < form_group_items->size(); ++i) | 123 for (size_t i = 0; i < form_group_items->size(); ++i) |
| 123 (*form_group_items)[i].SetInfo(type, CollapseWhitespace(values[i], false)); | 124 (*form_group_items)[i].SetInfo(type, CollapseWhitespace(values[i], false)); |
| 124 // Must have at least one (possibly empty) element. | 125 // Must have at least one (possibly empty) element. |
| 125 if (form_group_items->empty()) | 126 if (form_group_items->empty()) |
| 126 form_group_items->resize(1); | 127 form_group_items->resize(1, prototype); |
| 127 } | 128 } |
| 128 | 129 |
| 129 template <class T> | 130 template <class T> |
| 130 void CopyItemsToValues(AutofillFieldType type, | 131 void CopyItemsToValues(AutofillFieldType type, |
| 131 const std::vector<T>& form_group_items, | 132 const std::vector<T>& form_group_items, |
| 132 std::vector<string16>* values) { | 133 std::vector<string16>* values) { |
| 133 values->resize(form_group_items.size()); | 134 values->resize(form_group_items.size()); |
| 134 for (size_t i = 0; i < values->size(); ++i) | 135 for (size_t i = 0; i < values->size(); ++i) |
| 135 (*values)[i] = form_group_items[i].GetInfo(type); | 136 (*values)[i] = form_group_items[i].GetInfo(type); |
| 136 } | 137 } |
| (...skipping 30 matching lines...) Expand all Loading... |
| 167 collapsed_set.insert(PHONE_FAX_WHOLE_NUMBER); | 168 collapsed_set.insert(PHONE_FAX_WHOLE_NUMBER); |
| 168 break; | 169 break; |
| 169 | 170 |
| 170 default: | 171 default: |
| 171 collapsed_set.insert(*iter); | 172 collapsed_set.insert(*iter); |
| 172 } | 173 } |
| 173 } | 174 } |
| 174 std::swap(*type_set, collapsed_set); | 175 std::swap(*type_set, collapsed_set); |
| 175 } | 176 } |
| 176 | 177 |
| 178 class FindByPhone { |
| 179 public: |
| 180 FindByPhone(const string16& phone, const std::string& country_code) |
| 181 : phone_(phone), |
| 182 country_code_(country_code) { |
| 183 } |
| 184 |
| 185 bool operator()(const string16& phone) { |
| 186 return autofill_i18n::PhoneNumbersMatch(phone, phone_, country_code_); |
| 187 } |
| 188 |
| 189 bool operator()(const string16* phone) { |
| 190 return autofill_i18n::PhoneNumbersMatch(*phone, phone_, country_code_); |
| 191 } |
| 192 |
| 193 private: |
| 194 string16 phone_; |
| 195 std::string country_code_; |
| 196 }; |
| 197 |
| 177 } // namespace | 198 } // namespace |
| 178 | 199 |
| 179 AutofillProfile::AutofillProfile(const std::string& guid) | 200 AutofillProfile::AutofillProfile(const std::string& guid) |
| 180 : guid_(guid), name_(1), email_(1), home_number_(1), fax_number_(1) { | 201 : guid_(guid), |
| 202 name_(1), |
| 203 email_(1), |
| 204 home_number_(1, PhoneNumber(AutofillType::PHONE_HOME)), |
| 205 fax_number_(1, PhoneNumber(AutofillType::PHONE_FAX)) { |
| 181 } | 206 } |
| 182 | 207 |
| 183 AutofillProfile::AutofillProfile() | 208 AutofillProfile::AutofillProfile() |
| 184 : guid_(guid::GenerateGUID()), | 209 : guid_(guid::GenerateGUID()), |
| 185 name_(1), | 210 name_(1), |
| 186 email_(1), | 211 email_(1), |
| 187 home_number_(1), | 212 home_number_(1, PhoneNumber(AutofillType::PHONE_HOME)), |
| 188 fax_number_(1) { | 213 fax_number_(1, PhoneNumber(AutofillType::PHONE_FAX)) { |
| 189 } | 214 } |
| 190 | 215 |
| 191 AutofillProfile::AutofillProfile(const AutofillProfile& profile) | 216 AutofillProfile::AutofillProfile(const AutofillProfile& profile) |
| 192 : FormGroup() { | 217 : FormGroup() { |
| 193 operator=(profile); | 218 operator=(profile); |
| 194 } | 219 } |
| 195 | 220 |
| 196 AutofillProfile::~AutofillProfile() { | 221 AutofillProfile::~AutofillProfile() { |
| 197 } | 222 } |
| 198 | 223 |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 239 void AutofillProfile::SetInfo(AutofillFieldType type, const string16& value) { | 264 void AutofillProfile::SetInfo(AutofillFieldType type, const string16& value) { |
| 240 FormGroup* form_group = MutableFormGroupForType(type); | 265 FormGroup* form_group = MutableFormGroupForType(type); |
| 241 if (form_group) | 266 if (form_group) |
| 242 form_group->SetInfo(type, CollapseWhitespace(value, false)); | 267 form_group->SetInfo(type, CollapseWhitespace(value, false)); |
| 243 } | 268 } |
| 244 | 269 |
| 245 void AutofillProfile::SetMultiInfo(AutofillFieldType type, | 270 void AutofillProfile::SetMultiInfo(AutofillFieldType type, |
| 246 const std::vector<string16>& values) { | 271 const std::vector<string16>& values) { |
| 247 switch (AutofillType(type).group()) { | 272 switch (AutofillType(type).group()) { |
| 248 case AutofillType::NAME: | 273 case AutofillType::NAME: |
| 249 CopyValuesToItems(type, values, &name_); | 274 CopyValuesToItems(type, values, &name_, NameInfo()); |
| 250 break; | 275 break; |
| 251 case AutofillType::EMAIL: | 276 case AutofillType::EMAIL: |
| 252 CopyValuesToItems(type, values, &email_); | 277 CopyValuesToItems(type, values, &email_, EmailInfo()); |
| 253 break; | 278 break; |
| 254 case AutofillType::PHONE_HOME: | 279 case AutofillType::PHONE_HOME: |
| 255 CopyValuesToItems(type, values, &home_number_); | 280 CopyValuesToItems(type, |
| 281 values, |
| 282 &home_number_, |
| 283 PhoneNumber(AutofillType::PHONE_HOME)); |
| 256 break; | 284 break; |
| 257 case AutofillType::PHONE_FAX: | 285 case AutofillType::PHONE_FAX: |
| 258 CopyValuesToItems(type, values, &fax_number_); | 286 CopyValuesToItems(type, |
| 287 values, |
| 288 &fax_number_, |
| 289 PhoneNumber(AutofillType::PHONE_FAX)); |
| 259 break; | 290 break; |
| 260 default: | 291 default: |
| 261 if (values.size() == 1) { | 292 if (values.size() == 1) { |
| 262 SetInfo(type, values[0]); | 293 SetInfo(type, values[0]); |
| 263 } else if (values.size() == 0) { | 294 } else if (values.size() == 0) { |
| 264 SetInfo(type, string16()); | 295 SetInfo(type, string16()); |
| 265 } else { | 296 } else { |
| 266 NOTREACHED() | 297 NOTREACHED() |
| 267 << "Attempt to set multiple values on single-valued field."; | 298 << "Attempt to set multiple values on single-valued field."; |
| 268 } | 299 } |
| (...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 456 | 487 |
| 457 bool AutofillProfile::operator!=(const AutofillProfile& profile) const { | 488 bool AutofillProfile::operator!=(const AutofillProfile& profile) const { |
| 458 return !operator==(profile); | 489 return !operator==(profile); |
| 459 } | 490 } |
| 460 | 491 |
| 461 const string16 AutofillProfile::PrimaryValue() const { | 492 const string16 AutofillProfile::PrimaryValue() const { |
| 462 return GetInfo(ADDRESS_HOME_LINE1) + | 493 return GetInfo(ADDRESS_HOME_LINE1) + |
| 463 GetInfo(ADDRESS_HOME_CITY); | 494 GetInfo(ADDRESS_HOME_CITY); |
| 464 } | 495 } |
| 465 | 496 |
| 497 bool AutofillProfile::NormalizePhones() { |
| 498 // Successful either if nothing to parse, or everything is parsed correctly. |
| 499 bool success = true; |
| 500 for (size_t i = 0; i < home_number_.size(); ++i) { |
| 501 home_number_[i].set_locale(CountryCode()); |
| 502 if (!home_number_[i].NormalizePhone()) |
| 503 success = false; |
| 504 } |
| 505 for (size_t i = 0; i < fax_number_.size(); ++i) { |
| 506 fax_number_[i].set_locale(CountryCode()); |
| 507 if (!fax_number_[i].NormalizePhone()) |
| 508 success = false; |
| 509 } |
| 510 return success; |
| 511 } |
| 512 |
| 466 void AutofillProfile::OverwriteWithOrAddTo(const AutofillProfile& profile) { | 513 void AutofillProfile::OverwriteWithOrAddTo(const AutofillProfile& profile) { |
| 467 FieldTypeSet field_types; | 514 FieldTypeSet field_types; |
| 468 profile.GetNonEmptyTypes(&field_types); | 515 profile.GetNonEmptyTypes(&field_types); |
| 469 | 516 |
| 470 // Only transfer "full" types (e.g. full name) and not fragments (e.g. | 517 // Only transfer "full" types (e.g. full name) and not fragments (e.g. |
| 471 // first name, last name). | 518 // first name, last name). |
| 472 CollapseCompoundFieldTypes(&field_types); | 519 CollapseCompoundFieldTypes(&field_types); |
| 473 | 520 |
| 474 for (FieldTypeSet::const_iterator iter = field_types.begin(); | 521 for (FieldTypeSet::const_iterator iter = field_types.begin(); |
| 475 iter != field_types.end(); ++iter) { | 522 iter != field_types.end(); ++iter) { |
| 476 if (AutofillProfile::SupportsMultiValue(*iter)) { | 523 if (AutofillProfile::SupportsMultiValue(*iter)) { |
| 477 std::vector<string16> new_values; | 524 std::vector<string16> new_values; |
| 478 profile.GetMultiInfo(*iter, &new_values); | 525 profile.GetMultiInfo(*iter, &new_values); |
| 479 std::vector<string16> existing_values; | 526 std::vector<string16> existing_values; |
| 480 GetMultiInfo(*iter, &existing_values); | 527 GetMultiInfo(*iter, &existing_values); |
| 528 FieldTypeGroup group = AutofillType(*iter).group(); |
| 481 for (std::vector<string16>::iterator value_iter = new_values.begin(); | 529 for (std::vector<string16>::iterator value_iter = new_values.begin(); |
| 482 value_iter != new_values.end(); ++value_iter) { | 530 value_iter != new_values.end(); ++value_iter) { |
| 483 // Don't add duplicates. | 531 // Don't add duplicates. |
| 484 if (std::find(existing_values.begin(), existing_values.end(), | 532 if (group == AutofillType::PHONE_HOME || |
| 485 *value_iter) == existing_values.end()) { | 533 group == AutofillType::PHONE_FAX) { |
| 486 existing_values.insert(existing_values.end(), *value_iter); | 534 AddPhoneIfUnique(*value_iter, &existing_values); |
| 535 } else { |
| 536 if (std::find(existing_values.begin(), existing_values.end(), |
| 537 *value_iter) == existing_values.end()) { |
| 538 existing_values.insert(existing_values.end(), *value_iter); |
| 539 } |
| 487 } | 540 } |
| 488 } | 541 } |
| 489 SetMultiInfo(*iter, existing_values); | 542 SetMultiInfo(*iter, existing_values); |
| 490 } else { | 543 } else { |
| 491 SetInfo(*iter, profile.GetInfo(*iter)); | 544 SetInfo(*iter, profile.GetInfo(*iter)); |
| 492 } | 545 } |
| 493 } | 546 } |
| 494 } | 547 } |
| 495 | 548 |
| 549 void AutofillProfile::AddPhoneIfUnique(const string16& phone, |
| 550 std::vector<string16>* existing_phones) { |
| 551 DCHECK(existing_phones); |
| 552 // Phones allow "fuzzy" matching, so "1-800-FLOWERS", "18003569377", |
| 553 // "(800)356-9377" and "356-9377" are considered the same. |
| 554 std::vector<string16>::const_iterator phone_iter; |
| 555 if (std::find_if(existing_phones->begin(), existing_phones->end(), |
| 556 FindByPhone(phone, CountryCode())) == |
| 557 existing_phones->end()) { |
| 558 existing_phones->push_back(phone); |
| 559 } |
| 560 } |
| 561 |
| 496 string16 AutofillProfile::ConstructInferredLabel( | 562 string16 AutofillProfile::ConstructInferredLabel( |
| 497 const std::vector<AutofillFieldType>& included_fields, | 563 const std::vector<AutofillFieldType>& included_fields, |
| 498 size_t num_fields_to_use) const { | 564 size_t num_fields_to_use) const { |
| 499 const string16 separator = | 565 const string16 separator = |
| 500 l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_ADDRESS_SUMMARY_SEPARATOR); | 566 l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_ADDRESS_SUMMARY_SEPARATOR); |
| 501 | 567 |
| 502 string16 label; | 568 string16 label; |
| 503 size_t num_fields_used = 0; | 569 size_t num_fields_used = 0; |
| 504 for (std::vector<AutofillFieldType>::const_iterator it = | 570 for (std::vector<AutofillFieldType>::const_iterator it = |
| 505 included_fields.begin(); | 571 included_fields.begin(); |
| (...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 669 << UTF16ToUTF8(profile.GetInfo(ADDRESS_HOME_STATE)) | 735 << UTF16ToUTF8(profile.GetInfo(ADDRESS_HOME_STATE)) |
| 670 << " " | 736 << " " |
| 671 << UTF16ToUTF8(profile.GetInfo(ADDRESS_HOME_ZIP)) | 737 << UTF16ToUTF8(profile.GetInfo(ADDRESS_HOME_ZIP)) |
| 672 << " " | 738 << " " |
| 673 << UTF16ToUTF8(profile.GetInfo(ADDRESS_HOME_COUNTRY)) | 739 << UTF16ToUTF8(profile.GetInfo(ADDRESS_HOME_COUNTRY)) |
| 674 << " " | 740 << " " |
| 675 << UTF16ToUTF8(MultiString(profile, PHONE_HOME_WHOLE_NUMBER)) | 741 << UTF16ToUTF8(MultiString(profile, PHONE_HOME_WHOLE_NUMBER)) |
| 676 << " " | 742 << " " |
| 677 << UTF16ToUTF8(MultiString(profile, PHONE_FAX_WHOLE_NUMBER)); | 743 << UTF16ToUTF8(MultiString(profile, PHONE_FAX_WHOLE_NUMBER)); |
| 678 } | 744 } |
| OLD | NEW |