| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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/core/browser/autofill_field.h" | 5 #include "components/autofill/core/browser/autofill_field.h" |
| 6 | 6 |
| 7 #include "base/logging.h" | 7 #include "base/logging.h" |
| 8 #include "base/sha1.h" | 8 #include "base/sha1.h" |
| 9 #include "base/strings/string_number_conversions.h" | 9 #include "base/strings/string_number_conversions.h" |
| 10 #include "base/strings/string_split.h" | 10 #include "base/strings/string_split.h" |
| (...skipping 25 matching lines...) Expand all Loading... |
| 36 const char* const kMonthsFull[] = { | 36 const char* const kMonthsFull[] = { |
| 37 NULL, // Padding so index 1 = month 1 = January. | 37 NULL, // Padding so index 1 = month 1 = January. |
| 38 "January", "February", "March", "April", "May", "June", | 38 "January", "February", "March", "April", "May", "June", |
| 39 "July", "August", "September", "October", "November", "December", | 39 "July", "August", "September", "October", "November", "December", |
| 40 }; | 40 }; |
| 41 | 41 |
| 42 // Returns true if the value was successfully set, meaning |value| was found in | 42 // Returns true if the value was successfully set, meaning |value| was found in |
| 43 // the list of select options in |field|. | 43 // the list of select options in |field|. |
| 44 bool SetSelectControlValue(const base::string16& value, | 44 bool SetSelectControlValue(const base::string16& value, |
| 45 FormFieldData* field) { | 45 FormFieldData* field) { |
| 46 base::string16 value_lowercase = StringToLowerASCII(value); | 46 base::string16 value_lowercase = base::StringToLowerASCII(value); |
| 47 | 47 |
| 48 DCHECK_EQ(field->option_values.size(), field->option_contents.size()); | 48 DCHECK_EQ(field->option_values.size(), field->option_contents.size()); |
| 49 base::string16 best_match; | 49 base::string16 best_match; |
| 50 for (size_t i = 0; i < field->option_values.size(); ++i) { | 50 for (size_t i = 0; i < field->option_values.size(); ++i) { |
| 51 if (value == field->option_values[i] || | 51 if (value == field->option_values[i] || |
| 52 value == field->option_contents[i]) { | 52 value == field->option_contents[i]) { |
| 53 // An exact match, use it. | 53 // An exact match, use it. |
| 54 best_match = field->option_values[i]; | 54 best_match = field->option_values[i]; |
| 55 break; | 55 break; |
| 56 } | 56 } |
| 57 | 57 |
| 58 if (value_lowercase == StringToLowerASCII(field->option_values[i]) || | 58 if (value_lowercase == base::StringToLowerASCII(field->option_values[i]) || |
| 59 value_lowercase == StringToLowerASCII(field->option_contents[i])) { | 59 value_lowercase == |
| 60 base::StringToLowerASCII(field->option_contents[i])) { |
| 60 // A match, but not in the same case. Save it in case an exact match is | 61 // A match, but not in the same case. Save it in case an exact match is |
| 61 // not found. | 62 // not found. |
| 62 best_match = field->option_values[i]; | 63 best_match = field->option_values[i]; |
| 63 } | 64 } |
| 64 } | 65 } |
| 65 | 66 |
| 66 if (best_match.empty()) | 67 if (best_match.empty()) |
| 67 return false; | 68 return false; |
| 68 | 69 |
| 69 field->value = best_match; | 70 field->value = best_match; |
| 70 return true; | 71 return true; |
| 71 } | 72 } |
| 72 | 73 |
| 73 // Like SetSelectControlValue, but searches within the field values and options | 74 // Like SetSelectControlValue, but searches within the field values and options |
| 74 // for |value|. For example, "NC - North Carolina" would match "north carolina". | 75 // for |value|. For example, "NC - North Carolina" would match "north carolina". |
| 75 bool SetSelectControlValueSubstringMatch(const base::string16& value, | 76 bool SetSelectControlValueSubstringMatch(const base::string16& value, |
| 76 FormFieldData* field) { | 77 FormFieldData* field) { |
| 77 base::string16 value_lowercase = StringToLowerASCII(value); | 78 base::string16 value_lowercase = base::StringToLowerASCII(value); |
| 78 DCHECK_EQ(field->option_values.size(), field->option_contents.size()); | 79 DCHECK_EQ(field->option_values.size(), field->option_contents.size()); |
| 79 int best_match = -1; | 80 int best_match = -1; |
| 80 | 81 |
| 81 for (size_t i = 0; i < field->option_values.size(); ++i) { | 82 for (size_t i = 0; i < field->option_values.size(); ++i) { |
| 82 if (StringToLowerASCII(field->option_values[i]).find(value_lowercase) != | 83 if (base::StringToLowerASCII(field->option_values[i]).find(value_lowercase)
!= |
| 83 std::string::npos || | 84 std::string::npos || |
| 84 StringToLowerASCII(field->option_contents[i]).find(value_lowercase) != | 85 base::StringToLowerASCII(field->option_contents[i]).find( |
| 85 std::string::npos) { | 86 value_lowercase) != std::string::npos) { |
| 86 // The best match is the shortest one. | 87 // The best match is the shortest one. |
| 87 if (best_match == -1 || | 88 if (best_match == -1 || |
| 88 field->option_values[best_match].size() > | 89 field->option_values[best_match].size() > |
| 89 field->option_values[i].size()) { | 90 field->option_values[i].size()) { |
| 90 best_match = i; | 91 best_match = i; |
| 91 } | 92 } |
| 92 } | 93 } |
| 93 } | 94 } |
| 94 | 95 |
| 95 if (best_match >= 0) { | 96 if (best_match >= 0) { |
| 96 field->value = field->option_values[best_match]; | 97 field->value = field->option_values[best_match]; |
| 97 return true; | 98 return true; |
| 98 } | 99 } |
| 99 | 100 |
| 100 return false; | 101 return false; |
| 101 } | 102 } |
| 102 | 103 |
| 103 // Like SetSelectControlValue, but searches within the field values and options | 104 // Like SetSelectControlValue, but searches within the field values and options |
| 104 // for |value|. First it tokenizes the options, then tries to match against | 105 // for |value|. First it tokenizes the options, then tries to match against |
| 105 // tokens. For example, "NC - North Carolina" would match "nc" but not "ca". | 106 // tokens. For example, "NC - North Carolina" would match "nc" but not "ca". |
| 106 bool SetSelectControlValueTokenMatch(const base::string16& value, | 107 bool SetSelectControlValueTokenMatch(const base::string16& value, |
| 107 FormFieldData* field) { | 108 FormFieldData* field) { |
| 108 base::string16 value_lowercase = StringToLowerASCII(value); | 109 base::string16 value_lowercase = base::StringToLowerASCII(value); |
| 109 std::vector<base::string16> tokenized; | 110 std::vector<base::string16> tokenized; |
| 110 DCHECK_EQ(field->option_values.size(), field->option_contents.size()); | 111 DCHECK_EQ(field->option_values.size(), field->option_contents.size()); |
| 111 | 112 |
| 112 for (size_t i = 0; i < field->option_values.size(); ++i) { | 113 for (size_t i = 0; i < field->option_values.size(); ++i) { |
| 113 base::SplitStringAlongWhitespace( | 114 base::SplitStringAlongWhitespace( |
| 114 StringToLowerASCII(field->option_values[i]), &tokenized); | 115 base::StringToLowerASCII(field->option_values[i]), &tokenized); |
| 115 if (std::find(tokenized.begin(), tokenized.end(), value_lowercase) != | 116 if (std::find(tokenized.begin(), tokenized.end(), value_lowercase) != |
| 116 tokenized.end()) { | 117 tokenized.end()) { |
| 117 field->value = field->option_values[i]; | 118 field->value = field->option_values[i]; |
| 118 return true; | 119 return true; |
| 119 } | 120 } |
| 120 | 121 |
| 121 base::SplitStringAlongWhitespace( | 122 base::SplitStringAlongWhitespace( |
| 122 StringToLowerASCII(field->option_contents[i]), &tokenized); | 123 base::StringToLowerASCII(field->option_contents[i]), &tokenized); |
| 123 if (std::find(tokenized.begin(), tokenized.end(), value_lowercase) != | 124 if (std::find(tokenized.begin(), tokenized.end(), value_lowercase) != |
| 124 tokenized.end()) { | 125 tokenized.end()) { |
| 125 field->value = field->option_values[i]; | 126 field->value = field->option_values[i]; |
| 126 return true; | 127 return true; |
| 127 } | 128 } |
| 128 } | 129 } |
| 129 | 130 |
| 130 return false; | 131 return false; |
| 131 } | 132 } |
| 132 | 133 |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 239 | 240 |
| 240 return false; | 241 return false; |
| 241 } | 242 } |
| 242 | 243 |
| 243 // Try to fill a credit card type |value| (Visa, MasterCard, etc.) into the | 244 // Try to fill a credit card type |value| (Visa, MasterCard, etc.) into the |
| 244 // given |field|. | 245 // given |field|. |
| 245 bool FillCreditCardTypeSelectControl(const base::string16& value, | 246 bool FillCreditCardTypeSelectControl(const base::string16& value, |
| 246 FormFieldData* field) { | 247 FormFieldData* field) { |
| 247 // Try stripping off spaces. | 248 // Try stripping off spaces. |
| 248 base::string16 value_stripped; | 249 base::string16 value_stripped; |
| 249 base::RemoveChars(StringToLowerASCII(value), base::kWhitespaceUTF16, | 250 base::RemoveChars(base::StringToLowerASCII(value), base::kWhitespaceUTF16, |
| 250 &value_stripped); | 251 &value_stripped); |
| 251 | 252 |
| 252 for (size_t i = 0; i < field->option_values.size(); ++i) { | 253 for (size_t i = 0; i < field->option_values.size(); ++i) { |
| 253 base::string16 option_value_lowercase; | 254 base::string16 option_value_lowercase; |
| 254 base::RemoveChars(StringToLowerASCII(field->option_values[i]), | 255 base::RemoveChars(base::StringToLowerASCII(field->option_values[i]), |
| 255 base::kWhitespaceUTF16, &option_value_lowercase); | 256 base::kWhitespaceUTF16, &option_value_lowercase); |
| 256 base::string16 option_contents_lowercase; | 257 base::string16 option_contents_lowercase; |
| 257 base::RemoveChars(StringToLowerASCII(field->option_contents[i]), | 258 base::RemoveChars(base::StringToLowerASCII(field->option_contents[i]), |
| 258 base::kWhitespaceUTF16, &option_contents_lowercase); | 259 base::kWhitespaceUTF16, &option_contents_lowercase); |
| 259 | 260 |
| 260 // Perform a case-insensitive comparison; but fill the form with the | 261 // Perform a case-insensitive comparison; but fill the form with the |
| 261 // original text, not the lowercased version. | 262 // original text, not the lowercased version. |
| 262 if (value_stripped == option_value_lowercase || | 263 if (value_stripped == option_value_lowercase || |
| 263 value_stripped == option_contents_lowercase) { | 264 value_stripped == option_contents_lowercase) { |
| 264 field->value = field->option_values[i]; | 265 field->value = field->option_values[i]; |
| 265 return true; | 266 return true; |
| 266 } | 267 } |
| 267 } | 268 } |
| (...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 486 } else if (type.GetStorableType() == ADDRESS_HOME_STREET_ADDRESS) { | 487 } else if (type.GetStorableType() == ADDRESS_HOME_STREET_ADDRESS) { |
| 487 FillStreetAddress(value, address_language_code, field_data); | 488 FillStreetAddress(value, address_language_code, field_data); |
| 488 return true; | 489 return true; |
| 489 } | 490 } |
| 490 | 491 |
| 491 field_data->value = value; | 492 field_data->value = value; |
| 492 return true; | 493 return true; |
| 493 } | 494 } |
| 494 | 495 |
| 495 } // namespace autofill | 496 } // namespace autofill |
| OLD | NEW |