| 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_ecml.h" |
| 12 #include "chrome/browser/autofill/autofill_field.h" | 13 #include "chrome/browser/autofill/autofill_field.h" |
| 13 #include "chrome/browser/autofill/autofill_scanner.h" | 14 #include "chrome/browser/autofill/autofill_scanner.h" |
| 14 #include "chrome/browser/autofill/fax_number.h" | 15 #include "chrome/browser/autofill/fax_number.h" |
| 15 #include "chrome/browser/autofill/home_phone_number.h" | 16 #include "chrome/browser/autofill/home_phone_number.h" |
| 16 #include "grit/autofill_resources.h" | 17 #include "grit/autofill_resources.h" |
| 17 #include "ui/base/l10n/l10n_util.h" | 18 #include "ui/base/l10n/l10n_util.h" |
| 18 | 19 |
| 20 using autofill::GetEcmlPattern; |
| 21 |
| 19 // Phone field grammars - first matched grammar will be parsed. Grammars are | 22 // Phone field grammars - first matched grammar will be parsed. Grammars are |
| 20 // separated by { REGEX_SEPARATOR, FIELD_NONE, 0 }. Suffix and extension are | 23 // separated by { REGEX_SEPARATOR, FIELD_NONE, 0 }. Suffix and extension are |
| 21 // parsed separately unless they are necessary parts of the match. | 24 // parsed separately unless they are necessary parts of the match. |
| 22 // The following notation is used to describe the patterns: | 25 // The following notation is used to describe the patterns: |
| 23 // <cc> - country code field. | 26 // <cc> - country code field. |
| 24 // <ac> - area code field. | 27 // <ac> - area code field. |
| 25 // <phone> - phone or prefix. | 28 // <phone> - phone or prefix. |
| 26 // <suffix> - suffix. | 29 // <suffix> - suffix. |
| 27 // <ext> - extension. | 30 // <ext> - extension. |
| 28 // :N means field is limited to N characters, otherwise it is unlimited. | 31 // :N means field is limited to N characters, otherwise it is unlimited. |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 117 } | 120 } |
| 118 | 121 |
| 119 return NULL; | 122 return NULL; |
| 120 } | 123 } |
| 121 | 124 |
| 122 // static | 125 // static |
| 123 PhoneField* PhoneField::ParseECML(AutofillScanner* scanner) { | 126 PhoneField* PhoneField::ParseECML(AutofillScanner* scanner) { |
| 124 string16 pattern(GetEcmlPattern(kEcmlShipToPhone, kEcmlBillToPhone, '|')); | 127 string16 pattern(GetEcmlPattern(kEcmlShipToPhone, kEcmlBillToPhone, '|')); |
| 125 | 128 |
| 126 const AutofillField* field; | 129 const AutofillField* field; |
| 127 if (ParseText(scanner, pattern, &field)) { | 130 if (ParseField(scanner, pattern, &field)) { |
| 128 PhoneField* phone_field = new PhoneField(); | 131 PhoneField* phone_field = new PhoneField(); |
| 129 phone_field->parsed_phone_fields_[FIELD_PHONE] = field; | 132 phone_field->parsed_phone_fields_[FIELD_PHONE] = field; |
| 130 return phone_field; | 133 return phone_field; |
| 131 } | 134 } |
| 132 | 135 |
| 133 return NULL; | 136 return NULL; |
| 134 } | 137 } |
| 135 | 138 |
| 136 bool PhoneField::GetFieldInfo(FieldTypeMap* field_type_map) const { | 139 PhoneField::PhoneField() { |
| 140 memset(parsed_phone_fields_, 0, sizeof(parsed_phone_fields_)); |
| 141 SetPhoneType(HOME_PHONE); |
| 142 } |
| 143 |
| 144 bool PhoneField::ClassifyField(FieldTypeMap* map) const { |
| 137 bool ok = true; | 145 bool ok = true; |
| 138 | 146 |
| 139 DCHECK(parsed_phone_fields_[FIELD_PHONE]); // Phone was correctly parsed. | 147 DCHECK(parsed_phone_fields_[FIELD_PHONE]); // Phone was correctly parsed. |
| 140 | 148 |
| 141 if ((parsed_phone_fields_[FIELD_COUNTRY_CODE] != NULL) || | 149 if ((parsed_phone_fields_[FIELD_COUNTRY_CODE] != NULL) || |
| 142 (parsed_phone_fields_[FIELD_AREA_CODE] != NULL) || | 150 (parsed_phone_fields_[FIELD_AREA_CODE] != NULL) || |
| 143 (parsed_phone_fields_[FIELD_SUFFIX] != NULL)) { | 151 (parsed_phone_fields_[FIELD_SUFFIX] != NULL)) { |
| 144 if (parsed_phone_fields_[FIELD_COUNTRY_CODE] != NULL) { | 152 if (parsed_phone_fields_[FIELD_COUNTRY_CODE] != NULL) { |
| 145 ok = ok && Add(field_type_map, | 153 ok = ok && AddClassification(parsed_phone_fields_[FIELD_COUNTRY_CODE], |
| 146 parsed_phone_fields_[FIELD_COUNTRY_CODE], | 154 number_->GetCountryCodeType(), |
| 147 number_->GetCountryCodeType()); | 155 map); |
| 148 } | 156 } |
| 149 if (parsed_phone_fields_[FIELD_AREA_CODE] != NULL) { | 157 if (parsed_phone_fields_[FIELD_AREA_CODE] != NULL) { |
| 150 ok = ok && Add(field_type_map, | 158 ok = ok && AddClassification(parsed_phone_fields_[FIELD_AREA_CODE], |
| 151 parsed_phone_fields_[FIELD_AREA_CODE], | 159 number_->GetCityCodeType(), |
| 152 number_->GetCityCodeType()); | 160 map); |
| 153 } | 161 } |
| 154 // We tag the prefix as PHONE_HOME_NUMBER, then when filling the form | 162 // We tag the prefix as PHONE_HOME_NUMBER, then when filling the form |
| 155 // we fill only the prefix depending on the size of the input field. | 163 // we fill only the prefix depending on the size of the input field. |
| 156 ok = ok && Add(field_type_map, | 164 ok = ok && AddClassification(parsed_phone_fields_[FIELD_PHONE], |
| 157 parsed_phone_fields_[FIELD_PHONE], | 165 number_->GetNumberType(), |
| 158 number_->GetNumberType()); | 166 map); |
| 159 // We tag the suffix as PHONE_HOME_NUMBER, then when filling the form | 167 // We tag the suffix as PHONE_HOME_NUMBER, then when filling the form |
| 160 // we fill only the suffix depending on the size of the input field. | 168 // we fill only the suffix depending on the size of the input field. |
| 161 if (parsed_phone_fields_[FIELD_SUFFIX] != NULL) { | 169 if (parsed_phone_fields_[FIELD_SUFFIX] != NULL) { |
| 162 ok = ok && Add(field_type_map, | 170 ok = ok && AddClassification(parsed_phone_fields_[FIELD_SUFFIX], |
| 163 parsed_phone_fields_[FIELD_SUFFIX], | 171 number_->GetNumberType(), |
| 164 number_->GetNumberType()); | 172 map); |
| 165 } | 173 } |
| 166 } else { | 174 } else { |
| 167 ok = Add(field_type_map, | 175 ok = AddClassification(parsed_phone_fields_[FIELD_PHONE], |
| 168 parsed_phone_fields_[FIELD_PHONE], | 176 number_->GetWholeNumberType(), |
| 169 number_->GetWholeNumberType()); | 177 map); |
| 170 } | 178 } |
| 171 | 179 |
| 172 return ok; | 180 return ok; |
| 173 } | 181 } |
| 174 | 182 |
| 175 PhoneField::PhoneField() { | |
| 176 memset(parsed_phone_fields_, 0, sizeof(parsed_phone_fields_)); | |
| 177 SetPhoneType(HOME_PHONE); | |
| 178 } | |
| 179 | |
| 180 string16 PhoneField::GetCountryRegex() const { | 183 string16 PhoneField::GetCountryRegex() const { |
| 181 // This one is the same for Home and Fax numbers. | 184 // This one is the same for Home and Fax numbers. |
| 182 return l10n_util::GetStringUTF16(IDS_AUTOFILL_COUNTRY_CODE_RE); | 185 return l10n_util::GetStringUTF16(IDS_AUTOFILL_COUNTRY_CODE_RE); |
| 183 } | 186 } |
| 184 | 187 |
| 185 string16 PhoneField::GetAreaRegex() const { | 188 string16 PhoneField::GetAreaRegex() const { |
| 186 // This one is the same for Home and Fax numbers. | 189 // This one is the same for Home and Fax numbers. |
| 187 string16 area_code = l10n_util::GetStringUTF16(IDS_AUTOFILL_AREA_CODE_RE); | 190 string16 area_code = l10n_util::GetStringUTF16(IDS_AUTOFILL_AREA_CODE_RE); |
| 188 area_code.append(ASCIIToUTF16("|")); // Regexp separator. | 191 area_code.append(ASCIIToUTF16("|")); // Regexp separator. |
| 189 area_code.append(GetAreaNoTextRegex()); | 192 area_code.append(GetAreaNoTextRegex()); |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 259 const AutofillField* parsed_fields[FIELD_MAX]; | 262 const AutofillField* parsed_fields[FIELD_MAX]; |
| 260 | 263 |
| 261 for (size_t i = 0; i < arraysize(phone_field_grammars_); ++i) { | 264 for (size_t i = 0; i < arraysize(phone_field_grammars_); ++i) { |
| 262 memset(parsed_fields, 0, sizeof(parsed_fields)); | 265 memset(parsed_fields, 0, sizeof(parsed_fields)); |
| 263 scanner->Rewind(); | 266 scanner->Rewind(); |
| 264 scanner->SaveCursor(); | 267 scanner->SaveCursor(); |
| 265 | 268 |
| 266 // Attempt to parse according to the next grammar. | 269 // Attempt to parse according to the next grammar. |
| 267 for (; i < arraysize(phone_field_grammars_) && | 270 for (; i < arraysize(phone_field_grammars_) && |
| 268 phone_field_grammars_[i].regex != REGEX_SEPARATOR; ++i) { | 271 phone_field_grammars_[i].regex != REGEX_SEPARATOR; ++i) { |
| 269 if (!ParseText(scanner, | 272 if (!ParseField(scanner, |
| 270 phone_field->GetRegExp(phone_field_grammars_[i].regex), | 273 phone_field->GetRegExp(phone_field_grammars_[i].regex), |
| 271 &parsed_fields[phone_field_grammars_[i].phone_part])) | 274 &parsed_fields[phone_field_grammars_[i].phone_part])) |
| 272 break; | 275 break; |
| 273 if (phone_field_grammars_[i].max_size && | 276 if (phone_field_grammars_[i].max_size && |
| 274 (!parsed_fields[phone_field_grammars_[i].phone_part]->max_length || | 277 (!parsed_fields[phone_field_grammars_[i].phone_part]->max_length || |
| 275 phone_field_grammars_[i].max_size < | 278 phone_field_grammars_[i].max_size < |
| 276 parsed_fields[phone_field_grammars_[i].phone_part]->max_length)) { | 279 parsed_fields[phone_field_grammars_[i].phone_part]->max_length)) { |
| 277 break; | 280 break; |
| 278 } | 281 } |
| 279 } | 282 } |
| 280 | 283 |
| 281 if (i >= arraysize(phone_field_grammars_)) { | 284 if (i >= arraysize(phone_field_grammars_)) { |
| (...skipping 20 matching lines...) Expand all Loading... |
| 302 return false; | 305 return false; |
| 303 } | 306 } |
| 304 | 307 |
| 305 for (int i = 0; i < FIELD_MAX; ++i) | 308 for (int i = 0; i < FIELD_MAX; ++i) |
| 306 phone_field->parsed_phone_fields_[i] = parsed_fields[i]; | 309 phone_field->parsed_phone_fields_[i] = parsed_fields[i]; |
| 307 | 310 |
| 308 // Look for optional fields. | 311 // Look for optional fields. |
| 309 | 312 |
| 310 // Look for a third text box. | 313 // Look for a third text box. |
| 311 if (!phone_field->parsed_phone_fields_[FIELD_SUFFIX]) { | 314 if (!phone_field->parsed_phone_fields_[FIELD_SUFFIX]) { |
| 312 if (!ParseText(scanner, phone_field->GetSuffixRegex(), | 315 if (!ParseField(scanner, phone_field->GetSuffixRegex(), |
| 313 &phone_field->parsed_phone_fields_[FIELD_SUFFIX])) { | 316 &phone_field->parsed_phone_fields_[FIELD_SUFFIX])) { |
| 314 ParseText(scanner, phone_field->GetSuffixSeparatorRegex(), | 317 ParseField(scanner, phone_field->GetSuffixSeparatorRegex(), |
| 315 &phone_field->parsed_phone_fields_[FIELD_SUFFIX]); | 318 &phone_field->parsed_phone_fields_[FIELD_SUFFIX]); |
| 316 } | 319 } |
| 317 } | 320 } |
| 318 | 321 |
| 319 // Now look for an extension. | 322 // Now look for an extension. |
| 320 ParseText(scanner, phone_field->GetExtensionRegex(), | 323 ParseField(scanner, phone_field->GetExtensionRegex(), |
| 321 &phone_field->parsed_phone_fields_[FIELD_EXTENSION]); | 324 &phone_field->parsed_phone_fields_[FIELD_EXTENSION]); |
| 322 | 325 |
| 323 return true; | 326 return true; |
| 324 } | 327 } |
| 325 | 328 |
| 326 void PhoneField::SetPhoneType(PhoneType phone_type) { | 329 void PhoneField::SetPhoneType(PhoneType phone_type) { |
| 327 // Field types are different as well, so we create a temporary phone number, | 330 // Field types are different as well, so we create a temporary phone number, |
| 328 // to get relevant field types. | 331 // to get relevant field types. |
| 329 if (phone_type == HOME_PHONE) | 332 if (phone_type == HOME_PHONE) |
| 330 number_.reset(new HomePhoneNumber); | 333 number_.reset(new HomePhoneNumber); |
| 331 else | 334 else |
| 332 number_.reset(new FaxNumber); | 335 number_.reset(new FaxNumber); |
| 333 phone_type_ = phone_type; | 336 phone_type_ = phone_type; |
| 334 } | 337 } |
| 335 | 338 |
| OLD | NEW |