OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "components/autofill/browser/form_group.h" | 5 #include "components/autofill/browser/form_group.h" |
6 | 6 |
7 #include <algorithm> | |
8 #include <iterator> | |
9 | |
10 #include "base/basictypes.h" | |
11 #include "base/logging.h" | |
12 #include "base/strings/string_number_conversions.h" | |
13 #include "base/utf_string_conversions.h" | |
14 #include "components/autofill/browser/autofill_country.h" | |
15 #include "components/autofill/browser/state_names.h" | |
16 #include "components/autofill/browser/validation.h" | |
17 #include "components/autofill/common/form_field_data.h" | |
18 #include "grit/generated_resources.h" | |
19 #include "ui/base/l10n/l10n_util.h" | |
20 | |
21 namespace autofill { | 7 namespace autofill { |
22 namespace { | |
23 | |
24 const char* const kMonthsAbbreviated[] = { | |
25 NULL, // Padding so index 1 = month 1 = January. | |
26 "Jan", "Feb", "Mar", "Apr", "May", "Jun", | |
27 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", | |
28 }; | |
29 | |
30 const char* const kMonthsFull[] = { | |
31 NULL, // Padding so index 1 = month 1 = January. | |
32 "January", "February", "March", "April", "May", "June", | |
33 "July", "August", "September", "October", "November", "December", | |
34 }; | |
35 | |
36 const char* const kMonthsNumeric[] = { | |
37 NULL, // Padding so index 1 = month 1 = January. | |
38 "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", | |
39 }; | |
40 | |
41 // Returns true if the value was successfully set, meaning |value| was found in | |
42 // the list of select options in |field|. | |
43 bool SetSelectControlValue(const base::string16& value, | |
44 FormFieldData* field) { | |
45 base::string16 value_lowercase = StringToLowerASCII(value); | |
46 | |
47 DCHECK_EQ(field->option_values.size(), field->option_contents.size()); | |
48 for (size_t i = 0; i < field->option_values.size(); ++i) { | |
49 if (value_lowercase == StringToLowerASCII(field->option_values[i]) || | |
50 value_lowercase == StringToLowerASCII(field->option_contents[i])) { | |
51 field->value = field->option_values[i]; | |
52 return true; | |
53 } | |
54 } | |
55 | |
56 return false; | |
57 } | |
58 | |
59 bool FillStateSelectControl(const base::string16& value, | |
60 FormFieldData* field) { | |
61 base::string16 abbreviation = value; | |
62 base::string16 full = state_names::GetNameForAbbreviation(value); | |
63 if (full.empty()) { | |
64 abbreviation = state_names::GetAbbreviationForName(value); | |
65 full = value; | |
66 } | |
67 | |
68 // Try the abbreviation first. | |
69 if (!abbreviation.empty() && SetSelectControlValue(abbreviation, field)) | |
70 return true; | |
71 | |
72 return !full.empty() && SetSelectControlValue(full, field); | |
73 } | |
74 | |
75 bool FillExpirationMonthSelectControl(const base::string16& value, | |
76 FormFieldData* field) { | |
77 int index = 0; | |
78 if (!base::StringToInt(value, &index) || | |
79 index <= 0 || | |
80 static_cast<size_t>(index) >= arraysize(kMonthsFull)) | |
81 return false; | |
82 | |
83 bool filled = | |
84 SetSelectControlValue(ASCIIToUTF16(kMonthsAbbreviated[index]), field) || | |
85 SetSelectControlValue(ASCIIToUTF16(kMonthsFull[index]), field) || | |
86 SetSelectControlValue(ASCIIToUTF16(kMonthsNumeric[index]), field); | |
87 return filled; | |
88 } | |
89 | |
90 // Try to fill a credit card type |value| (Visa, MasterCard, etc.) into the | |
91 // given |field|. | |
92 bool FillCreditCardTypeSelectControl(const base::string16& value, | |
93 FormFieldData* field) { | |
94 // Try stripping off spaces. | |
95 base::string16 value_stripped; | |
96 RemoveChars(StringToLowerASCII(value), kWhitespaceUTF16, &value_stripped); | |
97 | |
98 for (size_t i = 0; i < field->option_values.size(); ++i) { | |
99 base::string16 option_value_lowercase; | |
100 RemoveChars(StringToLowerASCII(field->option_values[i]), kWhitespaceUTF16, | |
101 &option_value_lowercase); | |
102 base::string16 option_contents_lowercase; | |
103 RemoveChars(StringToLowerASCII(field->option_contents[i]), kWhitespaceUTF16, | |
104 &option_contents_lowercase); | |
105 | |
106 // Perform a case-insensitive comparison; but fill the form with the | |
107 // original text, not the lowercased version. | |
108 if (value_stripped == option_value_lowercase || | |
109 value_stripped == option_contents_lowercase) { | |
110 field->value = field->option_values[i]; | |
111 return true; | |
112 } | |
113 } | |
114 | |
115 // For American Express, also try filling as "AmEx". | |
116 if (value == l10n_util::GetStringUTF16(IDS_AUTOFILL_CC_AMEX)) | |
117 return FillCreditCardTypeSelectControl(ASCIIToUTF16("AmEx"), field); | |
118 | |
119 return false; | |
120 } | |
121 | |
122 } // namespace | |
123 | |
124 std::string FormGroup::GetGUID() const { | |
125 NOTREACHED(); | |
126 return std::string(); | |
127 } | |
128 | 8 |
129 void FormGroup::GetMatchingTypes(const base::string16& text, | 9 void FormGroup::GetMatchingTypes(const base::string16& text, |
130 const std::string& app_locale, | 10 const std::string& app_locale, |
131 FieldTypeSet* matching_types) const { | 11 FieldTypeSet* matching_types) const { |
132 if (text.empty()) { | 12 if (text.empty()) { |
133 matching_types->insert(EMPTY_TYPE); | 13 matching_types->insert(EMPTY_TYPE); |
134 return; | 14 return; |
135 } | 15 } |
136 | 16 |
137 FieldTypeSet types; | 17 FieldTypeSet types; |
(...skipping 24 matching lines...) Expand all Loading... |
162 return GetRawInfo(type); | 42 return GetRawInfo(type); |
163 } | 43 } |
164 | 44 |
165 bool FormGroup::SetInfo(AutofillFieldType type, | 45 bool FormGroup::SetInfo(AutofillFieldType type, |
166 const base::string16& value, | 46 const base::string16& value, |
167 const std::string& app_locale) { | 47 const std::string& app_locale) { |
168 SetRawInfo(type, value); | 48 SetRawInfo(type, value); |
169 return true; | 49 return true; |
170 } | 50 } |
171 | 51 |
172 void FormGroup::FillFormField(const AutofillField& field, | |
173 size_t variant, | |
174 const std::string& app_locale, | |
175 FormFieldData* field_data) const { | |
176 NOTREACHED(); | |
177 } | |
178 | |
179 void FormGroup::FillSelectControl(AutofillFieldType type, | |
180 const std::string& app_locale, | |
181 FormFieldData* field) const { | |
182 DCHECK(field); | |
183 DCHECK_EQ("select-one", field->form_control_type); | |
184 DCHECK_EQ(field->option_values.size(), field->option_contents.size()); | |
185 | |
186 base::string16 field_text = GetInfo(type, app_locale); | |
187 base::string16 field_text_lower = StringToLowerASCII(field_text); | |
188 if (field_text.empty()) | |
189 return; | |
190 | |
191 base::string16 value; | |
192 for (size_t i = 0; i < field->option_values.size(); ++i) { | |
193 if (field_text == field->option_values[i] || | |
194 field_text == field->option_contents[i]) { | |
195 // An exact match, use it. | |
196 value = field->option_values[i]; | |
197 break; | |
198 } | |
199 | |
200 if (field_text_lower == StringToLowerASCII(field->option_values[i]) || | |
201 field_text_lower == StringToLowerASCII(field->option_contents[i])) { | |
202 // A match, but not in the same case. Save it in case an exact match is | |
203 // not found. | |
204 value = field->option_values[i]; | |
205 } | |
206 } | |
207 | |
208 if (!value.empty()) { | |
209 field->value = value; | |
210 return; | |
211 } | |
212 | |
213 if (type == ADDRESS_HOME_STATE || type == ADDRESS_BILLING_STATE) { | |
214 FillStateSelectControl(field_text, field); | |
215 } else if (type == ADDRESS_HOME_COUNTRY || type == ADDRESS_BILLING_COUNTRY) { | |
216 FillCountrySelectControl(app_locale, field); | |
217 } else if (type == CREDIT_CARD_EXP_MONTH) { | |
218 FillExpirationMonthSelectControl(field_text, field); | |
219 } else if (type == CREDIT_CARD_EXP_4_DIGIT_YEAR) { | |
220 // Attempt to fill the year as a 2-digit year. This compensates for the | |
221 // fact that our heuristics do not always correctly detect when a website | |
222 // requests a 2-digit rather than a 4-digit year. | |
223 FillSelectControl(CREDIT_CARD_EXP_2_DIGIT_YEAR, app_locale, field); | |
224 } else if (type == CREDIT_CARD_TYPE) { | |
225 FillCreditCardTypeSelectControl(field_text, field); | |
226 } | |
227 } | |
228 | |
229 bool FormGroup::FillCountrySelectControl(const std::string& app_locale, | |
230 FormFieldData* field_data) const { | |
231 return false; | |
232 } | |
233 | |
234 } // namespace autofill | 52 } // namespace autofill |
OLD | NEW |