diff options
author | jhawkins@chromium.org <jhawkins@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-12-17 00:02:05 +0000 |
---|---|---|
committer | jhawkins@chromium.org <jhawkins@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-12-17 00:02:05 +0000 |
commit | 1cf1f4636373269d1c4f9da6197c72b6b37d4351 (patch) | |
tree | 87314f7a0934f46ce3049bcc1c1ed5355ff73bb5 /chrome | |
parent | 35f13ab63b056a8e36c06e41655684915c183701 (diff) | |
download | chromium_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.cc | 8 | ||||
-rw-r--r-- | chrome/browser/autofill/name_field.cc | 157 | ||||
-rw-r--r-- | chrome/browser/autofill/name_field.h | 73 | ||||
-rwxr-xr-x | chrome/chrome_browser.gypi | 2 |
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', |