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 3 // found in the LICENSE file. 4 5 #include "chrome/browser/autofill/phone_field.h" 6 7 #include "base/logging.h" 8 #include "base/memory/scoped_ptr.h" 9 #include "base/string16.h" 10 #include "base/string_util.h" 11 #include "base/utf_string_conversions.h" 12 #include "chrome/browser/autofill/autofill_field.h" 13 #include "chrome/browser/autofill/fax_number.h" 14 #include "chrome/browser/autofill/home_phone_number.h" 15 #include "grit/autofill_resources.h" 16 #include "ui/base/l10n/l10n_util.h" 17 18 // Phone field grammars - first matched grammar will be parsed. Grammars are 19 // separated by { REGEX_SEPARATOR, FIELD_NONE, 0 }. Suffix and extension are 20 // parsed separately unless they are necessary parts of the match. 21 // The following notation is used to describe the patterns: 22 // <cc> - country code field. 23 // <ac> - area code field. 24 // <phone> - phone or prefix. 25 // <suffix> - suffix. 26 // <ext> - extension. 27 // :N means field is limited to N characters, otherwise it is unlimited. 28 // (pattern <field>)? means pattern is optional and matched separately. 29 PhoneField::Parser PhoneField::phone_field_grammars_[] = { 30 // Country code: <cc> Area Code: <ac> Phone: <phone> (- <suffix> 31 // (Ext: <ext>)?)? 32 { PhoneField::REGEX_COUNTRY, PhoneField::FIELD_COUNTRY_CODE, 0 }, 33 { PhoneField::REGEX_AREA, PhoneField::FIELD_AREA_CODE, 0 }, 34 { PhoneField::REGEX_PHONE, PhoneField::FIELD_PHONE, 0 }, 35 { PhoneField::REGEX_SEPARATOR, FIELD_NONE, 0 }, 36 // Phone: <cc> <ac>:3 - <phone>:3 - <suffix>:4 (Ext: <ext>)? 37 { PhoneField::REGEX_PHONE, PhoneField::FIELD_COUNTRY_CODE, 0 }, 38 { PhoneField::REGEX_PHONE, PhoneField::FIELD_AREA_CODE, 3 }, 39 { PhoneField::REGEX_PREFIX_SEPARATOR, PhoneField::FIELD_PHONE, 3 }, 40 { PhoneField::REGEX_SUFFIX_SEPARATOR, PhoneField::FIELD_SUFFIX, 4 }, 41 { PhoneField::REGEX_SEPARATOR, FIELD_NONE, 0 }, 42 // Phone: <cc>:3 <ac>:3 <phone>:3 <suffix>:4 (Ext: <ext>)? 43 { PhoneField::REGEX_PHONE, PhoneField::FIELD_COUNTRY_CODE, 3 }, 44 { PhoneField::REGEX_PHONE, PhoneField::FIELD_AREA_CODE, 3 }, 45 { PhoneField::REGEX_PHONE, PhoneField::FIELD_PHONE, 3 }, 46 { PhoneField::REGEX_PHONE, PhoneField::FIELD_SUFFIX, 4 }, 47 { PhoneField::REGEX_SEPARATOR, FIELD_NONE, 0 }, 48 // Area Code: <ac> Phone: <phone> (- <suffix> (Ext: <ext>)?)? 49 { PhoneField::REGEX_AREA, PhoneField::FIELD_AREA_CODE, 0 }, 50 { PhoneField::REGEX_PHONE, PhoneField::FIELD_PHONE, 0 }, 51 { PhoneField::REGEX_SEPARATOR, FIELD_NONE, 0 }, 52 // Phone: <ac> <phone>:3 <suffix>:4 (Ext: <ext>)? 53 { PhoneField::REGEX_PHONE, PhoneField::FIELD_AREA_CODE, 0 }, 54 { PhoneField::REGEX_PHONE, PhoneField::FIELD_PHONE, 3 }, 55 { PhoneField::REGEX_PHONE, PhoneField::FIELD_SUFFIX, 4 }, 56 { PhoneField::REGEX_SEPARATOR, FIELD_NONE, 0 }, 57 // Phone: <cc> \( <ac> \) <phone> (- <suffix> (Ext: <ext>)?)? 58 { PhoneField::REGEX_PHONE, PhoneField::FIELD_COUNTRY_CODE, 0 }, 59 { PhoneField::REGEX_AREA_NOTEXT, PhoneField::FIELD_AREA_CODE, 0 }, 60 { PhoneField::REGEX_PREFIX_SEPARATOR, PhoneField::FIELD_PHONE, 0 }, 61 { PhoneField::REGEX_SEPARATOR, FIELD_NONE, 0 }, 62 // Phone: \( <ac> \) <phone> (- <suffix> (Ext: <ext>)?)? 63 { PhoneField::REGEX_PHONE, PhoneField::FIELD_COUNTRY_CODE, 0 }, 64 { PhoneField::REGEX_AREA_NOTEXT, PhoneField::FIELD_AREA_CODE, 0 }, 65 { PhoneField::REGEX_PREFIX_SEPARATOR, PhoneField::FIELD_PHONE, 0 }, 66 { PhoneField::REGEX_SEPARATOR, FIELD_NONE, 0 }, 67 // Phone: <cc> - <ac> - <phone> - <suffix> (Ext: <ext>)? 68 { PhoneField::REGEX_PHONE, PhoneField::FIELD_COUNTRY_CODE, 0 }, 69 { PhoneField::REGEX_PREFIX_SEPARATOR, PhoneField::FIELD_AREA_CODE, 0 }, 70 { PhoneField::REGEX_PREFIX_SEPARATOR, PhoneField::FIELD_PHONE, 0 }, 71 { PhoneField::REGEX_SUFFIX_SEPARATOR, PhoneField::FIELD_SUFFIX, 0 }, 72 { PhoneField::REGEX_SEPARATOR, FIELD_NONE, 0 }, 73 // Phone: <ac> Prefix: <phone> Suffix: <suffix> (Ext: <ext>)? 74 { PhoneField::REGEX_PHONE, PhoneField::FIELD_AREA_CODE, 0 }, 75 { PhoneField::REGEX_PREFIX, PhoneField::FIELD_PHONE, 0 }, 76 { PhoneField::REGEX_SUFFIX, PhoneField::FIELD_SUFFIX, 0 }, 77 { PhoneField::REGEX_SEPARATOR, FIELD_NONE, 0 }, 78 // Phone: <ac> - <phone>:3 - <suffix>:4 (Ext: <ext>)? 79 { PhoneField::REGEX_PHONE, PhoneField::FIELD_AREA_CODE, 0 }, 80 { PhoneField::REGEX_PREFIX_SEPARATOR, PhoneField::FIELD_PHONE, 3 }, 81 { PhoneField::REGEX_SUFFIX_SEPARATOR, PhoneField::FIELD_SUFFIX, 4 }, 82 { PhoneField::REGEX_SEPARATOR, FIELD_NONE, 0 }, 83 // Phone: <cc> - <ac> - <phone> (Ext: <ext>)? 84 { PhoneField::REGEX_PHONE, PhoneField::FIELD_COUNTRY_CODE, 0 }, 85 { PhoneField::REGEX_PREFIX_SEPARATOR, PhoneField::FIELD_AREA_CODE, 0 }, 86 { PhoneField::REGEX_SUFFIX_SEPARATOR, PhoneField::FIELD_PHONE, 0 }, 87 { PhoneField::REGEX_SEPARATOR, FIELD_NONE, 0 }, 88 // Phone: <ac> - <phone> (Ext: <ext>)? 89 { PhoneField::REGEX_AREA, PhoneField::FIELD_AREA_CODE, 0 }, 90 { PhoneField::REGEX_PHONE, PhoneField::FIELD_PHONE, 0 }, 91 { PhoneField::REGEX_SEPARATOR, FIELD_NONE, 0 }, 92 // Phone: <phone> (Ext: <ext>)? 93 { PhoneField::REGEX_PHONE, PhoneField::FIELD_PHONE, 0 }, 94 { PhoneField::REGEX_SEPARATOR, FIELD_NONE, 0 }, 95 }; 96 97 PhoneField::~PhoneField() {} 98 99 // static 100 PhoneField* PhoneField::Parse(std::vector<AutofillField*>::const_iterator* iter, 101 bool is_ecml) { 102 DCHECK(iter); 103 if (!iter) 104 return NULL; 105 106 if (is_ecml) 107 return ParseECML(iter); 108 109 scoped_ptr<PhoneField> phone_field(new PhoneField); 110 111 // Go through the phones in order HOME, FAX, attempting to match. HOME should 112 // be the last as it is a catch all case ("fax" and "faxarea" parsed as FAX, 113 // but "area" and "someotherarea" parsed as HOME, for example). 114 for (int i = PHONE_TYPE_MAX - 1; i >= PHONE_TYPE_FIRST; --i) { 115 phone_field->SetPhoneType(static_cast<PhoneField::PhoneType>(i)); 116 if (ParseInternal(phone_field.get(), iter, i == HOME_PHONE)) 117 return phone_field.release(); 118 } 119 120 return NULL; 121 } 122 123 // static 124 PhoneField* PhoneField::ParseECML( 125 std::vector<AutofillField*>::const_iterator* iter) { 126 string16 pattern(GetEcmlPattern(kEcmlShipToPhone, kEcmlBillToPhone, '|')); 127 128 AutofillField* field; 129 if (ParseText(iter, pattern, &field)) { 130 PhoneField* phone_field = new PhoneField(); 131 phone_field->parsed_phone_fields_[FIELD_PHONE] = field; 132 return phone_field; 133 } 134 135 return NULL; 136 } 137 138 bool PhoneField::GetFieldInfo(FieldTypeMap* field_type_map) const { 139 bool ok = false; 140 141 DCHECK(parsed_phone_fields_[FIELD_PHONE]); // Phone was correctly parsed. 142 143 if ((parsed_phone_fields_[FIELD_COUNTRY_CODE] != NULL) || 144 (parsed_phone_fields_[FIELD_AREA_CODE] != NULL) || 145 (parsed_phone_fields_[FIELD_SUFFIX] != NULL)) { 146 if (parsed_phone_fields_[FIELD_COUNTRY_CODE] != NULL) { 147 ok = Add(field_type_map, 148 parsed_phone_fields_[FIELD_COUNTRY_CODE], 149 AutofillType(number_->GetCountryCodeType())); 150 DCHECK(ok); 151 } 152 if (parsed_phone_fields_[FIELD_AREA_CODE] != NULL) { 153 ok = Add(field_type_map, 154 parsed_phone_fields_[FIELD_AREA_CODE], 155 AutofillType(number_->GetCityCodeType())); 156 DCHECK(ok); 157 } 158 // We tag the prefix as PHONE_HOME_NUMBER, then when filling the form 159 // we fill only the prefix depending on the size of the input field. 160 ok = Add(field_type_map, 161 parsed_phone_fields_[FIELD_PHONE], 162 AutofillType(number_->GetNumberType())); 163 DCHECK(ok); 164 // We tag the suffix as PHONE_HOME_NUMBER, then when filling the form 165 // we fill only the suffix depending on the size of the input field. 166 if (parsed_phone_fields_[FIELD_SUFFIX] != NULL) { 167 ok = Add(field_type_map, 168 parsed_phone_fields_[FIELD_SUFFIX], 169 AutofillType(number_->GetNumberType())); 170 DCHECK(ok); 171 } 172 } else { 173 ok = Add(field_type_map, 174 parsed_phone_fields_[FIELD_PHONE], 175 AutofillType(number_->GetWholeNumberType())); 176 DCHECK(ok); 177 } 178 179 return ok; 180 } 181 182 PhoneField::PhoneField() { 183 memset(parsed_phone_fields_, 0, sizeof(parsed_phone_fields_)); 184 SetPhoneType(HOME_PHONE); 185 } 186 187 string16 PhoneField::GetCountryRegex() const { 188 // This one is the same for Home and Fax numbers. 189 return l10n_util::GetStringUTF16(IDS_AUTOFILL_COUNTRY_CODE_RE); 190 } 191 192 string16 PhoneField::GetAreaRegex() const { 193 // This one is the same for Home and Fax numbers. 194 string16 area_code = l10n_util::GetStringUTF16(IDS_AUTOFILL_AREA_CODE_RE); 195 area_code.append(ASCIIToUTF16("|")); // Regexp separator. 196 area_code.append(GetAreaNoTextRegex()); 197 return area_code; 198 } 199 200 string16 PhoneField::GetAreaNoTextRegex() const { 201 // This one is the same for Home and Fax numbers. 202 return l10n_util::GetStringUTF16(IDS_AUTOFILL_AREA_CODE_NOTEXT_RE); 203 } 204 205 string16 PhoneField::GetPhoneRegex() const { 206 if (phone_type_ == HOME_PHONE) 207 return l10n_util::GetStringUTF16(IDS_AUTOFILL_PHONE_RE); 208 else if (phone_type_ == FAX_PHONE) 209 return l10n_util::GetStringUTF16(IDS_AUTOFILL_FAX_RE); 210 else 211 NOTREACHED(); 212 return string16(); 213 } 214 215 string16 PhoneField::GetPrefixSeparatorRegex() const { 216 // This one is the same for Home and Fax numbers. 217 return l10n_util::GetStringUTF16(IDS_AUTOFILL_PHONE_PREFIX_SEPARATOR_RE); 218 } 219 220 string16 PhoneField::GetPrefixRegex() const { 221 // This one is the same for Home and Fax numbers. 222 return l10n_util::GetStringUTF16(IDS_AUTOFILL_PHONE_PREFIX_RE); 223 } 224 225 string16 PhoneField::GetSuffixSeparatorRegex() const { 226 // This one is the same for Home and Fax numbers. 227 return l10n_util::GetStringUTF16(IDS_AUTOFILL_PHONE_SUFFIX_SEPARATOR_RE); 228 } 229 230 string16 PhoneField::GetSuffixRegex() const { 231 // This one is the same for Home and Fax numbers. 232 return l10n_util::GetStringUTF16(IDS_AUTOFILL_PHONE_SUFFIX_RE); 233 } 234 235 string16 PhoneField::GetExtensionRegex() const { 236 // This one is the same for Home and Fax numbers. 237 return l10n_util::GetStringUTF16(IDS_AUTOFILL_PHONE_EXTENSION_RE); 238 } 239 240 string16 PhoneField::GetRegExp(RegexType regex_id) const { 241 switch (regex_id) { 242 case REGEX_COUNTRY: return GetCountryRegex(); 243 case REGEX_AREA: return GetAreaRegex(); 244 case REGEX_AREA_NOTEXT: return GetAreaNoTextRegex(); 245 case REGEX_PHONE: return GetPhoneRegex(); 246 case REGEX_PREFIX_SEPARATOR: return GetPrefixSeparatorRegex(); 247 case REGEX_PREFIX: return GetPrefixRegex(); 248 case REGEX_SUFFIX_SEPARATOR: return GetSuffixSeparatorRegex(); 249 case REGEX_SUFFIX: return GetSuffixRegex(); 250 case REGEX_EXTENSION: return GetExtensionRegex(); 251 default: 252 NOTREACHED(); 253 break; 254 } 255 return string16(); 256 } 257 258 // static 259 bool PhoneField::ParseInternal( 260 PhoneField *phone_field, 261 std::vector<AutofillField*>::const_iterator* iter, 262 bool regular_phone) { 263 DCHECK(iter); 264 265 DCHECK(phone_field); 266 if (!phone_field) 267 return false; 268 269 std::vector<AutofillField*>::const_iterator q = *iter; 270 271 // The form owns the following variables, so they should not be deleted. 272 AutofillField* parsed_fields[FIELD_MAX]; 273 274 for (size_t i = 0; i < arraysize(phone_field_grammars_); ++i) { 275 memset(parsed_fields, 0, sizeof(parsed_fields)); 276 q = *iter; 277 // Attempt to parse next possible match. 278 for (; i < arraysize(phone_field_grammars_) && 279 phone_field_grammars_[i].regex != REGEX_SEPARATOR; ++i) { 280 if (!ParseText(&q, phone_field->GetRegExp(phone_field_grammars_[i].regex), 281 &parsed_fields[phone_field_grammars_[i].phone_part])) 282 break; 283 if (phone_field_grammars_[i].max_size && 284 (!parsed_fields[phone_field_grammars_[i].phone_part]->max_length || 285 phone_field_grammars_[i].max_size < 286 parsed_fields[phone_field_grammars_[i].phone_part]->max_length)) { 287 break; 288 } 289 } 290 if (i >= arraysize(phone_field_grammars_)) 291 return false; // Parsing failed. 292 if (phone_field_grammars_[i].regex == REGEX_SEPARATOR) 293 break; // Parsing succeeded. 294 do { 295 ++i; 296 } while (i < arraysize(phone_field_grammars_) && 297 phone_field_grammars_[i].regex != REGEX_SEPARATOR); 298 if (i + 1 == arraysize(phone_field_grammars_)) 299 return false; // Tried through all the possibilities - did not match. 300 } 301 if (!parsed_fields[FIELD_PHONE]) 302 return false; 303 304 for (int i = 0; i < FIELD_MAX; ++i) 305 phone_field->parsed_phone_fields_[i] = parsed_fields[i]; 306 307 // Look for optional fields. 308 309 // Look for a third text box. 310 if (!phone_field->parsed_phone_fields_[FIELD_SUFFIX]) { 311 if (!ParseText(&q, phone_field->GetSuffixRegex(), 312 &phone_field->parsed_phone_fields_[FIELD_SUFFIX])) { 313 ParseText(&q, phone_field->GetSuffixSeparatorRegex(), 314 &phone_field->parsed_phone_fields_[FIELD_SUFFIX]); 315 } 316 } 317 318 // Now look for an extension. 319 ParseText(&q, phone_field->GetExtensionRegex(), 320 &phone_field->parsed_phone_fields_[FIELD_EXTENSION]); 321 322 *iter = q; 323 return true; 324 } 325 326 void PhoneField::SetPhoneType(PhoneType phone_type) { 327 // Field types are different as well, so we create a temporary phone number, 328 // to get relevant field types. 329 if (phone_type == HOME_PHONE) 330 number_.reset(new HomePhoneNumber); 331 else 332 number_.reset(new FaxNumber); 333 phone_type_ = phone_type; 334 } 335 336