| 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_scanner.h" | 13 #include "chrome/browser/autofill/autofill_scanner.h" |
| 14 #include "chrome/browser/autofill/fax_number.h" | |
| 15 #include "chrome/browser/autofill/home_phone_number.h" | 14 #include "chrome/browser/autofill/home_phone_number.h" |
| 16 #include "ui/base/l10n/l10n_util.h" | 15 #include "ui/base/l10n/l10n_util.h" |
| 17 | 16 |
| 18 namespace { | 17 namespace { |
| 19 | 18 |
| 20 const char kPhoneRe[] = | 19 const char kPhoneRe[] = |
| 21 "phone|mobile" | 20 "phone|mobile" |
| 22 // de-DE | 21 // de-DE |
| 23 "|telefonnummer" | 22 "|telefonnummer" |
| 24 // es | 23 // es |
| (...skipping 13 matching lines...) Expand all Loading... |
| 38 "\xb4\xeb\x8c\x80\xed\x8f\xb0|\xed\x9c\xb4\xeb\x8c\x80\xec\xa0\x84\xed" | 37 "\xb4\xeb\x8c\x80\xed\x8f\xb0|\xed\x9c\xb4\xeb\x8c\x80\xec\xa0\x84\xed" |
| 39 "\x99\x94)(.?\xeb\xb2\x88\xed\x98\xb8)?"; | 38 "\x99\x94)(.?\xeb\xb2\x88\xed\x98\xb8)?"; |
| 40 const char kCountryCodeRe[] = | 39 const char kCountryCodeRe[] = |
| 41 "country.*code|ccode|_cc"; | 40 "country.*code|ccode|_cc"; |
| 42 const char kAreaCodeNotextRe[] = | 41 const char kAreaCodeNotextRe[] = |
| 43 "^\\($"; | 42 "^\\($"; |
| 44 const char kAreaCodeRe[] = | 43 const char kAreaCodeRe[] = |
| 45 "area.*code|acode|area" | 44 "area.*code|acode|area" |
| 46 // ko-KR | 45 // ko-KR |
| 47 "|\xec\xa7\x80\xec\x97\xad.?\xeb\xb2\x88\xed\x98\xb8"; | 46 "|\xec\xa7\x80\xec\x97\xad.?\xeb\xb2\x88\xed\x98\xb8"; |
| 48 const char kFaxRe[] = | |
| 49 "fax" | |
| 50 // fr-FR | |
| 51 "|t\xc3\xa9l\xc3\xa9""copie|telecopie" | |
| 52 // ja-JP | |
| 53 "|\xe3\x83\x95\xe3\x82\xa1\xe3\x83\x83\xe3\x82\xaf\xe3\x82\xb9" | |
| 54 // ru | |
| 55 "|\xd1\x84\xd0\xb0\xd0\xba\xd1\x81" | |
| 56 // zh-CN | |
| 57 "|\xe4\xbc\xa0\xe7\x9c\x9f" | |
| 58 // zh-TW | |
| 59 "|\xe5\x82\xb3\xe7\x9c\x9f" | |
| 60 // ko-KR | |
| 61 "|\xed\x8c\xa9\xec\x8a\xa4(.?\xeb\xb2\x88\xed\x98\xb8)?"; | |
| 62 const char kPhonePrefixSeparatorRe[] = | 47 const char kPhonePrefixSeparatorRe[] = |
| 63 "^-$|^\\)$"; | 48 "^-$|^\\)$"; |
| 64 const char kPhoneSuffixSeparatorRe[] = | 49 const char kPhoneSuffixSeparatorRe[] = |
| 65 "^-$"; | 50 "^-$"; |
| 66 const char kPhonePrefixRe[] = | 51 const char kPhonePrefixRe[] = |
| 67 "prefix|exchange" | 52 "prefix|exchange" |
| 68 // fr-FR | 53 // fr-FR |
| 69 "|preselection" | 54 "|preselection" |
| 70 // pt-BR, pt-PT | 55 // pt-BR, pt-PT |
| 71 "|ddd"; | 56 "|ddd"; |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 167 }; | 152 }; |
| 168 | 153 |
| 169 PhoneField::~PhoneField() {} | 154 PhoneField::~PhoneField() {} |
| 170 | 155 |
| 171 // static | 156 // static |
| 172 FormField* PhoneField::Parse(AutofillScanner* scanner) { | 157 FormField* PhoneField::Parse(AutofillScanner* scanner) { |
| 173 if (scanner->IsEnd()) | 158 if (scanner->IsEnd()) |
| 174 return NULL; | 159 return NULL; |
| 175 | 160 |
| 176 scoped_ptr<PhoneField> phone_field(new PhoneField); | 161 scoped_ptr<PhoneField> phone_field(new PhoneField); |
| 177 | 162 if (ParseInternal(phone_field.get(), scanner)) |
| 178 // Go through the phones in order HOME, FAX, attempting to match. HOME should | 163 return phone_field.release(); |
| 179 // be the last as it is a catch all case ("fax" and "faxarea" parsed as FAX, | |
| 180 // but "area" and "someotherarea" parsed as HOME, for example). | |
| 181 for (int i = PHONE_TYPE_MAX - 1; i >= PHONE_TYPE_FIRST; --i) { | |
| 182 phone_field->SetPhoneType(static_cast<PhoneField::PhoneType>(i)); | |
| 183 if (ParseInternal(phone_field.get(), scanner, i == HOME_PHONE)) | |
| 184 return phone_field.release(); | |
| 185 } | |
| 186 | 164 |
| 187 return NULL; | 165 return NULL; |
| 188 } | 166 } |
| 189 | 167 |
| 190 PhoneField::PhoneField() { | 168 PhoneField::PhoneField() { |
| 191 memset(parsed_phone_fields_, 0, sizeof(parsed_phone_fields_)); | 169 memset(parsed_phone_fields_, 0, sizeof(parsed_phone_fields_)); |
| 192 SetPhoneType(HOME_PHONE); | 170 number_.reset(new PhoneNumber(AutofillType::PHONE_HOME, NULL)); |
| 193 } | 171 } |
| 194 | 172 |
| 195 bool PhoneField::ClassifyField(FieldTypeMap* map) const { | 173 bool PhoneField::ClassifyField(FieldTypeMap* map) const { |
| 196 bool ok = true; | 174 bool ok = true; |
| 197 | 175 |
| 198 DCHECK(parsed_phone_fields_[FIELD_PHONE]); // Phone was correctly parsed. | 176 DCHECK(parsed_phone_fields_[FIELD_PHONE]); // Phone was correctly parsed. |
| 199 | 177 |
| 200 if ((parsed_phone_fields_[FIELD_COUNTRY_CODE] != NULL) || | 178 if ((parsed_phone_fields_[FIELD_COUNTRY_CODE] != NULL) || |
| 201 (parsed_phone_fields_[FIELD_AREA_CODE] != NULL) || | 179 (parsed_phone_fields_[FIELD_AREA_CODE] != NULL) || |
| 202 (parsed_phone_fields_[FIELD_SUFFIX] != NULL)) { | 180 (parsed_phone_fields_[FIELD_SUFFIX] != NULL)) { |
| (...skipping 28 matching lines...) Expand all Loading... |
| 231 } else { | 209 } else { |
| 232 ok = AddClassification(parsed_phone_fields_[FIELD_PHONE], | 210 ok = AddClassification(parsed_phone_fields_[FIELD_PHONE], |
| 233 number_->GetWholeNumberType(), | 211 number_->GetWholeNumberType(), |
| 234 map); | 212 map); |
| 235 } | 213 } |
| 236 | 214 |
| 237 return ok; | 215 return ok; |
| 238 } | 216 } |
| 239 | 217 |
| 240 string16 PhoneField::GetCountryRegex() const { | 218 string16 PhoneField::GetCountryRegex() const { |
| 241 // This one is the same for Home and Fax numbers. | |
| 242 return UTF8ToUTF16(kCountryCodeRe); | 219 return UTF8ToUTF16(kCountryCodeRe); |
| 243 } | 220 } |
| 244 | 221 |
| 245 string16 PhoneField::GetAreaRegex() const { | 222 string16 PhoneField::GetAreaRegex() const { |
| 246 // This one is the same for Home and Fax numbers. | |
| 247 string16 area_code = UTF8ToUTF16(kAreaCodeRe); | 223 string16 area_code = UTF8ToUTF16(kAreaCodeRe); |
| 248 area_code.append(ASCIIToUTF16("|")); // Regexp separator. | 224 area_code.append(ASCIIToUTF16("|")); // Regexp separator. |
| 249 area_code.append(GetAreaNoTextRegex()); | 225 area_code.append(GetAreaNoTextRegex()); |
| 250 return area_code; | 226 return area_code; |
| 251 } | 227 } |
| 252 | 228 |
| 253 string16 PhoneField::GetAreaNoTextRegex() const { | 229 string16 PhoneField::GetAreaNoTextRegex() const { |
| 254 // This one is the same for Home and Fax numbers. | |
| 255 return UTF8ToUTF16(kAreaCodeNotextRe); | 230 return UTF8ToUTF16(kAreaCodeNotextRe); |
| 256 } | 231 } |
| 257 | 232 |
| 258 string16 PhoneField::GetPhoneRegex() const { | 233 string16 PhoneField::GetPhoneRegex() const { |
| 259 if (phone_type_ == HOME_PHONE) | 234 return UTF8ToUTF16(kPhoneRe); |
| 260 return UTF8ToUTF16(kPhoneRe); | |
| 261 else if (phone_type_ == FAX_PHONE) | |
| 262 return UTF8ToUTF16(kFaxRe); | |
| 263 else | |
| 264 NOTREACHED(); | |
| 265 return string16(); | |
| 266 } | 235 } |
| 267 | 236 |
| 268 string16 PhoneField::GetPrefixSeparatorRegex() const { | 237 string16 PhoneField::GetPrefixSeparatorRegex() const { |
| 269 // This one is the same for Home and Fax numbers. | |
| 270 return UTF8ToUTF16(kPhonePrefixSeparatorRe); | 238 return UTF8ToUTF16(kPhonePrefixSeparatorRe); |
| 271 } | 239 } |
| 272 | 240 |
| 273 string16 PhoneField::GetPrefixRegex() const { | 241 string16 PhoneField::GetPrefixRegex() const { |
| 274 // This one is the same for Home and Fax numbers. | |
| 275 return UTF8ToUTF16(kPhonePrefixRe); | 242 return UTF8ToUTF16(kPhonePrefixRe); |
| 276 } | 243 } |
| 277 | 244 |
| 278 string16 PhoneField::GetSuffixSeparatorRegex() const { | 245 string16 PhoneField::GetSuffixSeparatorRegex() const { |
| 279 // This one is the same for Home and Fax numbers. | |
| 280 return UTF8ToUTF16(kPhoneSuffixSeparatorRe); | 246 return UTF8ToUTF16(kPhoneSuffixSeparatorRe); |
| 281 } | 247 } |
| 282 | 248 |
| 283 string16 PhoneField::GetSuffixRegex() const { | 249 string16 PhoneField::GetSuffixRegex() const { |
| 284 // This one is the same for Home and Fax numbers. | |
| 285 return UTF8ToUTF16(kPhoneSuffixRe); | 250 return UTF8ToUTF16(kPhoneSuffixRe); |
| 286 } | 251 } |
| 287 | 252 |
| 288 string16 PhoneField::GetExtensionRegex() const { | 253 string16 PhoneField::GetExtensionRegex() const { |
| 289 // This one is the same for Home and Fax numbers. | |
| 290 return UTF8ToUTF16(kPhoneExtensionRe); | 254 return UTF8ToUTF16(kPhoneExtensionRe); |
| 291 } | 255 } |
| 292 | 256 |
| 293 string16 PhoneField::GetRegExp(RegexType regex_id) const { | 257 string16 PhoneField::GetRegExp(RegexType regex_id) const { |
| 294 switch (regex_id) { | 258 switch (regex_id) { |
| 295 case REGEX_COUNTRY: return GetCountryRegex(); | 259 case REGEX_COUNTRY: return GetCountryRegex(); |
| 296 case REGEX_AREA: return GetAreaRegex(); | 260 case REGEX_AREA: return GetAreaRegex(); |
| 297 case REGEX_AREA_NOTEXT: return GetAreaNoTextRegex(); | 261 case REGEX_AREA_NOTEXT: return GetAreaNoTextRegex(); |
| 298 case REGEX_PHONE: return GetPhoneRegex(); | 262 case REGEX_PHONE: return GetPhoneRegex(); |
| 299 case REGEX_PREFIX_SEPARATOR: return GetPrefixSeparatorRegex(); | 263 case REGEX_PREFIX_SEPARATOR: return GetPrefixSeparatorRegex(); |
| 300 case REGEX_PREFIX: return GetPrefixRegex(); | 264 case REGEX_PREFIX: return GetPrefixRegex(); |
| 301 case REGEX_SUFFIX_SEPARATOR: return GetSuffixSeparatorRegex(); | 265 case REGEX_SUFFIX_SEPARATOR: return GetSuffixSeparatorRegex(); |
| 302 case REGEX_SUFFIX: return GetSuffixRegex(); | 266 case REGEX_SUFFIX: return GetSuffixRegex(); |
| 303 case REGEX_EXTENSION: return GetExtensionRegex(); | 267 case REGEX_EXTENSION: return GetExtensionRegex(); |
| 304 default: | 268 default: |
| 305 NOTREACHED(); | 269 NOTREACHED(); |
| 306 break; | 270 break; |
| 307 } | 271 } |
| 308 return string16(); | 272 return string16(); |
| 309 } | 273 } |
| 310 | 274 |
| 311 // static | 275 // static |
| 312 bool PhoneField::ParseInternal(PhoneField *phone_field, | 276 bool PhoneField::ParseInternal(PhoneField *phone_field, |
| 313 AutofillScanner* scanner, | 277 AutofillScanner* scanner) { |
| 314 bool regular_phone) { | |
| 315 DCHECK(phone_field); | 278 DCHECK(phone_field); |
| 316 scanner->SaveCursor(); | 279 scanner->SaveCursor(); |
| 317 | 280 |
| 318 // The form owns the following variables, so they should not be deleted. | 281 // The form owns the following variables, so they should not be deleted. |
| 319 const AutofillField* parsed_fields[FIELD_MAX]; | 282 const AutofillField* parsed_fields[FIELD_MAX]; |
| 320 | 283 |
| 321 for (size_t i = 0; i < arraysize(phone_field_grammars_); ++i) { | 284 for (size_t i = 0; i < arraysize(phone_field_grammars_); ++i) { |
| 322 memset(parsed_fields, 0, sizeof(parsed_fields)); | 285 memset(parsed_fields, 0, sizeof(parsed_fields)); |
| 323 scanner->SaveCursor(); | 286 scanner->SaveCursor(); |
| 324 | 287 |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 378 &phone_field->parsed_phone_fields_[FIELD_SUFFIX]); | 341 &phone_field->parsed_phone_fields_[FIELD_SUFFIX]); |
| 379 } | 342 } |
| 380 } | 343 } |
| 381 | 344 |
| 382 // Now look for an extension. | 345 // Now look for an extension. |
| 383 ParseField(scanner, phone_field->GetExtensionRegex(), | 346 ParseField(scanner, phone_field->GetExtensionRegex(), |
| 384 &phone_field->parsed_phone_fields_[FIELD_EXTENSION]); | 347 &phone_field->parsed_phone_fields_[FIELD_EXTENSION]); |
| 385 | 348 |
| 386 return true; | 349 return true; |
| 387 } | 350 } |
| 388 | |
| 389 void PhoneField::SetPhoneType(PhoneType phone_type) { | |
| 390 // Field types are different as well, so we create a temporary phone number, | |
| 391 // to get relevant field types. | |
| 392 if (phone_type == HOME_PHONE) | |
| 393 number_.reset(new PhoneNumber(AutofillType::PHONE_HOME, NULL)); | |
| 394 else | |
| 395 number_.reset(new PhoneNumber(AutofillType::PHONE_FAX, NULL)); | |
| 396 phone_type_ = phone_type; | |
| 397 } | |
| 398 | |
| OLD | NEW |