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. 4 5 #include "components/autofill/core/browser/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/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" 26 27 namespace autofill { 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 ServerFieldTypeMap* 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 base::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 base::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 ServerFieldType type, 129 ServerFieldTypeMap* 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 base::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 base::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 ServerFieldTypeMap* 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 } 198 199 } // namespace autofill 200