summaryrefslogtreecommitdiffstats
path: root/chrome/browser/autofill
diff options
context:
space:
mode:
authorjhawkins@chromium.org <jhawkins@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-12-16 19:40:29 +0000
committerjhawkins@chromium.org <jhawkins@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-12-16 19:40:29 +0000
commit9bd382a74497d0564c5e6feee48c1fea34c43d27 (patch)
tree34fff0a7a729eb15b109d41306f98542e39b62de /chrome/browser/autofill
parentb882d76636d5380e88904446c0c5d81a40cef9a1 (diff)
downloadchromium_src-9bd382a74497d0564c5e6feee48c1fea34c43d27.zip
chromium_src-9bd382a74497d0564c5e6feee48c1fea34c43d27.tar.gz
chromium_src-9bd382a74497d0564c5e6feee48c1fea34c43d27.tar.bz2
Implement CreditCardField, a FormField that matches a credit card field in a form.
BUG=none TEST=none Review URL: http://codereview.chromium.org/502018 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@34736 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/autofill')
-rw-r--r--chrome/browser/autofill/credit_card_field.cc163
-rw-r--r--chrome/browser/autofill/credit_card_field.h52
-rw-r--r--chrome/browser/autofill/form_field.cc5
3 files changed, 219 insertions, 1 deletions
diff --git a/chrome/browser/autofill/credit_card_field.cc b/chrome/browser/autofill/credit_card_field.cc
new file mode 100644
index 0000000..976ea07
--- /dev/null
+++ b/chrome/browser/autofill/credit_card_field.cc
@@ -0,0 +1,163 @@
+// 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/credit_card_field.h"
+
+#include "base/string16.h"
+#include "chrome/browser/autofill/autofill_field.h"
+
+bool CreditCardField::GetFieldInfo(FieldTypeMap* field_type_map) const {
+ return false;
+}
+
+// static
+CreditCardField* CreditCardField::Parse(
+ std::vector<AutoFillField*>::const_iterator* iter,
+ bool is_ecml) {
+ CreditCardField credit_card_field;
+ std::vector<AutoFillField*>::const_iterator q = *iter;
+ string16 pattern;
+
+ // Credit card fields can appear in many different orders.
+ for (int fields = 0; q != *iter; ++fields) {
+ // Sometimes the cardholder field is just labeled "name" (e.g. on test page
+ // Starbucks - Credit card.html). Unfortunately this is a dangerously
+ // generic word to search for, since it will often match a name (not
+ // cardholder name) field before or after credit card fields. So we search
+ // for "name" only when we've already parsed at least one other credit card
+ // field and haven't yet parsed the expiration date (which usually appears
+ // at the end).
+ if (credit_card_field.cardholder_ == NULL) {
+ string16 name_pattern;
+ if (is_ecml) {
+ name_pattern = GetEcmlPattern(kEcmlCardHolder);
+ } else {
+ if (fields == 0 || credit_card_field.expiration_month_) {
+ // at beginning or end
+ name_pattern = ASCIIToUTF16("card holder|name on card");
+ } else {
+ name_pattern = ASCIIToUTF16("name");
+ }
+ }
+
+ if (ParseText(&q, name_pattern, &credit_card_field.cardholder_)) {
+ continue;
+ }
+
+ // As a hard-coded hack for Expedia's billing pages (expedia_checkout.html
+ // and ExpediaBilling.html in our test suite), recognize separate fields
+ // for the cardholder's first and last name if they have the labels "cfnm"
+ // and "clnm".
+ std::vector<AutoFillField*>::const_iterator p = q;
+ AutoFillField* first;
+ if (!is_ecml && ParseText(&p, ASCIIToUTF16("^cfnm"), &first) &&
+ ParseText(&p, ASCIIToUTF16("^clnm"),
+ &credit_card_field.cardholder_last_)) {
+ credit_card_field.cardholder_ = first;
+ q = p;
+ continue;
+ }
+ }
+
+ // TODO(jhawkins): Parse the type select control.
+
+ // We look for a card security code before we look for a credit card number
+ // and match the general term "number". The security code has a plethora of
+ // names; we've seen "verification #", "verification number",
+ // "card identification number" and others listed in the ParseText() call
+ // below.
+ if (is_ecml) {
+ pattern = GetEcmlPattern(kEcmlCardVerification);
+ } else {
+ pattern = ASCIIToUTF16(
+ "verification|card identification|cvn|security code|cvv code|cvc");
+ }
+
+ if (credit_card_field.verification_ == NULL &&
+ ParseText(&q, pattern, &credit_card_field.verification_)) {
+ continue;
+ }
+
+ if (is_ecml)
+ pattern = GetEcmlPattern(kEcmlCardNumber);
+ else
+ pattern = ASCIIToUTF16("number|card #|card no.|card_number");
+
+ if (credit_card_field.number_ == NULL && ParseText(&q, pattern,
+ &credit_card_field.number_)) {
+ continue;
+ }
+
+ // "Expiration date" is the most common label here, but some pages have
+ // "Expires", "exp. date" or "exp. month" and "exp. year". We also look for
+ // the field names ccmonth and ccyear, which appear on at least 4 of our
+ // test pages.
+ //
+ // -> On at least one page (The China Shop2.html) we find only the labels
+ // "month" and "year". So for now we match these words directly; we'll
+ // see if this turns out to be too general.
+ //
+ // Toolbar Bug 51451: indeed, simply matching "month" is too general for
+ // https://rps.fidelity.com/ftgw/rps/RtlCust/CreatePIN/Init.
+ // Instead, we match only words beginning with "month".
+ if (is_ecml)
+ pattern = GetEcmlPattern(kEcmlCardExpireMonth);
+ else
+ pattern = ASCIIToUTF16("expir|exp month|exp date|ccmonth|&month");
+
+ if (!credit_card_field.expiration_month_ ||
+ credit_card_field.expiration_month_->IsEmpty() &&
+ ParseText(&q, pattern, &credit_card_field.expiration_month_)) {
+ if (is_ecml)
+ pattern = GetEcmlPattern(kEcmlCardExpireYear);
+ else
+ pattern = ASCIIToUTF16("|exp|^/|ccyear|year");
+
+ if (!ParseText(&q, pattern, &credit_card_field.expiration_year_)) {
+ return NULL;
+ }
+
+ continue;
+ }
+
+ if (ParseText(&q, GetEcmlPattern(kEcmlCardExpireDay)))
+ continue;
+
+ // Some pages (e.g. ExpediaBilling.html) have a "card description"
+ // field; we parse this field but ignore it.
+ ParseText(&q, ASCIIToUTF16("card description"));
+ }
+
+ // On some pages, the user selects a card type using radio buttons
+ // (e.g. test page Apple Store Billing.html). We can't handle that yet,
+ // so we treat the card type as optional for now.
+ if (credit_card_field.number_ != NULL &&
+ credit_card_field.expiration_month_ &&
+ !credit_card_field.expiration_month_->IsEmpty()) {
+ *iter = q;
+ return new CreditCardField(credit_card_field);
+ }
+
+ return NULL;
+}
+
+CreditCardField::CreditCardField()
+ : cardholder_(NULL),
+ cardholder_last_(NULL),
+ type_(NULL),
+ number_(NULL),
+ verification_(NULL),
+ expiration_month_(NULL),
+ expiration_year_(NULL) {
+}
+
+CreditCardField::CreditCardField(const CreditCardField& field)
+ : cardholder_(field.cardholder_),
+ cardholder_last_(field.cardholder_last_),
+ type_(field.type_),
+ number_(field.number_),
+ verification_(field.verification_),
+ expiration_month_(field.expiration_month_),
+ expiration_year_(field.expiration_year_) {
+}
diff --git a/chrome/browser/autofill/credit_card_field.h b/chrome/browser/autofill/credit_card_field.h
new file mode 100644
index 0000000..4fed417
--- /dev/null
+++ b/chrome/browser/autofill/credit_card_field.h
@@ -0,0 +1,52 @@
+// 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_CREDIT_CARD_FIELD_H_
+#define CHROME_BROWSER_AUTOFILL_CREDIT_CARD_FIELD_H_
+
+#include <vector>
+
+#include "chrome/browser/autofill/form_field.h"
+
+class AutoFillField;
+
+class CreditCardField : public FormField {
+ public:
+ // FormField implementation:
+ virtual bool GetFieldInfo(FieldTypeMap* field_type_map) const;
+ virtual FormFieldType GetFormFieldType() { return kCreditCardType; }
+ virtual int priority() const { return 4; }
+
+ static CreditCardField* Parse(
+ std::vector<AutoFillField*>::const_iterator* iter,
+ bool is_ecml);
+
+ private:
+ CreditCardField();
+ explicit CreditCardField(const CreditCardField& field);
+ void operator=(const CreditCardField&);
+
+ AutoFillField* cardholder_; // Optional.
+
+ // Occasionally pages have separate fields for the cardholder's first and
+ // last names; for such pages cardholder_ holds the first name field and
+ // we store the last name field here.
+ // (We could store an embedded NameField object here, but we don't do so
+ // because the text patterns for matching a cardholder name are different
+ // than for ordinary names, and because cardholder names never have titles,
+ // middle names or suffixes.)
+ AutoFillField* cardholder_last_;
+
+ AutoFillField* type_; // Optional. TODO(jhawkins): Parse the select control.
+ AutoFillField* number_;
+
+ // The 3-digit card verification number; we don't currently fill this.
+ AutoFillField* verification_;
+
+ // Both optional. TODO(jhawkins): Parse the select control.
+ AutoFillField* expiration_month_;
+ AutoFillField* expiration_year_;
+};
+
+#endif // CHROME_BROWSER_AUTOFILL_CREDIT_CARD_FIELD_H_
diff --git a/chrome/browser/autofill/form_field.cc b/chrome/browser/autofill/form_field.cc
index 1ab2c88..ec15120 100644
--- a/chrome/browser/autofill/form_field.cc
+++ b/chrome/browser/autofill/form_field.cc
@@ -6,6 +6,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/phone_field.h"
#include "third_party/WebKit/WebKit/chromium/public/WebRegularExpression.h"
#include "third_party/WebKit/WebKit/chromium/public/WebString.h"
@@ -72,9 +73,11 @@ FormField* FormField::ParseFormField(
field = AddressField::Parse(iter, is_ecml);
if (field != NULL)
return field;
+ field = CreditCardField::Parse(iter, is_ecml);
+ if (field != NULL)
+ return field;
// TODO(jhawkins):
- // - CreditCardField
// - NameField
return NULL;