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/form_field.h" | 5 #include "chrome/browser/autofill/form_field.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 #include <string> | 8 #include <string> |
9 #include <utility> | 9 #include <utility> |
10 | 10 |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
138 ecml_fields[i].length_) == 0) { | 138 ecml_fields[i].length_) == 0) { |
139 return true; | 139 return true; |
140 } | 140 } |
141 } | 141 } |
142 } | 142 } |
143 } | 143 } |
144 | 144 |
145 return false; | 145 return false; |
146 } | 146 } |
147 | 147 |
| 148 bool isTextInput(const string16& form_control_type) { |
| 149 const char* text_types[] = {"text", "email", "search", "tel", "url", |
| 150 "number", "date", "datetime", "datetime-local", "month", "week", |
| 151 "time", "range"}; |
| 152 bool is_text_input = false; |
| 153 for (size_t i = 0; i < sizeof(text_types)/sizeof(const char*); ++i) |
| 154 is_text_input |= form_control_type == ASCIIToUTF16(text_types[i]); |
| 155 return is_text_input; |
| 156 } |
| 157 |
148 } // namespace | 158 } // namespace |
149 | 159 |
150 // static | 160 // static |
151 void FormField::ParseFormFields(const std::vector<AutofillField*>& fields, | 161 void FormField::ParseFormFields(const std::vector<AutofillField*>& fields, |
152 FieldTypeMap* field_type_map) { | 162 FieldTypeMap* field_type_map) { |
153 // First, check if there is at least one form field with an ECML name. | 163 // First, check if there is at least one form field with an ECML name. |
154 // If there is, then we will match an element only if it is in the standard. | 164 // If there is, then we will match an element only if it is in the standard. |
155 bool is_ecml = HasECMLField(fields); | 165 bool is_ecml = HasECMLField(fields); |
156 | 166 |
157 // Parse fields. | 167 // Parse fields. |
158 AutofillScanner scanner(fields); | 168 AutofillScanner scanner(fields); |
159 while (!scanner.IsEnd()) { | 169 while (!scanner.IsEnd()) { |
160 scoped_ptr<FormField> form_field( | 170 scoped_ptr<FormField> form_field( |
161 FormField::ParseFormField(&scanner, is_ecml)); | 171 FormField::ParseFormField(&scanner, is_ecml)); |
162 if (!form_field.get()) { | 172 if (!form_field.get()) { |
163 scanner.Advance(); | 173 scanner.Advance(); |
164 continue; | 174 continue; |
165 } | 175 } |
166 | 176 |
167 bool ok = form_field->GetFieldInfo(field_type_map); | 177 bool ok = form_field->GetFieldInfo(field_type_map); |
168 DCHECK(ok); | 178 DCHECK(ok); |
169 } | 179 } |
170 } | 180 } |
171 | 181 |
172 // static | 182 // static |
| 183 bool FormField::MatchWithType(const AutofillField* field, |
| 184 const string16& pattern, |
| 185 int match_type) { |
| 186 if ((match_type & MATCH_LABEL) && MatchLabel(field, pattern)) |
| 187 return true; |
| 188 |
| 189 // For now, we apply the same pattern to the field's label and the field's |
| 190 // name. Matching the name is a bit of a long shot for many patterns, but |
| 191 // it generally doesn't hurt to try. |
| 192 if ((match_type & MATCH_NAME) && MatchName(field, pattern)) |
| 193 return true; |
| 194 |
| 195 return false; |
| 196 } |
| 197 |
| 198 // static |
173 bool FormField::Match(const AutofillField* field, | 199 bool FormField::Match(const AutofillField* field, |
174 const string16& pattern, | 200 const string16& pattern, |
175 bool match_label_only) { | 201 bool match_label_only) { |
176 if (MatchLabel(field, pattern)) | 202 return MatchWithType(field, pattern, |
177 return true; | 203 MATCH_NAME | (match_label_only ? 0 : MATCH_LABEL)); |
178 | |
179 // For now, we apply the same pattern to the field's label and the field's | |
180 // name. Matching the name is a bit of a long shot for many patterns, but | |
181 // it generally doesn't hurt to try. | |
182 if (!match_label_only && MatchName(field, pattern)) | |
183 return true; | |
184 | |
185 return false; | |
186 } | 204 } |
187 | 205 |
188 // static | 206 // static |
189 bool FormField::MatchName(const AutofillField* field, const string16& pattern) { | 207 bool FormField::MatchName(const AutofillField* field, const string16& pattern) { |
190 // TODO(jhawkins): Remove StringToLowerASCII. WebRegularExpression needs to | 208 // TODO(jhawkins): Remove StringToLowerASCII. WebRegularExpression needs to |
191 // be fixed to take WebTextCaseInsensitive into account. | 209 // be fixed to take WebTextCaseInsensitive into account. |
192 WebKit::WebRegularExpression re(WebKit::WebString(pattern), | 210 WebKit::WebRegularExpression re(WebKit::WebString(pattern), |
193 WebKit::WebTextCaseInsensitive); | 211 WebKit::WebTextCaseInsensitive); |
194 bool match = re.match( | 212 bool match = re.match( |
195 WebKit::WebString(StringToLowerASCII(field->name))) != -1; | 213 WebKit::WebString(StringToLowerASCII(field->name))) != -1; |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
228 field = CreditCardField::Parse(scanner, is_ecml); | 246 field = CreditCardField::Parse(scanner, is_ecml); |
229 if (field) | 247 if (field) |
230 return field; | 248 return field; |
231 | 249 |
232 // We search for a |NameField| last since it matches the word "name", which is | 250 // We search for a |NameField| last since it matches the word "name", which is |
233 // relatively general. | 251 // relatively general. |
234 return NameField::Parse(scanner, is_ecml); | 252 return NameField::Parse(scanner, is_ecml); |
235 } | 253 } |
236 | 254 |
237 // static | 255 // static |
238 bool FormField::ParseText(AutofillScanner* scanner, const string16& pattern) { | |
239 const AutofillField* field; | |
240 return ParseText(scanner, pattern, &field); | |
241 } | |
242 | |
243 // static | |
244 bool FormField::ParseText(AutofillScanner* scanner, | 256 bool FormField::ParseText(AutofillScanner* scanner, |
245 const string16& pattern, | 257 const string16& pattern, |
| 258 int match_type) { |
| 259 const AutofillField* field; |
| 260 return ParseText(scanner, pattern, match_type, &field); |
| 261 } |
| 262 |
| 263 // static |
| 264 bool FormField::ParseText(AutofillScanner* scanner, |
| 265 const string16& pattern, |
| 266 int match_type, |
246 const AutofillField** dest) { | 267 const AutofillField** dest) { |
247 return ParseText(scanner, pattern, dest, false); | 268 return ParseText(scanner, pattern, dest, match_type); |
248 } | 269 } |
249 | 270 |
250 // static | 271 // static |
251 bool FormField::ParseEmptyText(AutofillScanner* scanner, | 272 bool FormField::ParseEmptyText(AutofillScanner* scanner, |
252 const AutofillField** dest) { | 273 const AutofillField** dest) { |
253 return ParseLabelText(scanner, ASCIIToUTF16("^$"), dest); | 274 return ParseText(scanner, ASCIIToUTF16("^$"), |
254 } | 275 MATCH_LABEL | MATCH_TEXT | MATCH_SELECT, dest); |
255 | |
256 // static | |
257 bool FormField::ParseLabelText(AutofillScanner* scanner, | |
258 const string16& pattern, | |
259 const AutofillField** dest) { | |
260 return ParseText(scanner, pattern, dest, true); | |
261 } | 276 } |
262 | 277 |
263 // static | 278 // static |
264 bool FormField::ParseText(AutofillScanner* scanner, | 279 bool FormField::ParseText(AutofillScanner* scanner, |
265 const string16& pattern, | 280 const string16& pattern, |
266 const AutofillField** dest, | 281 const AutofillField** dest, |
267 bool match_label_only) { | 282 int match_type) { |
268 if (scanner->IsEnd()) | 283 if (scanner->IsEnd()) |
269 return false; | 284 return false; |
270 | 285 |
271 const AutofillField* field = scanner->Cursor(); | 286 const AutofillField* field = scanner->Cursor(); |
272 if (Match(field, pattern, match_label_only)) { | 287 |
| 288 // if (!(match_type & MATCH_SELECT) && |
| 289 // field->form_control_type == ASCIIToUTF16("select-one")) |
| 290 // return false; |
| 291 // |
| 292 // if (!(match_type & MATCH_TEXT) && |
| 293 // isTextInput(field->form_control_type)) |
| 294 // return false; |
| 295 |
| 296 if (MatchWithType(field, pattern, match_type)) { |
273 if (dest) | 297 if (dest) |
274 *dest = field; | 298 *dest = field; |
275 scanner->Advance(); | 299 scanner->Advance(); |
276 return true; | 300 return true; |
277 } | 301 } |
278 | 302 |
279 return false; | 303 return false; |
280 } | 304 } |
281 | 305 |
282 // static | 306 // static |
283 bool FormField::ParseLabelAndName(AutofillScanner* scanner, | 307 bool FormField::ParseEmpty(AutofillScanner* scanner) { |
284 const string16& pattern, | 308 // TODO(jhawkins): Handle select fields. |
285 const AutofillField** dest) { | 309 const string16 pattern(ASCIIToUTF16("^$")); |
286 const AutofillField* field = scanner->Cursor(); | 310 const AutofillField* field = scanner->Cursor(); |
287 if (MatchLabel(field, pattern) && MatchName(field, pattern)) { | 311 if (MatchLabel(field, pattern) && MatchName(field, pattern)) { |
288 if (dest) | |
289 *dest = field; | |
290 scanner->Advance(); | 312 scanner->Advance(); |
291 return true; | 313 return true; |
292 } | 314 } |
293 | 315 |
294 return false; | 316 return false; |
295 } | 317 } |
296 | 318 |
297 // static | 319 // static |
298 bool FormField::ParseEmpty(AutofillScanner* scanner) { | |
299 // TODO(jhawkins): Handle select fields. | |
300 return ParseLabelAndName(scanner, ASCIIToUTF16("^$"), NULL); | |
301 } | |
302 | |
303 // static | |
304 bool FormField::Add(FieldTypeMap* field_type_map, | 320 bool FormField::Add(FieldTypeMap* field_type_map, |
305 const AutofillField* field, | 321 const AutofillField* field, |
306 AutofillFieldType type) { | 322 AutofillFieldType type) { |
307 // Several fields are optional. | 323 // Several fields are optional. |
308 if (!field) | 324 if (!field) |
309 return true; | 325 return true; |
310 | 326 |
311 // TODO(isherman): Is this the intent? | 327 // TODO(isherman): Is this the intent? |
312 return field_type_map->insert(make_pair(field->unique_name(), type)).second; | 328 return field_type_map->insert(make_pair(field->unique_name(), type)).second; |
313 } | 329 } |
314 | 330 |
315 string16 FormField::GetEcmlPattern(const char* ecml_name) { | 331 string16 FormField::GetEcmlPattern(const char* ecml_name) { |
316 return ASCIIToUTF16(std::string("^") + ecml_name); | 332 return ASCIIToUTF16(std::string("^") + ecml_name); |
317 } | 333 } |
318 | 334 |
319 string16 FormField::GetEcmlPattern(const char* ecml_name1, | 335 string16 FormField::GetEcmlPattern(const char* ecml_name1, |
320 const char* ecml_name2, | 336 const char* ecml_name2, |
321 char pattern_operator) { | 337 char pattern_operator) { |
322 return ASCIIToUTF16(StringPrintf("^%s%c^%s", | 338 return ASCIIToUTF16(StringPrintf("^%s%c^%s", |
323 ecml_name1, pattern_operator, ecml_name2)); | 339 ecml_name1, pattern_operator, ecml_name2)); |
324 } | 340 } |
OLD | NEW |