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

Side by Side Diff: components/autofill/core/browser/autofill_profile.cc

Issue 22009003: [Autofill] Distinguish between native field types and potentially HTML field types. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase Created 7 years, 4 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 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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 "components/autofill/core/browser/autofill_profile.h" 5 #include "components/autofill/core/browser/autofill_profile.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <functional> 8 #include <functional>
9 #include <map> 9 #include <map>
10 #include <ostream> 10 #include <ostream>
(...skipping 14 matching lines...) Expand all
25 #include "components/autofill/core/browser/validation.h" 25 #include "components/autofill/core/browser/validation.h"
26 #include "components/autofill/core/common/form_field_data.h" 26 #include "components/autofill/core/common/form_field_data.h"
27 #include "grit/component_strings.h" 27 #include "grit/component_strings.h"
28 #include "ui/base/l10n/l10n_util.h" 28 #include "ui/base/l10n/l10n_util.h"
29 29
30 namespace autofill { 30 namespace autofill {
31 namespace { 31 namespace {
32 32
33 // Like |AutofillType::GetEquivalentFieldType()|, but also returns |NAME_FULL| 33 // Like |AutofillType::GetEquivalentFieldType()|, but also returns |NAME_FULL|
34 // for first, middle, and last name field types. 34 // for first, middle, and last name field types.
35 AutofillFieldType GetEquivalentFieldTypeCollapsingNames( 35 ServerFieldType GetEquivalentFieldTypeCollapsingNames(ServerFieldType type) {
36 AutofillFieldType field_type) { 36 if (type == NAME_FIRST || type == NAME_MIDDLE || type == NAME_LAST ||
37 if (field_type == NAME_FIRST || field_type == NAME_MIDDLE || 37 type == NAME_MIDDLE_INITIAL)
38 field_type == NAME_LAST || field_type == NAME_MIDDLE_INITIAL)
39 return NAME_FULL; 38 return NAME_FULL;
40 39
41 return AutofillType::GetEquivalentFieldType(field_type); 40 return AutofillType::GetEquivalentFieldType(type);
42 } 41 }
43 42
44 // Fills |distinguishing_fields| with a list of fields to use when creating 43 // Fills |distinguishing_fields| with a list of fields to use when creating
45 // labels that can help to distinguish between two profiles. Draws fields from 44 // labels that can help to distinguish between two profiles. Draws fields from
46 // |suggested_fields| if it is non-NULL; otherwise returns a default list. 45 // |suggested_fields| if it is non-NULL; otherwise returns a default list.
47 // If |suggested_fields| is non-NULL, does not include |excluded_field| in the 46 // If |suggested_fields| is non-NULL, does not include |excluded_field| in the
48 // list. Otherwise, |excluded_field| is ignored, and should be set to 47 // list. Otherwise, |excluded_field| is ignored, and should be set to
49 // |UNKNOWN_TYPE| by convention. The resulting list of fields is sorted in 48 // |UNKNOWN_TYPE| by convention. The resulting list of fields is sorted in
50 // decreasing order of importance. 49 // decreasing order of importance.
51 void GetFieldsForDistinguishingProfiles( 50 void GetFieldsForDistinguishingProfiles(
52 const std::vector<AutofillFieldType>* suggested_fields, 51 const std::vector<ServerFieldType>* suggested_fields,
53 AutofillFieldType excluded_field, 52 ServerFieldType excluded_field,
54 std::vector<AutofillFieldType>* distinguishing_fields) { 53 std::vector<ServerFieldType>* distinguishing_fields) {
55 static const AutofillFieldType kDefaultDistinguishingFields[] = { 54 static const ServerFieldType kDefaultDistinguishingFields[] = {
56 NAME_FULL, 55 NAME_FULL,
57 ADDRESS_HOME_LINE1, 56 ADDRESS_HOME_LINE1,
58 ADDRESS_HOME_LINE2, 57 ADDRESS_HOME_LINE2,
59 ADDRESS_HOME_CITY, 58 ADDRESS_HOME_CITY,
60 ADDRESS_HOME_STATE, 59 ADDRESS_HOME_STATE,
61 ADDRESS_HOME_ZIP, 60 ADDRESS_HOME_ZIP,
62 ADDRESS_HOME_COUNTRY, 61 ADDRESS_HOME_COUNTRY,
63 EMAIL_ADDRESS, 62 EMAIL_ADDRESS,
64 PHONE_HOME_WHOLE_NUMBER, 63 PHONE_HOME_WHOLE_NUMBER,
65 COMPANY_NAME, 64 COMPANY_NAME,
66 }; 65 };
67 66
68 if (!suggested_fields) { 67 if (!suggested_fields) {
69 DCHECK_EQ(excluded_field, UNKNOWN_TYPE); 68 DCHECK_EQ(excluded_field, UNKNOWN_TYPE);
70 distinguishing_fields->assign( 69 distinguishing_fields->assign(
71 kDefaultDistinguishingFields, 70 kDefaultDistinguishingFields,
72 kDefaultDistinguishingFields + arraysize(kDefaultDistinguishingFields)); 71 kDefaultDistinguishingFields + arraysize(kDefaultDistinguishingFields));
73 return; 72 return;
74 } 73 }
75 74
76 // Keep track of which fields we've seen so that we avoid duplicate entries. 75 // Keep track of which fields we've seen so that we avoid duplicate entries.
77 // Always ignore fields of unknown type and the excluded field. 76 // Always ignore fields of unknown type and the excluded field.
78 std::set<AutofillFieldType> seen_fields; 77 std::set<ServerFieldType> seen_fields;
79 seen_fields.insert(UNKNOWN_TYPE); 78 seen_fields.insert(UNKNOWN_TYPE);
80 seen_fields.insert(GetEquivalentFieldTypeCollapsingNames(excluded_field)); 79 seen_fields.insert(GetEquivalentFieldTypeCollapsingNames(excluded_field));
81 80
82 distinguishing_fields->clear(); 81 distinguishing_fields->clear();
83 for (std::vector<AutofillFieldType>::const_iterator it = 82 for (std::vector<ServerFieldType>::const_iterator it =
84 suggested_fields->begin(); 83 suggested_fields->begin();
85 it != suggested_fields->end(); ++it) { 84 it != suggested_fields->end(); ++it) {
86 AutofillFieldType suggested_type = 85 ServerFieldType suggested_type = GetEquivalentFieldTypeCollapsingNames(*it);
87 GetEquivalentFieldTypeCollapsingNames(*it);
88 if (seen_fields.insert(suggested_type).second) 86 if (seen_fields.insert(suggested_type).second)
89 distinguishing_fields->push_back(suggested_type); 87 distinguishing_fields->push_back(suggested_type);
90 } 88 }
91 89
92 // Special case: If the excluded field is a partial name (e.g. first name) and 90 // Special case: If the excluded field is a partial name (e.g. first name) and
93 // the suggested fields include other name fields, include |NAME_FULL| in the 91 // the suggested fields include other name fields, include |NAME_FULL| in the
94 // list of distinguishing fields as a last-ditch fallback. This allows us to 92 // list of distinguishing fields as a last-ditch fallback. This allows us to
95 // distinguish between profiles that are identical except for the name. 93 // distinguish between profiles that are identical except for the name.
96 if (excluded_field != NAME_FULL && 94 if (excluded_field != NAME_FULL &&
97 GetEquivalentFieldTypeCollapsingNames(excluded_field) == NAME_FULL) { 95 GetEquivalentFieldTypeCollapsingNames(excluded_field) == NAME_FULL) {
98 for (std::vector<AutofillFieldType>::const_iterator it = 96 for (std::vector<ServerFieldType>::const_iterator it =
99 suggested_fields->begin(); 97 suggested_fields->begin();
100 it != suggested_fields->end(); ++it) { 98 it != suggested_fields->end(); ++it) {
101 if (*it != excluded_field && 99 if (*it != excluded_field &&
102 GetEquivalentFieldTypeCollapsingNames(*it) == NAME_FULL) { 100 GetEquivalentFieldTypeCollapsingNames(*it) == NAME_FULL) {
103 distinguishing_fields->push_back(NAME_FULL); 101 distinguishing_fields->push_back(NAME_FULL);
104 break; 102 break;
105 } 103 }
106 } 104 }
107 } 105 }
108 } 106 }
109 107
110 // A helper function for string streaming. Concatenates multi-valued entries 108 // A helper function for string streaming. Concatenates multi-valued entries
111 // stored for a given |type| into a single string. This string is returned. 109 // stored for a given |type| into a single string. This string is returned.
112 const base::string16 MultiString(const AutofillProfile& p, 110 const base::string16 MultiString(const AutofillProfile& p,
113 AutofillFieldType type) { 111 ServerFieldType type) {
114 std::vector<base::string16> values; 112 std::vector<base::string16> values;
115 p.GetRawMultiInfo(type, &values); 113 p.GetRawMultiInfo(type, &values);
116 base::string16 accumulate; 114 base::string16 accumulate;
117 for (size_t i = 0; i < values.size(); ++i) { 115 for (size_t i = 0; i < values.size(); ++i) {
118 if (i > 0) 116 if (i > 0)
119 accumulate += ASCIIToUTF16(" "); 117 accumulate += ASCIIToUTF16(" ");
120 accumulate += values[i]; 118 accumulate += values[i];
121 } 119 }
122 return accumulate; 120 return accumulate;
123 } 121 }
124 122
125 base::string16 GetFormGroupInfo(const FormGroup& form_group, 123 base::string16 GetFormGroupInfo(const FormGroup& form_group,
126 AutofillFieldType type, 124 const AutofillType& type,
127 const std::string& app_locale) { 125 const std::string& app_locale) {
128 return app_locale.empty() ? 126 return app_locale.empty() ?
129 form_group.GetRawInfo(type) : 127 form_group.GetRawInfo(type.server_type()) :
130 form_group.GetInfo(type, app_locale); 128 form_group.GetInfo(type, app_locale);
131 } 129 }
132 130
133 template <class T> 131 template <class T>
134 void CopyValuesToItems(AutofillFieldType type, 132 void CopyValuesToItems(ServerFieldType type,
135 const std::vector<base::string16>& values, 133 const std::vector<base::string16>& values,
136 std::vector<T>* form_group_items, 134 std::vector<T>* form_group_items,
137 const T& prototype) { 135 const T& prototype) {
138 form_group_items->resize(values.size(), prototype); 136 form_group_items->resize(values.size(), prototype);
139 for (size_t i = 0; i < form_group_items->size(); ++i) { 137 for (size_t i = 0; i < form_group_items->size(); ++i) {
140 (*form_group_items)[i].SetRawInfo(type, 138 (*form_group_items)[i].SetRawInfo(type,
141 CollapseWhitespace(values[i], false)); 139 CollapseWhitespace(values[i], false));
142 } 140 }
143 // Must have at least one (possibly empty) element. 141 // Must have at least one (possibly empty) element.
144 if (form_group_items->empty()) 142 if (form_group_items->empty())
145 form_group_items->resize(1, prototype); 143 form_group_items->resize(1, prototype);
146 } 144 }
147 145
148 template <class T> 146 template <class T>
149 void CopyItemsToValues(AutofillFieldType type, 147 void CopyItemsToValues(const AutofillType& type,
150 const std::vector<T>& form_group_items, 148 const std::vector<T>& form_group_items,
151 const std::string& app_locale, 149 const std::string& app_locale,
152 std::vector<base::string16>* values) { 150 std::vector<base::string16>* values) {
153 values->resize(form_group_items.size()); 151 values->resize(form_group_items.size());
154 for (size_t i = 0; i < values->size(); ++i) { 152 for (size_t i = 0; i < values->size(); ++i) {
155 (*values)[i] = GetFormGroupInfo(form_group_items[i], type, app_locale); 153 (*values)[i] = GetFormGroupInfo(form_group_items[i], type, app_locale);
156 } 154 }
157 } 155 }
158 156
159 // Collapse compound field types to their "full" type. I.e. First name 157 // Collapse compound field types to their "full" type. I.e. First name
160 // collapses to full name, area code collapses to full phone, etc. 158 // collapses to full name, area code collapses to full phone, etc.
161 void CollapseCompoundFieldTypes(FieldTypeSet* type_set) { 159 void CollapseCompoundFieldTypes(ServerFieldTypeSet* type_set) {
162 FieldTypeSet collapsed_set; 160 ServerFieldTypeSet collapsed_set;
163 for (FieldTypeSet::iterator iter = type_set->begin(); iter != type_set->end(); 161 for (ServerFieldTypeSet::iterator it = type_set->begin();
164 ++iter) { 162 it != type_set->end(); ++it) {
165 switch (*iter) { 163 switch (*it) {
166 case NAME_FIRST: 164 case NAME_FIRST:
167 case NAME_MIDDLE: 165 case NAME_MIDDLE:
168 case NAME_LAST: 166 case NAME_LAST:
169 case NAME_MIDDLE_INITIAL: 167 case NAME_MIDDLE_INITIAL:
170 case NAME_FULL: 168 case NAME_FULL:
171 case NAME_SUFFIX: 169 case NAME_SUFFIX:
172 collapsed_set.insert(NAME_FULL); 170 collapsed_set.insert(NAME_FULL);
173 break; 171 break;
174 172
175 case PHONE_HOME_NUMBER: 173 case PHONE_HOME_NUMBER:
176 case PHONE_HOME_CITY_CODE: 174 case PHONE_HOME_CITY_CODE:
177 case PHONE_HOME_COUNTRY_CODE: 175 case PHONE_HOME_COUNTRY_CODE:
178 case PHONE_HOME_CITY_AND_NUMBER: 176 case PHONE_HOME_CITY_AND_NUMBER:
179 case PHONE_HOME_WHOLE_NUMBER: 177 case PHONE_HOME_WHOLE_NUMBER:
180 collapsed_set.insert(PHONE_HOME_WHOLE_NUMBER); 178 collapsed_set.insert(PHONE_HOME_WHOLE_NUMBER);
181 break; 179 break;
182 180
183 default: 181 default:
184 collapsed_set.insert(*iter); 182 collapsed_set.insert(*it);
185 } 183 }
186 } 184 }
187 std::swap(*type_set, collapsed_set); 185 std::swap(*type_set, collapsed_set);
188 } 186 }
189 187
190 class FindByPhone { 188 class FindByPhone {
191 public: 189 public:
192 FindByPhone(const base::string16& phone, 190 FindByPhone(const base::string16& phone,
193 const std::string& country_code, 191 const std::string& country_code,
194 const std::string& app_locale) 192 const std::string& app_locale)
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
260 phone_number_ = profile.phone_number_; 258 phone_number_ = profile.phone_number_;
261 259
262 for (size_t i = 0; i < phone_number_.size(); ++i) 260 for (size_t i = 0; i < phone_number_.size(); ++i)
263 phone_number_[i].set_profile(this); 261 phone_number_[i].set_profile(this);
264 262
265 address_ = profile.address_; 263 address_ = profile.address_;
266 264
267 return *this; 265 return *this;
268 } 266 }
269 267
270 void AutofillProfile::GetMatchingTypes(const base::string16& text, 268 void AutofillProfile::GetMatchingTypes(
271 const std::string& app_locale, 269 const base::string16& text,
272 FieldTypeSet* matching_types) const { 270 const std::string& app_locale,
271 ServerFieldTypeSet* matching_types) const {
273 FormGroupList info = FormGroups(); 272 FormGroupList info = FormGroups();
274 for (FormGroupList::const_iterator it = info.begin(); it != info.end(); ++it) 273 for (FormGroupList::const_iterator it = info.begin(); it != info.end(); ++it)
275 (*it)->GetMatchingTypes(text, app_locale, matching_types); 274 (*it)->GetMatchingTypes(text, app_locale, matching_types);
276 } 275 }
277 276
278 base::string16 AutofillProfile::GetRawInfo(AutofillFieldType type) const { 277 base::string16 AutofillProfile::GetRawInfo(ServerFieldType type) const {
279 AutofillFieldType return_type = AutofillType::GetEquivalentFieldType(type); 278 ServerFieldType return_type = AutofillType::GetEquivalentFieldType(type);
280 const FormGroup* form_group = FormGroupForType(return_type); 279 const FormGroup* form_group = FormGroupForType(AutofillType(return_type));
281 if (!form_group) 280 if (!form_group)
282 return base::string16(); 281 return base::string16();
283 282
284 return form_group->GetRawInfo(return_type); 283 return form_group->GetRawInfo(return_type);
285 } 284 }
286 285
287 void AutofillProfile::SetRawInfo(AutofillFieldType type, 286 void AutofillProfile::SetRawInfo(ServerFieldType type,
288 const base::string16& value) { 287 const base::string16& value) {
289 FormGroup* form_group = MutableFormGroupForType(type); 288 FormGroup* form_group = MutableFormGroupForType(AutofillType(type));
290 if (form_group) 289 if (form_group)
291 form_group->SetRawInfo(type, CollapseWhitespace(value, false)); 290 form_group->SetRawInfo(type, CollapseWhitespace(value, false));
292 } 291 }
293 292
294 base::string16 AutofillProfile::GetInfo(AutofillFieldType type, 293 base::string16 AutofillProfile::GetInfo(const AutofillType& type,
295 const std::string& app_locale) const { 294 const std::string& app_locale) const {
296 AutofillFieldType return_type = AutofillType::GetEquivalentFieldType(type); 295 ServerFieldType return_type =
297 const FormGroup* form_group = FormGroupForType(return_type); 296 AutofillType::GetEquivalentFieldType(type.server_type());
297 const FormGroup* form_group = FormGroupForType(AutofillType(return_type));
298 if (!form_group) 298 if (!form_group)
299 return base::string16(); 299 return base::string16();
300 300
301 return form_group->GetInfo(return_type, app_locale); 301 return form_group->GetInfo(AutofillType(return_type), app_locale);
302 } 302 }
303 303
304 bool AutofillProfile::SetInfo(AutofillFieldType type, 304 bool AutofillProfile::SetInfo(const AutofillType& type,
305 const base::string16& value, 305 const base::string16& value,
306 const std::string& app_locale) { 306 const std::string& app_locale) {
307 FormGroup* form_group = MutableFormGroupForType(type); 307 FormGroup* form_group = MutableFormGroupForType(type);
308 if (!form_group) 308 if (!form_group)
309 return false; 309 return false;
310 310
311 return 311 return
312 form_group->SetInfo(type, CollapseWhitespace(value, false), app_locale); 312 form_group->SetInfo(type, CollapseWhitespace(value, false), app_locale);
313 } 313 }
314 314
315 void AutofillProfile::SetRawMultiInfo( 315 void AutofillProfile::SetRawMultiInfo(
316 AutofillFieldType type, 316 ServerFieldType type,
317 const std::vector<base::string16>& values) { 317 const std::vector<base::string16>& values) {
318 switch (AutofillType(type).group()) { 318 switch (AutofillType(type).group()) {
319 case NAME: 319 case NAME:
320 case NAME_BILLING: 320 case NAME_BILLING:
321 CopyValuesToItems(type, values, &name_, NameInfo()); 321 CopyValuesToItems(type, values, &name_, NameInfo());
322 break; 322 break;
323 case EMAIL: 323 case EMAIL:
324 CopyValuesToItems(type, values, &email_, EmailInfo()); 324 CopyValuesToItems(type, values, &email_, EmailInfo());
325 break; 325 break;
326 case PHONE_HOME: 326 case PHONE_HOME:
(...skipping 10 matching lines...) Expand all
337 SetRawInfo(type, base::string16()); 337 SetRawInfo(type, base::string16());
338 } else { 338 } else {
339 // Shouldn't attempt to set multiple values on single-valued field. 339 // Shouldn't attempt to set multiple values on single-valued field.
340 NOTREACHED(); 340 NOTREACHED();
341 } 341 }
342 break; 342 break;
343 } 343 }
344 } 344 }
345 345
346 void AutofillProfile::GetRawMultiInfo( 346 void AutofillProfile::GetRawMultiInfo(
347 AutofillFieldType type, 347 ServerFieldType type,
348 std::vector<base::string16>* values) const { 348 std::vector<base::string16>* values) const {
349 GetMultiInfoImpl(type, std::string(), values); 349 GetMultiInfoImpl(AutofillType(type), std::string(), values);
350 } 350 }
351 351
352 void AutofillProfile::GetMultiInfo(AutofillFieldType type, 352 void AutofillProfile::GetMultiInfo(const AutofillType& type,
353 const std::string& app_locale, 353 const std::string& app_locale,
354 std::vector<base::string16>* values) const { 354 std::vector<base::string16>* values) const {
355 GetMultiInfoImpl(type, app_locale, values); 355 GetMultiInfoImpl(type, app_locale, values);
356 } 356 }
357 357
358 void AutofillProfile::FillFormField(const AutofillField& field, 358 void AutofillProfile::FillFormField(const AutofillField& field,
359 size_t variant, 359 size_t variant,
360 const std::string& app_locale, 360 const std::string& app_locale,
361 FormFieldData* field_data) const { 361 FormFieldData* field_data) const {
362 AutofillFieldType type = field.type(); 362 AutofillType type = field.Type();
363 DCHECK_NE(CREDIT_CARD, AutofillType(type).group()); 363 DCHECK_NE(CREDIT_CARD, type.group());
364 DCHECK(field_data); 364 DCHECK(field_data);
365 365
366 if (type == PHONE_HOME_NUMBER || type == PHONE_BILLING_NUMBER) { 366 if (type.server_type() == PHONE_HOME_NUMBER ||
367 type.server_type() == PHONE_BILLING_NUMBER) {
367 FillPhoneNumberField(field, variant, app_locale, field_data); 368 FillPhoneNumberField(field, variant, app_locale, field_data);
368 } else if (field_data->form_control_type == "select-one") { 369 } else if (field_data->form_control_type == "select-one") {
369 FillSelectControl(type, app_locale, field_data); 370 FillSelectControl(type, app_locale, field_data);
370 } else { 371 } else {
371 std::vector<base::string16> values; 372 std::vector<base::string16> values;
372 GetMultiInfo(type, app_locale, &values); 373 GetMultiInfo(type, app_locale, &values);
373 if (variant >= values.size()) { 374 if (variant >= values.size()) {
374 // If the variant is unavailable, bail. This case is reachable, for 375 // If the variant is unavailable, bail. This case is reachable, for
375 // example if Sync updates a profile during the filling process. 376 // example if Sync updates a profile during the filling process.
376 return; 377 return;
377 } 378 }
378 379
379 field_data->value = values[variant]; 380 field_data->value = values[variant];
380 } 381 }
381 } 382 }
382 383
383 void AutofillProfile::FillPhoneNumberField(const AutofillField& field, 384 void AutofillProfile::FillPhoneNumberField(const AutofillField& field,
384 size_t variant, 385 size_t variant,
385 const std::string& app_locale, 386 const std::string& app_locale,
386 FormFieldData* field_data) const { 387 FormFieldData* field_data) const {
387 std::vector<base::string16> values; 388 std::vector<base::string16> values;
388 GetMultiInfo(field.type(), app_locale, &values); 389 GetMultiInfo(field.Type(), app_locale, &values);
389 DCHECK(variant < values.size()); 390 DCHECK(variant < values.size());
390 391
391 // If we are filling a phone number, check to see if the size field 392 // If we are filling a phone number, check to see if the size field
392 // matches the "prefix" or "suffix" sizes and fill accordingly. 393 // matches the "prefix" or "suffix" sizes and fill accordingly.
393 base::string16 number = values[variant]; 394 base::string16 number = values[variant];
394 if (number.length() == 395 if (number.length() ==
395 PhoneNumber::kPrefixLength + PhoneNumber::kSuffixLength) { 396 PhoneNumber::kPrefixLength + PhoneNumber::kSuffixLength) {
396 if (field.phone_part() == AutofillField::PHONE_PREFIX || 397 if (field.phone_part() == AutofillField::PHONE_PREFIX ||
397 field_data->max_length == PhoneNumber::kPrefixLength) { 398 field_data->max_length == PhoneNumber::kPrefixLength) {
398 number = number.substr(PhoneNumber::kPrefixOffset, 399 number = number.substr(PhoneNumber::kPrefixOffset,
399 PhoneNumber::kPrefixLength); 400 PhoneNumber::kPrefixLength);
400 } else if (field.phone_part() == AutofillField::PHONE_SUFFIX || 401 } else if (field.phone_part() == AutofillField::PHONE_SUFFIX ||
401 field_data->max_length == PhoneNumber::kSuffixLength) { 402 field_data->max_length == PhoneNumber::kSuffixLength) {
402 number = number.substr(PhoneNumber::kSuffixOffset, 403 number = number.substr(PhoneNumber::kSuffixOffset,
403 PhoneNumber::kSuffixLength); 404 PhoneNumber::kSuffixLength);
404 } 405 }
405 } 406 }
406 407
407 field_data->value = number; 408 field_data->value = number;
408 } 409 }
409 410
410 const base::string16 AutofillProfile::Label() const { 411 const base::string16 AutofillProfile::Label() const {
411 return label_; 412 return label_;
412 } 413 }
413 414
414 bool AutofillProfile::IsEmpty(const std::string& app_locale) const { 415 bool AutofillProfile::IsEmpty(const std::string& app_locale) const {
415 FieldTypeSet types; 416 ServerFieldTypeSet types;
416 GetNonEmptyTypes(app_locale, &types); 417 GetNonEmptyTypes(app_locale, &types);
417 return types.empty(); 418 return types.empty();
418 } 419 }
419 420
420 bool AutofillProfile::IsPresentButInvalid(AutofillFieldType type) const { 421 bool AutofillProfile::IsPresentButInvalid(ServerFieldType type) const {
421 std::string country = UTF16ToUTF8(GetRawInfo(ADDRESS_HOME_COUNTRY)); 422 std::string country = UTF16ToUTF8(GetRawInfo(ADDRESS_HOME_COUNTRY));
422 base::string16 data = GetRawInfo(type); 423 base::string16 data = GetRawInfo(type);
423 switch (type) { 424 switch (type) {
424 case ADDRESS_HOME_STATE: 425 case ADDRESS_HOME_STATE:
425 if (!data.empty() && country == "US" && !autofill::IsValidState(data)) 426 if (!data.empty() && country == "US" && !autofill::IsValidState(data))
426 return true; 427 return true;
427 break; 428 break;
428 429
429 case ADDRESS_HOME_ZIP: 430 case ADDRESS_HOME_ZIP:
430 if (!data.empty() && country == "US" && !autofill::IsValidZip(data)) 431 if (!data.empty() && country == "US" && !autofill::IsValidZip(data))
431 return true; 432 return true;
432 break; 433 break;
433 434
434 case PHONE_HOME_WHOLE_NUMBER: { 435 case PHONE_HOME_WHOLE_NUMBER: {
435 if (!data.empty() && !i18n::PhoneObject(data, country).IsValidNumber()) 436 if (!data.empty() && !i18n::PhoneObject(data, country).IsValidNumber())
436 return true; 437 return true;
437 break; 438 break;
438 } 439 }
439 440
440 default: 441 default:
441 NOTREACHED(); 442 NOTREACHED();
442 break; 443 break;
443 } 444 }
444 445
445 return false; 446 return false;
446 } 447 }
447 448
448 449
449 int AutofillProfile::Compare(const AutofillProfile& profile) const { 450 int AutofillProfile::Compare(const AutofillProfile& profile) const {
450 const AutofillFieldType single_value_types[] = { COMPANY_NAME, 451 const ServerFieldType single_value_types[] = { COMPANY_NAME,
451 ADDRESS_HOME_LINE1, 452 ADDRESS_HOME_LINE1,
452 ADDRESS_HOME_LINE2, 453 ADDRESS_HOME_LINE2,
453 ADDRESS_HOME_CITY, 454 ADDRESS_HOME_CITY,
454 ADDRESS_HOME_STATE, 455 ADDRESS_HOME_STATE,
455 ADDRESS_HOME_ZIP, 456 ADDRESS_HOME_ZIP,
456 ADDRESS_HOME_COUNTRY }; 457 ADDRESS_HOME_COUNTRY };
457 458
458 for (size_t i = 0; i < arraysize(single_value_types); ++i) { 459 for (size_t i = 0; i < arraysize(single_value_types); ++i) {
459 int comparison = GetRawInfo(single_value_types[i]).compare( 460 int comparison = GetRawInfo(single_value_types[i]).compare(
460 profile.GetRawInfo(single_value_types[i])); 461 profile.GetRawInfo(single_value_types[i]));
461 if (comparison != 0) 462 if (comparison != 0)
462 return comparison; 463 return comparison;
463 } 464 }
464 465
465 const AutofillFieldType multi_value_types[] = { NAME_FIRST, 466 const ServerFieldType multi_value_types[] = { NAME_FIRST,
466 NAME_MIDDLE, 467 NAME_MIDDLE,
467 NAME_LAST, 468 NAME_LAST,
468 EMAIL_ADDRESS, 469 EMAIL_ADDRESS,
469 PHONE_HOME_WHOLE_NUMBER }; 470 PHONE_HOME_WHOLE_NUMBER };
470 471
471 for (size_t i = 0; i < arraysize(multi_value_types); ++i) { 472 for (size_t i = 0; i < arraysize(multi_value_types); ++i) {
472 std::vector<base::string16> values_a; 473 std::vector<base::string16> values_a;
473 std::vector<base::string16> values_b; 474 std::vector<base::string16> values_b;
474 GetRawMultiInfo(multi_value_types[i], &values_a); 475 GetRawMultiInfo(multi_value_types[i], &values_a);
475 profile.GetRawMultiInfo(multi_value_types[i], &values_b); 476 profile.GetRawMultiInfo(multi_value_types[i], &values_b);
476 if (values_a.size() < values_b.size()) 477 if (values_a.size() < values_b.size())
477 return -1; 478 return -1;
478 if (values_a.size() > values_b.size()) 479 if (values_a.size() > values_b.size())
479 return 1; 480 return 1;
(...skipping 16 matching lines...) Expand all
496 bool AutofillProfile::operator!=(const AutofillProfile& profile) const { 497 bool AutofillProfile::operator!=(const AutofillProfile& profile) const {
497 return !operator==(profile); 498 return !operator==(profile);
498 } 499 }
499 500
500 const base::string16 AutofillProfile::PrimaryValue() const { 501 const base::string16 AutofillProfile::PrimaryValue() const {
501 return GetRawInfo(ADDRESS_HOME_LINE1) + GetRawInfo(ADDRESS_HOME_CITY); 502 return GetRawInfo(ADDRESS_HOME_LINE1) + GetRawInfo(ADDRESS_HOME_CITY);
502 } 503 }
503 504
504 bool AutofillProfile::IsSubsetOf(const AutofillProfile& profile, 505 bool AutofillProfile::IsSubsetOf(const AutofillProfile& profile,
505 const std::string& app_locale) const { 506 const std::string& app_locale) const {
506 FieldTypeSet types; 507 ServerFieldTypeSet types;
507 GetNonEmptyTypes(app_locale, &types); 508 GetNonEmptyTypes(app_locale, &types);
508 509
509 for (FieldTypeSet::const_iterator iter = types.begin(); iter != types.end(); 510 for (ServerFieldTypeSet::const_iterator it = types.begin(); it != types.end();
510 ++iter) { 511 ++it) {
511 if (*iter == NAME_FULL) { 512 if (*it == NAME_FULL) {
512 // Ignore the compound "full name" field type. We are only interested in 513 // Ignore the compound "full name" field type. We are only interested in
513 // comparing the constituent parts. For example, if |this| has a middle 514 // comparing the constituent parts. For example, if |this| has a middle
514 // name saved, but |profile| lacks one, |profile| could still be a subset 515 // name saved, but |profile| lacks one, |profile| could still be a subset
515 // of |this|. 516 // of |this|.
516 continue; 517 continue;
517 } else if (AutofillType(*iter).group() == PHONE_HOME) { 518 } else if (AutofillType(*it).group() == PHONE_HOME) {
518 // Phone numbers should be canonicalized prior to being compared. 519 // Phone numbers should be canonicalized prior to being compared.
519 if (*iter != PHONE_HOME_WHOLE_NUMBER) { 520 if (*it != PHONE_HOME_WHOLE_NUMBER) {
520 continue; 521 continue;
521 } else if (!i18n::PhoneNumbersMatch( 522 } else if (!i18n::PhoneNumbersMatch(
522 GetRawInfo(*iter), 523 GetRawInfo(*it),
523 profile.GetRawInfo(*iter), 524 profile.GetRawInfo(*it),
524 UTF16ToASCII(GetRawInfo(ADDRESS_HOME_COUNTRY)), 525 UTF16ToASCII(GetRawInfo(ADDRESS_HOME_COUNTRY)),
525 app_locale)) { 526 app_locale)) {
526 return false; 527 return false;
527 } 528 }
528 } else if (StringToLowerASCII(GetRawInfo(*iter)) != 529 } else if (StringToLowerASCII(GetRawInfo(*it)) !=
529 StringToLowerASCII(profile.GetRawInfo(*iter))) { 530 StringToLowerASCII(profile.GetRawInfo(*it))) {
530 return false; 531 return false;
531 } 532 }
532 } 533 }
533 534
534 return true; 535 return true;
535 } 536 }
536 537
537 void AutofillProfile::OverwriteWithOrAddTo(const AutofillProfile& profile, 538 void AutofillProfile::OverwriteWithOrAddTo(const AutofillProfile& profile,
538 const std::string& app_locale) { 539 const std::string& app_locale) {
539 // Verified profiles should never be overwritten with unverified data. 540 // Verified profiles should never be overwritten with unverified data.
540 DCHECK(!IsVerified() || profile.IsVerified()); 541 DCHECK(!IsVerified() || profile.IsVerified());
541 set_origin(profile.origin()); 542 set_origin(profile.origin());
542 543
543 FieldTypeSet field_types; 544 ServerFieldTypeSet field_types;
544 profile.GetNonEmptyTypes(app_locale, &field_types); 545 profile.GetNonEmptyTypes(app_locale, &field_types);
545 546
546 // Only transfer "full" types (e.g. full name) and not fragments (e.g. 547 // Only transfer "full" types (e.g. full name) and not fragments (e.g.
547 // first name, last name). 548 // first name, last name).
548 CollapseCompoundFieldTypes(&field_types); 549 CollapseCompoundFieldTypes(&field_types);
549 550
550 for (FieldTypeSet::const_iterator iter = field_types.begin(); 551 for (ServerFieldTypeSet::const_iterator iter = field_types.begin();
551 iter != field_types.end(); ++iter) { 552 iter != field_types.end(); ++iter) {
552 if (AutofillProfile::SupportsMultiValue(*iter)) { 553 if (AutofillProfile::SupportsMultiValue(*iter)) {
553 std::vector<base::string16> new_values; 554 std::vector<base::string16> new_values;
554 profile.GetRawMultiInfo(*iter, &new_values); 555 profile.GetRawMultiInfo(*iter, &new_values);
555 std::vector<base::string16> existing_values; 556 std::vector<base::string16> existing_values;
556 GetRawMultiInfo(*iter, &existing_values); 557 GetRawMultiInfo(*iter, &existing_values);
557 558
558 // GetMultiInfo always returns at least one element, even if the profile 559 // GetMultiInfo always returns at least one element, even if the profile
559 // has no data stored for this field type. 560 // has no data stored for this field type.
560 if (existing_values.size() == 1 && existing_values.front().empty()) 561 if (existing_values.size() == 1 && existing_values.front().empty())
(...skipping 20 matching lines...) Expand all
581 base::string16 new_value = profile.GetRawInfo(*iter); 582 base::string16 new_value = profile.GetRawInfo(*iter);
582 if (StringToLowerASCII(GetRawInfo(*iter)) != 583 if (StringToLowerASCII(GetRawInfo(*iter)) !=
583 StringToLowerASCII(new_value)) { 584 StringToLowerASCII(new_value)) {
584 SetRawInfo(*iter, new_value); 585 SetRawInfo(*iter, new_value);
585 } 586 }
586 } 587 }
587 } 588 }
588 } 589 }
589 590
590 // static 591 // static
591 bool AutofillProfile::SupportsMultiValue(AutofillFieldType type) { 592 bool AutofillProfile::SupportsMultiValue(ServerFieldType type) {
592 FieldTypeGroup group = AutofillType(type).group(); 593 FieldTypeGroup group = AutofillType(type).group();
593 return group == NAME || 594 return group == NAME ||
594 group == NAME_BILLING || 595 group == NAME_BILLING ||
595 group == EMAIL || 596 group == EMAIL ||
596 group == PHONE_HOME || 597 group == PHONE_HOME ||
597 group == PHONE_BILLING; 598 group == PHONE_BILLING;
598 } 599 }
599 600
600 // static 601 // static
601 bool AutofillProfile::AdjustInferredLabels( 602 bool AutofillProfile::AdjustInferredLabels(
(...skipping 11 matching lines...) Expand all
613 updated_labels = true; 614 updated_labels = true;
614 (*profiles)[i]->label_ = created_labels[i]; 615 (*profiles)[i]->label_ = created_labels[i];
615 } 616 }
616 } 617 }
617 return updated_labels; 618 return updated_labels;
618 } 619 }
619 620
620 // static 621 // static
621 void AutofillProfile::CreateInferredLabels( 622 void AutofillProfile::CreateInferredLabels(
622 const std::vector<AutofillProfile*>* profiles, 623 const std::vector<AutofillProfile*>* profiles,
623 const std::vector<AutofillFieldType>* suggested_fields, 624 const std::vector<ServerFieldType>* suggested_fields,
624 AutofillFieldType excluded_field, 625 ServerFieldType excluded_field,
625 size_t minimal_fields_shown, 626 size_t minimal_fields_shown,
626 std::vector<base::string16>* created_labels) { 627 std::vector<base::string16>* created_labels) {
627 DCHECK(profiles); 628 DCHECK(profiles);
628 DCHECK(created_labels); 629 DCHECK(created_labels);
629 630
630 std::vector<AutofillFieldType> fields_to_use; 631 std::vector<ServerFieldType> fields_to_use;
631 GetFieldsForDistinguishingProfiles(suggested_fields, excluded_field, 632 GetFieldsForDistinguishingProfiles(suggested_fields, excluded_field,
632 &fields_to_use); 633 &fields_to_use);
633 634
634 // Construct the default label for each profile. Also construct a map that 635 // Construct the default label for each profile. Also construct a map that
635 // associates each label with the profiles that have this label. This map is 636 // associates each label with the profiles that have this label. This map is
636 // then used to detect which labels need further differentiating fields. 637 // then used to detect which labels need further differentiating fields.
637 std::map<base::string16, std::list<size_t> > labels; 638 std::map<base::string16, std::list<size_t> > labels;
638 for (size_t i = 0; i < profiles->size(); ++i) { 639 for (size_t i = 0; i < profiles->size(); ++i) {
639 base::string16 label = 640 base::string16 label =
640 (*profiles)[i]->ConstructInferredLabel(fields_to_use, 641 (*profiles)[i]->ConstructInferredLabel(fields_to_use,
(...skipping 12 matching lines...) Expand all
653 (*created_labels)[profile_index] = label; 654 (*created_labels)[profile_index] = label;
654 } else { 655 } else {
655 // We have more than one profile with the same label, so add 656 // We have more than one profile with the same label, so add
656 // differentiating fields. 657 // differentiating fields.
657 CreateDifferentiatingLabels(*profiles, it->second, fields_to_use, 658 CreateDifferentiatingLabels(*profiles, it->second, fields_to_use,
658 minimal_fields_shown, created_labels); 659 minimal_fields_shown, created_labels);
659 } 660 }
660 } 661 }
661 } 662 }
662 663
663 void AutofillProfile::GetSupportedTypes(FieldTypeSet* supported_types) const { 664 void AutofillProfile::GetSupportedTypes(
665 ServerFieldTypeSet* supported_types) const {
664 FormGroupList info = FormGroups(); 666 FormGroupList info = FormGroups();
665 for (FormGroupList::const_iterator it = info.begin(); it != info.end(); ++it) 667 for (FormGroupList::const_iterator it = info.begin(); it != info.end(); ++it)
666 (*it)->GetSupportedTypes(supported_types); 668 (*it)->GetSupportedTypes(supported_types);
667 } 669 }
668 670
669 bool AutofillProfile::FillCountrySelectControl( 671 bool AutofillProfile::FillCountrySelectControl(
670 const std::string& app_locale, 672 const std::string& app_locale,
671 FormFieldData* field_data) const { 673 FormFieldData* field_data) const {
672 std::string country_code = UTF16ToASCII(GetRawInfo(ADDRESS_HOME_COUNTRY)); 674 std::string country_code = UTF16ToASCII(GetRawInfo(ADDRESS_HOME_COUNTRY));
673 675
674 DCHECK_EQ(field_data->option_values.size(), 676 DCHECK_EQ(field_data->option_values.size(),
675 field_data->option_contents.size()); 677 field_data->option_contents.size());
676 for (size_t i = 0; i < field_data->option_values.size(); ++i) { 678 for (size_t i = 0; i < field_data->option_values.size(); ++i) {
677 // Canonicalize each <option> value to a country code, and compare to the 679 // Canonicalize each <option> value to a country code, and compare to the
678 // target country code. 680 // target country code.
679 base::string16 value = field_data->option_values[i]; 681 base::string16 value = field_data->option_values[i];
680 base::string16 contents = field_data->option_contents[i]; 682 base::string16 contents = field_data->option_contents[i];
681 if (country_code == AutofillCountry::GetCountryCode(value, app_locale) || 683 if (country_code == AutofillCountry::GetCountryCode(value, app_locale) ||
682 country_code == AutofillCountry::GetCountryCode(contents, app_locale)) { 684 country_code == AutofillCountry::GetCountryCode(contents, app_locale)) {
683 field_data->value = value; 685 field_data->value = value;
684 return true; 686 return true;
685 } 687 }
686 } 688 }
687 689
688 return false; 690 return false;
689 } 691 }
690 692
691 void AutofillProfile::GetMultiInfoImpl( 693 void AutofillProfile::GetMultiInfoImpl(
692 AutofillFieldType type, 694 const AutofillType& type,
693 const std::string& app_locale, 695 const std::string& app_locale,
694 std::vector<base::string16>* values) const { 696 std::vector<base::string16>* values) const {
695 switch (AutofillType(type).group()) { 697 switch (type.group()) {
696 case NAME: 698 case NAME:
697 case NAME_BILLING: 699 case NAME_BILLING:
698 CopyItemsToValues(type, name_, app_locale, values); 700 CopyItemsToValues(type, name_, app_locale, values);
699 break; 701 break;
700 case EMAIL: 702 case EMAIL:
701 CopyItemsToValues(type, email_, app_locale, values); 703 CopyItemsToValues(type, email_, app_locale, values);
702 break; 704 break;
703 case PHONE_HOME: 705 case PHONE_HOME:
704 case PHONE_BILLING: 706 case PHONE_BILLING:
705 CopyItemsToValues(type, phone_number_, app_locale, values); 707 CopyItemsToValues(type, phone_number_, app_locale, values);
(...skipping 13 matching lines...) Expand all
719 // "(800)356-9377" and "356-9377" are considered the same. 721 // "(800)356-9377" and "356-9377" are considered the same.
720 std::string country_code = UTF16ToASCII(GetRawInfo(ADDRESS_HOME_COUNTRY)); 722 std::string country_code = UTF16ToASCII(GetRawInfo(ADDRESS_HOME_COUNTRY));
721 if (std::find_if(existing_phones->begin(), existing_phones->end(), 723 if (std::find_if(existing_phones->begin(), existing_phones->end(),
722 FindByPhone(phone, country_code, app_locale)) == 724 FindByPhone(phone, country_code, app_locale)) ==
723 existing_phones->end()) { 725 existing_phones->end()) {
724 existing_phones->push_back(phone); 726 existing_phones->push_back(phone);
725 } 727 }
726 } 728 }
727 729
728 base::string16 AutofillProfile::ConstructInferredLabel( 730 base::string16 AutofillProfile::ConstructInferredLabel(
729 const std::vector<AutofillFieldType>& included_fields, 731 const std::vector<ServerFieldType>& included_fields,
730 size_t num_fields_to_use) const { 732 size_t num_fields_to_use) const {
731 const base::string16 separator = 733 const base::string16 separator =
732 l10n_util::GetStringUTF16(IDS_AUTOFILL_ADDRESS_SUMMARY_SEPARATOR); 734 l10n_util::GetStringUTF16(IDS_AUTOFILL_ADDRESS_SUMMARY_SEPARATOR);
733 735
734 base::string16 label; 736 base::string16 label;
735 size_t num_fields_used = 0; 737 size_t num_fields_used = 0;
736 for (std::vector<AutofillFieldType>::const_iterator it = 738 for (std::vector<ServerFieldType>::const_iterator it =
737 included_fields.begin(); 739 included_fields.begin();
738 it != included_fields.end() && num_fields_used < num_fields_to_use; 740 it != included_fields.end() && num_fields_used < num_fields_to_use;
739 ++it) { 741 ++it) {
740 base::string16 field = GetRawInfo(*it); 742 base::string16 field = GetRawInfo(*it);
741 if (field.empty()) 743 if (field.empty())
742 continue; 744 continue;
743 745
744 if (!label.empty()) 746 if (!label.empty())
745 label.append(separator); 747 label.append(separator);
746 748
747 label.append(field); 749 label.append(field);
748 ++num_fields_used; 750 ++num_fields_used;
749 } 751 }
750 return label; 752 return label;
751 } 753 }
752 754
753 // static 755 // static
754 void AutofillProfile::CreateDifferentiatingLabels( 756 void AutofillProfile::CreateDifferentiatingLabels(
755 const std::vector<AutofillProfile*>& profiles, 757 const std::vector<AutofillProfile*>& profiles,
756 const std::list<size_t>& indices, 758 const std::list<size_t>& indices,
757 const std::vector<AutofillFieldType>& fields, 759 const std::vector<ServerFieldType>& fields,
758 size_t num_fields_to_include, 760 size_t num_fields_to_include,
759 std::vector<base::string16>* created_labels) { 761 std::vector<base::string16>* created_labels) {
760 // For efficiency, we first construct a map of fields to their text values and 762 // For efficiency, we first construct a map of fields to their text values and
761 // each value's frequency. 763 // each value's frequency.
762 std::map<AutofillFieldType, 764 std::map<ServerFieldType,
763 std::map<base::string16, size_t> > field_text_frequencies_by_field; 765 std::map<base::string16, size_t> > field_text_frequencies_by_field;
764 for (std::vector<AutofillFieldType>::const_iterator field = fields.begin(); 766 for (std::vector<ServerFieldType>::const_iterator field = fields.begin();
765 field != fields.end(); ++field) { 767 field != fields.end(); ++field) {
766 std::map<base::string16, size_t>& field_text_frequencies = 768 std::map<base::string16, size_t>& field_text_frequencies =
767 field_text_frequencies_by_field[*field]; 769 field_text_frequencies_by_field[*field];
768 770
769 for (std::list<size_t>::const_iterator it = indices.begin(); 771 for (std::list<size_t>::const_iterator it = indices.begin();
770 it != indices.end(); ++it) { 772 it != indices.end(); ++it) {
771 const AutofillProfile* profile = profiles[*it]; 773 const AutofillProfile* profile = profiles[*it];
772 base::string16 field_text = profile->GetRawInfo(*field); 774 base::string16 field_text = profile->GetRawInfo(*field);
773 775
774 // If this label is not already in the map, add it with frequency 0. 776 // If this label is not already in the map, add it with frequency 0.
775 if (!field_text_frequencies.count(field_text)) 777 if (!field_text_frequencies.count(field_text))
776 field_text_frequencies[field_text] = 0; 778 field_text_frequencies[field_text] = 0;
777 779
778 // Now, increment the frequency for this label. 780 // Now, increment the frequency for this label.
779 ++field_text_frequencies[field_text]; 781 ++field_text_frequencies[field_text];
780 } 782 }
781 } 783 }
782 784
783 // Now comes the meat of the algorithm. For each profile, we scan the list of 785 // Now comes the meat of the algorithm. For each profile, we scan the list of
784 // fields to use, looking for two things: 786 // fields to use, looking for two things:
785 // 1. A (non-empty) field that differentiates the profile from all others 787 // 1. A (non-empty) field that differentiates the profile from all others
786 // 2. At least |num_fields_to_include| non-empty fields 788 // 2. At least |num_fields_to_include| non-empty fields
787 // Before we've satisfied condition (2), we include all fields, even ones that 789 // Before we've satisfied condition (2), we include all fields, even ones that
788 // are identical across all the profiles. Once we've satisfied condition (2), 790 // are identical across all the profiles. Once we've satisfied condition (2),
789 // we only include fields that that have at last two distinct values. 791 // we only include fields that that have at last two distinct values.
790 for (std::list<size_t>::const_iterator it = indices.begin(); 792 for (std::list<size_t>::const_iterator it = indices.begin();
791 it != indices.end(); ++it) { 793 it != indices.end(); ++it) {
792 const AutofillProfile* profile = profiles[*it]; 794 const AutofillProfile* profile = profiles[*it];
793 795
794 std::vector<AutofillFieldType> label_fields; 796 std::vector<ServerFieldType> label_fields;
795 bool found_differentiating_field = false; 797 bool found_differentiating_field = false;
796 for (std::vector<AutofillFieldType>::const_iterator field = fields.begin(); 798 for (std::vector<ServerFieldType>::const_iterator field = fields.begin();
797 field != fields.end(); ++field) { 799 field != fields.end(); ++field) {
798 // Skip over empty fields. 800 // Skip over empty fields.
799 base::string16 field_text = profile->GetRawInfo(*field); 801 base::string16 field_text = profile->GetRawInfo(*field);
800 if (field_text.empty()) 802 if (field_text.empty())
801 continue; 803 continue;
802 804
803 std::map<base::string16, size_t>& field_text_frequencies = 805 std::map<base::string16, size_t>& field_text_frequencies =
804 field_text_frequencies_by_field[*field]; 806 field_text_frequencies_by_field[*field];
805 found_differentiating_field |= 807 found_differentiating_field |=
806 !field_text_frequencies.count(base::string16()) && 808 !field_text_frequencies.count(base::string16()) &&
(...skipping 24 matching lines...) Expand all
831 FormGroupList v(5); 833 FormGroupList v(5);
832 v[0] = &name_[0]; 834 v[0] = &name_[0];
833 v[1] = &email_[0]; 835 v[1] = &email_[0];
834 v[2] = &company_; 836 v[2] = &company_;
835 v[3] = &phone_number_[0]; 837 v[3] = &phone_number_[0];
836 v[4] = &address_; 838 v[4] = &address_;
837 return v; 839 return v;
838 } 840 }
839 841
840 const FormGroup* AutofillProfile::FormGroupForType( 842 const FormGroup* AutofillProfile::FormGroupForType(
841 AutofillFieldType type) const { 843 const AutofillType& type) const {
842 return const_cast<AutofillProfile*>(this)->MutableFormGroupForType(type); 844 return const_cast<AutofillProfile*>(this)->MutableFormGroupForType(type);
843 } 845 }
844 846
845 FormGroup* AutofillProfile::MutableFormGroupForType(AutofillFieldType type) { 847 FormGroup* AutofillProfile::MutableFormGroupForType(const AutofillType& type) {
846 FormGroup* form_group = NULL; 848 switch (type.group()) {
847 switch (AutofillType(type).group()) {
848 case NAME: 849 case NAME:
849 case NAME_BILLING: 850 case NAME_BILLING:
850 form_group = &name_[0]; 851 return &name_[0];
851 break; 852
852 case EMAIL: 853 case EMAIL:
853 form_group = &email_[0]; 854 return &email_[0];
854 break; 855
855 case COMPANY: 856 case COMPANY:
856 form_group = &company_; 857 return &company_;
857 break; 858
858 case PHONE_HOME: 859 case PHONE_HOME:
859 case PHONE_BILLING: 860 case PHONE_BILLING:
860 form_group = &phone_number_[0]; 861 return &phone_number_[0];
861 break; 862
862 case ADDRESS_HOME: 863 case ADDRESS_HOME:
863 case ADDRESS_BILLING: 864 case ADDRESS_BILLING:
864 form_group = &address_; 865 return &address_;
865 break; 866
866 default: 867 case NO_GROUP:
867 break; 868 case CREDIT_CARD:
869 return NULL;
868 } 870 }
869 871
870 return form_group; 872 NOTREACHED();
873 return NULL;
871 } 874 }
872 875
873 // So we can compare AutofillProfiles with EXPECT_EQ(). 876 // So we can compare AutofillProfiles with EXPECT_EQ().
874 std::ostream& operator<<(std::ostream& os, const AutofillProfile& profile) { 877 std::ostream& operator<<(std::ostream& os, const AutofillProfile& profile) {
875 return os 878 return os
876 << UTF16ToUTF8(profile.Label()) 879 << UTF16ToUTF8(profile.Label())
877 << " " 880 << " "
878 << profile.guid() 881 << profile.guid()
879 << " " 882 << " "
880 << profile.origin() 883 << profile.origin()
(...skipping 17 matching lines...) Expand all
898 << UTF16ToUTF8(profile.GetRawInfo(ADDRESS_HOME_STATE)) 901 << UTF16ToUTF8(profile.GetRawInfo(ADDRESS_HOME_STATE))
899 << " " 902 << " "
900 << UTF16ToUTF8(profile.GetRawInfo(ADDRESS_HOME_ZIP)) 903 << UTF16ToUTF8(profile.GetRawInfo(ADDRESS_HOME_ZIP))
901 << " " 904 << " "
902 << UTF16ToUTF8(profile.GetRawInfo(ADDRESS_HOME_COUNTRY)) 905 << UTF16ToUTF8(profile.GetRawInfo(ADDRESS_HOME_COUNTRY))
903 << " " 906 << " "
904 << UTF16ToUTF8(MultiString(profile, PHONE_HOME_WHOLE_NUMBER)); 907 << UTF16ToUTF8(MultiString(profile, PHONE_HOME_WHOLE_NUMBER));
905 } 908 }
906 909
907 } // namespace autofill 910 } // namespace autofill
OLDNEW
« no previous file with comments | « components/autofill/core/browser/autofill_profile.h ('k') | components/autofill/core/browser/autofill_profile_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698