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