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 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
59 } | 59 } |
60 } | 60 } |
61 | 61 |
62 if (best_match.empty()) | 62 if (best_match.empty()) |
63 return false; | 63 return false; |
64 | 64 |
65 field->value = best_match; | 65 field->value = best_match; |
66 return true; | 66 return true; |
67 } | 67 } |
68 | 68 |
| 69 // Like SetSelectControlValue, but searches within the field values and options |
| 70 // for |value|. For example, "NC - North Carolina" would match "north carolina". |
| 71 bool SetSelectControlValueSubstringMatch(const base::string16& value, |
| 72 FormFieldData* field) { |
| 73 base::string16 value_lowercase = StringToLowerASCII(value); |
| 74 DCHECK_EQ(field->option_values.size(), field->option_contents.size()); |
| 75 int best_match = -1; |
| 76 |
| 77 for (size_t i = 0; i < field->option_values.size(); ++i) { |
| 78 if (StringToLowerASCII(field->option_values[i]).find(value_lowercase) != |
| 79 std::string::npos || |
| 80 StringToLowerASCII(field->option_contents[i]).find(value_lowercase) != |
| 81 std::string::npos) { |
| 82 // The best match is the shortest one. |
| 83 if (best_match == -1 || |
| 84 field->option_values[best_match].size() > |
| 85 field->option_values[i].size()) { |
| 86 best_match = i; |
| 87 } |
| 88 } |
| 89 } |
| 90 |
| 91 if (best_match >= 0) { |
| 92 field->value = field->option_values[best_match]; |
| 93 return true; |
| 94 } |
| 95 |
| 96 return false; |
| 97 } |
| 98 |
| 99 // Like SetSelectControlValue, but searches within the field values and options |
| 100 // for |value|. First it tokenizes the options, then tries to match against |
| 101 // tokens. For example, "NC - North Carolina" would match "nc" but not "ca". |
| 102 bool SetSelectControlValueTokenMatch(const base::string16& value, |
| 103 FormFieldData* field) { |
| 104 base::string16 value_lowercase = StringToLowerASCII(value); |
| 105 std::vector<base::string16> tokenized; |
| 106 DCHECK_EQ(field->option_values.size(), field->option_contents.size()); |
| 107 |
| 108 for (size_t i = 0; i < field->option_values.size(); ++i) { |
| 109 base::SplitStringAlongWhitespace( |
| 110 StringToLowerASCII(field->option_values[i]), &tokenized); |
| 111 if (std::find(tokenized.begin(), tokenized.end(), value_lowercase) != |
| 112 tokenized.end()) { |
| 113 field->value = field->option_values[i]; |
| 114 return true; |
| 115 } |
| 116 |
| 117 base::SplitStringAlongWhitespace( |
| 118 StringToLowerASCII(field->option_contents[i]), &tokenized); |
| 119 if (std::find(tokenized.begin(), tokenized.end(), value_lowercase) != |
| 120 tokenized.end()) { |
| 121 field->value = field->option_values[i]; |
| 122 return true; |
| 123 } |
| 124 } |
| 125 |
| 126 return false; |
| 127 } |
69 | 128 |
70 // Try to fill a numeric |value| into the given |field|. | 129 // Try to fill a numeric |value| into the given |field|. |
71 bool FillNumericSelectControl(int value, | 130 bool FillNumericSelectControl(int value, |
72 FormFieldData* field) { | 131 FormFieldData* field) { |
73 DCHECK_EQ(field->option_values.size(), field->option_contents.size()); | 132 DCHECK_EQ(field->option_values.size(), field->option_contents.size()); |
74 for (size_t i = 0; i < field->option_values.size(); ++i) { | 133 for (size_t i = 0; i < field->option_values.size(); ++i) { |
75 int option; | 134 int option; |
76 if ((StringToInt(field->option_values[i], &option) && option == value) || | 135 if ((StringToInt(field->option_values[i], &option) && option == value) || |
77 (StringToInt(field->option_contents[i], &option) && option == value)) { | 136 (StringToInt(field->option_contents[i], &option) && option == value)) { |
78 field->value = field->option_values[i]; | 137 field->value = field->option_values[i]; |
79 return true; | 138 return true; |
80 } | 139 } |
81 } | 140 } |
82 | 141 |
83 return false; | 142 return false; |
84 } | 143 } |
85 | 144 |
86 bool FillStateSelectControl(const base::string16& value, | 145 bool FillStateSelectControl(const base::string16& value, |
87 FormFieldData* field) { | 146 FormFieldData* field) { |
88 base::string16 full, abbreviation; | 147 base::string16 full, abbreviation; |
89 state_names::GetNameAndAbbreviation(value, &full, &abbreviation); | 148 state_names::GetNameAndAbbreviation(value, &full, &abbreviation); |
90 | 149 |
91 // Try the abbreviation first. | 150 // Try an exact match of the abbreviation first. |
92 if (!abbreviation.empty() && SetSelectControlValue(abbreviation, field)) | 151 if (!abbreviation.empty() && SetSelectControlValue(abbreviation, field)) { |
93 return true; | 152 return true; |
| 153 } |
94 | 154 |
95 return !full.empty() && SetSelectControlValue(full, field); | 155 // Try an exact match of the full name. |
| 156 if (!full.empty() && SetSelectControlValue(full, field)) { |
| 157 return true; |
| 158 } |
| 159 |
| 160 // Then try an inexact match of the full name. |
| 161 if (!full.empty() && SetSelectControlValueSubstringMatch(full, field)) { |
| 162 return true; |
| 163 } |
| 164 |
| 165 // Then try an inexact match of the abbreviation name. |
| 166 return !abbreviation.empty() && |
| 167 SetSelectControlValueTokenMatch(abbreviation, field); |
96 } | 168 } |
97 | 169 |
98 bool FillCountrySelectControl(const base::string16& value, | 170 bool FillCountrySelectControl(const base::string16& value, |
99 const std::string& app_locale, | 171 const std::string& app_locale, |
100 FormFieldData* field_data) { | 172 FormFieldData* field_data) { |
101 std::string country_code = AutofillCountry::GetCountryCode(value, app_locale); | 173 std::string country_code = AutofillCountry::GetCountryCode(value, app_locale); |
102 if (country_code.empty()) | 174 if (country_code.empty()) |
103 return false; | 175 return false; |
104 | 176 |
105 DCHECK_EQ(field_data->option_values.size(), | 177 DCHECK_EQ(field_data->option_values.size(), |
(...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
404 } else if (type.GetStorableType() == ADDRESS_HOME_STREET_ADDRESS) { | 476 } else if (type.GetStorableType() == ADDRESS_HOME_STREET_ADDRESS) { |
405 FillStreetAddress(value, field_data); | 477 FillStreetAddress(value, field_data); |
406 return true; | 478 return true; |
407 } | 479 } |
408 | 480 |
409 field_data->value = value; | 481 field_data->value = value; |
410 return true; | 482 return true; |
411 } | 483 } |
412 | 484 |
413 } // namespace autofill | 485 } // namespace autofill |
OLD | NEW |