OLD | NEW |
| (Empty) |
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 | |
3 // found in the LICENSE file. | |
4 | |
5 #include "chrome/browser/autofill/form_field.h" | |
6 | |
7 #include <stddef.h> | |
8 #include <string> | |
9 #include <utility> | |
10 | |
11 #include "base/logging.h" | |
12 #include "base/memory/scoped_ptr.h" | |
13 #include "base/string_util.h" | |
14 #include "base/stringprintf.h" | |
15 #include "base/utf_string_conversions.h" | |
16 #include "chrome/browser/autofill/address_field.h" | |
17 #include "chrome/browser/autofill/autofill_field.h" | |
18 #include "chrome/browser/autofill/autofill_regexes.h" | |
19 #include "chrome/browser/autofill/autofill_scanner.h" | |
20 #include "chrome/browser/autofill/credit_card_field.h" | |
21 #include "chrome/browser/autofill/email_field.h" | |
22 #include "chrome/browser/autofill/field_types.h" | |
23 #include "chrome/browser/autofill/form_structure.h" | |
24 #include "chrome/browser/autofill/name_field.h" | |
25 #include "chrome/browser/autofill/phone_field.h" | |
26 #include "ui/base/l10n/l10n_util.h" | |
27 | |
28 namespace { | |
29 | |
30 bool IsTextField(const std::string& type) { | |
31 return type == "text"; | |
32 } | |
33 | |
34 bool IsEmailField(const std::string& type) { | |
35 return type == "email"; | |
36 } | |
37 | |
38 bool IsTelephoneField(const std::string& type) { | |
39 return type == "tel"; | |
40 } | |
41 | |
42 bool IsSelectField(const std::string& type) { | |
43 return type == "select-one"; | |
44 } | |
45 | |
46 bool IsCheckable(const AutofillField* field) { | |
47 return field->is_checkable; | |
48 } | |
49 | |
50 } // namespace | |
51 | |
52 // static | |
53 void FormField::ParseFormFields(const std::vector<AutofillField*>& fields, | |
54 FieldTypeMap* map) { | |
55 // Set up a working copy of the fields to be processed. | |
56 std::vector<const AutofillField*> remaining_fields(fields.size()); | |
57 std::copy(fields.begin(), fields.end(), remaining_fields.begin()); | |
58 | |
59 // Ignore checkable fields as they interfere with parsers assuming context. | |
60 // Eg., while parsing address, "Is PO box" checkbox after ADDRESS_LINE1 | |
61 // interferes with correctly understanding ADDRESS_LINE2. | |
62 remaining_fields.erase( | |
63 std::remove_if(remaining_fields.begin(), remaining_fields.end(), | |
64 IsCheckable), | |
65 remaining_fields.end()); | |
66 | |
67 // Email pass. | |
68 ParseFormFieldsPass(EmailField::Parse, &remaining_fields, map); | |
69 | |
70 // Phone pass. | |
71 ParseFormFieldsPass(PhoneField::Parse, &remaining_fields, map); | |
72 | |
73 // Address pass. | |
74 ParseFormFieldsPass(AddressField::Parse, &remaining_fields, map); | |
75 | |
76 // Credit card pass. | |
77 ParseFormFieldsPass(CreditCardField::Parse, &remaining_fields, map); | |
78 | |
79 // Name pass. | |
80 ParseFormFieldsPass(NameField::Parse, &remaining_fields, map); | |
81 } | |
82 | |
83 // static | |
84 bool FormField::ParseField(AutofillScanner* scanner, | |
85 const string16& pattern, | |
86 const AutofillField** match) { | |
87 return ParseFieldSpecifics(scanner, pattern, MATCH_DEFAULT, match); | |
88 } | |
89 | |
90 // static | |
91 bool FormField::ParseFieldSpecifics(AutofillScanner* scanner, | |
92 const string16& pattern, | |
93 int match_type, | |
94 const AutofillField** match) { | |
95 if (scanner->IsEnd()) | |
96 return false; | |
97 | |
98 const AutofillField* field = scanner->Cursor(); | |
99 | |
100 if ((match_type & MATCH_TEXT) && IsTextField(field->form_control_type)) | |
101 return MatchAndAdvance(scanner, pattern, match_type, match); | |
102 | |
103 if ((match_type & MATCH_EMAIL) && IsEmailField(field->form_control_type)) | |
104 return MatchAndAdvance(scanner, pattern, match_type, match); | |
105 | |
106 if ((match_type & MATCH_TELEPHONE) && | |
107 IsTelephoneField(field->form_control_type)) { | |
108 return MatchAndAdvance(scanner, pattern, match_type, match); | |
109 } | |
110 | |
111 if ((match_type & MATCH_SELECT) && IsSelectField(field->form_control_type)) | |
112 return MatchAndAdvance(scanner, pattern, match_type, match); | |
113 | |
114 return false; | |
115 } | |
116 | |
117 // static | |
118 bool FormField::ParseEmptyLabel(AutofillScanner* scanner, | |
119 const AutofillField** match) { | |
120 return ParseFieldSpecifics(scanner, | |
121 ASCIIToUTF16("^$"), | |
122 MATCH_LABEL | MATCH_ALL_INPUTS, | |
123 match); | |
124 } | |
125 | |
126 // static | |
127 bool FormField::AddClassification(const AutofillField* field, | |
128 AutofillFieldType type, | |
129 FieldTypeMap* map) { | |
130 // Several fields are optional. | |
131 if (!field) | |
132 return true; | |
133 | |
134 return map->insert(make_pair(field->unique_name(), type)).second; | |
135 } | |
136 | |
137 // static. | |
138 bool FormField::MatchAndAdvance(AutofillScanner* scanner, | |
139 const string16& pattern, | |
140 int match_type, | |
141 const AutofillField** match) { | |
142 const AutofillField* field = scanner->Cursor(); | |
143 if (FormField::Match(field, pattern, match_type)) { | |
144 if (match) | |
145 *match = field; | |
146 scanner->Advance(); | |
147 return true; | |
148 } | |
149 | |
150 return false; | |
151 } | |
152 | |
153 // static | |
154 bool FormField::Match(const AutofillField* field, | |
155 const string16& pattern, | |
156 int match_type) { | |
157 if ((match_type & FormField::MATCH_LABEL) && | |
158 autofill::MatchesPattern(field->label, pattern)) { | |
159 return true; | |
160 } | |
161 | |
162 if ((match_type & FormField::MATCH_NAME) && | |
163 autofill::MatchesPattern(field->name, pattern)) { | |
164 return true; | |
165 } | |
166 | |
167 if ((match_type & FormField::MATCH_VALUE) && | |
168 autofill::MatchesPattern(field->value, pattern)) { | |
169 return true; | |
170 } | |
171 | |
172 return false; | |
173 } | |
174 | |
175 // static | |
176 void FormField::ParseFormFieldsPass(ParseFunction parse, | |
177 std::vector<const AutofillField*>* fields, | |
178 FieldTypeMap* map) { | |
179 // Store unmatched fields for further processing by the caller. | |
180 std::vector<const AutofillField*> remaining_fields; | |
181 | |
182 AutofillScanner scanner(*fields); | |
183 while (!scanner.IsEnd()) { | |
184 scoped_ptr<FormField> form_field(parse(&scanner)); | |
185 if (!form_field.get()) { | |
186 remaining_fields.push_back(scanner.Cursor()); | |
187 scanner.Advance(); | |
188 continue; | |
189 } | |
190 | |
191 // Add entries into the map for each field type found in |form_field|. | |
192 bool ok = form_field->ClassifyField(map); | |
193 DCHECK(ok); | |
194 } | |
195 | |
196 std::swap(*fields, remaining_fields); | |
197 } | |
OLD | NEW |