| 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_.IsValidNumber()) |
| 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_.IsValidNumber()) |
| 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_.IsValidNumber()) |
| 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 |