Home | History | Annotate | Download | only in browser
      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