Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1019)

Side by Side Diff: chrome/browser/autofill/phone_field.cc

Issue 6480083: Changed parsing code for the phonenumbers fields to incorporate different com... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 9 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome/browser/autofill/phone_field.h ('k') | chrome/browser/autofill/phone_field_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2009 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/scoped_ptr.h" 8 #include "base/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/fax_number.h" 13 #include "chrome/browser/autofill/fax_number.h"
14 #include "chrome/browser/autofill/home_phone_number.h" 14 #include "chrome/browser/autofill/home_phone_number.h"
15 #include "grit/autofill_resources.h" 15 #include "grit/autofill_resources.h"
16 #include "ui/base/l10n/l10n_util.h" 16 #include "ui/base/l10n/l10n_util.h"
17 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 part of the match.
Ilya Sherman 2011/02/16 23:22:08 nit: part -> parts
GeorgeY 2011/02/17 00:21:18 Done.
21 // The following comment are indicating the matched pattern:
Ilya Sherman 2011/02/16 23:22:08 nit: Perhaps: "The following notation is used to d
GeorgeY 2011/02/17 00:21:18 Done.
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 patter is optional and matche d separately.
Ilya Sherman 2011/02/16 23:22:08 nit: patter -> pattern, matche d -> matched
GeorgeY 2011/02/17 00:21:18 Done.
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
18 // static 97 // static
19 PhoneField* PhoneField::Parse(std::vector<AutoFillField*>::const_iterator* iter, 98 PhoneField* PhoneField::Parse(std::vector<AutoFillField*>::const_iterator* iter,
20 bool is_ecml) { 99 bool is_ecml) {
21 DCHECK(iter); 100 DCHECK(iter);
22 if (!iter) 101 if (!iter)
23 return NULL; 102 return NULL;
24 103
25 if (is_ecml) 104 if (is_ecml)
26 return ParseECML(iter); 105 return ParseECML(iter);
27 106
28 scoped_ptr<PhoneField> phone_field(new PhoneField); 107 scoped_ptr<PhoneField> phone_field(new PhoneField);
29 108
30 // Go through the phones in order HOME, FAX, attempting to match. HOME should 109 // Go through the phones in order HOME, FAX, attempting to match. HOME should
31 // be the last as it is a catch all case ("fax" and "faxarea" parsed as FAX, 110 // be the last as it is a catch all case ("fax" and "faxarea" parsed as FAX,
32 // but "area" and "someotherarea" parsed as HOME, for example). 111 // but "area" and "someotherarea" parsed as HOME, for example).
33 for (int i = PHONE_TYPE_MAX - 1; i >= PHONE_TYPE_FIRST; --i) { 112 for (int i = PHONE_TYPE_MAX - 1; i >= PHONE_TYPE_FIRST; --i) {
34 phone_field->SetPhoneType(static_cast<PhoneField::PHONE_TYPE>(i)); 113 phone_field->SetPhoneType(static_cast<PhoneField::PhoneType>(i));
35 if (ParseInternal(phone_field.get(), iter, i == HOME_PHONE)) 114 if (ParseInternal(phone_field.get(), iter, i == HOME_PHONE))
36 return phone_field.release(); 115 return phone_field.release();
37 } 116 }
38 117
39 return NULL; 118 return NULL;
40 } 119 }
41 120
42 // static 121 // static
43 PhoneField* PhoneField::ParseECML( 122 PhoneField* PhoneField::ParseECML(
44 std::vector<AutoFillField*>::const_iterator* iter) { 123 std::vector<AutoFillField*>::const_iterator* iter) {
45 string16 pattern(GetEcmlPattern(kEcmlShipToPhone, kEcmlBillToPhone, '|')); 124 string16 pattern(GetEcmlPattern(kEcmlShipToPhone, kEcmlBillToPhone, '|'));
46 125
47 AutoFillField* field; 126 AutoFillField* field;
48 if (ParseText(iter, pattern, &field)) { 127 if (ParseText(iter, pattern, &field)) {
49 PhoneField* phone_field = new PhoneField(); 128 PhoneField* phone_field = new PhoneField();
50 phone_field->phone_ = field; 129 phone_field->parsed_phone_fields_[FIELD_PHONE] = field;
51 return phone_field; 130 return phone_field;
52 } 131 }
53 132
54 return NULL; 133 return NULL;
55 } 134 }
56 135
57 bool PhoneField::GetFieldInfo(FieldTypeMap* field_type_map) const { 136 bool PhoneField::GetFieldInfo(FieldTypeMap* field_type_map) const {
58 bool ok; 137 bool ok = false;
59 138
60 if (area_code_ != NULL) { 139 DCHECK(parsed_phone_fields_[FIELD_PHONE]); // Phone was correctly parsed.
61 ok = Add(field_type_map, area_code_, 140
62 AutoFillType(number_->GetCityCodeType())); 141 if ((parsed_phone_fields_[FIELD_COUNTRY_CODE] != NULL) ||
142 (parsed_phone_fields_[FIELD_AREA_CODE] != NULL) ||
143 (parsed_phone_fields_[FIELD_SUFFIX] != NULL)) {
144 if (parsed_phone_fields_[FIELD_COUNTRY_CODE] != NULL) {
145 ok = Add(field_type_map,
146 parsed_phone_fields_[FIELD_COUNTRY_CODE],
147 AutoFillType(number_->GetCountryCodeType()));
148 DCHECK(ok);
149 }
150 if (parsed_phone_fields_[FIELD_AREA_CODE] != NULL) {
151 ok = Add(field_type_map,
152 parsed_phone_fields_[FIELD_AREA_CODE],
153 AutoFillType(number_->GetCityCodeType()));
154 DCHECK(ok);
155 }
156 // We tag the prefix as PHONE_HOME_NUMBER, then when filling the form
157 // we fill only the prefix depending on the size of the input field.
158 ok = Add(field_type_map,
159 parsed_phone_fields_[FIELD_PHONE],
160 AutoFillType(number_->GetNumberType()));
63 DCHECK(ok); 161 DCHECK(ok);
64 162 // We tag the suffix as PHONE_HOME_NUMBER, then when filling the form
65 if (prefix_ != NULL) { 163 // we fill only the suffix depending on the size of the input field.
66 // We tag the prefix as PHONE_HOME_NUMBER, then when filling the form 164 if (parsed_phone_fields_[FIELD_SUFFIX] != NULL) {
67 // we fill only the prefix depending on the size of the input field. 165 ok = Add(field_type_map,
68 ok = ok && Add(field_type_map, 166 parsed_phone_fields_[FIELD_SUFFIX],
69 prefix_, 167 AutoFillType(number_->GetNumberType()));
70 AutoFillType(number_->GetNumberType()));
71 DCHECK(ok);
72 // We tag the suffix as PHONE_HOME_NUMBER, then when filling the form
73 // we fill only the suffix depending on the size of the input field.
74 ok = ok && Add(field_type_map,
75 phone_,
76 AutoFillType(number_->GetNumberType()));
77 DCHECK(ok);
78 } else {
79 ok = ok && Add(field_type_map,
80 phone_,
81 AutoFillType(number_->GetNumberType()));
82 DCHECK(ok); 168 DCHECK(ok);
83 } 169 }
84 } else { 170 } else {
85 ok = Add(field_type_map, 171 ok = Add(field_type_map,
86 phone_, 172 parsed_phone_fields_[FIELD_PHONE],
87 AutoFillType(number_->GetWholeNumberType())); 173 AutoFillType(number_->GetWholeNumberType()));
88 DCHECK(ok); 174 DCHECK(ok);
89 } 175 }
90 176
91 return ok; 177 return ok;
92 } 178 }
93 179
94 PhoneField::PhoneField() 180 PhoneField::PhoneField() {
95 : phone_(NULL), 181 memset(parsed_phone_fields_, 0, sizeof(parsed_phone_fields_));
96 area_code_(NULL),
97 prefix_(NULL),
98 extension_(NULL) {
99 SetPhoneType(HOME_PHONE); 182 SetPhoneType(HOME_PHONE);
100 } 183 }
101 184
185 string16 PhoneField::GetCountryRegex() const {
186 // This one is the same for Home and Fax numbers.
187 return l10n_util::GetStringUTF16(IDS_AUTOFILL_COUNTRY_CODE_RE);
188 }
189
102 string16 PhoneField::GetAreaRegex() const { 190 string16 PhoneField::GetAreaRegex() const {
103 // This one is the same for Home and Fax numbers. 191 // This one is the same for Home and Fax numbers.
104 return l10n_util::GetStringUTF16(IDS_AUTOFILL_AREA_CODE_RE); 192 string16 area_code = l10n_util::GetStringUTF16(IDS_AUTOFILL_AREA_CODE_RE);
193 area_code.append(ASCIIToUTF16("|")); // Regexp separator.
194 area_code.append(GetAreaNoTextRegex());
195 return area_code;
196 }
197
198 string16 PhoneField::GetAreaNoTextRegex() const {
199 // This one is the same for Home and Fax numbers.
200 return l10n_util::GetStringUTF16(IDS_AUTOFILL_AREA_CODE_NOTEXT_RE);
105 } 201 }
106 202
107 string16 PhoneField::GetPhoneRegex() const { 203 string16 PhoneField::GetPhoneRegex() const {
108 if (phone_type_ == HOME_PHONE) 204 if (phone_type_ == HOME_PHONE)
109 return l10n_util::GetStringUTF16(IDS_AUTOFILL_PHONE_RE); 205 return l10n_util::GetStringUTF16(IDS_AUTOFILL_PHONE_RE);
110 else if (phone_type_ == FAX_PHONE) 206 else if (phone_type_ == FAX_PHONE)
111 return l10n_util::GetStringUTF16(IDS_AUTOFILL_FAX_RE); 207 return l10n_util::GetStringUTF16(IDS_AUTOFILL_FAX_RE);
112 else 208 else
113 NOTREACHED(); 209 NOTREACHED();
114 return string16(); 210 return string16();
115 } 211 }
116 212
213 string16 PhoneField::GetPrefixSeparatorRegex() const {
214 // This one is the same for Home and Fax numbers.
215 return l10n_util::GetStringUTF16(IDS_AUTOFILL_PHONE_PREFIX_SEPARATOR_RE);
216 }
217
117 string16 PhoneField::GetPrefixRegex() const { 218 string16 PhoneField::GetPrefixRegex() const {
118 // This one is the same for Home and Fax numbers. 219 // This one is the same for Home and Fax numbers.
119 return l10n_util::GetStringUTF16(IDS_AUTOFILL_PHONE_PREFIX_RE); 220 return l10n_util::GetStringUTF16(IDS_AUTOFILL_PHONE_PREFIX_RE);
120 } 221 }
121 222
223 string16 PhoneField::GetSuffixSeparatorRegex() const {
224 // This one is the same for Home and Fax numbers.
225 return l10n_util::GetStringUTF16(IDS_AUTOFILL_PHONE_SUFFIX_SEPARATOR_RE);
226 }
227
122 string16 PhoneField::GetSuffixRegex() const { 228 string16 PhoneField::GetSuffixRegex() const {
123 // This one is the same for Home and Fax numbers. 229 // This one is the same for Home and Fax numbers.
124 return l10n_util::GetStringUTF16(IDS_AUTOFILL_PHONE_SUFFIX_RE); 230 return l10n_util::GetStringUTF16(IDS_AUTOFILL_PHONE_SUFFIX_RE);
125 } 231 }
126 232
127 string16 PhoneField::GetExtensionRegex() const { 233 string16 PhoneField::GetExtensionRegex() const {
128 // This one is the same for Home and Fax numbers. 234 // This one is the same for Home and Fax numbers.
129 return l10n_util::GetStringUTF16(IDS_AUTOFILL_PHONE_EXTENSION_RE); 235 return l10n_util::GetStringUTF16(IDS_AUTOFILL_PHONE_EXTENSION_RE);
130 } 236 }
131 237
238 string16 PhoneField::GetRegExp(RegexType regex_id) const {
239 switch (regex_id) {
240 case REGEX_COUNTRY: return GetCountryRegex();
241 case REGEX_AREA: return GetAreaRegex();
242 case REGEX_AREA_NOTEXT: return GetAreaNoTextRegex();
243 case REGEX_PHONE: return GetPhoneRegex();
244 case REGEX_PREFIX_SEPARATOR: return GetPrefixSeparatorRegex();
245 case REGEX_PREFIX: return GetPrefixRegex();
246 case REGEX_SUFFIX_SEPARATOR: return GetSuffixSeparatorRegex();
247 case REGEX_SUFFIX: return GetSuffixRegex();
248 case REGEX_EXTENSION: return GetExtensionRegex();
249 default:
250 NOTREACHED();
251 break;
252 }
253 return string16();
254 }
255
132 // static 256 // static
133 bool PhoneField::ParseInternal( 257 bool PhoneField::ParseInternal(
134 PhoneField *phone_field, 258 PhoneField *phone_field,
135 std::vector<AutoFillField*>::const_iterator* iter, 259 std::vector<AutoFillField*>::const_iterator* iter,
136 bool regular_phone) { 260 bool regular_phone) {
137 DCHECK(iter); 261 DCHECK(iter);
138 262
139 DCHECK(phone_field); 263 DCHECK(phone_field);
140 if (!phone_field) 264 if (!phone_field)
141 return false; 265 return false;
142 266
143 std::vector<AutoFillField*>::const_iterator q = *iter; 267 std::vector<AutoFillField*>::const_iterator q = *iter;
268
144 // The form owns the following variables, so they should not be deleted. 269 // The form owns the following variables, so they should not be deleted.
145 AutoFillField* phone = NULL; 270 AutoFillField* parsed_fields[FIELD_MAX];
146 AutoFillField* phone2 = NULL;
147 AutoFillField* phone3 = NULL;
148 bool area_code = false; // true if we've parsed an area code field.
149 271
150 // Some pages, such as BloomingdalesShipping.html, have a field labeled 272 for (size_t i = 0; i < arraysize(phone_field_grammars_); ++i) {
151 // "Area Code and Phone"; we want to parse this as a phone number field so 273 memset(parsed_fields, 0, sizeof(parsed_fields));
152 // we look for "phone" before we look for "area code". 274 q = *iter;
153 if (ParseText(&q, phone_field->GetPhoneRegex(), &phone)) { 275 // Attempt to parse next possible match.
154 area_code = false; 276 for (; i < arraysize(phone_field_grammars_) &&
155 // Check the case when the match is for non-home phone and area code, e.g. 277 phone_field_grammars_[i].regex != REGEX_SEPARATOR; ++i) {
156 // first field is a "Fax area code" and the subsequent is "Fax phone". 278 if (!ParseText(&q, phone_field->GetRegExp(phone_field_grammars_[i].regex),
157 if (!regular_phone) { 279 &parsed_fields[phone_field_grammars_[i].phone_part]))
158 // Attempt parsing of the same field as an area code and then phone: 280 break;
159 std::vector<AutoFillField*>::const_iterator temp_it = *iter; 281 if (phone_field_grammars_[i].max_size &&
160 AutoFillField* tmp_phone1 = NULL; 282 (!parsed_fields[phone_field_grammars_[i].phone_part]->max_length() ||
161 AutoFillField* tmp_phone2 = NULL; 283 phone_field_grammars_[i].max_size <
162 if (ParseText(&temp_it, phone_field->GetAreaRegex(), &tmp_phone1) && 284 parsed_fields[phone_field_grammars_[i].phone_part]->max_length())) {
163 ParseText(&temp_it, phone_field->GetPhoneRegex(), &tmp_phone2)) { 285 break;
164 phone = tmp_phone1;
165 phone2 = tmp_phone2;
166 q = temp_it;
167 area_code = true;
168 } 286 }
169 } 287 }
170 } else { 288 if (i >= arraysize(phone_field_grammars_))
171 if (!ParseText(&q, phone_field->GetAreaRegex(), &phone)) 289 return false; // Parsing failed.
172 return false; 290 if (phone_field_grammars_[i].regex == REGEX_SEPARATOR)
173 area_code = true; 291 break; // Parsing succeeded.
174 // If this is not a home phone and there was no specification before 292 do {
175 // the phone number actually starts (e.g. field 1 "Area code:", field 2 293 ++i;
176 // "Fax:"), we skip searching for preffix and suffix and bail out. 294 } while (phone_field_grammars_[i].regex != REGEX_SEPARATOR);
177 if (!ParseText(&q, phone_field->GetPhoneRegex(), &phone2) && !regular_phone)
178 return false;
179 } 295 }
296 if (!parsed_fields[FIELD_PHONE])
297 return false;
Ilya Sherman 2011/02/16 23:22:08 Suppose the final pattern were "// Phone: <ac> - <
GeorgeY 2011/02/17 00:21:18 Nope. We will not get here until we have a complet
Ilya Sherman 2011/02/17 00:35:12 But there is no next pattern after the final patte
GeorgeY 2011/02/17 01:12:24 After the last pattern we bail out of the function
180 298
181 // Sometimes phone number fields are separated by "-" (e.g. test page 299 for (int i = 0; i < FIELD_MAX; ++i)
182 // Crate and Barrel Check Out.html). Also, area codes are sometimes 300 phone_field->parsed_phone_fields_[i] = parsed_fields[i];
183 // surrounded by parentheses, so a ")" may appear after the area code field. 301
184 // 302 // Look for optional fields.
185 // We used to match "tel" here, which we've seen in field names (e.g. on
186 // Newegg2.html), but that's too general: some pages (e.g.
187 // uk/Furniture123-1.html) have several phone numbers in succession and we
188 // don't want those to be parsed as components of a single phone number.
189 if (phone2 == NULL)
190 ParseText(&q, phone_field->GetPrefixRegex(), &phone2);
191 303
192 // Look for a third text box. 304 // Look for a third text box.
193 if (phone2) 305 if (!phone_field->parsed_phone_fields_[FIELD_SUFFIX]) {
194 ParseText(&q, phone_field->GetSuffixRegex(), &phone3); 306 if (!ParseText(&q, phone_field->GetSuffixRegex(),
195 307 &phone_field->parsed_phone_fields_[FIELD_SUFFIX])) {
196 // Now we have one, two, or three phone number text fields. Package them 308 ParseText(&q, phone_field->GetSuffixSeparatorRegex(),
197 // up into a PhoneField object. 309 &phone_field->parsed_phone_fields_[FIELD_SUFFIX]);
198
199 if (phone2 == NULL) { // only one field
200 if (area_code) {
201 // It's an area code - it doesn't make sense.
202 return false;
203 }
204 phone_field->phone_ = phone;
205 } else {
206 phone_field->area_code_ = phone;
207 if (phone3 == NULL) { // two fields
208 phone_field->phone_ = phone2;
209 } else { // three boxes: area code, prefix and suffix
210 phone_field->prefix_ = phone2;
211 phone_field->phone_ = phone3;
212 } 310 }
213 } 311 }
214 312
215 // Now look for an extension. 313 // Now look for an extension.
216 ParseText(&q, phone_field->GetExtensionRegex(), &phone_field->extension_); 314 ParseText(&q, phone_field->GetExtensionRegex(),
315 &phone_field->parsed_phone_fields_[FIELD_EXTENSION]);
217 316
218 *iter = q; 317 *iter = q;
219 return true; 318 return true;
220 } 319 }
221 320
222 void PhoneField::SetPhoneType(PHONE_TYPE phone_type) { 321 void PhoneField::SetPhoneType(PhoneType phone_type) {
223 // Field types are different as well, so we create a temporary phone number, 322 // Field types are different as well, so we create a temporary phone number,
224 // to get relevant field types. 323 // to get relevant field types.
225 if (phone_type == HOME_PHONE) 324 if (phone_type == HOME_PHONE)
226 number_.reset(new HomePhoneNumber); 325 number_.reset(new HomePhoneNumber);
227 else 326 else
228 number_.reset(new FaxNumber); 327 number_.reset(new FaxNumber);
229 phone_type_ = phone_type; 328 phone_type_ = phone_type;
230 } 329 }
231 330
OLDNEW
« no previous file with comments | « chrome/browser/autofill/phone_field.h ('k') | chrome/browser/autofill/phone_field_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698