summaryrefslogtreecommitdiffstats
path: root/components
diff options
context:
space:
mode:
authorthestig <thestig@chromium.org>2015-03-25 22:09:25 -0700
committerCommit bot <commit-bot@chromium.org>2015-03-26 05:10:23 +0000
commite2f6955f2d3c01c6ec05a54a5848b4827201397a (patch)
tree48df31ca4b1dda0f3e19d8c9b112660c1a8c7734 /components
parente823d885146e3afea82f31a685bbab560a523e3f (diff)
downloadchromium_src-e2f6955f2d3c01c6ec05a54a5848b4827201397a.zip
chromium_src-e2f6955f2d3c01c6ec05a54a5848b4827201397a.tar.gz
chromium_src-e2f6955f2d3c01c6ec05a54a5848b4827201397a.tar.bz2
Autofill: Better recognize credit card type fields.
BUG=464002, 466685, 469012 Review URL: https://codereview.chromium.org/1030073003 Cr-Commit-Position: refs/heads/master@{#322325}
Diffstat (limited to 'components')
-rw-r--r--components/autofill/core/browser/autofill_field.cc52
-rw-r--r--components/autofill/core/browser/autofill_field.h7
-rw-r--r--components/autofill/core/browser/autofill_regex_constants.cc.utf84
-rw-r--r--components/autofill/core/browser/credit_card_field.cc38
-rw-r--r--components/autofill/core/browser/credit_card_field.h4
-rw-r--r--components/autofill/core/browser/credit_card_field_unittest.cc11
6 files changed, 74 insertions, 42 deletions
diff --git a/components/autofill/core/browser/autofill_field.cc b/components/autofill/core/browser/autofill_field.cc
index 75a0d0a..db3046a 100644
--- a/components/autofill/core/browser/autofill_field.cc
+++ b/components/autofill/core/browser/autofill_field.cc
@@ -248,26 +248,10 @@ bool FillYearSelectControl(const base::string16& value,
// given |field|.
bool FillCreditCardTypeSelectControl(const base::string16& value,
FormFieldData* field) {
- // Try stripping off spaces.
- base::string16 value_stripped;
- base::RemoveChars(base::StringToLowerASCII(value), base::kWhitespaceUTF16,
- &value_stripped);
-
- for (size_t i = 0; i < field->option_values.size(); ++i) {
- base::string16 option_value_lowercase;
- base::RemoveChars(base::StringToLowerASCII(field->option_values[i]),
- base::kWhitespaceUTF16, &option_value_lowercase);
- base::string16 option_contents_lowercase;
- base::RemoveChars(base::StringToLowerASCII(field->option_contents[i]),
- base::kWhitespaceUTF16, &option_contents_lowercase);
-
- // Perform a case-insensitive comparison; but fill the form with the
- // original text, not the lowercased version.
- if (value_stripped == option_value_lowercase ||
- value_stripped == option_contents_lowercase) {
- field->value = field->option_values[i];
- return true;
- }
+ size_t idx;
+ if (AutofillField::FindValueInSelectControl(*field, value, &idx)) {
+ field->value = field->option_values[idx];
+ return true;
}
// For American Express, also try filling as "AmEx".
@@ -541,4 +525,32 @@ base::string16 AutofillField::GetPhoneNumberValue(
return number;
}
+// static
+bool AutofillField::FindValueInSelectControl(const FormFieldData& field,
+ const base::string16& value,
+ size_t* index) {
+ // TODO(thestig): Improve this. See http://crbug.com/470726)
+ // Try stripping off spaces.
+ base::string16 value_stripped;
+ base::RemoveChars(base::StringToLowerASCII(value), base::kWhitespaceUTF16,
+ &value_stripped);
+ for (size_t i = 0; i < field.option_values.size(); ++i) {
+ base::string16 option_value_lowercase;
+ base::RemoveChars(base::StringToLowerASCII(field.option_values[i]),
+ base::kWhitespaceUTF16, &option_value_lowercase);
+ base::string16 option_contents_lowercase;
+ base::RemoveChars(base::StringToLowerASCII(field.option_contents[i]),
+ base::kWhitespaceUTF16, &option_contents_lowercase);
+
+ // Perform a case-insensitive comparison.
+ if (value_stripped == option_value_lowercase ||
+ value_stripped == option_contents_lowercase) {
+ if (index)
+ *index = i;
+ return true;
+ }
+ }
+ return false;
+}
+
} // namespace autofill
diff --git a/components/autofill/core/browser/autofill_field.h b/components/autofill/core/browser/autofill_field.h
index 1c79bb2..19a26c2 100644
--- a/components/autofill/core/browser/autofill_field.h
+++ b/components/autofill/core/browser/autofill_field.h
@@ -89,6 +89,13 @@ class AutofillField : public FormFieldData {
const base::string16& number,
const FormFieldData& field_data);
+ // Returns true if the select |field| contains an option that matches |value|.
+ // If the return value is true and |index| is non-NULL, write the index of the
+ // matching option into |index|.
+ static bool FindValueInSelectControl(const FormFieldData& field,
+ const base::string16& value,
+ size_t* index);
+
private:
// The unique name of this field, generated by Autofill.
base::string16 unique_name_;
diff --git a/components/autofill/core/browser/autofill_regex_constants.cc.utf8 b/components/autofill/core/browser/autofill_regex_constants.cc.utf8
index 7339f8a..22cc386 100644
--- a/components/autofill/core/browser/autofill_regex_constants.cc.utf8
+++ b/components/autofill/core/browser/autofill_regex_constants.cc.utf8
@@ -149,8 +149,6 @@ const char kCardCvcRe[] =
"verification|card identification|security code|card code"
"|cvn|cvv|cvc|csc|cvd|cid|ccv"
"|\\bcid\\b";
-const char kCardTypeRe[] =
- "(card|cc|payment).?type|payment.?method|card.*brand";
// "Expiration date" is the most common label here, but some pages have
// "Expires", "exp. date" or "exp. month" and "exp. year". We also look
@@ -197,8 +195,6 @@ const char kExpirationDateRe[] =
"|有効期限" // ja-JP
"|validade" // pt-BR, pt-PT
"|Срок действия карты"; // ru
-const char kCardIgnoredRe[] =
- "^card";
const char kGiftCardRe[] =
"gift.?card";
diff --git a/components/autofill/core/browser/credit_card_field.cc b/components/autofill/core/browser/credit_card_field.cc
index a9fe79e..0e8d25d 100644
--- a/components/autofill/core/browser/credit_card_field.cc
+++ b/components/autofill/core/browser/credit_card_field.cc
@@ -18,6 +18,8 @@
#include "components/autofill/core/browser/autofill_regexes.h"
#include "components/autofill/core/browser/autofill_scanner.h"
#include "components/autofill/core/browser/field_types.h"
+#include "grit/components_strings.h"
+#include "ui/base/l10n/l10n_util.h"
namespace autofill {
@@ -60,7 +62,7 @@ scoped_ptr<FormField> CreditCardField::Parse(AutofillScanner* scanner) {
// Credit card fields can appear in many different orders.
// We loop until no more credit card related fields are found, see |break| at
- // bottom of the loop.
+ // the bottom of the loop.
for (int fields = 0; !scanner->IsEnd(); ++fields) {
// Ignore gift card fields.
if (ParseField(scanner, base::UTF8ToUTF16(kGiftCardRe), nullptr))
@@ -89,11 +91,10 @@ scoped_ptr<FormField> CreditCardField::Parse(AutofillScanner* scanner) {
}
// Check for a credit card type (Visa, MasterCard, etc.) field.
- if (!credit_card_field->type_ &&
- ParseFieldSpecifics(scanner,
- base::UTF8ToUTF16(kCardTypeRe),
- MATCH_DEFAULT | MATCH_SELECT,
- &credit_card_field->type_)) {
+ // All CC type fields encountered so far have been of type select.
+ if (!credit_card_field->type_ && LikelyCardTypeSelectField(scanner)) {
+ credit_card_field->type_ = scanner->Cursor();
+ scanner->Advance();
continue;
}
@@ -150,14 +151,6 @@ scoped_ptr<FormField> CreditCardField::Parse(AutofillScanner* scanner) {
return nullptr;
}
- // Some pages (e.g. ExpediaBilling.html) have a "card description"
- // field; we parse this field but ignore it.
- // We also ignore any other fields within a credit card block that
- // start with "card", under the assumption that they are related to
- // the credit card section being processed but are uninteresting to us.
- if (ParseField(scanner, base::UTF8ToUTF16(kCardIgnoredRe), nullptr))
- continue;
-
break;
}
@@ -247,6 +240,23 @@ bool CreditCardField::LikelyCardYearSelectField(AutofillScanner* scanner) {
FindConsecutiveStrings(years_to_check, field->option_contents));
}
+// static
+bool CreditCardField::LikelyCardTypeSelectField(AutofillScanner* scanner) {
+ if (scanner->IsEnd())
+ return false;
+
+ AutofillField* field = scanner->Cursor();
+ if (!MatchesFormControlType(field->form_control_type, MATCH_SELECT))
+ return false;
+
+ return AutofillField::FindValueInSelectControl(
+ *field, l10n_util::GetStringUTF16(IDS_AUTOFILL_CC_VISA),
+ nullptr) ||
+ AutofillField::FindValueInSelectControl(
+ *field, l10n_util::GetStringUTF16(IDS_AUTOFILL_CC_MASTERCARD),
+ nullptr);
+}
+
CreditCardField::CreditCardField()
: cardholder_(nullptr),
cardholder_last_(nullptr),
diff --git a/components/autofill/core/browser/credit_card_field.h b/components/autofill/core/browser/credit_card_field.h
index 2d8ba6f..0f94f3edd 100644
--- a/components/autofill/core/browser/credit_card_field.h
+++ b/components/autofill/core/browser/credit_card_field.h
@@ -40,6 +40,10 @@ class CreditCardField : public FormField {
// the next few years.
static bool LikelyCardYearSelectField(AutofillScanner* scanner);
+ // Returns true if |scanner| points to a <select> field that contains credit
+ // card type options.
+ static bool LikelyCardTypeSelectField(AutofillScanner* scanner);
+
CreditCardField();
// Parses the expiration month/year/date fields. Returns true if it finds
diff --git a/components/autofill/core/browser/credit_card_field_unittest.cc b/components/autofill/core/browser/credit_card_field_unittest.cc
index 3e4f21c..56ed3ae 100644
--- a/components/autofill/core/browser/credit_card_field_unittest.cc
+++ b/components/autofill/core/browser/credit_card_field_unittest.cc
@@ -117,10 +117,6 @@ TEST_F(CreditCardFieldTest, ParseFullCreditCard) {
FormFieldData field;
field.form_control_type = "text";
- field.label = ASCIIToUTF16("Card Type");
- field.name = ASCIIToUTF16("card_type");
- list_.push_back(new AutofillField(field, ASCIIToUTF16("type")));
-
field.label = ASCIIToUTF16("Name on Card");
field.name = ASCIIToUTF16("name_on_card");
list_.push_back(new AutofillField(field, ASCIIToUTF16("name")));
@@ -141,6 +137,13 @@ TEST_F(CreditCardFieldTest, ParseFullCreditCard) {
field.name = ASCIIToUTF16("verification");
list_.push_back(new AutofillField(field, ASCIIToUTF16("cvc")));
+ field.form_control_type = "select-one";
+ field.label = ASCIIToUTF16("Card Type");
+ field.name = ASCIIToUTF16("card_type");
+ field.option_contents.push_back(ASCIIToUTF16("visa"));
+ field.option_values.push_back(ASCIIToUTF16("visa"));
+ list_.push_back(new AutofillField(field, ASCIIToUTF16("type")));
+
Parse();
ASSERT_NE(nullptr, field_.get());
EXPECT_TRUE(ClassifyField());