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_scanner.h"
19 #include "components/autofill/core/browser/credit_card_field.h"
20 #include "components/autofill/core/browser/email_field.h"
21 #include "components/autofill/core/browser/form_structure.h"
22 #include "components/autofill/core/browser/name_field.h"
23 #include "components/autofill/core/browser/phone_field.h"
24 #include "components/autofill/core/common/autofill_regexes.h"
29 bool ShouldBeIgnored(const AutofillField
* field
) {
30 // Ignore checkable fields as they interfere with parsers assuming context.
31 // Eg., while parsing address, "Is PO box" checkbox after ADDRESS_LINE1
32 // interferes with correctly understanding ADDRESS_LINE2.
33 // Ignore fields marked as presentational. See
34 // http://www.w3.org/TR/wai-aria/roles#presentation
35 return field
->is_checkable
||
36 field
->role
== FormFieldData::ROLE_ATTRIBUTE_PRESENTATION
;
42 void FormField::ParseFormFields(const std::vector
<AutofillField
*>& fields
,
44 ServerFieldTypeMap
* map
) {
47 // Set up a working copy of the fields to be processed.
48 std::vector
<AutofillField
*> remaining_fields(fields
.size());
49 std::copy(fields
.begin(), fields
.end(), remaining_fields
.begin());
51 remaining_fields
.erase(
52 std::remove_if(remaining_fields
.begin(), remaining_fields
.end(),
54 remaining_fields
.end());
56 ServerFieldTypeMap saved_map
= *map
;
59 ParseFormFieldsPass(EmailField::Parse
, &remaining_fields
, map
);
60 size_t email_count
= map
->size();
63 ParseFormFieldsPass(PhoneField::Parse
, &remaining_fields
, map
);
66 ParseFormFieldsPass(AddressField::Parse
, &remaining_fields
, map
);
69 ParseFormFieldsPass(CreditCardField::Parse
, &remaining_fields
, map
);
72 ParseFormFieldsPass(NameField::Parse
, &remaining_fields
, map
);
74 // Do not autofill a form if there are less than 3 recognized fields.
75 // Otherwise it is very easy to have false positives. http://crbug.com/447332
76 // For <form> tags, make an exception for email fields, which are commonly the
77 // only recognized field on account registration sites.
78 size_t kThreshold
= 3;
79 bool accept_parsing
= (map
->size() >= kThreshold
||
80 (is_form_tag
&& email_count
> 0));
86 bool FormField::ParseField(AutofillScanner
* scanner
,
87 const base::string16
& pattern
,
88 AutofillField
** match
) {
89 return ParseFieldSpecifics(scanner
, pattern
, MATCH_DEFAULT
, match
);
93 bool FormField::ParseFieldSpecifics(AutofillScanner
* scanner
,
94 const base::string16
& pattern
,
96 AutofillField
** match
) {
100 const AutofillField
* field
= scanner
->Cursor();
102 if (!MatchesFormControlType(field
->form_control_type
, match_type
))
105 return MatchAndAdvance(scanner
, pattern
, match_type
, match
);
109 FormField::ParseNameLabelResult
FormField::ParseNameAndLabelSeparately(
110 AutofillScanner
* scanner
,
111 const base::string16
& pattern
,
113 AutofillField
** match
) {
114 if (scanner
->IsEnd())
115 return RESULT_MATCH_NONE
;
117 AutofillField
* cur_match
= nullptr;
118 size_t saved_cursor
= scanner
->SaveCursor();
119 bool parsed_name
= ParseFieldSpecifics(scanner
,
121 match_type
& ~MATCH_LABEL
,
123 scanner
->RewindTo(saved_cursor
);
124 bool parsed_label
= ParseFieldSpecifics(scanner
,
126 match_type
& ~MATCH_NAME
,
128 if (parsed_name
&& parsed_label
) {
131 return RESULT_MATCH_NAME_LABEL
;
134 scanner
->RewindTo(saved_cursor
);
136 return RESULT_MATCH_NAME
;
138 return RESULT_MATCH_LABEL
;
139 return RESULT_MATCH_NONE
;
143 bool FormField::ParseEmptyLabel(AutofillScanner
* scanner
,
144 AutofillField
** match
) {
145 return ParseFieldSpecifics(scanner
,
146 base::ASCIIToUTF16("^$"),
147 MATCH_LABEL
| MATCH_ALL_INPUTS
,
152 bool FormField::AddClassification(const AutofillField
* field
,
153 ServerFieldType type
,
154 ServerFieldTypeMap
* map
) {
155 // Several fields are optional.
159 return map
->insert(make_pair(field
->unique_name(), type
)).second
;
163 bool FormField::MatchAndAdvance(AutofillScanner
* scanner
,
164 const base::string16
& pattern
,
166 AutofillField
** match
) {
167 AutofillField
* field
= scanner
->Cursor();
168 if (FormField::Match(field
, pattern
, match_type
)) {
179 bool FormField::Match(const AutofillField
* field
,
180 const base::string16
& pattern
,
182 if ((match_type
& FormField::MATCH_LABEL
) &&
183 MatchesPattern(field
->label
, pattern
)) {
187 if ((match_type
& FormField::MATCH_NAME
) &&
188 MatchesPattern(field
->name
, pattern
)) {
196 void FormField::ParseFormFieldsPass(ParseFunction parse
,
197 std::vector
<AutofillField
*>* fields
,
198 ServerFieldTypeMap
* map
) {
199 // Store unmatched fields for further processing by the caller.
200 std::vector
<AutofillField
*> remaining_fields
;
202 AutofillScanner
scanner(*fields
);
203 while (!scanner
.IsEnd()) {
204 scoped_ptr
<FormField
> form_field(parse(&scanner
));
206 remaining_fields
.push_back(scanner
.Cursor());
211 // Add entries into the map for each field type found in |form_field|.
212 bool ok
= form_field
->ClassifyField(map
);
216 std::swap(*fields
, remaining_fields
);
219 bool FormField::MatchesFormControlType(const std::string
& type
,
221 if ((match_type
& MATCH_TEXT
) && type
== "text")
224 if ((match_type
& MATCH_EMAIL
) && type
== "email")
227 if ((match_type
& MATCH_TELEPHONE
) && type
== "tel")
230 if ((match_type
& MATCH_SELECT
) && type
== "select-one")
233 if ((match_type
& MATCH_TEXT_AREA
) && type
== "textarea")
236 if ((match_type
& MATCH_PASSWORD
) && type
== "password")
239 if ((match_type
& MATCH_NUMBER
) && type
== "number")
245 } // namespace autofill