summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authorjhawkins@chromium.org <jhawkins@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-12-09 23:42:34 +0000
committerjhawkins@chromium.org <jhawkins@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-12-09 23:42:34 +0000
commite2d8667b7a2bb47a25ddd9a74cbd627bf17b5c7e (patch)
tree776a15005671831ab776df8e0deb7d2a366aa23e /chrome
parent7d01a10bbf5887f4d095f53f5a7b376aa99f4635 (diff)
downloadchromium_src-e2d8667b7a2bb47a25ddd9a74cbd627bf17b5c7e.zip
chromium_src-e2d8667b7a2bb47a25ddd9a74cbd627bf17b5c7e.tar.gz
chromium_src-e2d8667b7a2bb47a25ddd9a74cbd627bf17b5c7e.tar.bz2
autofill: Add the FormField interface. Classes that implement the FormField interface provide heuristics for determining the type of a form field. An initial implementation, EmailField, is provided.
BUG=none TEST=none Review URL: http://codereview.chromium.org/469013 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@34201 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r--chrome/browser/autofill/autofill_field.cc32
-rw-r--r--chrome/browser/autofill/autofill_field.h35
-rw-r--r--chrome/browser/autofill/autofill_manager.cc17
-rw-r--r--chrome/browser/autofill/autofill_manager.h4
-rw-r--r--chrome/browser/autofill/field_types.h6
-rw-r--r--chrome/browser/autofill/form_field.cc191
-rw-r--r--chrome/browser/autofill/form_field.h151
-rw-r--r--chrome/browser/autofill/form_structure.cc67
-rw-r--r--chrome/browser/autofill/form_structure.h34
-rw-r--r--chrome/browser/autofill/personal_data_manager.cc4
-rw-r--r--chrome/browser/autofill/personal_data_manager.h13
-rwxr-xr-xchrome/chrome_browser.gypi2
12 files changed, 541 insertions, 15 deletions
diff --git a/chrome/browser/autofill/autofill_field.cc b/chrome/browser/autofill/autofill_field.cc
index fba28a0..0fcfdc6 100644
--- a/chrome/browser/autofill/autofill_field.cc
+++ b/chrome/browser/autofill/autofill_field.cc
@@ -25,8 +25,28 @@ static std::string Hash32Bit(const std::string& str) {
} // namespace
-AutoFillField::AutoFillField(const webkit_glue::FormField& field)
- : webkit_glue::FormField(field) {
+AutoFillField::AutoFillField()
+ : server_type_(NO_SERVER_DATA),
+ heuristic_type_(UNKNOWN_TYPE) {
+}
+
+AutoFillField::AutoFillField(const webkit_glue::FormField& field,
+ const string16& unique_name)
+ : webkit_glue::FormField(field),
+ unique_name_(unique_name),
+ server_type_(NO_SERVER_DATA),
+ heuristic_type_(UNKNOWN_TYPE) {
+}
+
+AutoFillFieldType AutoFillField::type() const {
+ if (server_type_ != NO_SERVER_DATA)
+ return server_type_;
+
+ return heuristic_type_;
+}
+
+bool AutoFillField::IsEmpty() const {
+ return value().empty();
}
std::string AutoFillField::FieldSignature() const {
@@ -35,3 +55,11 @@ std::string AutoFillField::FieldSignature() const {
std::string field_string = field_name + "&" + type;
return Hash32Bit(field_string);
}
+
+void AutoFillField::set_heuristic_type(const AutoFillFieldType& type) {
+ DCHECK(type >= 0 && type < MAX_VALID_FIELD_TYPE);
+ if (type >= 0 && type < MAX_VALID_FIELD_TYPE)
+ heuristic_type_ = type;
+ else
+ heuristic_type_ = UNKNOWN_TYPE;
+}
diff --git a/chrome/browser/autofill/autofill_field.h b/chrome/browser/autofill/autofill_field.h
index e8672d0..84a5fb2 100644
--- a/chrome/browser/autofill/autofill_field.h
+++ b/chrome/browser/autofill/autofill_field.h
@@ -5,21 +5,52 @@
#ifndef CHROME_BROWSER_AUTOFILL_AUTOFILL_FIELD_H_
#define CHROME_BROWSER_AUTOFILL_AUTOFILL_FIELD_H_
+#include <string>
+
+#include "base/string16.h"
#include "chrome/browser/autofill/field_types.h"
#include "webkit/glue/form_field.h"
class AutoFillField : public webkit_glue::FormField {
public:
- explicit AutoFillField(const webkit_glue::FormField& field);
+ AutoFillField();
+ AutoFillField(const webkit_glue::FormField& field,
+ const string16& unique_name);
+
+ string16 unique_name() const { return unique_name_; }
+ AutoFillFieldType heuristic_type() const { return heuristic_type_; }
const FieldTypeSet& possible_types() const { return possible_types_; }
+ void set_possible_types(const FieldTypeSet& possible_types) {
+ possible_types_ = possible_types;
+ }
+
+ // This function automatically chooses between server and heuristic autofill
+ // type, depending on the data available.
+ AutoFillFieldType type() const;
+
+ // Returns true if the value of this field is empty.
+ bool IsEmpty() const;
// The unique signature of this field, composed of the field name and the html
// input type in a 32-bit hash.
std::string FieldSignature() const;
+ // Sets the heuristic type of this field, validating the input.
+ void set_heuristic_type(const AutoFillFieldType& type);
+
private:
- FieldTypeSet possible_types_;
+ // The unique name of this field, generated by AutoFill.
+ string16 unique_name_;
+
+ // The type of the field, as determined by the AutoFill server.
+ AutoFillFieldType server_type_;
+
+ // The type of the field, as determined by the local heuristics.
+ AutoFillFieldType heuristic_type_;
+
+ // The set of possible types for this field.
+ FieldTypeSet possible_types_;
};
#endif // CHROME_BROWSER_AUTOFILL_AUTOFILL_FIELD_H_
diff --git a/chrome/browser/autofill/autofill_manager.cc b/chrome/browser/autofill/autofill_manager.cc
index 15271f5..5632d63 100644
--- a/chrome/browser/autofill/autofill_manager.cc
+++ b/chrome/browser/autofill/autofill_manager.cc
@@ -37,7 +37,8 @@ void AutoFillManager::FormFieldValuesSubmitted(
if (!upload_form_structure_->IsAutoFillable())
return;
- // TODO(jhawkins): Determine possible field types.
+ // Determine the possible field types.
+ DeterminePossibleFieldTypes(upload_form_structure_.get());
if (!personal_data_->ImportFormData(form_structures_, this))
return;
@@ -46,6 +47,20 @@ void AutoFillManager::FormFieldValuesSubmitted(
infobar_.reset(new AutoFillInfoBarDelegate(tab_contents_, this));
}
+void AutoFillManager::DeterminePossibleFieldTypes(
+ FormStructure* form_structure) {
+ // TODO(jhawkins): Update field text.
+
+ form_structure->GetHeuristicAutoFillTypes();
+
+ for (size_t i = 0; i < form_structure->field_count(); i++) {
+ const AutoFillField* field = form_structure->field(i);
+ FieldTypeSet field_types;
+ personal_data_->GetPossibleFieldTypes(field->value(), &field_types);
+ form_structure->set_possible_types(i, field_types);
+ }
+}
+
void AutoFillManager::SaveFormData() {
UploadFormData();
diff --git a/chrome/browser/autofill/autofill_manager.h b/chrome/browser/autofill/autofill_manager.h
index e5b3b58..dac7ffd 100644
--- a/chrome/browser/autofill/autofill_manager.h
+++ b/chrome/browser/autofill/autofill_manager.h
@@ -30,6 +30,10 @@ class AutoFillManager : public RenderViewHostDelegate::AutoFill {
virtual void FormFieldValuesSubmitted(
const webkit_glue::FormFieldValues& form);
+ // Uses heuristics and existing personal data to determine the possible field
+ // types.
+ void DeterminePossibleFieldTypes(FormStructure* form_structure);
+
// Saves the form data to the web database.
void SaveFormData();
diff --git a/chrome/browser/autofill/field_types.h b/chrome/browser/autofill/field_types.h
index 903af7e..d202a2e 100644
--- a/chrome/browser/autofill/field_types.h
+++ b/chrome/browser/autofill/field_types.h
@@ -7,6 +7,12 @@
#include <set>
+typedef enum _AddressType {
+ kGenericAddress = 0,
+ kBillingAddress,
+ kShippingAddress
+} AddressType;
+
// NOTE: This list MUST not be modified. The server aggregates and stores these
// types over several versions, so we must remain fully compatible with the
// autofill server, which is itself backward-compatible. The list must be kept
diff --git a/chrome/browser/autofill/form_field.cc b/chrome/browser/autofill/form_field.cc
new file mode 100644
index 0000000..dca943f
--- /dev/null
+++ b/chrome/browser/autofill/form_field.cc
@@ -0,0 +1,191 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/autofill/form_field.h"
+
+#include "chrome/browser/autofill/autofill_field.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebRegularExpression.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebString.h"
+
+class EmailField : public FormField {
+ public:
+ virtual bool GetFieldInfo(FieldTypeMap* field_type_map) const {
+ bool ok = Add(field_type_map, field_, AutoFillType(EMAIL_ADDRESS));
+ DCHECK(ok);
+ return true;
+ }
+
+ static EmailField* Parse(std::vector<AutoFillField*>::const_iterator* iter,
+ bool is_ecml) {
+ string16 pattern;
+ if (is_ecml) {
+ pattern = GetEcmlPattern(kEcmlShipToEmail, kEcmlBillToEmail, '|');
+ } else {
+ pattern = ASCIIToUTF16("email|e-mail");
+ }
+
+ AutoFillField* field;
+ if (ParseText(iter, pattern, &field))
+ return new EmailField(field);
+
+ return NULL;
+ }
+
+ virtual int priority() const { return 1; }
+
+ private:
+ explicit EmailField(AutoFillField *field) : field_(field) {}
+
+ AutoFillField* field_;
+};
+
+// static
+bool FormField::Match(AutoFillField* field, const string16& pattern) {
+ WebKit::WebRegularExpression re(WebKit::WebString(pattern),
+ WebKit::WebTextCaseInsensitive);
+
+ // For now, we apply the same pattern to the field's label and the field's
+ // name. Matching the name is a bit of a long shot for many patterns, but
+ // it generally doesn't hurt to try.
+ if (re.match(WebKit::WebString(field->label())) ||
+ re.match(WebKit::WebString(field->name()))) {
+ return true;
+ }
+
+ return false;
+}
+
+// static
+FormField* FormField::ParseFormField(
+ std::vector<AutoFillField*>::const_iterator* iter,
+ bool is_ecml) {
+ FormField *field;
+ field = EmailField::Parse(iter, is_ecml);
+ if (field != NULL)
+ return field;
+
+ // TODO(jhawkins):
+ // - AddressField
+ // - CreditCardField
+ // - NameField
+ // - PhoneField
+
+ return NULL;
+}
+
+// static
+bool FormField::ParseText(std::vector<AutoFillField*>::const_iterator* iter,
+ const string16& pattern) {
+ AutoFillField* field;
+ return ParseText(iter, pattern, &field);
+}
+
+// static
+bool FormField::ParseText(std::vector<AutoFillField*>::const_iterator* iter,
+ const string16& pattern,
+ AutoFillField** dest) {
+ AutoFillField* field = **iter;
+ if (!field)
+ return false;
+
+ if (Match(field, pattern)) {
+ *dest = field;
+ (*iter)++;
+ return true;
+ }
+
+ return false;
+}
+
+// static
+bool FormField::ParseEmpty(std::vector<AutoFillField*>::const_iterator* iter) {
+ // TODO(jhawkins): Handle select fields.
+ return ParseText(iter, ASCIIToUTF16(""));
+}
+
+// static
+bool FormField::Add(FieldTypeMap* field_type_map, AutoFillField* field,
+ const AutoFillType& type) {
+ // Several fields are optional.
+ if (field)
+ field_type_map->insert(make_pair(field->unique_name(), type.field_type()));
+
+ return true;
+}
+
+string16 FormField::GetEcmlPattern(const string16& ecml_name) {
+ return ASCIIToUTF16("&") + ecml_name;
+}
+
+string16 FormField::GetEcmlPattern(const string16& ecml_name1,
+ const string16& ecml_name2,
+ string16::value_type pattern_operator) {
+ string16 ampersand = ASCIIToUTF16("&");
+ return ampersand + ecml_name1 + pattern_operator + ampersand + ecml_name2;
+}
+
+FormFieldSet::FormFieldSet(FormStructure* fields) {
+ bool is_ecml = CheckECML(fields);
+
+ // Parse fields.
+ std::vector<AutoFillField*>::const_iterator field = fields->begin();
+ while (field != fields->end() && *field != NULL) {
+ FormField* form_field = FormField::ParseFormField(&field, is_ecml);
+ if (!form_field) {
+ field++;
+ continue;
+ }
+
+ push_back(form_field);
+ }
+}
+
+bool FormFieldSet::CheckECML(FormStructure* fields) {
+ size_t num_fields = fields->field_count();
+ for (size_t index = 0; index < num_fields; ++index) {
+ string16 name(fields->field(index)->name());
+ if (name.substr(0, 4) == ASCIIToUTF16("ecom") &&
+ (StartsWith(name, kEcmlShipToTitle, false) ||
+ StartsWith(name, kEcmlShipToFirstName, false) ||
+ StartsWith(name, kEcmlShipToMiddleName, false) ||
+ StartsWith(name, kEcmlShipToLastName, false) ||
+ StartsWith(name, kEcmlShipToNameSuffix, false) ||
+ StartsWith(name, kEcmlShipToCompanyName, false) ||
+ StartsWith(name, kEcmlShipToAddress1, false) ||
+ StartsWith(name, kEcmlShipToAddress2, false) ||
+ StartsWith(name, kEcmlShipToAddress3, false) ||
+ StartsWith(name, kEcmlShipToCity, false) ||
+ StartsWith(name, kEcmlShipToStateProv, false) ||
+ StartsWith(name, kEcmlShipToPostalCode, false) ||
+ StartsWith(name, kEcmlShipToCountry, false) ||
+ StartsWith(name, kEcmlShipToPhone, false) ||
+ StartsWith(name, kEcmlShipToPhone, false) ||
+ StartsWith(name, kEcmlShipToEmail, false) ||
+ StartsWith(name, kEcmlBillToTitle, false) ||
+ StartsWith(name, kEcmlBillToFirstName, false) ||
+ StartsWith(name, kEcmlBillToMiddleName, false) ||
+ StartsWith(name, kEcmlBillToLastName, false) ||
+ StartsWith(name, kEcmlBillToNameSuffix, false) ||
+ StartsWith(name, kEcmlBillToCompanyName, false) ||
+ StartsWith(name, kEcmlBillToAddress1, false) ||
+ StartsWith(name, kEcmlBillToAddress2, false) ||
+ StartsWith(name, kEcmlBillToAddress3, false) ||
+ StartsWith(name, kEcmlBillToCity, false) ||
+ StartsWith(name, kEcmlBillToStateProv, false) ||
+ StartsWith(name, kEcmlBillToPostalCode, false) ||
+ StartsWith(name, kEcmlBillToCountry, false) ||
+ StartsWith(name, kEcmlBillToPhone, false) ||
+ StartsWith(name, kEcmlBillToPhone, false) ||
+ StartsWith(name, kEcmlBillToEmail, false) ||
+ StartsWith(name, kEcmlCardHolder, false) ||
+ StartsWith(name, kEcmlCardType, false) ||
+ StartsWith(name, kEcmlCardNumber, false) ||
+ StartsWith(name, kEcmlCardVerification, false) ||
+ StartsWith(name, kEcmlCardExpireMonth, false) ||
+ StartsWith(name, kEcmlCardExpireYear, false))) {
+ return true;
+ }
+ }
+ return false;
+}
diff --git a/chrome/browser/autofill/form_field.h b/chrome/browser/autofill/form_field.h
new file mode 100644
index 0000000..72fbb22
--- /dev/null
+++ b/chrome/browser/autofill/form_field.h
@@ -0,0 +1,151 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_AUTOFILL_FORM_FIELD_H_
+#define CHROME_BROWSER_AUTOFILL_FORM_FIELD_H_
+
+#include <vector>
+
+#include "base/string16.h"
+#include "base/string_util.h"
+#include "chrome/browser/autofill/autofill_type.h"
+#include "chrome/browser/autofill/form_structure.h"
+
+// Field names from the ECML specification; see RFC 3106. We've
+// made these names lowercase since we convert labels and field names to
+// lowercase before searching.
+
+// shipping name/address fields
+static string16 kEcmlShipToTitle = ASCIIToUTF16("ecom_shipto_postal_name_prefix");
+static string16 kEcmlShipToFirstName = ASCIIToUTF16("ecom_shipto_postal_name_first");
+static string16 kEcmlShipToMiddleName = ASCIIToUTF16("ecom_shipto_postal_name_middle");
+static string16 kEcmlShipToLastName = ASCIIToUTF16("ecom_shipto_postal_name_last");
+static string16 kEcmlShipToNameSuffix = ASCIIToUTF16("ecom_shipto_postal_name_suffix");
+static string16 kEcmlShipToCompanyName = ASCIIToUTF16("ecom_shipto_postal_company");
+static string16 kEcmlShipToAddress1 = ASCIIToUTF16("ecom_shipto_postal_street_line1");
+static string16 kEcmlShipToAddress2 = ASCIIToUTF16("ecom_shipto_postal_street_line2");
+static string16 kEcmlShipToAddress3 = ASCIIToUTF16("ecom_shipto_postal_street_line3");
+static string16 kEcmlShipToCity = ASCIIToUTF16("ecom_shipto_postal_city");
+static string16 kEcmlShipToStateProv = ASCIIToUTF16("ecom_shipto_postal_stateprov");
+static string16 kEcmlShipToPostalCode = ASCIIToUTF16("ecom_shipto_postal_postalcode");
+static string16 kEcmlShipToCountry = ASCIIToUTF16("ecom_shipto_postal_countrycode");
+static string16 kEcmlShipToPhone = ASCIIToUTF16("ecom_shipto_telecom_phone_number");
+static string16 kEcmlShipToEmail = ASCIIToUTF16("ecom_shipto_online_email");
+
+ // billing name/address fields
+static string16 kEcmlBillToTitle = ASCIIToUTF16("ecom_billto_postal_name_prefix");
+static string16 kEcmlBillToFirstName = ASCIIToUTF16("ecom_billto_postal_name_first");
+static string16 kEcmlBillToMiddleName = ASCIIToUTF16("ecom_billto_postal_name_middle");
+static string16 kEcmlBillToLastName = ASCIIToUTF16("ecom_billto_postal_name_last");
+static string16 kEcmlBillToNameSuffix = ASCIIToUTF16("ecom_billto_postal_name_suffix");
+static string16 kEcmlBillToCompanyName = ASCIIToUTF16("ecom_billto_postal_company");
+static string16 kEcmlBillToAddress1 = ASCIIToUTF16("ecom_billto_postal_street_line1");
+static string16 kEcmlBillToAddress2 = ASCIIToUTF16("ecom_billto_postal_street_line2");
+static string16 kEcmlBillToAddress3 = ASCIIToUTF16("ecom_billto_postal_street_line3");
+static string16 kEcmlBillToCity = ASCIIToUTF16("ecom_billto_postal_city");
+static string16 kEcmlBillToStateProv = ASCIIToUTF16("ecom_billto_postal_stateprov");
+static string16 kEcmlBillToPostalCode = ASCIIToUTF16("ecom_billto_postal_postalcode");
+static string16 kEcmlBillToCountry = ASCIIToUTF16("ecom_billto_postal_countrycode");
+static string16 kEcmlBillToPhone = ASCIIToUTF16("ecom_billto_telecom_phone_number");
+static string16 kEcmlBillToEmail = ASCIIToUTF16("ecom_billto_online_email");
+
+ // credit card fields
+static string16 kEcmlCardHolder = ASCIIToUTF16("ecom_payment_card_name");
+static string16 kEcmlCardType = ASCIIToUTF16("ecom_payment_card_type");
+static string16 kEcmlCardNumber = ASCIIToUTF16("ecom_payment_card_number");
+static string16 kEcmlCardVerification = ASCIIToUTF16("ecom_payment_card_verification");
+static string16 kEcmlCardExpireDay = ASCIIToUTF16("ecom_payment_card_expdate_day");
+static string16 kEcmlCardExpireMonth = ASCIIToUTF16("ecom_payment_card_expdate_month");
+static string16 kEcmlCardExpireYear = ASCIIToUTF16("ecom_payment_card_expdate_year");
+
+enum FormFieldType {
+ kAddressType,
+ kCreditCardType,
+ kOtherFieldType
+};
+
+class AutoFillField;
+
+// Represents a logical form field in a web form. Classes that implement this
+// interface can identify themselves as a particular type of form field, e.g.
+// name, phone number, or address field.
+class FormField {
+ public:
+ virtual ~FormField() {}
+
+ // Associates the available AutoFillTypes of a FormField into
+ // |field_type_map|.
+ virtual bool GetFieldInfo(FieldTypeMap* field_type_map) const = 0;
+
+ // Returns the type of form field of the class implementing this interface.
+ virtual FormFieldType GetFormFieldType() const { return kOtherFieldType; }
+
+ // TODO(jhawkins): I'm pretty sure this is not necessary in AutoFill++ because
+ // we use a static dialog setup.
+ virtual int priority() const = 0;
+
+ // Returns true if |field| contains the regexp |pattern| in the name or label.
+ static bool Match(AutoFillField* field, const string16& pattern);
+
+ // Parses a field using the different field views we know about. |is_ecml|
+ // should be true when the field conforms to the ECML specification.
+ static FormField* ParseFormField(
+ std::vector<AutoFillField*>::const_iterator* field,
+ bool is_ecml);
+
+ // Attempts to parse a text field with the given pattern; returns true on
+ // success, but doesn't return the actual text field itself.
+ static bool ParseText(std::vector<AutoFillField*>::const_iterator* iter,
+ const string16& pattern);
+
+ // Attempts to parse a text field with the given pattern. Returns true on
+ // success and fills |dest| with a pointer to the field.
+ static bool ParseText(std::vector<AutoFillField*>::const_iterator* iter,
+ const string16& pattern,
+ AutoFillField** dest);
+
+ // Attempts to parse a control with an empty label.
+ static bool ParseEmpty(std::vector<AutoFillField*>::const_iterator* iter);
+
+ // Adds an association between a field and a type to |field_type_map|.
+ static bool Add(FieldTypeMap* field_type_map, AutoFillField* field,
+ const AutoFillType& type);
+
+ protected:
+ // Note: ECML compliance checking has been modified to accommodate Google
+ // Checkout field name limitation. All ECML compliant web forms will be
+ // recognized correctly as such however the restrictions on having exactly
+ // ECML compliant names have been loosened to only require that field names
+ // be prefixed with an ECML compiant name in order to accommodate checkout.
+ // Additionally we allow the use of '.' as a word delimiter in addition to the
+ // ECML standard '_' (see FormField::FormField for details).
+ static string16 GetEcmlPattern(const string16& ecml_name);
+ static string16 GetEcmlPattern(const string16& ecml_name1,
+ const string16& ecml_name2,
+ string16::value_type pattern_operator);
+};
+
+class FormFieldSet : public std::vector<FormField*> {
+ public:
+ explicit FormFieldSet(FormStructure* form);
+
+ class FormFieldSorter {
+ public:
+ bool operator() (FormField *v1, FormField *v2) {
+ return v1->priority() < v2->priority();
+ }
+ };
+
+ ~FormFieldSet() {
+ for (iterator i = begin(); i != end(); ++i)
+ delete *i;
+ }
+
+ private:
+ // Checks if any of the labels are named according to the ECML standard.
+ // Returns true if at least one ECML named element is found.
+ bool CheckECML(FormStructure* fields);
+};
+
+#endif // CHROME_BROWSER_AUTOFILL_FORM_FIELD_H_
diff --git a/chrome/browser/autofill/form_structure.cc b/chrome/browser/autofill/form_structure.cc
index 354a36c..ab4ac14 100644
--- a/chrome/browser/autofill/form_structure.cc
+++ b/chrome/browser/autofill/form_structure.cc
@@ -10,6 +10,7 @@
#include "base/string_util.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/autofill/field_types.h"
+#include "chrome/browser/autofill/form_field.h"
#include "third_party/libjingle/files/talk/xmllite/xmlelement.h"
#include "webkit/glue/form_field.h"
#include "webkit/glue/form_field_values.h"
@@ -56,9 +57,14 @@ FormStructure::FormStructure(const webkit_glue::FormFieldValues& values)
std::vector<webkit_glue::FormField>::const_iterator field;
for (field = values.elements.begin();
field != values.elements.end(); field++) {
- fields_.push_back(AutoFillField(*field));
+ // Generate a unique name for this field by appending a counter to the name.
+ string16 unique_name = field->name() + IntToString16(fields_.size() + 1);
+ fields_.push_back(new AutoFillField(*field, unique_name));
}
+ // Terminate the vector with a NULL item.
+ fields_.push_back(NULL);
+
std::string method = UTF16ToUTF8(values.method);
if (method == kFormMethodPost) {
method_ = POST;
@@ -96,8 +102,8 @@ bool FormStructure::EncodeUploadRequest(bool auto_fill_used,
autofill_upload.SetAttr(buzz::QName(kAttributeDataPresent), "");
// Add the child nodes for the form fields.
- std::vector<AutoFillField>::const_iterator field;
- for (field = fields_.begin(); field != fields_.end(); field++) {
+ for (size_t index = 0; index < field_count(); index++) {
+ const AutoFillField* field = fields_[index];
FieldTypeSet types = field->possible_types();
for (FieldTypeSet::const_iterator type = types.begin();
type != types.end(); type++) {
@@ -121,6 +127,33 @@ bool FormStructure::EncodeUploadRequest(bool auto_fill_used,
return true;
}
+void FormStructure::GetHeuristicAutoFillTypes() {
+ has_credit_card_field_ = false;
+ has_autofillable_field_ = false;
+
+ FieldTypeMap field_type_map;
+ GetHeuristicFieldInfo(&field_type_map);
+
+ for (size_t index = 0; index < field_count(); index++) {
+ AutoFillField* field = fields_[index];
+ FieldTypeMap::iterator iter = field_type_map.find(field->unique_name());
+
+ AutoFillFieldType heuristic_auto_fill_type;
+ if (iter == field_type_map.end())
+ heuristic_auto_fill_type = UNKNOWN_TYPE;
+ else
+ heuristic_auto_fill_type = iter->second;
+
+ field->set_heuristic_type(heuristic_auto_fill_type);
+
+ AutoFillType autofill_type(field->type());
+ if (autofill_type.group() == AutoFillType::CREDIT_CARD)
+ has_credit_card_field_ = true;
+ if (autofill_type.field_type() != UNKNOWN_TYPE)
+ has_autofillable_field_ = true;
+ }
+}
+
std::string FormStructure::FormSignature() const {
std::string form_string = target_url_.host() +
"&" +
@@ -142,7 +175,7 @@ bool FormStructure::IsAutoFillable() const {
// Disqualify all forms that are likely to be search boxes (like google.com).
if (fields_.size() == 1) {
- std::string name = UTF16ToUTF8(fields_[0].name());
+ std::string name = UTF16ToUTF8(fields_[0]->name());
if (name == "q")
return false;
}
@@ -152,3 +185,29 @@ bool FormStructure::IsAutoFillable() const {
return true;
}
+
+void FormStructure::set_possible_types(int index, const FieldTypeSet& types) {
+ int num_fields = static_cast<int>(fields_.size());
+ DCHECK(index >= 0 && index < num_fields);
+ if (index >= 0 && index < num_fields)
+ fields_[index]->set_possible_types(types);
+}
+
+AutoFillField* FormStructure::field(int index) {
+ return fields_[index];
+}
+
+size_t FormStructure::field_count() const {
+ // Don't count the NULL terminator.
+ return fields_.size() - 1;
+}
+
+void FormStructure::GetHeuristicFieldInfo(FieldTypeMap* field_type_map) {
+ FormFieldSet fields = FormFieldSet(this);
+
+ FormFieldSet::const_iterator field;
+ for (field = fields.begin(); field != fields.end(); field++) {
+ bool ok = (*field)->GetFieldInfo(field_type_map);
+ DCHECK(ok);
+ }
+}
diff --git a/chrome/browser/autofill/form_structure.h b/chrome/browser/autofill/form_structure.h
index c0d178d9..5892941 100644
--- a/chrome/browser/autofill/form_structure.h
+++ b/chrome/browser/autofill/form_structure.h
@@ -8,8 +8,10 @@
#include <string>
#include <vector>
-#include "base/scoped_ptr.h"
+#include "base/scoped_vector.h"
#include "chrome/browser/autofill/autofill_field.h"
+#include "chrome/browser/autofill/autofill_type.h"
+#include "chrome/browser/autofill/field_types.h"
#include "googleurl/src/gurl.h"
namespace webkit_glue {
@@ -30,6 +32,10 @@ class FormStructure {
// Encodes the XML upload request from this FormStructure.
bool EncodeUploadRequest(bool auto_fill_used, std::string* encoded_xml) const;
+ // Runs several heuristics against the form fields to determine their possible
+ // types.
+ void GetHeuristicAutoFillTypes();
+
// The unique signature for this form, composed of the target url domain,
// the form name, and the form field names in a 64-bit hash.
std::string FormSignature() const;
@@ -38,7 +44,24 @@ class FormStructure {
// like google/yahoo/msn search, etc.
bool IsAutoFillable() const;
+ // Sets the possible types for the field at |index|.
+ void set_possible_types(int index, const FieldTypeSet& types);
+
+ AutoFillField* field(int index);
+ size_t field_count() const;
+
+ // Used for iterating over the fields.
+ std::vector<AutoFillField*>::const_iterator begin() const {
+ return fields_.begin();
+ }
+ std::vector<AutoFillField*>::const_iterator end() const {
+ return fields_.end();
+ }
+
private:
+ // Associates the field with the heuristic type for each of the field views.
+ void GetHeuristicFieldInfo(FieldTypeMap* field_types_map);
+
// The name of the form.
std::string form_name_;
@@ -48,8 +71,13 @@ class FormStructure {
// The target URL.
GURL target_url_;
- // A vector of all the input fields in the form.
- std::vector<AutoFillField> fields_;
+ bool has_credit_card_field_;
+ bool has_autofillable_field_;
+ bool has_password_fields_;
+
+ // A vector of all the input fields in the form. The vector is terminated by
+ // a NULL entry.
+ ScopedVector<AutoFillField> fields_;
// The names of the form input elements, that are part of the form signature.
// The string starts with "&" and the names are also separated by the "&"
diff --git a/chrome/browser/autofill/personal_data_manager.cc b/chrome/browser/autofill/personal_data_manager.cc
index 8333c699..ca204636 100644
--- a/chrome/browser/autofill/personal_data_manager.cc
+++ b/chrome/browser/autofill/personal_data_manager.cc
@@ -16,5 +16,9 @@ bool PersonalDataManager::ImportFormData(
return true;
}
+void PersonalDataManager::GetPossibleFieldTypes(const string16& text,
+ FieldTypeSet* possible_types) {
+}
+
PersonalDataManager::PersonalDataManager() {
}
diff --git a/chrome/browser/autofill/personal_data_manager.h b/chrome/browser/autofill/personal_data_manager.h
index f8a7b01..1d27f16 100644
--- a/chrome/browser/autofill/personal_data_manager.h
+++ b/chrome/browser/autofill/personal_data_manager.h
@@ -7,6 +7,9 @@
#include <vector>
+#include "base/string16.h"
+#include "chrome/browser/autofill/field_types.h"
+
class AutoFillManager;
class FormStructure;
@@ -22,9 +25,13 @@ class PersonalDataManager {
// has not previously been prompted, the user will be asked if he would like
// to import the data. If the user selects yes, a profile will be created
// with all of the information from recognized fields.
- virtual bool ImportFormData(
- const std::vector<FormStructure*>& form_structures,
- AutoFillManager* autofill_manager);
+ bool ImportFormData(const std::vector<FormStructure*>& form_structures,
+ AutoFillManager* autofill_manager);
+
+ // Gets the possible field types for the given text, determined by matching
+ // the text with all known personal information and returning matching types.
+ void GetPossibleFieldTypes(const string16& text,
+ FieldTypeSet* possible_types);
private:
// Make sure that only Profile can create an instance of PersonalDataManager.
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index 805bbfe..240574d 100755
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -87,6 +87,8 @@
'browser/autofill/autofill_type.cc',
'browser/autofill/autofill_type.h',
'browser/autofill/field_types.h',
+ 'browser/autofill/form_field.cc',
+ 'browser/autofill/form_field.h',
'browser/autofill/form_structure.cc',
'browser/autofill/form_structure.h',
'browser/autofill/personal_data_manager.cc',