summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authorjhawkins@chromium.org <jhawkins@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-12-17 00:02:05 +0000
committerjhawkins@chromium.org <jhawkins@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-12-17 00:02:05 +0000
commit1cf1f4636373269d1c4f9da6197c72b6b37d4351 (patch)
tree87314f7a0934f46ce3049bcc1c1ed5355ff73bb5 /chrome
parent35f13ab63b056a8e36c06e41655684915c183701 (diff)
downloadchromium_src-1cf1f4636373269d1c4f9da6197c72b6b37d4351.zip
chromium_src-1cf1f4636373269d1c4f9da6197c72b6b37d4351.tar.gz
chromium_src-1cf1f4636373269d1c4f9da6197c72b6b37d4351.tar.bz2
Implement NameField, a FormField that matches a name field in a form.
BUG=none TEST=none Review URL: http://codereview.chromium.org/504030 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@34784 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r--chrome/browser/autofill/form_field.cc8
-rw-r--r--chrome/browser/autofill/name_field.cc157
-rw-r--r--chrome/browser/autofill/name_field.h73
-rwxr-xr-xchrome/chrome_browser.gypi2
4 files changed, 236 insertions, 4 deletions
diff --git a/chrome/browser/autofill/form_field.cc b/chrome/browser/autofill/form_field.cc
index ec15120..e6e375b 100644
--- a/chrome/browser/autofill/form_field.cc
+++ b/chrome/browser/autofill/form_field.cc
@@ -7,6 +7,7 @@
#include "chrome/browser/autofill/address_field.h"
#include "chrome/browser/autofill/autofill_field.h"
#include "chrome/browser/autofill/credit_card_field.h"
+#include "chrome/browser/autofill/name_field.h"
#include "chrome/browser/autofill/phone_field.h"
#include "third_party/WebKit/WebKit/chromium/public/WebRegularExpression.h"
#include "third_party/WebKit/WebKit/chromium/public/WebString.h"
@@ -77,10 +78,9 @@ FormField* FormField::ParseFormField(
if (field != NULL)
return field;
- // TODO(jhawkins):
- // - NameField
-
- return NULL;
+ // We search for a NameField last since it matches the word "name", which is
+ // relatively general.
+ return NameField::Parse(iter, is_ecml);
}
// static
diff --git a/chrome/browser/autofill/name_field.cc b/chrome/browser/autofill/name_field.cc
new file mode 100644
index 0000000..8a32dd6
--- /dev/null
+++ b/chrome/browser/autofill/name_field.cc
@@ -0,0 +1,157 @@
+// 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/name_field.h"
+
+#include "base/string_util.h"
+#include "chrome/browser/autofill/autofill_type.h"
+
+NameField* NameField::Parse(std::vector<AutoFillField*>::const_iterator* iter,
+ bool is_ecml) {
+ // Try FirstLastNameField first since it's more specific.
+ NameField* field = FirstLastNameField::Parse(iter, is_ecml);
+ if (field == NULL && !is_ecml)
+ field = FullNameField::Parse(iter);
+ return field;
+}
+
+FullNameField* FullNameField::Parse(
+ std::vector<AutoFillField*>::const_iterator* iter) {
+ // Exclude labels containing the string "username", which typically
+ // denotes a login ID rather than the user's actual name.
+ AutoFillField* field = **iter;
+ if (Match(field, ASCIIToUTF16("username")))
+ return NULL;
+
+ // Searching for any label containing the word "name" is too general;
+ // for example, Travelocity_Edit travel profile.html contains a field
+ // "Travel Profile Name".
+ if (ParseText(iter, ASCIIToUTF16("^name|full name|your name|customer name"),
+ &field))
+ return new FullNameField(field);
+
+ return NULL;
+}
+
+FirstLastNameField* FirstLastNameField::Parse1(
+ std::vector<AutoFillField*>::const_iterator* iter) {
+ // Some pages (e.g. Overstock_comBilling.html, SmithsonianCheckout.html)
+ // have the label "Name" followed by two or three text fields.
+ FirstLastNameField v;
+ std::vector<AutoFillField*>::const_iterator q = *iter;
+
+ AutoFillField* next;
+ if (ParseText(&q, ASCIIToUTF16("^name"), &v.first_name_) &&
+ ParseText(&q, ASCIIToUTF16(""), &next)) {
+ if (ParseText(&q, ASCIIToUTF16(""), &v.last_name_)) {
+ // There are three name fields; assume that the middle one is a
+ // middle initial (it is, at least, on SmithsonianCheckout.html).
+ v.middle_name_ = next;
+ v.middle_initial_ = true;
+ } else { // only two name fields
+ v.last_name_ = next;
+ }
+
+ *iter = q;
+ return new FirstLastNameField(v);
+ }
+
+ return NULL;
+}
+
+FirstLastNameField* FirstLastNameField::Parse2(
+ std::vector<AutoFillField*>::const_iterator* iter) {
+ FirstLastNameField v;
+ std::vector<AutoFillField*>::const_iterator q = *iter;
+
+ // A fair number of pages use the names "fname" and "lname" for naming
+ // first and last name fields (examples from the test suite:
+ // BESTBUY_COM - Sign In2.html; Crate and Barrel Check Out.html;
+ // dell_checkout1.html). At least one UK page (The China Shop2.html)
+ // asks, in stuffy English style, for just initials and a surname,
+ // so we match "initials" here (and just fill in a first name there,
+ // American-style).
+ if (!ParseText(&q, ASCIIToUTF16("first name|initials|fname"), &v.first_name_))
+ return NULL;
+
+ // We check for a middle initial before checking for a middle name
+ // because at least one page (PC Connection.html) has a field marked
+ // as both (the label text is "MI" and the element name is
+ // "txtmiddlename"); such a field probably actually represents a
+ // middle initial.
+ if (ParseText(&q, ASCIIToUTF16("^mi|middle initial|m.i."), &v.middle_name_)) {
+ v.middle_initial_ = true;
+ } else {
+ ParseText(&q, ASCIIToUTF16("middle name|mname"), &v.middle_name_);
+ }
+
+ if (!ParseText(&q, ASCIIToUTF16("last name|lname|surname"), &v.last_name_))
+ return NULL;
+
+ *iter = q;
+ return new FirstLastNameField(v);
+}
+
+FirstLastNameField* FirstLastNameField::ParseEcmlName(
+ std::vector<AutoFillField*>::const_iterator* iter) {
+ FirstLastNameField field;
+ std::vector<AutoFillField*>::const_iterator q = *iter;
+
+ string16 pattern = GetEcmlPattern(kEcmlShipToFirstName,
+ kEcmlBillToFirstName, '|');
+ if (!ParseText(&q, pattern, &field.first_name_))
+ return NULL;
+
+ pattern = GetEcmlPattern(kEcmlShipToMiddleName, kEcmlBillToMiddleName, '|');
+ ParseText(&q, pattern, &field.middle_name_);
+
+ pattern = GetEcmlPattern(kEcmlShipToLastName, kEcmlBillToLastName, '|');
+ if (ParseText(&q, pattern, &field.last_name_)) {
+ *iter = q;
+ return new FirstLastNameField(field);
+ }
+
+ return NULL;
+}
+
+FirstLastNameField* FirstLastNameField::Parse(
+ std::vector<AutoFillField*>::const_iterator* iter,
+ bool is_ecml) {
+ if (is_ecml) {
+ return ParseEcmlName(iter);
+ } else {
+ FirstLastNameField* v = Parse1(iter);
+ if (v != NULL)
+ return v;
+
+ return Parse2(iter);
+ }
+}
+
+bool FirstLastNameField::GetFieldInfo(FieldTypeMap* field_type_map) const {
+ bool ok = Add(field_type_map, first_name_, AutoFillType(NAME_FIRST));
+ DCHECK(ok);
+ ok = ok && Add(field_type_map, last_name_, AutoFillType(NAME_LAST));
+ DCHECK(ok);
+ AutoFillType type = middle_initial_ ?
+ AutoFillType(NAME_MIDDLE_INITIAL) : AutoFillType(NAME_MIDDLE);
+ ok = ok && Add(field_type_map, middle_name_, type);
+ DCHECK(ok);
+
+ return ok;
+}
+
+FirstLastNameField::FirstLastNameField()
+ : first_name_(NULL),
+ middle_name_(NULL),
+ last_name_(NULL),
+ middle_initial_(false) {
+}
+
+FirstLastNameField::FirstLastNameField(const FirstLastNameField& field)
+ : first_name_(field.first_name_),
+ middle_name_(field.middle_name_),
+ last_name_(field.last_name_),
+ middle_initial_(field.middle_initial_) {
+}
diff --git a/chrome/browser/autofill/name_field.h b/chrome/browser/autofill/name_field.h
new file mode 100644
index 0000000..c827d6c
--- /dev/null
+++ b/chrome/browser/autofill/name_field.h
@@ -0,0 +1,73 @@
+// 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_NAME_FIELD_H_
+#define CHROME_BROWSER_AUTOFILL_NAME_FIELD_H_
+
+#include <vector>
+
+#include "base/logging.h"
+#include "chrome/browser/autofill/autofill_field.h"
+#include "chrome/browser/autofill/form_field.h"
+
+// A form field that can parse either a FullNameField or a FirstLastNameField.
+class NameField : public FormField {
+ public:
+ static NameField* Parse(std::vector<AutoFillField*>::const_iterator* iter,
+ bool is_ecml);
+
+ virtual int priority() const { return 0; }
+
+ protected:
+ NameField() {}
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(NameField);
+};
+
+// A form field that can parse a full name field.
+class FullNameField : public NameField {
+ public:
+ virtual bool GetFieldInfo(FieldTypeMap* field_type_map) const {
+ bool ok = Add(field_type_map, field_, AutoFillType(NAME_FULL));
+ DCHECK(ok);
+ return true;
+ }
+
+ static FullNameField* Parse(
+ std::vector<AutoFillField*>::const_iterator* iter);
+
+ private:
+ explicit FullNameField(AutoFillField* field) : field_(field) {}
+
+ AutoFillField* field_;
+ DISALLOW_COPY_AND_ASSIGN(FullNameField);
+};
+
+// A form field that can parse a first and last name field.
+class FirstLastNameField : public NameField {
+ public:
+ static FirstLastNameField* Parse1(
+ std::vector<AutoFillField*>::const_iterator* iter);
+ static FirstLastNameField* Parse2(
+ std::vector<AutoFillField*>::const_iterator* iter);
+ static FirstLastNameField* ParseEcmlName(
+ std::vector<AutoFillField*>::const_iterator* iter);
+ static FirstLastNameField* Parse(
+ std::vector<AutoFillField*>::const_iterator* iter, bool is_ecml);
+
+ virtual bool GetFieldInfo(FieldTypeMap* field_type_map) const;
+
+ private:
+ FirstLastNameField();
+ explicit FirstLastNameField(const FirstLastNameField& field);
+ void operator=(const FirstLastNameField& field);
+
+ AutoFillField* first_name_;
+ AutoFillField* middle_name_; // Optional.
+ AutoFillField* last_name_;
+ bool middle_initial_; // True if middle_name_ is a middle initial.
+};
+
+#endif // CHROME_BROWSER_AUTOFILL_NAME_FIELD_H_
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index 5004d95..71224bd 100755
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -97,6 +97,8 @@
'browser/autofill/form_field.h',
'browser/autofill/form_structure.cc',
'browser/autofill/form_structure.h',
+ 'browser/autofill/name_field.cc',
+ 'browser/autofill/name_field.h',
'browser/autofill/personal_data_manager.cc',
'browser/autofill/personal_data_manager.h',
'browser/autofill/phone_field.cc',