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
3 // found in the LICENSE file.
5 #include "components/autofill/core/browser/form_field.h"
11 #include "base/logging.h"
12 #include "base/memory/scoped_ptr.h"
13 #include "base/strings/string_util.h"
14 #include "base/strings/stringprintf.h"
15 #include "base/strings/utf_string_conversions.h"
16 #include "components/autofill/core/browser/address_field.h"
17 #include "components/autofill/core/browser/autofill_field.h"
18 #include "components/autofill/core/browser/autofill_regexes.h"
19 #include "components/autofill/core/browser/autofill_scanner.h"
20 #include "components/autofill/core/browser/credit_card_field.h"
21 #include "components/autofill/core/browser/email_field.h"
22 #include "components/autofill/core/browser/form_structure.h"
23 #include "components/autofill/core/browser/name_field.h"
24 #include "components/autofill/core/browser/phone_field.h"
25 #include "ui/base/l10n/l10n_util.h"
30 bool IsCheckable(const AutofillField* field) {
31 return field->is_checkable;
37 void FormField::ParseFormFields(const std::vector<AutofillField*>& fields,
38 ServerFieldTypeMap* map) {
39 // Set up a working copy of the fields to be processed.
40 std::vector<AutofillField*> remaining_fields(fields.size());
41 std::copy(fields.begin(), fields.end(), remaining_fields.begin());
43 // Ignore checkable fields as they interfere with parsers assuming context.
44 // Eg., while parsing address, "Is PO box" checkbox after ADDRESS_LINE1
45 // interferes with correctly understanding ADDRESS_LINE2.
46 remaining_fields.erase(
47 std::remove_if(remaining_fields.begin(), remaining_fields.end(),
49 remaining_fields.end());
52 ParseFormFieldsPass(EmailField::Parse, &remaining_fields, map);
55 ParseFormFieldsPass(PhoneField::Parse, &remaining_fields, map);
58 ParseFormFieldsPass(AddressField::Parse, &remaining_fields, map);
61 ParseFormFieldsPass(CreditCardField::Parse, &remaining_fields, map);
64 ParseFormFieldsPass(NameField::Parse, &remaining_fields, map);
68 bool FormField::ParseField(AutofillScanner* scanner,
69 const base::string16& pattern,
70 AutofillField** match) {
71 return ParseFieldSpecifics(scanner, pattern, MATCH_DEFAULT, match);
75 bool FormField::ParseFieldSpecifics(AutofillScanner* scanner,
76 const base::string16& pattern,
78 AutofillField** match) {
82 const AutofillField* field = scanner->Cursor();
84 if (!MatchesFormControlType(field->form_control_type, match_type))
87 return MatchAndAdvance(scanner, pattern, match_type, match);
91 bool FormField::ParseEmptyLabel(AutofillScanner* scanner,
92 AutofillField** match) {
93 return ParseFieldSpecifics(scanner,
94 base::ASCIIToUTF16("^$"),
95 MATCH_LABEL | MATCH_ALL_INPUTS,
100 bool FormField::AddClassification(const AutofillField* field,
101 ServerFieldType type,
102 ServerFieldTypeMap* map) {
103 // Several fields are optional.
107 return map->insert(make_pair(field->unique_name(), type)).second;
111 bool FormField::MatchAndAdvance(AutofillScanner* scanner,
112 const base::string16& pattern,
114 AutofillField** match) {
115 AutofillField* field = scanner->Cursor();
116 if (FormField::Match(field, pattern, match_type)) {
127 bool FormField::Match(const AutofillField* field,
128 const base::string16& pattern,
130 if ((match_type & FormField::MATCH_LABEL) &&
131 autofill::MatchesPattern(field->label, pattern)) {
135 if ((match_type & FormField::MATCH_NAME) &&
136 autofill::MatchesPattern(field->name, pattern)) {
140 if ((match_type & FormField::MATCH_VALUE) &&
141 autofill::MatchesPattern(field->value, pattern)) {
149 void FormField::ParseFormFieldsPass(ParseFunction parse,
150 std::vector<AutofillField*>* fields,
151 ServerFieldTypeMap* map) {
152 // Store unmatched fields for further processing by the caller.
153 std::vector<AutofillField*> remaining_fields;
155 AutofillScanner scanner(*fields);
156 while (!scanner.IsEnd()) {
157 scoped_ptr<FormField> form_field(parse(&scanner));
158 if (!form_field.get()) {
159 remaining_fields.push_back(scanner.Cursor());
164 // Add entries into the map for each field type found in |form_field|.
165 bool ok = form_field->ClassifyField(map);
169 std::swap(*fields, remaining_fields);
172 bool FormField::MatchesFormControlType(const std::string& type,
174 if ((match_type & MATCH_TEXT) && type == "text")
177 if ((match_type & MATCH_EMAIL) && type == "email")
180 if ((match_type & MATCH_TELEPHONE) && type == "tel")
183 if ((match_type & MATCH_SELECT) && type == "select-one")
186 if ((match_type & MATCH_TEXT_AREA) && type == "textarea")
192 } // namespace autofill