diff options
author | thestig <thestig@chromium.org> | 2015-03-25 22:09:25 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-03-26 05:10:23 +0000 |
commit | e2f6955f2d3c01c6ec05a54a5848b4827201397a (patch) | |
tree | 48df31ca4b1dda0f3e19d8c9b112660c1a8c7734 /components | |
parent | e823d885146e3afea82f31a685bbab560a523e3f (diff) | |
download | chromium_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')
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()); |