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 IsCheckable(const AutofillField* field) {
     31   return field->is_checkable;
     32 }
     33 
     34 }  // namespace
     35 
     36 // static
     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<const AutofillField*> remaining_fields(fields.size());
     41   std::copy(fields.begin(), fields.end(), remaining_fields.begin());
     42 
     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(),
     48                      IsCheckable),
     49       remaining_fields.end());
     50 
     51   // Email pass.
     52   ParseFormFieldsPass(EmailField::Parse, &remaining_fields, map);
     53 
     54   // Phone pass.
     55   ParseFormFieldsPass(PhoneField::Parse, &remaining_fields, map);
     56 
     57   // Address pass.
     58   ParseFormFieldsPass(AddressField::Parse, &remaining_fields, map);
     59 
     60   // Credit card pass.
     61   ParseFormFieldsPass(CreditCardField::Parse, &remaining_fields, map);
     62 
     63   // Name pass.
     64   ParseFormFieldsPass(NameField::Parse, &remaining_fields, map);
     65 }
     66 
     67 // static
     68 bool FormField::ParseField(AutofillScanner* scanner,
     69                            const base::string16& pattern,
     70                            const AutofillField** match) {
     71   return ParseFieldSpecifics(scanner, pattern, MATCH_DEFAULT, match);
     72 }
     73 
     74 // static
     75 bool FormField::ParseFieldSpecifics(AutofillScanner* scanner,
     76                                     const base::string16& pattern,
     77                                     int match_type,
     78                                     const AutofillField** match) {
     79   if (scanner->IsEnd())
     80     return false;
     81 
     82   const AutofillField* field = scanner->Cursor();
     83 
     84   if (!MatchesFormControlType(field->form_control_type, match_type))
     85     return false;
     86 
     87   return MatchAndAdvance(scanner, pattern, match_type, match);
     88 }
     89 
     90 // static
     91 bool FormField::ParseEmptyLabel(AutofillScanner* scanner,
     92                                 const AutofillField** match) {
     93   return ParseFieldSpecifics(scanner,
     94                              base::ASCIIToUTF16("^$"),
     95                              MATCH_LABEL | MATCH_ALL_INPUTS,
     96                              match);
     97 }
     98 
     99 // static
    100 bool FormField::AddClassification(const AutofillField* field,
    101                                   ServerFieldType type,
    102                                   ServerFieldTypeMap* map) {
    103   // Several fields are optional.
    104   if (!field)
    105     return true;
    106 
    107   return map->insert(make_pair(field->unique_name(), type)).second;
    108 }
    109 
    110 // static.
    111 bool FormField::MatchAndAdvance(AutofillScanner* scanner,
    112                                 const base::string16& pattern,
    113                                 int match_type,
    114                                 const AutofillField** match) {
    115   const AutofillField* field = scanner->Cursor();
    116   if (FormField::Match(field, pattern, match_type)) {
    117     if (match)
    118       *match = field;
    119     scanner->Advance();
    120     return true;
    121   }
    122 
    123   return false;
    124 }
    125 
    126 // static
    127 bool FormField::Match(const AutofillField* field,
    128                       const base::string16& pattern,
    129                       int match_type) {
    130   if ((match_type & FormField::MATCH_LABEL) &&
    131       autofill::MatchesPattern(field->label, pattern)) {
    132     return true;
    133   }
    134 
    135   if ((match_type & FormField::MATCH_NAME) &&
    136       autofill::MatchesPattern(field->name, pattern)) {
    137     return true;
    138   }
    139 
    140   if ((match_type & FormField::MATCH_VALUE) &&
    141       autofill::MatchesPattern(field->value, pattern)) {
    142     return true;
    143   }
    144 
    145   return false;
    146 }
    147 
    148 // static
    149 void FormField::ParseFormFieldsPass(ParseFunction parse,
    150                                     std::vector<const AutofillField*>* fields,
    151                                     ServerFieldTypeMap* map) {
    152   // Store unmatched fields for further processing by the caller.
    153   std::vector<const AutofillField*> remaining_fields;
    154 
    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());
    160       scanner.Advance();
    161       continue;
    162     }
    163 
    164     // Add entries into the map for each field type found in |form_field|.
    165     bool ok = form_field->ClassifyField(map);
    166     DCHECK(ok);
    167   }
    168 
    169   std::swap(*fields, remaining_fields);
    170 }
    171 
    172 bool FormField::MatchesFormControlType(const std::string& type,
    173                                        int match_type) {
    174   if ((match_type & MATCH_TEXT) && type == "text")
    175     return true;
    176 
    177   if ((match_type & MATCH_EMAIL) && type == "email")
    178     return true;
    179 
    180   if ((match_type & MATCH_TELEPHONE) && type == "tel")
    181     return true;
    182 
    183   if ((match_type & MATCH_SELECT) && type == "select-one")
    184     return true;
    185 
    186   if ((match_type & MATCH_TEXT_AREA) && type == "textarea")
    187     return true;
    188 
    189   return false;
    190 }
    191 
    192 }  // namespace autofill
    193