diff options
author | isherman@chromium.org <isherman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-04-19 03:29:55 +0000 |
---|---|---|
committer | isherman@chromium.org <isherman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-04-19 03:29:55 +0000 |
commit | 8b0a918e40699ea7732ab1da7c5f7a6e2dbad01a (patch) | |
tree | 220452a550381ed1bf80ebb6dbaaf45aaad78dc2 /components/autofill/browser/autofill_data_model.cc | |
parent | b920e7d74733aa20587ca620efedd4088c4bff3d (diff) | |
download | chromium_src-8b0a918e40699ea7732ab1da7c5f7a6e2dbad01a.zip chromium_src-8b0a918e40699ea7732ab1da7c5f7a6e2dbad01a.tar.gz chromium_src-8b0a918e40699ea7732ab1da7c5f7a6e2dbad01a.tar.bz2 |
[Autofill] Split off AutofillDataModel as a subclass of FormData.
BUG=170401, 231029
Review URL: https://chromiumcodereview.appspot.com/14096009
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@195071 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'components/autofill/browser/autofill_data_model.cc')
-rw-r--r-- | components/autofill/browser/autofill_data_model.cc | 182 |
1 files changed, 182 insertions, 0 deletions
diff --git a/components/autofill/browser/autofill_data_model.cc b/components/autofill/browser/autofill_data_model.cc new file mode 100644 index 0000000..501184d --- /dev/null +++ b/components/autofill/browser/autofill_data_model.cc @@ -0,0 +1,182 @@ +// Copyright 2013 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 "components/autofill/browser/autofill_data_model.h" + +#include "base/basictypes.h" +#include "base/logging.h" +#include "base/string_util.h" +#include "base/strings/string_number_conversions.h" +#include "base/utf_string_conversions.h" +#include "components/autofill/browser/autofill_country.h" +#include "components/autofill/browser/autofill_field.h" +#include "components/autofill/browser/state_names.h" +#include "components/autofill/browser/validation.h" +#include "components/autofill/common/form_field_data.h" +#include "grit/generated_resources.h" +#include "ui/base/l10n/l10n_util.h" + +namespace autofill { +namespace { + +const char* const kMonthsAbbreviated[] = { + NULL, // Padding so index 1 = month 1 = January. + "Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", +}; + +const char* const kMonthsFull[] = { + NULL, // Padding so index 1 = month 1 = January. + "January", "February", "March", "April", "May", "June", + "July", "August", "September", "October", "November", "December", +}; + +const char* const kMonthsNumeric[] = { + NULL, // Padding so index 1 = month 1 = January. + "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", +}; + +// Returns true if the value was successfully set, meaning |value| was found in +// the list of select options in |field|. +bool SetSelectControlValue(const base::string16& value, + FormFieldData* field) { + base::string16 value_lowercase = StringToLowerASCII(value); + + DCHECK_EQ(field->option_values.size(), field->option_contents.size()); + for (size_t i = 0; i < field->option_values.size(); ++i) { + if (value_lowercase == StringToLowerASCII(field->option_values[i]) || + value_lowercase == StringToLowerASCII(field->option_contents[i])) { + field->value = field->option_values[i]; + return true; + } + } + + return false; +} + +bool FillStateSelectControl(const base::string16& value, + FormFieldData* field) { + base::string16 abbreviation = value; + base::string16 full = state_names::GetNameForAbbreviation(value); + if (full.empty()) { + abbreviation = state_names::GetAbbreviationForName(value); + full = value; + } + + // Try the abbreviation first. + if (!abbreviation.empty() && SetSelectControlValue(abbreviation, field)) + return true; + + return !full.empty() && SetSelectControlValue(full, field); +} + +bool FillExpirationMonthSelectControl(const base::string16& value, + FormFieldData* field) { + int index = 0; + if (!base::StringToInt(value, &index) || + index <= 0 || + static_cast<size_t>(index) >= arraysize(kMonthsFull)) + return false; + + bool filled = + SetSelectControlValue(ASCIIToUTF16(kMonthsAbbreviated[index]), field) || + SetSelectControlValue(ASCIIToUTF16(kMonthsFull[index]), field) || + SetSelectControlValue(ASCIIToUTF16(kMonthsNumeric[index]), field); + return filled; +} + +// Try to fill a credit card type |value| (Visa, MasterCard, etc.) into the +// given |field|. +bool FillCreditCardTypeSelectControl(const base::string16& value, + FormFieldData* field) { + // Try stripping off spaces. + base::string16 value_stripped; + RemoveChars(StringToLowerASCII(value), kWhitespaceUTF16, &value_stripped); + + for (size_t i = 0; i < field->option_values.size(); ++i) { + base::string16 option_value_lowercase; + RemoveChars(StringToLowerASCII(field->option_values[i]), kWhitespaceUTF16, + &option_value_lowercase); + base::string16 option_contents_lowercase; + RemoveChars(StringToLowerASCII(field->option_contents[i]), 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; + } + } + + // For American Express, also try filling as "AmEx". + if (value == l10n_util::GetStringUTF16(IDS_AUTOFILL_CC_AMEX)) + return FillCreditCardTypeSelectControl(ASCIIToUTF16("AmEx"), field); + + return false; +} + +} // namespace + +AutofillDataModel::AutofillDataModel(const std::string& guid) : guid_(guid) {} +AutofillDataModel::~AutofillDataModel() {} + +void AutofillDataModel::FillSelectControl(AutofillFieldType type, + const std::string& app_locale, + FormFieldData* field) const { + DCHECK(field); + DCHECK_EQ("select-one", field->form_control_type); + DCHECK_EQ(field->option_values.size(), field->option_contents.size()); + + base::string16 field_text = GetInfo(type, app_locale); + base::string16 field_text_lower = StringToLowerASCII(field_text); + if (field_text.empty()) + return; + + base::string16 value; + for (size_t i = 0; i < field->option_values.size(); ++i) { + if (field_text == field->option_values[i] || + field_text == field->option_contents[i]) { + // An exact match, use it. + value = field->option_values[i]; + break; + } + + if (field_text_lower == StringToLowerASCII(field->option_values[i]) || + field_text_lower == StringToLowerASCII(field->option_contents[i])) { + // A match, but not in the same case. Save it in case an exact match is + // not found. + value = field->option_values[i]; + } + } + + if (!value.empty()) { + field->value = value; + return; + } + + if (type == ADDRESS_HOME_STATE || type == ADDRESS_BILLING_STATE) { + FillStateSelectControl(field_text, field); + } else if (type == ADDRESS_HOME_COUNTRY || type == ADDRESS_BILLING_COUNTRY) { + FillCountrySelectControl(app_locale, field); + } else if (type == CREDIT_CARD_EXP_MONTH) { + FillExpirationMonthSelectControl(field_text, field); + } else if (type == CREDIT_CARD_EXP_4_DIGIT_YEAR) { + // Attempt to fill the year as a 2-digit year. This compensates for the + // fact that our heuristics do not always correctly detect when a website + // requests a 2-digit rather than a 4-digit year. + FillSelectControl(CREDIT_CARD_EXP_2_DIGIT_YEAR, app_locale, field); + } else if (type == CREDIT_CARD_TYPE) { + FillCreditCardTypeSelectControl(field_text, field); + } +} + +bool AutofillDataModel::FillCountrySelectControl( + const std::string& app_locale, + FormFieldData* field_data) const { + return false; +} + +} // namespace autofill |