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_number.h" | 5 #include "chrome/browser/autofill/phone_number.h" |
6 | 6 |
7 #include "base/basictypes.h" | 7 #include "base/basictypes.h" |
8 #include "base/string_number_conversions.h" | 8 #include "base/string_number_conversions.h" |
9 #include "base/string_util.h" | 9 #include "base/string_util.h" |
10 #include "base/utf_string_conversions.h" | 10 #include "base/utf_string_conversions.h" |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
47 *this = number; | 47 *this = number; |
48 } | 48 } |
49 | 49 |
50 PhoneNumber::~PhoneNumber() {} | 50 PhoneNumber::~PhoneNumber() {} |
51 | 51 |
52 PhoneNumber& PhoneNumber::operator=(const PhoneNumber& number) { | 52 PhoneNumber& PhoneNumber::operator=(const PhoneNumber& number) { |
53 if (this == &number) | 53 if (this == &number) |
54 return *this; | 54 return *this; |
55 number_ = number.number_; | 55 number_ = number.number_; |
56 phone_group_ = number.phone_group_; | 56 phone_group_ = number.phone_group_; |
57 ClearCachedNumbers(); | 57 cached_parsed_phone_ = number.cached_parsed_phone_; |
58 return *this; | 58 return *this; |
59 } | 59 } |
60 | 60 |
61 void PhoneNumber::GetMatchingTypes(const string16& text, | 61 void PhoneNumber::GetMatchingTypes(const string16& text, |
62 FieldTypeSet* matching_types) const { | 62 FieldTypeSet* matching_types) const { |
63 string16 stripped_text(text); | 63 string16 stripped_text(text); |
64 StripPunctuation(&stripped_text); | 64 StripPunctuation(&stripped_text); |
65 | 65 |
66 if (!UpdateCacheIfNeeded()) | 66 if (!cached_parsed_phone_.ValidNumber()) |
67 return; | 67 return; |
68 | 68 |
69 if (IsNumber(stripped_text, cached_local_number_)) | 69 if (IsNumber(stripped_text, cached_parsed_phone_.GetNumber())) |
70 matching_types->insert(GetNumberType()); | 70 matching_types->insert(GetNumberType()); |
71 | 71 |
72 if (stripped_text == cached_city_code_) | 72 if (stripped_text == cached_parsed_phone_.GetCityCode()) |
73 matching_types->insert(GetCityCodeType()); | 73 matching_types->insert(GetCityCodeType()); |
74 | 74 |
75 if (stripped_text == cached_country_code_) | 75 if (stripped_text == cached_parsed_phone_.GetCountryCode()) |
76 matching_types->insert(GetCountryCodeType()); | 76 matching_types->insert(GetCountryCodeType()); |
77 | 77 |
78 string16 city_and_local(cached_city_code_); | 78 string16 city_and_local(cached_parsed_phone_.GetCityCode()); |
79 city_and_local.append(cached_local_number_); | 79 city_and_local.append(cached_parsed_phone_.GetNumber()); |
80 if (stripped_text == city_and_local) | 80 if (stripped_text == city_and_local) |
81 matching_types->insert(GetCityAndNumberType()); | 81 matching_types->insert(GetCityAndNumberType()); |
82 | 82 |
83 // Whole number is compared to unfiltered text - it would be parsed for phone | 83 // Whole number is compared to unfiltered text - it would be parsed for phone |
84 // comparision (e.g. 1-800-FLOWERS and 18003569377 are the same) | 84 // comparision (e.g. 1-800-FLOWERS and 18003569377 are the same) |
85 if (IsWholeNumber(text)) | 85 if (IsWholeNumber(text)) |
86 matching_types->insert(GetWholeNumberType()); | 86 matching_types->insert(GetWholeNumberType()); |
87 } | 87 } |
88 | 88 |
89 void PhoneNumber::GetNonEmptyTypes(FieldTypeSet* non_empty_types) const { | 89 void PhoneNumber::GetNonEmptyTypes(FieldTypeSet* non_empty_types) const { |
90 DCHECK(non_empty_types); | 90 DCHECK(non_empty_types); |
91 | 91 |
92 if (number_.empty()) | 92 if (number_.empty()) |
93 return; | 93 return; |
94 | 94 |
95 non_empty_types->insert(GetWholeNumberType()); | 95 non_empty_types->insert(GetWholeNumberType()); |
96 | 96 |
97 if (!UpdateCacheIfNeeded()) | 97 if (!cached_parsed_phone_.ValidNumber()) |
98 return; | 98 return; |
99 | 99 |
100 non_empty_types->insert(GetNumberType()); | 100 non_empty_types->insert(GetNumberType()); |
101 | 101 |
102 if (!cached_city_code_.empty()) { | 102 if (!cached_parsed_phone_.GetCityCode().empty()) { |
103 non_empty_types->insert(GetCityCodeType()); | 103 non_empty_types->insert(GetCityCodeType()); |
104 non_empty_types->insert(GetCityAndNumberType()); | 104 non_empty_types->insert(GetCityAndNumberType()); |
105 } | 105 } |
106 | 106 |
107 if (!cached_country_code_.empty()) | 107 if (!cached_parsed_phone_.GetCountryCode().empty()) |
108 non_empty_types->insert(GetCountryCodeType()); | 108 non_empty_types->insert(GetCountryCodeType()); |
109 } | 109 } |
110 | 110 |
111 string16 PhoneNumber::GetInfo(AutofillFieldType type) const { | 111 string16 PhoneNumber::GetInfo(AutofillFieldType type) const { |
112 if (type == GetWholeNumberType()) | 112 if (type == GetWholeNumberType()) |
113 return number_; | 113 return number_; |
114 if (!UpdateCacheIfNeeded()) | 114 |
| 115 if (!cached_parsed_phone_.ValidNumber()) |
115 return string16(); | 116 return string16(); |
116 | 117 |
117 if (type == GetNumberType()) | 118 if (type == GetNumberType()) |
118 return cached_local_number_; | 119 return cached_parsed_phone_.GetNumber(); |
119 | 120 |
120 if (type == GetCityCodeType()) | 121 if (type == GetCityCodeType()) |
121 return cached_city_code_; | 122 return cached_parsed_phone_.GetCityCode(); |
122 | 123 |
123 if (type == GetCountryCodeType()) | 124 if (type == GetCountryCodeType()) |
124 return cached_country_code_; | 125 return cached_parsed_phone_.GetCountryCode(); |
125 | 126 |
126 string16 city_and_local(cached_city_code_); | 127 string16 city_and_local(cached_parsed_phone_.GetCityCode()); |
127 city_and_local.append(cached_local_number_); | 128 city_and_local.append(cached_parsed_phone_.GetNumber()); |
128 if (type == GetCityAndNumberType()) | 129 if (type == GetCityAndNumberType()) |
129 return city_and_local; | 130 return city_and_local; |
130 | 131 |
131 return string16(); | 132 return string16(); |
132 } | 133 } |
133 | 134 |
134 void PhoneNumber::SetInfo(AutofillFieldType type, const string16& value) { | 135 void PhoneNumber::SetInfo(AutofillFieldType type, const string16& value) { |
135 FieldTypeSubGroup subgroup = AutofillType(type).subgroup(); | 136 FieldTypeSubGroup subgroup = AutofillType(type).subgroup(); |
136 FieldTypeGroup group = AutofillType(type).group(); | 137 FieldTypeGroup group = AutofillType(type).group(); |
137 if (phone_group_ == AutofillType::NO_GROUP) | 138 if (phone_group_ == AutofillType::NO_GROUP) |
138 phone_group_ = group; // First call on empty phone - set the group. | 139 phone_group_ = group; // First call on empty phone - set the group. |
139 ClearCachedNumbers(); | |
140 if (subgroup == AutofillType::PHONE_NUMBER) { | 140 if (subgroup == AutofillType::PHONE_NUMBER) { |
141 // Should not be set directly. | 141 // Should not be set directly. |
142 NOTREACHED(); | 142 NOTREACHED(); |
143 } else if (subgroup == AutofillType::PHONE_CITY_CODE) { | 143 } else if (subgroup == AutofillType::PHONE_CITY_CODE) { |
144 // Should not be set directly. | 144 // Should not be set directly. |
145 NOTREACHED(); | 145 NOTREACHED(); |
146 } else if (subgroup == AutofillType::PHONE_COUNTRY_CODE) { | 146 } else if (subgroup == AutofillType::PHONE_COUNTRY_CODE) { |
147 // Should not be set directly. | 147 // Should not be set directly. |
148 NOTREACHED(); | 148 NOTREACHED(); |
149 } else if (subgroup == AutofillType::PHONE_CITY_AND_NUMBER || | 149 } else if (subgroup == AutofillType::PHONE_CITY_AND_NUMBER || |
150 subgroup == AutofillType::PHONE_WHOLE_NUMBER) { | 150 subgroup == AutofillType::PHONE_WHOLE_NUMBER) { |
151 number_ = value; | 151 number_ = value; |
| 152 cached_parsed_phone_ = autofill_i18n::PhoneObject(number_, locale_); |
152 StripPunctuation(&number_); | 153 StripPunctuation(&number_); |
153 } else { | 154 } else { |
154 NOTREACHED(); | 155 NOTREACHED(); |
155 } | 156 } |
156 } | 157 } |
157 | 158 |
158 bool PhoneNumber::NormalizePhone() { | 159 bool PhoneNumber::NormalizePhone() { |
159 // Empty number does not need normalization. | 160 // Empty number does not need normalization. |
160 if (number_.empty()) | 161 if (number_.empty()) |
161 return true; | 162 return true; |
162 | 163 |
163 ClearCachedNumbers(); | 164 number_ = cached_parsed_phone_.GetWholeNumber(); |
164 number_ = autofill_i18n::NormalizePhoneNumber(number_, locale_); | |
165 return !number_.empty(); | 165 return !number_.empty(); |
166 } | 166 } |
167 | 167 |
168 void PhoneNumber::set_locale(const std::string& locale) { | 168 void PhoneNumber::set_locale(const std::string& locale) { |
169 locale_ = locale; | 169 locale_ = locale; |
170 ClearCachedNumbers(); | 170 if (!number_.empty() && cached_parsed_phone_.GetLocale() != locale_) |
| 171 cached_parsed_phone_ = autofill_i18n::PhoneObject(number_, locale_); |
171 } | 172 } |
172 | 173 |
173 AutofillFieldType PhoneNumber::GetNumberType() const { | 174 AutofillFieldType PhoneNumber::GetNumberType() const { |
174 if (phone_group_ == AutofillType::PHONE_HOME) | 175 if (phone_group_ == AutofillType::PHONE_HOME) |
175 return PHONE_HOME_NUMBER; | 176 return PHONE_HOME_NUMBER; |
176 else if (phone_group_ == AutofillType::PHONE_FAX) | 177 else if (phone_group_ == AutofillType::PHONE_FAX) |
177 return PHONE_FAX_NUMBER; | 178 return PHONE_FAX_NUMBER; |
178 else | 179 else |
179 NOTREACHED(); | 180 NOTREACHED(); |
180 return UNKNOWN_TYPE; | 181 return UNKNOWN_TYPE; |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
262 return true; | 263 return true; |
263 if (text.length() == kPrefixLength && StartsWith(number, text, true)) | 264 if (text.length() == kPrefixLength && StartsWith(number, text, true)) |
264 return true; | 265 return true; |
265 if (text.length() == kSuffixLength && EndsWith(number, text, true)) | 266 if (text.length() == kSuffixLength && EndsWith(number, text, true)) |
266 return true; | 267 return true; |
267 | 268 |
268 return false; | 269 return false; |
269 } | 270 } |
270 | 271 |
271 bool PhoneNumber::IsWholeNumber(const string16& text) const { | 272 bool PhoneNumber::IsWholeNumber(const string16& text) const { |
272 return autofill_i18n::ComparePhones(text, number_, locale_) == | 273 return cached_parsed_phone_.ComparePhones(text) == |
273 autofill_i18n::PHONES_EQUAL; | 274 autofill_i18n::PHONES_EQUAL; |
274 } | 275 } |
275 | 276 |
276 // Static. | 277 // Static. |
277 void PhoneNumber::StripPunctuation(string16* number) { | 278 void PhoneNumber::StripPunctuation(string16* number) { |
278 RemoveChars(*number, kPhoneNumberSeparators, number); | 279 RemoveChars(*number, kPhoneNumberSeparators, number); |
279 } | 280 } |
280 | |
281 void PhoneNumber::ClearCachedNumbers() const { | |
282 cached_country_code_.clear(); | |
283 cached_city_code_.clear(); | |
284 cached_local_number_.clear(); | |
285 } | |
286 | |
287 bool PhoneNumber::UpdateCacheIfNeeded() const { | |
288 if (cached_local_number_.empty() && !number_.empty()) { | |
289 return autofill_i18n::ParsePhoneNumber( | |
290 number_, locale_, &cached_country_code_, &cached_city_code_, | |
291 &cached_local_number_); | |
292 } else { | |
293 return true; | |
294 } | |
295 } | |
OLD | NEW |