| 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 "chrome/browser/autofill/phone_field.h" | 5 #include "chrome/browser/autofill/phone_field.h" |
| 6 | 6 |
| 7 #include "base/logging.h" | 7 #include "base/logging.h" |
| 8 #include "base/memory/scoped_ptr.h" | 8 #include "base/memory/scoped_ptr.h" |
| 9 #include "base/string16.h" | 9 #include "base/string16.h" |
| 10 #include "base/string_util.h" | 10 #include "base/string_util.h" |
| 11 #include "base/utf_string_conversions.h" | 11 #include "base/utf_string_conversions.h" |
| 12 #include "chrome/browser/autofill/autofill_field.h" | 12 #include "chrome/browser/autofill/autofill_field.h" |
| 13 #include "chrome/browser/autofill/autofill_regex_constants.h" | 13 #include "chrome/browser/autofill/autofill_regex_constants.h" |
| 14 #include "chrome/browser/autofill/autofill_scanner.h" | 14 #include "chrome/browser/autofill/autofill_scanner.h" |
| 15 #include "chrome/browser/autofill/fax_number.h" | |
| 16 #include "chrome/browser/autofill/home_phone_number.h" | 15 #include "chrome/browser/autofill/home_phone_number.h" |
| 17 #include "ui/base/l10n/l10n_util.h" | 16 #include "ui/base/l10n/l10n_util.h" |
| 18 | 17 |
| 18 namespace { |
| 19 |
| 20 // This string includes all area code separators, including NoText. |
| 21 string16 GetAreaRegex() { |
| 22 string16 area_code = UTF8ToUTF16(autofill::kAreaCodeRe); |
| 23 area_code.append(ASCIIToUTF16("|")); // Regexp separator. |
| 24 area_code.append(UTF8ToUTF16(autofill::kAreaCodeNotextRe)); |
| 25 return area_code; |
| 26 } |
| 27 |
| 28 } // namespace |
| 29 |
| 19 // Phone field grammars - first matched grammar will be parsed. Grammars are | 30 // Phone field grammars - first matched grammar will be parsed. Grammars are |
| 20 // separated by { REGEX_SEPARATOR, FIELD_NONE, 0 }. Suffix and extension are | 31 // separated by { REGEX_SEPARATOR, FIELD_NONE, 0 }. Suffix and extension are |
| 21 // parsed separately unless they are necessary parts of the match. | 32 // parsed separately unless they are necessary parts of the match. |
| 22 // The following notation is used to describe the patterns: | 33 // The following notation is used to describe the patterns: |
| 23 // <cc> - country code field. | 34 // <cc> - country code field. |
| 24 // <ac> - area code field. | 35 // <ac> - area code field. |
| 25 // <phone> - phone or prefix. | 36 // <phone> - phone or prefix. |
| 26 // <suffix> - suffix. | 37 // <suffix> - suffix. |
| 27 // <ext> - extension. | 38 // <ext> - extension. |
| 28 // :N means field is limited to N characters, otherwise it is unlimited. | 39 // :N means field is limited to N characters, otherwise it is unlimited. |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 105 }; | 116 }; |
| 106 | 117 |
| 107 PhoneField::~PhoneField() {} | 118 PhoneField::~PhoneField() {} |
| 108 | 119 |
| 109 // static | 120 // static |
| 110 FormField* PhoneField::Parse(AutofillScanner* scanner) { | 121 FormField* PhoneField::Parse(AutofillScanner* scanner) { |
| 111 if (scanner->IsEnd()) | 122 if (scanner->IsEnd()) |
| 112 return NULL; | 123 return NULL; |
| 113 | 124 |
| 114 scoped_ptr<PhoneField> phone_field(new PhoneField); | 125 scoped_ptr<PhoneField> phone_field(new PhoneField); |
| 115 | 126 if (ParseInternal(phone_field.get(), scanner)) |
| 116 // Go through the phones in order HOME, FAX, attempting to match. HOME should | 127 return phone_field.release(); |
| 117 // be the last as it is a catch all case ("fax" and "faxarea" parsed as FAX, | |
| 118 // but "area" and "someotherarea" parsed as HOME, for example). | |
| 119 for (int i = PHONE_TYPE_MAX - 1; i >= PHONE_TYPE_FIRST; --i) { | |
| 120 phone_field->SetPhoneType(static_cast<PhoneField::PhoneType>(i)); | |
| 121 if (ParseInternal(phone_field.get(), scanner, i == HOME_PHONE)) | |
| 122 return phone_field.release(); | |
| 123 } | |
| 124 | 128 |
| 125 return NULL; | 129 return NULL; |
| 126 } | 130 } |
| 127 | 131 |
| 128 PhoneField::PhoneField() { | 132 PhoneField::PhoneField() { |
| 129 memset(parsed_phone_fields_, 0, sizeof(parsed_phone_fields_)); | 133 memset(parsed_phone_fields_, 0, sizeof(parsed_phone_fields_)); |
| 130 SetPhoneType(HOME_PHONE); | |
| 131 } | 134 } |
| 132 | 135 |
| 133 bool PhoneField::ClassifyField(FieldTypeMap* map) const { | 136 bool PhoneField::ClassifyField(FieldTypeMap* map) const { |
| 134 bool ok = true; | 137 bool ok = true; |
| 135 | 138 |
| 136 DCHECK(parsed_phone_fields_[FIELD_PHONE]); // Phone was correctly parsed. | 139 DCHECK(parsed_phone_fields_[FIELD_PHONE]); // Phone was correctly parsed. |
| 137 | 140 |
| 138 if ((parsed_phone_fields_[FIELD_COUNTRY_CODE] != NULL) || | 141 if ((parsed_phone_fields_[FIELD_COUNTRY_CODE] != NULL) || |
| 139 (parsed_phone_fields_[FIELD_AREA_CODE] != NULL) || | 142 (parsed_phone_fields_[FIELD_AREA_CODE] != NULL) || |
| 140 (parsed_phone_fields_[FIELD_SUFFIX] != NULL)) { | 143 (parsed_phone_fields_[FIELD_SUFFIX] != NULL)) { |
| 141 if (parsed_phone_fields_[FIELD_COUNTRY_CODE] != NULL) { | 144 if (parsed_phone_fields_[FIELD_COUNTRY_CODE] != NULL) { |
| 142 ok = ok && AddClassification(parsed_phone_fields_[FIELD_COUNTRY_CODE], | 145 ok = ok && AddClassification(parsed_phone_fields_[FIELD_COUNTRY_CODE], |
| 143 number_->GetCountryCodeType(), | 146 PHONE_HOME_COUNTRY_CODE, |
| 144 map); | 147 map); |
| 145 } | 148 } |
| 146 | 149 |
| 147 AutofillFieldType field_number_type = number_->GetNumberType(); | 150 AutofillFieldType field_number_type = PHONE_HOME_NUMBER; |
| 148 if (parsed_phone_fields_[FIELD_AREA_CODE] != NULL) { | 151 if (parsed_phone_fields_[FIELD_AREA_CODE] != NULL) { |
| 149 ok = ok && AddClassification(parsed_phone_fields_[FIELD_AREA_CODE], | 152 ok = ok && AddClassification(parsed_phone_fields_[FIELD_AREA_CODE], |
| 150 number_->GetCityCodeType(), | 153 PHONE_HOME_CITY_CODE, |
| 151 map); | 154 map); |
| 152 } else if (parsed_phone_fields_[FIELD_COUNTRY_CODE] != NULL) { | 155 } else if (parsed_phone_fields_[FIELD_COUNTRY_CODE] != NULL) { |
| 153 // Only if we can find country code without city code, it means the phone | 156 // Only if we can find country code without city code, it means the phone |
| 154 // number include city code. | 157 // number include city code. |
| 155 field_number_type = number_->GetCityAndNumberType(); | 158 field_number_type = PHONE_HOME_CITY_AND_NUMBER; |
| 156 } | 159 } |
| 157 // We tag the prefix as PHONE_HOME_NUMBER, then when filling the form | 160 // We tag the prefix as PHONE_HOME_NUMBER, then when filling the form |
| 158 // we fill only the prefix depending on the size of the input field. | 161 // we fill only the prefix depending on the size of the input field. |
| 159 ok = ok && AddClassification(parsed_phone_fields_[FIELD_PHONE], | 162 ok = ok && AddClassification(parsed_phone_fields_[FIELD_PHONE], |
| 160 field_number_type, | 163 field_number_type, |
| 161 map); | 164 map); |
| 162 // We tag the suffix as PHONE_HOME_NUMBER, then when filling the form | 165 // We tag the suffix as PHONE_HOME_NUMBER, then when filling the form |
| 163 // we fill only the suffix depending on the size of the input field. | 166 // we fill only the suffix depending on the size of the input field. |
| 164 if (parsed_phone_fields_[FIELD_SUFFIX] != NULL) { | 167 if (parsed_phone_fields_[FIELD_SUFFIX] != NULL) { |
| 165 ok = ok && AddClassification(parsed_phone_fields_[FIELD_SUFFIX], | 168 ok = ok && AddClassification(parsed_phone_fields_[FIELD_SUFFIX], |
| 166 number_->GetNumberType(), | 169 PHONE_HOME_NUMBER, |
| 167 map); | 170 map); |
| 168 } | 171 } |
| 169 } else { | 172 } else { |
| 170 ok = AddClassification(parsed_phone_fields_[FIELD_PHONE], | 173 ok = AddClassification(parsed_phone_fields_[FIELD_PHONE], |
| 171 number_->GetWholeNumberType(), | 174 PHONE_HOME_WHOLE_NUMBER, |
| 172 map); | 175 map); |
| 173 } | 176 } |
| 174 | 177 |
| 175 return ok; | 178 return ok; |
| 176 } | 179 } |
| 177 | 180 |
| 178 string16 PhoneField::GetCountryRegex() const { | |
| 179 // This one is the same for Home and Fax numbers. | |
| 180 return UTF8ToUTF16(autofill::kCountryCodeRe); | |
| 181 } | |
| 182 | |
| 183 string16 PhoneField::GetAreaRegex() const { | |
| 184 // This one is the same for Home and Fax numbers. | |
| 185 string16 area_code = UTF8ToUTF16(autofill::kAreaCodeRe); | |
| 186 area_code.append(ASCIIToUTF16("|")); // Regexp separator. | |
| 187 area_code.append(GetAreaNoTextRegex()); | |
| 188 return area_code; | |
| 189 } | |
| 190 | |
| 191 string16 PhoneField::GetAreaNoTextRegex() const { | |
| 192 // This one is the same for Home and Fax numbers. | |
| 193 return UTF8ToUTF16(autofill::kAreaCodeNotextRe); | |
| 194 } | |
| 195 | |
| 196 string16 PhoneField::GetPhoneRegex() const { | |
| 197 if (phone_type_ == HOME_PHONE) | |
| 198 return UTF8ToUTF16(autofill::kPhoneRe); | |
| 199 else if (phone_type_ == FAX_PHONE) | |
| 200 return UTF8ToUTF16(autofill::kFaxRe); | |
| 201 else | |
| 202 NOTREACHED(); | |
| 203 return string16(); | |
| 204 } | |
| 205 | |
| 206 string16 PhoneField::GetPrefixSeparatorRegex() const { | |
| 207 // This one is the same for Home and Fax numbers. | |
| 208 return UTF8ToUTF16(autofill::kPhonePrefixSeparatorRe); | |
| 209 } | |
| 210 | |
| 211 string16 PhoneField::GetPrefixRegex() const { | |
| 212 // This one is the same for Home and Fax numbers. | |
| 213 return UTF8ToUTF16(autofill::kPhonePrefixRe); | |
| 214 } | |
| 215 | |
| 216 string16 PhoneField::GetSuffixSeparatorRegex() const { | |
| 217 // This one is the same for Home and Fax numbers. | |
| 218 return UTF8ToUTF16(autofill::kPhoneSuffixSeparatorRe); | |
| 219 } | |
| 220 | |
| 221 string16 PhoneField::GetSuffixRegex() const { | |
| 222 // This one is the same for Home and Fax numbers. | |
| 223 return UTF8ToUTF16(autofill::kPhoneSuffixRe); | |
| 224 } | |
| 225 | |
| 226 string16 PhoneField::GetExtensionRegex() const { | |
| 227 // This one is the same for Home and Fax numbers. | |
| 228 return UTF8ToUTF16(autofill::kPhoneExtensionRe); | |
| 229 } | |
| 230 | |
| 231 string16 PhoneField::GetRegExp(RegexType regex_id) const { | 181 string16 PhoneField::GetRegExp(RegexType regex_id) const { |
| 232 switch (regex_id) { | 182 switch (regex_id) { |
| 233 case REGEX_COUNTRY: return GetCountryRegex(); | 183 case REGEX_COUNTRY: |
| 234 case REGEX_AREA: return GetAreaRegex(); | 184 return UTF8ToUTF16(autofill::kCountryCodeRe); |
| 235 case REGEX_AREA_NOTEXT: return GetAreaNoTextRegex(); | 185 case REGEX_AREA: |
| 236 case REGEX_PHONE: return GetPhoneRegex(); | 186 return GetAreaRegex(); |
| 237 case REGEX_PREFIX_SEPARATOR: return GetPrefixSeparatorRegex(); | 187 case REGEX_AREA_NOTEXT: |
| 238 case REGEX_PREFIX: return GetPrefixRegex(); | 188 return UTF8ToUTF16(autofill::kAreaCodeNotextRe); |
| 239 case REGEX_SUFFIX_SEPARATOR: return GetSuffixSeparatorRegex(); | 189 case REGEX_PHONE: |
| 240 case REGEX_SUFFIX: return GetSuffixRegex(); | 190 return UTF8ToUTF16(autofill::kPhoneRe); |
| 241 case REGEX_EXTENSION: return GetExtensionRegex(); | 191 case REGEX_PREFIX_SEPARATOR: |
| 192 return UTF8ToUTF16(autofill::kPhonePrefixSeparatorRe); |
| 193 case REGEX_PREFIX: |
| 194 return UTF8ToUTF16(autofill::kPhonePrefixRe); |
| 195 case REGEX_SUFFIX_SEPARATOR: |
| 196 return UTF8ToUTF16(autofill::kPhoneSuffixSeparatorRe); |
| 197 case REGEX_SUFFIX: |
| 198 return UTF8ToUTF16(autofill::kPhoneSuffixRe); |
| 199 case REGEX_EXTENSION: |
| 200 return UTF8ToUTF16(autofill::kPhoneExtensionRe); |
| 242 default: | 201 default: |
| 243 NOTREACHED(); | 202 NOTREACHED(); |
| 244 break; | 203 break; |
| 245 } | 204 } |
| 246 return string16(); | 205 return string16(); |
| 247 } | 206 } |
| 248 | 207 |
| 249 // static | 208 // static |
| 250 bool PhoneField::ParseInternal(PhoneField *phone_field, | 209 bool PhoneField::ParseInternal(PhoneField *phone_field, |
| 251 AutofillScanner* scanner, | 210 AutofillScanner* scanner) { |
| 252 bool regular_phone) { | |
| 253 DCHECK(phone_field); | 211 DCHECK(phone_field); |
| 254 scanner->SaveCursor(); | 212 scanner->SaveCursor(); |
| 255 | 213 |
| 256 // The form owns the following variables, so they should not be deleted. | 214 // The form owns the following variables, so they should not be deleted. |
| 257 const AutofillField* parsed_fields[FIELD_MAX]; | 215 const AutofillField* parsed_fields[FIELD_MAX]; |
| 258 | 216 |
| 259 for (size_t i = 0; i < arraysize(phone_field_grammars_); ++i) { | 217 for (size_t i = 0; i < arraysize(phone_field_grammars_); ++i) { |
| 260 memset(parsed_fields, 0, sizeof(parsed_fields)); | 218 memset(parsed_fields, 0, sizeof(parsed_fields)); |
| 261 scanner->SaveCursor(); | 219 scanner->SaveCursor(); |
| 262 | 220 |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 303 return false; | 261 return false; |
| 304 } | 262 } |
| 305 | 263 |
| 306 for (int i = 0; i < FIELD_MAX; ++i) | 264 for (int i = 0; i < FIELD_MAX; ++i) |
| 307 phone_field->parsed_phone_fields_[i] = parsed_fields[i]; | 265 phone_field->parsed_phone_fields_[i] = parsed_fields[i]; |
| 308 | 266 |
| 309 // Look for optional fields. | 267 // Look for optional fields. |
| 310 | 268 |
| 311 // Look for a third text box. | 269 // Look for a third text box. |
| 312 if (!phone_field->parsed_phone_fields_[FIELD_SUFFIX]) { | 270 if (!phone_field->parsed_phone_fields_[FIELD_SUFFIX]) { |
| 313 if (!ParseField(scanner, phone_field->GetSuffixRegex(), | 271 if (!ParseField(scanner, UTF8ToUTF16(autofill::kPhoneSuffixRe), |
| 314 &phone_field->parsed_phone_fields_[FIELD_SUFFIX])) { | 272 &phone_field->parsed_phone_fields_[FIELD_SUFFIX])) { |
| 315 ParseField(scanner, phone_field->GetSuffixSeparatorRegex(), | 273 ParseField(scanner, UTF8ToUTF16(autofill::kPhoneSuffixSeparatorRe), |
| 316 &phone_field->parsed_phone_fields_[FIELD_SUFFIX]); | 274 &phone_field->parsed_phone_fields_[FIELD_SUFFIX]); |
| 317 } | 275 } |
| 318 } | 276 } |
| 319 | 277 |
| 320 // Now look for an extension. | 278 // Now look for an extension. |
| 321 ParseField(scanner, phone_field->GetExtensionRegex(), | 279 ParseField(scanner, UTF8ToUTF16(autofill::kPhoneExtensionRe), |
| 322 &phone_field->parsed_phone_fields_[FIELD_EXTENSION]); | 280 &phone_field->parsed_phone_fields_[FIELD_EXTENSION]); |
| 323 | 281 |
| 324 return true; | 282 return true; |
| 325 } | 283 } |
| 326 | |
| 327 void PhoneField::SetPhoneType(PhoneType phone_type) { | |
| 328 // Field types are different as well, so we create a temporary phone number, | |
| 329 // to get relevant field types. | |
| 330 if (phone_type == HOME_PHONE) | |
| 331 number_.reset(new PhoneNumber(AutofillType::PHONE_HOME, NULL)); | |
| 332 else | |
| 333 number_.reset(new PhoneNumber(AutofillType::PHONE_FAX, NULL)); | |
| 334 phone_type_ = phone_type; | |
| 335 } | |
| 336 | |
| OLD | NEW |