summaryrefslogtreecommitdiffstats
path: root/chrome/browser/autofill/name_field.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/browser/autofill/name_field.cc')
-rw-r--r--chrome/browser/autofill/name_field.cc157
1 files changed, 157 insertions, 0 deletions
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_) {
+}