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

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

Issue 11198048: [Autofill] Update the autocomplete types implementation to match the current HTML spec. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 2 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) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/form_structure.h" 5 #include "chrome/browser/autofill/form_structure.h"
6 6
7 #include <utility> 7 #include <utility>
8 8
9 #include "base/basictypes.h" 9 #include "base/basictypes.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
78 // Print all meaningfull bytes into a string. 78 // Print all meaningfull bytes into a string.
79 std::string data_presence; 79 std::string data_presence;
80 data_presence.reserve(data_end * 2 + 1); 80 data_presence.reserve(data_end * 2 + 1);
81 for (size_t i = 0; i < data_end; ++i) { 81 for (size_t i = 0; i < data_end; ++i) {
82 base::StringAppendF(&data_presence, "%02x", bit_field[i]); 82 base::StringAppendF(&data_presence, "%02x", bit_field[i]);
83 } 83 }
84 84
85 return data_presence; 85 return data_presence;
86 } 86 }
87 87
88 bool UpdateFromAutocompleteType(const string16& autocomplete_type, 88 // Returns |true| iff the |token| is a type hint for a contact field, as
89 AutofillField* field) { 89 // specified in the implementation section of
90 if (autocomplete_type == ASCIIToUTF16("given-name")) { 90 // http://www.whatwg.org/specs/web-apps/current-work/multipage/association-of-co ntrols-and-forms.html#autofilling-form-controls:-the-autocomplete-attribute
Dan Beam 2012/10/19 00:12:44 nit: it might be useful to URL shorten some of the
Ilya Sherman 2012/10/19 04:19:32 Done.
91 field->set_heuristic_type(NAME_FIRST); 91 // Note that "fax" is intentionally ignored, as Chrome does not support filling
92 return true; 92 // fax information.
93 bool IsContactTypeHint(const string16& token) {
94 return
Dan Beam 2012/10/19 00:12:44 nit: isn't the chromium style more return token
Ilya Sherman 2012/10/19 04:19:32 Done.
Dan Beam 2012/10/23 00:28:59 it doesn't seem like anything other than stripping
Ilya Sherman 2012/10/23 01:06:12 Whoops. Actually done now.
95 token == ASCIIToUTF16("home") ||
96 token == ASCIIToUTF16("work") ||
97 token == ASCIIToUTF16("mobile") ||
98 token == ASCIIToUTF16("pager");
99 }
100
101 // Returns |true| iff the |token| is a type hint appropriate for a field of the
102 // given |field_type|, as specified in the implementation section of
103 // http://www.whatwg.org/specs/web-apps/current-work/multipage/association-of-co ntrols-and-forms.html#autofilling-form-controls:-the-autocomplete-attribute
104 bool ContactTypeHintMatchesFieldType(const string16& token,
105 AutofillFieldType field_type) {
106 // The "home" and "work" type hints are only appropriate for email and phone
107 // number field types.
108 if (token == ASCIIToUTF16("home") || token == ASCIIToUTF16("work")) {
109 return
110 field_type == EMAIL_ADDRESS ||
111 (field_type >= PHONE_HOME_NUMBER &&
112 field_type <= PHONE_HOME_WHOLE_NUMBER);
93 } 113 }
94 114
95 if (autocomplete_type == ASCIIToUTF16("middle-name")) { 115 // The remaining type hints are only appropriate for phone number field types.
96 field->set_heuristic_type(NAME_MIDDLE); 116 // Note that "fax" is intentionally ignored, as Chrome does not support
97 return true; 117 // filling fax information.
98 } 118 if (token == ASCIIToUTF16("mobile") || token == ASCIIToUTF16("pager")) {
99 119 return
100 if (autocomplete_type == ASCIIToUTF16("middle-initial")) { 120 field_type >= PHONE_HOME_NUMBER &&
101 field->set_heuristic_type(NAME_MIDDLE_INITIAL); 121 field_type <= PHONE_HOME_WHOLE_NUMBER;
102 return true;
103 }
104
105 if (autocomplete_type == ASCIIToUTF16("surname")) {
106 field->set_heuristic_type(NAME_LAST);
107 return true;
108 }
109
110 if (autocomplete_type == ASCIIToUTF16("full-name")) {
111 field->set_heuristic_type(NAME_FULL);
112 return true;
113 }
114
115 if (autocomplete_type == ASCIIToUTF16("street-address") ||
116 autocomplete_type == ASCIIToUTF16("address-line1")) {
117 field->set_heuristic_type(ADDRESS_HOME_LINE1);
118 return true;
119 }
120
121 if (autocomplete_type == ASCIIToUTF16("address-line2")) {
122 field->set_heuristic_type(ADDRESS_HOME_LINE2);
123 return true;
124 }
125
126 if (autocomplete_type == ASCIIToUTF16("locality") ||
127 autocomplete_type == ASCIIToUTF16("city")) {
128 field->set_heuristic_type(ADDRESS_HOME_CITY);
129 return true;
130 }
131
132 if (autocomplete_type == ASCIIToUTF16("administrative-area") ||
133 autocomplete_type == ASCIIToUTF16("state") ||
134 autocomplete_type == ASCIIToUTF16("province") ||
135 autocomplete_type == ASCIIToUTF16("region")) {
136 field->set_heuristic_type(ADDRESS_HOME_STATE);
137 return true;
138 }
139
140 if (autocomplete_type == ASCIIToUTF16("postal-code")) {
141 field->set_heuristic_type(ADDRESS_HOME_ZIP);
142 return true;
143 }
144
145 if (autocomplete_type == ASCIIToUTF16("country")) {
146 field->set_heuristic_type(ADDRESS_HOME_COUNTRY);
147 return true;
148 }
149
150 if (autocomplete_type == ASCIIToUTF16("organization")) {
151 field->set_heuristic_type(COMPANY_NAME);
152 return true;
153 }
154
155 if (autocomplete_type == ASCIIToUTF16("email")) {
156 field->set_heuristic_type(EMAIL_ADDRESS);
157 return true;
158 }
159
160 if (autocomplete_type == ASCIIToUTF16("phone-full")) {
161 field->set_heuristic_type(PHONE_HOME_WHOLE_NUMBER);
162 return true;
163 }
164
165 if (autocomplete_type == ASCIIToUTF16("phone-country-code")) {
166 field->set_heuristic_type(PHONE_HOME_COUNTRY_CODE);
167 return true;
168 }
169
170 if (autocomplete_type == ASCIIToUTF16("phone-national")) {
171 field->set_heuristic_type(PHONE_HOME_CITY_AND_NUMBER);
172 return true;
173 }
174
175 if (autocomplete_type == ASCIIToUTF16("phone-area-code")) {
176 field->set_heuristic_type(PHONE_HOME_CITY_CODE);
177 return true;
178 }
179
180 if (autocomplete_type == ASCIIToUTF16("phone-local")) {
181 field->set_heuristic_type(PHONE_HOME_NUMBER);
182 return true;
183 }
184
185 if (autocomplete_type == ASCIIToUTF16("phone-local-prefix")) {
186 field->set_heuristic_type(PHONE_HOME_NUMBER);
187 field->set_phone_part(AutofillField::PHONE_PREFIX);
188 return true;
189 }
190
191 if (autocomplete_type == ASCIIToUTF16("phone-local-suffix")) {
192 field->set_heuristic_type(PHONE_HOME_NUMBER);
193 field->set_phone_part(AutofillField::PHONE_SUFFIX);
194 return true;
195 }
196
197 if (autocomplete_type == ASCIIToUTF16("cc-full-name")) {
198 field->set_heuristic_type(CREDIT_CARD_NAME);
199 return true;
200 }
201
202 if (autocomplete_type == ASCIIToUTF16("cc-number")) {
203 field->set_heuristic_type(CREDIT_CARD_NUMBER);
204 return true;
205 }
206
207 if (autocomplete_type == ASCIIToUTF16("cc-exp-month")) {
208 field->set_heuristic_type(CREDIT_CARD_EXP_MONTH);
209 return true;
210 }
211
212 if (autocomplete_type == ASCIIToUTF16("cc-exp-year")) {
213 if (field->max_length == 2)
214 field->set_heuristic_type(CREDIT_CARD_EXP_2_DIGIT_YEAR);
215 else
216 field->set_heuristic_type(CREDIT_CARD_EXP_4_DIGIT_YEAR);
217 return true;
218 }
219
220 if (autocomplete_type == ASCIIToUTF16("cc-exp")) {
221 if (field->max_length == 5)
222 field->set_heuristic_type(CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR);
223 else
224 field->set_heuristic_type(CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR);
225 return true;
226 } 122 }
227 123
228 return false; 124 return false;
229 } 125 }
230 126
127 // Returns the Chrome Autofill-supported field type corresponding to the given
128 // |autocomplete_type|, if there is one, in the context of the given |field|.
129 // Chrome Autofill supports a subset of the field types listed at
130 // http://www.whatwg.org/specs/web-apps/current-work/multipage/association-of-co ntrols-and-forms.html#autofilling-form-controls:-the-autocomplete-attribute
131 AutofillFieldType FieldTypeFromAutocompleteType(
132 const string16& autocomplete_type,
133 const AutofillField& field) {
134 if (autocomplete_type == ASCIIToUTF16("name"))
135 return NAME_FULL;
136
137 if (autocomplete_type == ASCIIToUTF16("given-name"))
138 return NAME_FIRST;
139
140 if (autocomplete_type == ASCIIToUTF16("additional-name")) {
141 if (field.max_length == 1)
142 return NAME_MIDDLE_INITIAL;
143 else
144 return NAME_MIDDLE;
145 }
146
147 if (autocomplete_type == ASCIIToUTF16("family-name"))
148 return NAME_LAST;
149
150 if (autocomplete_type == ASCIIToUTF16("honorific-suffix"))
151 return NAME_SUFFIX;
152
153 if (autocomplete_type == ASCIIToUTF16("organization"))
Dan Beam 2012/10/19 00:12:44 organization == company always?
Ilya Sherman 2012/10/19 04:19:32 The spec defines this token as meaning "Company na
Dan Beam 2012/10/19 04:25:41 I know, I noticed that. My issue is really with t
154 return COMPANY_NAME;
155
156 if (autocomplete_type == ASCIIToUTF16("street-address") ||
157 autocomplete_type == ASCIIToUTF16("address-line1"))
158 return ADDRESS_HOME_LINE1;
159
160 if (autocomplete_type == ASCIIToUTF16("address-line2"))
161 return ADDRESS_HOME_LINE2;
162
163 if (autocomplete_type == ASCIIToUTF16("locality"))
164 return ADDRESS_HOME_CITY;
165
166 if (autocomplete_type == ASCIIToUTF16("region"))
Dan Beam 2012/10/19 00:12:44 region == state always?
Ilya Sherman 2012/10/19 04:19:32 "state" is the name that Autofill internally uses
Dan Beam 2012/10/19 04:25:41 So we could have things like Bavaria as the state.
Ilya Sherman 2012/10/19 04:54:11 Yes, we could have things like Bavaria as the "sta
167 return ADDRESS_HOME_STATE;
168
169 if (autocomplete_type == ASCIIToUTF16("country"))
170 return ADDRESS_HOME_COUNTRY;
171
172 if (autocomplete_type == ASCIIToUTF16("postal-code"))
173 return ADDRESS_HOME_ZIP;
Dan Beam 2012/10/19 00:12:44 postal-code == zip always?
Ilya Sherman 2012/10/19 04:19:32 Ditto: This is just what the Autofill code calls t
174
175 if (autocomplete_type == ASCIIToUTF16("cc-name"))
176 return CREDIT_CARD_NAME;
177
178 if (autocomplete_type == ASCIIToUTF16("cc-number"))
179 return CREDIT_CARD_NUMBER;
180
181 if (autocomplete_type == ASCIIToUTF16("cc-exp")) {
182 if (field.max_length == 5)
183 return CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR;
184 else
185 return CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR;
186 }
187
188 if (autocomplete_type == ASCIIToUTF16("cc-exp-month"))
189 return CREDIT_CARD_EXP_MONTH;
190
191 if (autocomplete_type == ASCIIToUTF16("cc-exp-year")) {
192 if (field.max_length == 2)
193 return CREDIT_CARD_EXP_2_DIGIT_YEAR;
194 else
195 return CREDIT_CARD_EXP_4_DIGIT_YEAR;
196 }
197
198 if (autocomplete_type == ASCIIToUTF16("tel"))
199 return PHONE_HOME_WHOLE_NUMBER;
200
201 if (autocomplete_type == ASCIIToUTF16("tel-country-code"))
202 return PHONE_HOME_COUNTRY_CODE;
203
204 if (autocomplete_type == ASCIIToUTF16("tel-national"))
205 return PHONE_HOME_CITY_AND_NUMBER;
206
207 if (autocomplete_type == ASCIIToUTF16("tel-area-code"))
208 return PHONE_HOME_CITY_CODE;
209
210 if (autocomplete_type == ASCIIToUTF16("tel-local"))
211 return PHONE_HOME_NUMBER;
212
213 if (autocomplete_type == ASCIIToUTF16("tel-local-prefix"))
214 return PHONE_HOME_NUMBER;
215
216 if (autocomplete_type == ASCIIToUTF16("tel-local-suffix"))
217 return PHONE_HOME_NUMBER;
218
219 if (autocomplete_type == ASCIIToUTF16("email"))
220 return EMAIL_ADDRESS;
221
222 return UNKNOWN_TYPE;
223 }
224
231 } // namespace 225 } // namespace
232 226
233 FormStructure::FormStructure(const FormData& form) 227 FormStructure::FormStructure(const FormData& form)
234 : form_name_(form.name), 228 : form_name_(form.name),
235 source_url_(form.origin), 229 source_url_(form.origin),
236 target_url_(form.action), 230 target_url_(form.action),
237 autofill_count_(0), 231 autofill_count_(0),
238 upload_required_(USE_UPLOAD_RATES), 232 upload_required_(USE_UPLOAD_RATES),
239 server_experiment_id_("no server response"), 233 server_experiment_id_("no server response"),
240 has_author_specified_types_(false) { 234 has_author_specified_types_(false) {
(...skipping 25 matching lines...) Expand all
266 } else { 260 } else {
267 // Either the method is 'get', or we don't know. In this case we default 261 // Either the method is 'get', or we don't know. In this case we default
268 // to GET. 262 // to GET.
269 method_ = GET; 263 method_ = GET;
270 } 264 }
271 } 265 }
272 266
273 FormStructure::~FormStructure() {} 267 FormStructure::~FormStructure() {}
274 268
275 void FormStructure::DetermineHeuristicTypes() { 269 void FormStructure::DetermineHeuristicTypes() {
276 // First, try to detect field types based on the fields' |autocompletetype| 270 // First, try to detect field types based on each field's |autocomplete|
277 // attributes. If there is at least one form field with this attribute, don't 271 // attribute value. If there is at least one form field with that specifies
Dan Beam 2012/10/19 00:12:44 If there is at least one form field that specifies
Ilya Sherman 2012/10/19 04:19:32 Done.
278 // try to apply other heuristics to match fields in this form. 272 // an autocomplete type hint, don't try to apply other heuristics to match
273 // fields in this form.
279 bool has_author_specified_sections; 274 bool has_author_specified_sections;
280 ParseAutocompletetypeAttributes(&has_author_specified_types_, 275 ParseFieldTypesFromAutocompleteAttributes(&has_author_specified_types_,
281 &has_author_specified_sections); 276 &has_author_specified_sections);
282 277
283 if (!has_author_specified_types_) { 278 if (!has_author_specified_types_) {
284 FieldTypeMap field_type_map; 279 FieldTypeMap field_type_map;
285 FormField::ParseFormFields(fields_.get(), &field_type_map); 280 FormField::ParseFormFields(fields_.get(), &field_type_map);
286 for (size_t index = 0; index < field_count(); index++) { 281 for (size_t index = 0; index < field_count(); index++) {
287 AutofillField* field = fields_[index]; 282 AutofillField* field = fields_[index];
288 FieldTypeMap::iterator iter = field_type_map.find(field->unique_name()); 283 FieldTypeMap::iterator iter = field_type_map.find(field->unique_name());
289 if (iter != field_type_map.end()) 284 if (iter != field_type_map.end())
290 field->set_heuristic_type(iter->second); 285 field->set_heuristic_type(iter->second);
291 } 286 }
(...skipping 579 matching lines...) Expand 10 before | Expand all | Expand 10 after
871 buzz::XmlElement *field_element = new buzz::XmlElement( 866 buzz::XmlElement *field_element = new buzz::XmlElement(
872 buzz::QName(kXMLElementField)); 867 buzz::QName(kXMLElementField));
873 field_element->SetAttr(buzz::QName(kAttributeSignature), 868 field_element->SetAttr(buzz::QName(kAttributeSignature),
874 field->FieldSignature()); 869 field->FieldSignature());
875 encompassing_xml_element->AddElement(field_element); 870 encompassing_xml_element->AddElement(field_element);
876 } 871 }
877 } 872 }
878 return true; 873 return true;
879 } 874 }
880 875
881 void FormStructure::ParseAutocompletetypeAttributes(bool* found_attribute, 876 // TODO(isherman): This method could use a shorter name...
Ilya Sherman 2012/10/18 00:11:19 Any suggestions?
Dan Beam 2012/10/19 00:12:44 Not really, maybe just FieldTypeFromAutocompleteAt
Ilya Sherman 2012/10/19 04:19:32 Ok. I like having parse in the name, so I guess l
882 bool* found_sections) { 877 void FormStructure::ParseFieldTypesFromAutocompleteAttributes(
883 *found_attribute = false; 878 bool* found_types,
879 bool* found_sections) {
880 *found_types = false;
884 *found_sections = false; 881 *found_sections = false;
885 for (std::vector<AutofillField*>::iterator field = fields_.begin(); 882 for (std::vector<AutofillField*>::iterator field = fields_.begin();
886 field != fields_.end(); ++field) { 883 field != fields_.end(); ++field) {
887 if ((*field)->autocomplete_type.empty()) 884 // Canonicalize the attribute value by trimming whitespace and converting to
885 // lowercase ASCII.
886 string16 autocomplete_attribute = (*field)->autocomplete_attribute;
887 TrimWhitespace(autocomplete_attribute, TRIM_ALL, &autocomplete_attribute);
888 autocomplete_attribute = StringToLowerASCII(autocomplete_attribute);
889
890 // The autocomplete attribute is overloaded: it can specify either a field
891 // type hint or whether autocomplete should be enabled at all. Ignore the
892 // latter type of attribute value.
893 if (autocomplete_attribute.empty() ||
894 autocomplete_attribute == ASCIIToUTF16("on") ||
895 autocomplete_attribute == ASCIIToUTF16("off")) {
896 continue;
897 }
898
899 // Any other value, even it is invalid, is considered to be a type hint.
900 // This allows a website's author to specify an attribute like
901 // autocomplete="other" on a field to disable all Autofill heuristics for
902 // the form.
903 *found_types = true;
904
905 // Tokenize the attribute value. Per the spec, the tokens are parsed in
906 // reverse order.
907 std::vector<string16> tokens;
908 Tokenize(autocomplete_attribute, ASCIIToUTF16(" "), &tokens);
909
910 // The final token must be the field type.
911 // If it is not one of the known types, abort.
912 DCHECK(!tokens.empty());
913 string16 field_type_token = tokens.back();
914 tokens.pop_back();
915 AutofillFieldType field_type =
916 FieldTypeFromAutocompleteType(field_type_token, **field);
917 if (field_type == UNKNOWN_TYPE)
888 continue; 918 continue;
889 919
890 *found_attribute = true; 920 // The preceding token, if any, may be a type hint.
891 std::vector<string16> types; 921 if (!tokens.empty() && IsContactTypeHint(tokens.back())) {
892 Tokenize((*field)->autocomplete_type, ASCIIToUTF16(" "), &types); 922 // If it is, it must match the field type; otherwise, abort.
Dan Beam 2012/10/19 00:12:44 you may want to add/hint at that there could be va
Ilya Sherman 2012/10/19 04:19:32 Done.
923 if (!ContactTypeHintMatchesFieldType(tokens.back(), field_type))
924 continue;
893 925
894 // Look for a named section. 926 // Chrome Autofill ignore these type hints.
Dan Beam 2012/10/19 00:12:44 ignores
Ilya Sherman 2012/10/19 04:19:32 Done.
895 const string16 kSectionPrefix = ASCIIToUTF16("section-"); 927 tokens.pop_back();
896 if (!types.empty() && StartsWith(types.front(), kSectionPrefix, true)) {
897 *found_sections = true;
898 (*field)->set_section(types.front().substr(kSectionPrefix.size()));
899 } 928 }
900 929
901 // Look for specified types. 930 // The preceding token, if any, may be a fixed string that is either
902 for (std::vector<string16>::const_iterator type = types.begin(); 931 // "shipping" or "billing". Chrome Autofill treats these as implicit
903 type != types.end(); ++type) { 932 // section name suffixes.
904 if (UpdateFromAutocompleteType(*type, *field)) 933 if (!tokens.empty() &&
905 break; 934 (tokens.back() == ASCIIToUTF16("shipping") ||
935 tokens.back() == ASCIIToUTF16("billing"))) {
936 *found_sections = true;
937 (*field)->set_section(ASCIIToUTF16("-") + tokens.back());
938 tokens.pop_back();
939 } else {
940 // To prevent potential section name collisions, add a default suffix for
Dan Beam 2012/10/19 00:12:44 you might want to add a comment here explaining wh
Ilya Sherman 2012/10/19 04:19:32 Done.
941 // other fields.
942 (*field)->set_section(ASCIIToUTF16("-default"));
906 } 943 }
944
945 // The preceding token, if any, may be a named section.
946 const string16 kSectionPrefix = ASCIIToUTF16("section-");
947 if (!tokens.empty() && StartsWith(tokens.back(), kSectionPrefix, true)) {
948 *found_sections = true;
949 // Prepend this section name to the suffix set in the preceding block.
950 (*field)->set_section(
951 tokens.back().substr(kSectionPrefix.size()) + (*field)->section());
952 tokens.pop_back();
953 }
954
955 // No other tokens are allowed. If there are any remaining, abort.
956 if (!tokens.empty())
957 continue;
958
959 // No errors encountered while parsing!
960 // Update the |field|'s type based on what was parsed from the attribute.
961 (*field)->set_heuristic_type(field_type);
962 if (field_type_token == ASCIIToUTF16("tel-local-prefix"))
963 (*field)->set_phone_part(AutofillField::PHONE_PREFIX);
964 else if (field_type_token == ASCIIToUTF16("tel-local-suffix"))
965 (*field)->set_phone_part(AutofillField::PHONE_SUFFIX);
907 } 966 }
908 } 967 }
909 968
910 void FormStructure::IdentifySections(bool has_author_specified_sections) { 969 void FormStructure::IdentifySections(bool has_author_specified_sections) {
911 if (fields_.empty()) 970 if (fields_.empty())
912 return; 971 return;
913 972
914 if (!has_author_specified_sections) { 973 if (!has_author_specified_sections) {
915 // Name sections after the first field in the section. 974 // Name sections after the first field in the section.
916 string16 current_section = fields_.front()->unique_name(); 975 string16 current_section = fields_.front()->unique_name();
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
962 for (std::vector<AutofillField*>::iterator field = fields_.begin(); 1021 for (std::vector<AutofillField*>::iterator field = fields_.begin();
963 field != fields_.end(); ++field) { 1022 field != fields_.end(); ++field) {
964 AutofillType::FieldTypeGroup field_type_group = 1023 AutofillType::FieldTypeGroup field_type_group =
965 AutofillType((*field)->type()).group(); 1024 AutofillType((*field)->type()).group();
966 if (field_type_group == AutofillType::CREDIT_CARD) 1025 if (field_type_group == AutofillType::CREDIT_CARD)
967 (*field)->set_section((*field)->section() + ASCIIToUTF16("-cc")); 1026 (*field)->set_section((*field)->section() + ASCIIToUTF16("-cc"));
968 else 1027 else
969 (*field)->set_section((*field)->section() + ASCIIToUTF16("-default")); 1028 (*field)->set_section((*field)->section() + ASCIIToUTF16("-default"));
970 } 1029 }
971 } 1030 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698