Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(382)

Side by Side Diff: chrome/browser/autofill/autofill_profile.cc

Issue 6877130: These changes *are* for review :) (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 9 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « chrome/browser/autofill/autofill_profile.h ('k') | chrome/browser/autofill/autofill_profile_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698