| Index: chrome/browser/autofill/name_field.cc
|
| diff --git a/chrome/browser/autofill/name_field.cc b/chrome/browser/autofill/name_field.cc
|
| index 87f98cea3989bcb78d520fd30380fe716747f721..2356afc08f8b910758c3e7e6af90ecad9ea194fa 100644
|
| --- a/chrome/browser/autofill/name_field.cc
|
| +++ b/chrome/browser/autofill/name_field.cc
|
| @@ -8,11 +8,58 @@
|
| #include "base/memory/scoped_ptr.h"
|
| #include "base/string_util.h"
|
| #include "base/utf_string_conversions.h"
|
| +#include "chrome/browser/autofill/autofill_ecml.h"
|
| #include "chrome/browser/autofill/autofill_scanner.h"
|
| #include "chrome/browser/autofill/autofill_type.h"
|
| #include "grit/autofill_resources.h"
|
| #include "ui/base/l10n/l10n_util.h"
|
|
|
| +using autofill::GetEcmlPattern;
|
| +
|
| +namespace {
|
| +
|
| +// A form field that can parse a full name field.
|
| +class FullNameField : public NameField {
|
| + public:
|
| + static FullNameField* Parse(AutofillScanner* scanner);
|
| +
|
| + protected:
|
| + // FormField:
|
| + virtual bool ClassifyField(FieldTypeMap* map) const OVERRIDE;
|
| +
|
| + private:
|
| + explicit FullNameField(const AutofillField* field);
|
| +
|
| + const 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* ParseSpecificName(AutofillScanner* scanner);
|
| + static FirstLastNameField* ParseComponentNames(AutofillScanner* scanner);
|
| + static FirstLastNameField* ParseEcmlName(AutofillScanner* scanner);
|
| + static FirstLastNameField* Parse(AutofillScanner* scanner, bool is_ecml);
|
| +
|
| + protected:
|
| + // FormField:
|
| + virtual bool ClassifyField(FieldTypeMap* map) const OVERRIDE;
|
| +
|
| + private:
|
| + FirstLastNameField();
|
| +
|
| + const AutofillField* first_name_;
|
| + const AutofillField* middle_name_; // Optional.
|
| + const AutofillField* last_name_;
|
| + bool middle_initial_; // True if middle_name_ is a middle initial.
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(FirstLastNameField);
|
| +};
|
| +
|
| +} // namespace
|
| +
|
| NameField* NameField::Parse(AutofillScanner* scanner, bool is_ecml) {
|
| if (scanner->IsEnd())
|
| return NULL;
|
| @@ -24,37 +71,38 @@ NameField* NameField::Parse(AutofillScanner* scanner, bool is_ecml) {
|
| return field;
|
| }
|
|
|
| -bool FullNameField::GetFieldInfo(FieldTypeMap* field_type_map) const {
|
| - return Add(field_type_map, field_, NAME_FULL);
|
| +// This is overriden in concrete subclasses.
|
| +bool NameField::ClassifyField(FieldTypeMap* map) const {
|
| + return false;
|
| }
|
|
|
| FullNameField* FullNameField::Parse(AutofillScanner* scanner) {
|
| // Exclude labels containing the string "username", which typically
|
| // denotes a login ID rather than the user's actual name.
|
| - const AutofillField* field = scanner->Cursor();
|
| - if (Match(field, l10n_util::GetStringUTF16(IDS_AUTOFILL_USERNAME_RE), false))
|
| + scanner->SaveCursor();
|
| + bool is_username = ParseField(
|
| + scanner, l10n_util::GetStringUTF16(IDS_AUTOFILL_USERNAME_RE), NULL);
|
| + scanner->Rewind();
|
| + if (is_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(scanner, l10n_util::GetStringUTF16(IDS_AUTOFILL_NAME_RE),
|
| - &field))
|
| + const AutofillField* field = NULL;
|
| + if (ParseField(scanner, l10n_util::GetStringUTF16(IDS_AUTOFILL_NAME_RE),
|
| + &field))
|
| return new FullNameField(field);
|
|
|
| return NULL;
|
| }
|
|
|
| -FullNameField::FullNameField(const AutofillField* field)
|
| - : field_(field) {
|
| +bool FullNameField::ClassifyField(FieldTypeMap* map) const {
|
| + return AddClassification(field_, NAME_FULL, map);
|
| }
|
|
|
| -bool FirstLastNameField::GetFieldInfo(FieldTypeMap* field_type_map) const {
|
| - bool ok = Add(field_type_map, first_name_, NAME_FIRST);
|
| - ok = ok && Add(field_type_map, last_name_, NAME_LAST);
|
| - AutofillFieldType type = middle_initial_ ? NAME_MIDDLE_INITIAL : NAME_MIDDLE;
|
| - ok = ok && Add(field_type_map, middle_name_, type);
|
| - return ok;
|
| +FullNameField::FullNameField(const AutofillField* field)
|
| + : field_(field) {
|
| }
|
|
|
| FirstLastNameField* FirstLastNameField::ParseSpecificName(
|
| @@ -65,11 +113,11 @@ FirstLastNameField* FirstLastNameField::ParseSpecificName(
|
| scanner->SaveCursor();
|
|
|
| const AutofillField* next;
|
| - if (ParseText(scanner,
|
| - l10n_util::GetStringUTF16(IDS_AUTOFILL_NAME_SPECIFIC_RE),
|
| - &v->first_name_) &&
|
| - ParseEmptyText(scanner, &next)) {
|
| - if (ParseEmptyText(scanner, &v->last_name_)) {
|
| + if (ParseField(scanner,
|
| + l10n_util::GetStringUTF16(IDS_AUTOFILL_NAME_SPECIFIC_RE),
|
| + &v->first_name_) &&
|
| + ParseEmptyLabel(scanner, &next)) {
|
| + if (ParseEmptyLabel(scanner, &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;
|
| @@ -98,26 +146,28 @@ FirstLastNameField* FirstLastNameField::ParseComponentNames(
|
| // so we match "initials" here (and just fill in a first name there,
|
| // American-style).
|
| // The ".*first$" matches fields ending in "first" (example in sample8.html).
|
| - if (!ParseText(scanner, l10n_util::GetStringUTF16(IDS_AUTOFILL_FIRST_NAME_RE),
|
| - &v->first_name_))
|
| + if (!ParseField(scanner,
|
| + l10n_util::GetStringUTF16(IDS_AUTOFILL_FIRST_NAME_RE),
|
| + &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(scanner,
|
| + if (ParseField(scanner,
|
| l10n_util::GetStringUTF16(IDS_AUTOFILL_MIDDLE_INITIAL_RE),
|
| &v->middle_name_)) {
|
| v->middle_initial_ = true;
|
| } else {
|
| - ParseText(scanner, l10n_util::GetStringUTF16(IDS_AUTOFILL_MIDDLE_NAME_RE),
|
| + ParseField(scanner, l10n_util::GetStringUTF16(IDS_AUTOFILL_MIDDLE_NAME_RE),
|
| &v->middle_name_);
|
| }
|
|
|
| // The ".*last$" matches fields ending in "last" (example in sample8.html).
|
| - if (ParseText(scanner, l10n_util::GetStringUTF16(IDS_AUTOFILL_LAST_NAME_RE),
|
| + if (ParseField(scanner, l10n_util::GetStringUTF16(IDS_AUTOFILL_LAST_NAME_RE),
|
| &v->last_name_)) {
|
| return v.release();
|
| }
|
| @@ -133,14 +183,14 @@ FirstLastNameField* FirstLastNameField::ParseEcmlName(
|
|
|
| string16 pattern = GetEcmlPattern(kEcmlShipToFirstName,
|
| kEcmlBillToFirstName, '|');
|
| - if (!ParseText(scanner, pattern, &field->first_name_))
|
| + if (!ParseField(scanner, pattern, &field->first_name_))
|
| return NULL;
|
|
|
| pattern = GetEcmlPattern(kEcmlShipToMiddleName, kEcmlBillToMiddleName, '|');
|
| - ParseText(scanner, pattern, &field->middle_name_);
|
| + ParseField(scanner, pattern, &field->middle_name_);
|
|
|
| pattern = GetEcmlPattern(kEcmlShipToLastName, kEcmlBillToLastName, '|');
|
| - if (ParseText(scanner, pattern, &field->last_name_))
|
| + if (ParseField(scanner, pattern, &field->last_name_))
|
| return field.release();
|
|
|
| scanner->Rewind();
|
| @@ -164,3 +214,11 @@ FirstLastNameField::FirstLastNameField()
|
| last_name_(NULL),
|
| middle_initial_(false) {
|
| }
|
| +
|
| +bool FirstLastNameField::ClassifyField(FieldTypeMap* map) const {
|
| + bool ok = AddClassification(first_name_, NAME_FIRST, map);
|
| + ok = ok && AddClassification(last_name_, NAME_LAST, map);
|
| + AutofillFieldType type = middle_initial_ ? NAME_MIDDLE_INITIAL : NAME_MIDDLE;
|
| + ok = ok && AddClassification(middle_name_, type, map);
|
| + return ok;
|
| +}
|
|
|