 Chromium Code Reviews
 Chromium Code Reviews Issue 2883333003:
  Payment request shipping address editor now properly handles countries  (Closed)
    
  
    Issue 2883333003:
  Payment request shipping address editor now properly handles countries  (Closed) 
  | OLD | NEW | 
|---|---|
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. | 1 // Copyright 2017 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/ui/views/payments/shipping_address_editor_view_controll er.h" | 5 #include "chrome/browser/ui/views/payments/shipping_address_editor_view_controll er.h" | 
| 6 | 6 | 
| 7 #include <utility> | |
| 8 | |
| 9 #include "base/bind.h" | 7 #include "base/bind.h" | 
| 10 #include "base/bind_helpers.h" | 8 #include "base/bind_helpers.h" | 
| 11 #include "base/callback.h" | 9 #include "base/callback.h" | 
| 12 #include "base/memory/ptr_util.h" | 10 #include "base/memory/ptr_util.h" | 
| 13 #include "base/strings/utf_string_conversions.h" | 11 #include "base/strings/utf_string_conversions.h" | 
| 14 #include "base/threading/thread_task_runner_handle.h" | 12 #include "base/threading/thread_task_runner_handle.h" | 
| 15 #include "chrome/browser/ui/views/payments/payment_request_dialog_view.h" | 13 #include "chrome/browser/ui/views/payments/payment_request_dialog_view.h" | 
| 16 #include "chrome/browser/ui/views/payments/payment_request_dialog_view_ids.h" | 14 #include "chrome/browser/ui/views/payments/payment_request_dialog_view_ids.h" | 
| 17 #include "chrome/browser/ui/views/payments/validating_combobox.h" | 15 #include "chrome/browser/ui/views/payments/validating_combobox.h" | 
| 18 #include "chrome/browser/ui/views/payments/validating_textfield.h" | 16 #include "chrome/browser/ui/views/payments/validating_textfield.h" | 
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 56 if (type == autofill::kPostalCodeField) | 54 if (type == autofill::kPostalCodeField) | 
| 57 return autofill::ADDRESS_HOME_ZIP; | 55 return autofill::ADDRESS_HOME_ZIP; | 
| 58 if (type == autofill::kSortingCodeField) | 56 if (type == autofill::kSortingCodeField) | 
| 59 return autofill::ADDRESS_HOME_SORTING_CODE; | 57 return autofill::ADDRESS_HOME_SORTING_CODE; | 
| 60 if (type == autofill::kCountryField) | 58 if (type == autofill::kCountryField) | 
| 61 return autofill::ADDRESS_HOME_COUNTRY; | 59 return autofill::ADDRESS_HOME_COUNTRY; | 
| 62 NOTREACHED(); | 60 NOTREACHED(); | 
| 63 return autofill::UNKNOWN_TYPE; | 61 return autofill::UNKNOWN_TYPE; | 
| 64 } | 62 } | 
| 65 | 63 | 
| 64 const size_t kInvalidCountryIndex = static_cast<size_t>(-1); | |
| 
Mathieu
2017/05/17 19:18:30
isn't size_t unsigned?  What happens here?
 
MAD
2017/05/17 19:54:29
It created a SIZE_MAX value without having to incl
 | |
| 65 | |
| 66 } // namespace | 66 } // namespace | 
| 67 | 67 | 
| 68 ShippingAddressEditorViewController::ShippingAddressEditorViewController( | 68 ShippingAddressEditorViewController::ShippingAddressEditorViewController( | 
| 69 PaymentRequestSpec* spec, | 69 PaymentRequestSpec* spec, | 
| 70 PaymentRequestState* state, | 70 PaymentRequestState* state, | 
| 71 PaymentRequestDialogView* dialog, | 71 PaymentRequestDialogView* dialog, | 
| 72 BackNavigationType back_navigation_type, | 72 BackNavigationType back_navigation_type, | 
| 73 base::OnceClosure on_edited, | 73 base::OnceClosure on_edited, | 
| 74 base::OnceCallback<void(const autofill::AutofillProfile&)> on_added, | 74 base::OnceCallback<void(const autofill::AutofillProfile&)> on_added, | 
| 75 autofill::AutofillProfile* profile) | 75 autofill::AutofillProfile* profile) | 
| 76 : EditorViewController(spec, state, dialog, back_navigation_type), | 76 : EditorViewController(spec, state, dialog, back_navigation_type), | 
| 77 on_edited_(std::move(on_edited)), | 77 on_edited_(std::move(on_edited)), | 
| 78 on_added_(std::move(on_added)), | 78 on_added_(std::move(on_added)), | 
| 79 profile_to_edit_(profile), | 79 profile_to_edit_(profile), | 
| 80 chosen_country_index_(0), | 80 chosen_country_index_(kInvalidCountryIndex), | 
| 81 failed_to_load_region_data_(false) { | 81 failed_to_load_region_data_(false) { | 
| 82 UpdateCountries(nullptr); | |
| 
Mathieu
2017/05/17 19:18:30
nit: /*model=*/nullptr
 
MAD
2017/05/17 19:54:29
Done.
 | |
| 82 UpdateEditorFields(); | 83 UpdateEditorFields(); | 
| 83 } | 84 } | 
| 84 | 85 | 
| 85 ShippingAddressEditorViewController::~ShippingAddressEditorViewController() {} | 86 ShippingAddressEditorViewController::~ShippingAddressEditorViewController() {} | 
| 86 | 87 | 
| 87 std::vector<EditorField> | 88 std::vector<EditorField> | 
| 88 ShippingAddressEditorViewController::GetFieldDefinitions() { | 89 ShippingAddressEditorViewController::GetFieldDefinitions() { | 
| 89 return editor_fields_; | 90 return editor_fields_; | 
| 90 } | 91 } | 
| 91 | 92 | 
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 144 std::unique_ptr<ui::ComboboxModel> | 145 std::unique_ptr<ui::ComboboxModel> | 
| 145 ShippingAddressEditorViewController::GetComboboxModelForType( | 146 ShippingAddressEditorViewController::GetComboboxModelForType( | 
| 146 const autofill::ServerFieldType& type) { | 147 const autofill::ServerFieldType& type) { | 
| 147 switch (type) { | 148 switch (type) { | 
| 148 case autofill::ADDRESS_HOME_COUNTRY: { | 149 case autofill::ADDRESS_HOME_COUNTRY: { | 
| 149 std::unique_ptr<autofill::CountryComboboxModel> model = | 150 std::unique_ptr<autofill::CountryComboboxModel> model = | 
| 150 base::MakeUnique<autofill::CountryComboboxModel>(); | 151 base::MakeUnique<autofill::CountryComboboxModel>(); | 
| 151 model->SetCountries(*state()->GetPersonalDataManager(), | 152 model->SetCountries(*state()->GetPersonalDataManager(), | 
| 152 base::Callback<bool(const std::string&)>(), | 153 base::Callback<bool(const std::string&)>(), | 
| 153 state()->GetApplicationLocale()); | 154 state()->GetApplicationLocale()); | 
| 154 country_codes_.clear(); | 155 if (model->countries().size() != countries_.size()) | 
| 155 for (size_t i = 0; i < model->countries().size(); ++i) { | 156 UpdateCountries(model.get()); | 
| 156 if (model->countries()[i].get()) | |
| 157 country_codes_.push_back(model->countries()[i]->country_code()); | |
| 158 else | |
| 159 country_codes_.push_back(""); // Separator. | |
| 160 } | |
| 161 return std::move(model); | 157 return std::move(model); | 
| 162 } | 158 } | 
| 163 case autofill::ADDRESS_HOME_STATE: { | 159 case autofill::ADDRESS_HOME_STATE: { | 
| 164 std::unique_ptr<autofill::RegionComboboxModel> model = | 160 std::unique_ptr<autofill::RegionComboboxModel> model = | 
| 165 base::MakeUnique<autofill::RegionComboboxModel>(); | 161 base::MakeUnique<autofill::RegionComboboxModel>(); | 
| 166 model->LoadRegionData(country_codes_[chosen_country_index_], | 162 if (chosen_country_index_ < countries_.size()) { | 
| 167 state()->GetRegionDataLoader(), | 163 model->LoadRegionData(countries_[chosen_country_index_].first, | 
| 168 /*timeout_ms=*/5000); | 164 state()->GetRegionDataLoader(), | 
| 169 if (!model->IsPendingRegionDataLoad()) { | 165 /*timeout_ms=*/5000); | 
| 170 // If the data was already pre-loaded, the observer won't get notified | 166 if (!model->IsPendingRegionDataLoad()) { | 
| 171 // so we have to check for failure here. | 167 // If the data was already pre-loaded, the observer won't get notified | 
| 172 failed_to_load_region_data_ = model->failed_to_load_data(); | 168 // so we have to check for failure here. | 
| 173 if (failed_to_load_region_data_) { | 169 failed_to_load_region_data_ = model->failed_to_load_data(); | 
| 174 // We can update the view synchronously while building the view. | |
| 175 OnDataChanged(/*synchronous=*/false); | |
| 176 } | 170 } | 
| 171 } else { | |
| 172 failed_to_load_region_data_ = true; | |
| 173 } | |
| 174 if (failed_to_load_region_data_) { | |
| 175 // We can't update the view synchronously while building the view. | |
| 176 OnDataChanged(/*synchronous=*/false); | |
| 177 } | 177 } | 
| 178 return std::move(model); | 178 return std::move(model); | 
| 179 } | 179 } | 
| 180 default: | 180 default: | 
| 181 NOTREACHED(); | 181 NOTREACHED(); | 
| 182 break; | 182 break; | 
| 183 } | 183 } | 
| 184 return std::unique_ptr<ui::ComboboxModel>(); | 184 return std::unique_ptr<ui::ComboboxModel>(); | 
| 185 } | 185 } | 
| 186 | 186 | 
| 187 void ShippingAddressEditorViewController::OnPerformAction( | 187 void ShippingAddressEditorViewController::OnPerformAction( | 
| 188 views::Combobox* sender) { | 188 views::Combobox* sender) { | 
| 189 EditorViewController::OnPerformAction(sender); | 189 EditorViewController::OnPerformAction(sender); | 
| 190 if (sender->id() != autofill::ADDRESS_HOME_COUNTRY) | 190 if (sender->id() != autofill::ADDRESS_HOME_COUNTRY) | 
| 191 return; | 191 return; | 
| 192 DCHECK_GE(sender->selected_index(), 0); | 192 DCHECK_GE(sender->selected_index(), 0); | 
| 193 if (chosen_country_index_ != static_cast<size_t>(sender->selected_index())) { | 193 if (chosen_country_index_ != static_cast<size_t>(sender->selected_index())) { | 
| 194 chosen_country_index_ = sender->selected_index(); | 194 chosen_country_index_ = sender->selected_index(); | 
| 195 failed_to_load_region_data_ = false; | 195 failed_to_load_region_data_ = false; | 
| 196 // View update must be asynchronous to let the combobox finish performing | 196 // View update must be asynchronous to let the combobox finish performing | 
| 197 // the action. | 197 // the action. | 
| 198 OnDataChanged(/*synchronous=*/false); | 198 OnDataChanged(/*synchronous=*/false); | 
| 199 } | 199 } | 
| 200 } | 200 } | 
| 201 | 201 | 
| 202 void ShippingAddressEditorViewController::UpdateEditorView() { | 202 void ShippingAddressEditorViewController::UpdateEditorView() { | 
| 203 EditorViewController::UpdateEditorView(); | 203 EditorViewController::UpdateEditorView(); | 
| 204 if (chosen_country_index_ > 0UL) { | 204 if (chosen_country_index_ > 0UL && | 
| 205 chosen_country_index_ < countries_.size()) { | |
| 205 views::Combobox* country_combo_box = static_cast<views::Combobox*>( | 206 views::Combobox* country_combo_box = static_cast<views::Combobox*>( | 
| 206 dialog()->GetViewByID(autofill::ADDRESS_HOME_COUNTRY)); | 207 dialog()->GetViewByID(autofill::ADDRESS_HOME_COUNTRY)); | 
| 207 DCHECK(country_combo_box); | 208 DCHECK(country_combo_box); | 
| 209 DCHECK_EQ(countries_.size(), | |
| 210 static_cast<size_t>(country_combo_box->GetRowCount())); | |
| 208 country_combo_box->SetSelectedIndex(chosen_country_index_); | 211 country_combo_box->SetSelectedIndex(chosen_country_index_); | 
| 212 } else if (countries_.size() > 0UL) { | |
| 213 chosen_country_index_ = 0UL; | |
| 214 } else { | |
| 215 chosen_country_index_ = kInvalidCountryIndex; | |
| 209 } | 216 } | 
| 210 // Ignore temporary profile once the editor view has been updated. | 217 // Ignore temporary profile once the editor view has been updated. | 
| 211 temporary_profile_.reset(nullptr); | 218 temporary_profile_.reset(nullptr); | 
| 
Mathieu
2017/05/17 19:18:30
just reset() is fine here
 
MAD
2017/05/17 19:54:29
Done.
 | |
| 212 } | 219 } | 
| 213 | 220 | 
| 214 base::string16 ShippingAddressEditorViewController::GetSheetTitle() { | 221 base::string16 ShippingAddressEditorViewController::GetSheetTitle() { | 
| 215 // TODO(crbug.com/712074): Editor title should reflect the missing information | 222 // TODO(crbug.com/712074): Editor title should reflect the missing information | 
| 216 // in the case that one or more fields are missing. | 223 // in the case that one or more fields are missing. | 
| 217 return profile_to_edit_ ? l10n_util::GetStringUTF16(IDS_PAYMENTS_EDIT_ADDRESS) | 224 return profile_to_edit_ ? l10n_util::GetStringUTF16(IDS_PAYMENTS_EDIT_ADDRESS) | 
| 218 : l10n_util::GetStringUTF16(IDS_PAYMENTS_ADD_ADDRESS); | 225 : l10n_util::GetStringUTF16(IDS_PAYMENTS_ADD_ADDRESS); | 
| 219 } | 226 } | 
| 220 | 227 | 
| 221 std::unique_ptr<views::Button> | 228 std::unique_ptr<views::Button> | 
| 222 ShippingAddressEditorViewController::CreatePrimaryButton() { | 229 ShippingAddressEditorViewController::CreatePrimaryButton() { | 
| 223 std::unique_ptr<views::Button> button( | 230 std::unique_ptr<views::Button> button( | 
| 224 EditorViewController::CreatePrimaryButton()); | 231 EditorViewController::CreatePrimaryButton()); | 
| 225 button->set_id(static_cast<int>(DialogViewID::SAVE_ADDRESS_BUTTON)); | 232 button->set_id(static_cast<int>(DialogViewID::SAVE_ADDRESS_BUTTON)); | 
| 226 return button; | 233 return button; | 
| 227 } | 234 } | 
| 228 | 235 | 
| 236 void ShippingAddressEditorViewController::UpdateCountries( | |
| 237 autofill::CountryComboboxModel* model) { | |
| 238 autofill::CountryComboboxModel local_model; | |
| 239 if (!model) { | |
| 240 local_model.SetCountries(*state()->GetPersonalDataManager(), | |
| 241 base::Callback<bool(const std::string&)>(), | |
| 242 state()->GetApplicationLocale()); | |
| 243 model = &local_model; | |
| 244 } | |
| 245 | |
| 246 for (size_t i = 0; i < model->countries().size(); ++i) { | |
| 247 autofill::AutofillCountry* country(model->countries()[i].get()); | |
| 248 if (country) { | |
| 249 countries_.push_back( | |
| 250 std::make_pair(country->country_code(), country->name())); | |
| 251 } else { | |
| 252 // Separator, kept to make sure the size of the vector stays the same. | |
| 253 countries_.push_back(std::make_pair("", base::UTF8ToUTF16(""))); | |
| 254 } | |
| 255 } | |
| 256 // If there is a profile to edit, make sure to use its country for the initial | |
| 257 // |chosen_country_index_|. | |
| 258 if (profile_to_edit_) { | |
| 259 autofill::AutofillType country_type(autofill::ADDRESS_HOME_COUNTRY); | |
| 260 base::string16 chosen_country(profile_to_edit_->GetInfo( | |
| 261 country_type, state()->GetApplicationLocale())); | |
| 262 for (chosen_country_index_ = 0; chosen_country_index_ < countries_.size(); | |
| 263 ++chosen_country_index_) { | |
| 264 if (chosen_country == countries_[chosen_country_index_].second) | |
| 265 break; | |
| 266 } | |
| 267 // Make sure the the country was actually found in |countries_|, otherwise | |
| 268 // set |chosen_country_index_| as the default country at index 0. | |
| 269 if (chosen_country_index_ >= countries_.size()) { | |
| 270 // But only if there is at least one country. | |
| 271 if (countries_.size() > 0) { | |
| 272 LOG(ERROR) << "Unexpected country: " << chosen_country; | |
| 273 chosen_country_index_ = 0; | |
| 274 profile_to_edit_->SetInfo(country_type, | |
| 275 countries_[chosen_country_index_].second, | |
| 276 state()->GetApplicationLocale()); | |
| 277 } else { | |
| 278 LOG(ERROR) << "Unexpected empty country list!"; | |
| 279 chosen_country_index_ = kInvalidCountryIndex; | |
| 280 } | |
| 281 } | |
| 282 } else if (countries_.size() > 0) { | |
| 283 chosen_country_index_ = 0; | |
| 284 } | |
| 285 } | |
| 286 | |
| 229 void ShippingAddressEditorViewController::UpdateEditorFields() { | 287 void ShippingAddressEditorViewController::UpdateEditorFields() { | 
| 230 editor_fields_.clear(); | 288 editor_fields_.clear(); | 
| 231 std::string chosen_country_code; | 289 std::string chosen_country_code; | 
| 232 if (chosen_country_index_ < country_codes_.size()) | 290 if (chosen_country_index_ < countries_.size()) | 
| 233 chosen_country_code = country_codes_[chosen_country_index_]; | 291 chosen_country_code = countries_[chosen_country_index_].first; | 
| 234 | 292 | 
| 235 std::unique_ptr<base::ListValue> components(new base::ListValue); | 293 std::unique_ptr<base::ListValue> components(new base::ListValue); | 
| 236 std::string unused; | 294 std::string unused; | 
| 237 autofill::GetAddressComponents(chosen_country_code, | 295 autofill::GetAddressComponents(chosen_country_code, | 
| 238 state()->GetApplicationLocale(), | 296 state()->GetApplicationLocale(), | 
| 239 components.get(), &unused); | 297 components.get(), &unused); | 
| 240 for (size_t line_index = 0; line_index < components->GetSize(); | 298 for (size_t line_index = 0; line_index < components->GetSize(); | 
| 241 ++line_index) { | 299 ++line_index) { | 
| 242 const base::ListValue* line = nullptr; | 300 const base::ListValue* line = nullptr; | 
| 243 if (!components->GetList(line_index, &line)) { | 301 if (!components->GetList(line_index, &line)) { | 
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 316 FROM_HERE, | 374 FROM_HERE, | 
| 317 base::BindOnce(&ShippingAddressEditorViewController::UpdateEditorView, | 375 base::BindOnce(&ShippingAddressEditorViewController::UpdateEditorView, | 
| 318 base::Unretained(this))); | 376 base::Unretained(this))); | 
| 319 } | 377 } | 
| 320 } | 378 } | 
| 321 | 379 | 
| 322 bool ShippingAddressEditorViewController::SaveFieldsToProfile( | 380 bool ShippingAddressEditorViewController::SaveFieldsToProfile( | 
| 323 autofill::AutofillProfile* profile, | 381 autofill::AutofillProfile* profile, | 
| 324 bool ignore_errors) { | 382 bool ignore_errors) { | 
| 325 const std::string& locale = state()->GetApplicationLocale(); | 383 const std::string& locale = state()->GetApplicationLocale(); | 
| 384 // The country must be set first, because the profile uses the country to | |
| 385 // interpret some of the data (e.g., phone numbers) passed to SetInfo. | |
| 386 views::Combobox* combobox = static_cast<views::Combobox*>( | |
| 387 dialog()->GetViewByID(autofill::ADDRESS_HOME_COUNTRY)); | |
| 388 // The combobox can be null when saving to temporary profile while updating | |
| 389 // the view. | |
| 390 if (combobox) { | |
| 391 base::string16 country(combobox->GetTextForRow(combobox->selected_index())); | |
| 392 bool success = | |
| 393 profile->SetInfo(autofill::AutofillType(autofill::ADDRESS_HOME_COUNTRY), | |
| 394 country, locale); | |
| 395 LOG_IF(ERROR, !success && !ignore_errors) | |
| 396 << "Can't set profile country to: " << country; | |
| 397 if (!success && !ignore_errors) | |
| 398 return false; | |
| 399 } else { | |
| 400 DCHECK_EQ(temporary_profile_.get(), profile); | |
| 401 } | |
| 402 | |
| 326 bool success = true; | 403 bool success = true; | 
| 327 for (const auto& field : text_fields()) { | 404 for (const auto& field : text_fields()) { | 
| 328 // Force a blur in case the value was left untouched. | 405 // Force a blur in case the value was left untouched. | 
| 329 field.first->OnBlur(); | 406 field.first->OnBlur(); | 
| 330 // ValidatingTextfield* is the key, EditorField is the value. | 407 // ValidatingTextfield* is the key, EditorField is the value. | 
| 331 if (field.first->invalid()) { | 408 if (field.first->invalid()) { | 
| 332 success = false; | 409 success = false; | 
| 333 } else { | 410 } else { | 
| 334 success = profile->SetInfo(autofill::AutofillType(field.second.type), | 411 success = profile->SetInfo(autofill::AutofillType(field.second.type), | 
| 335 field.first->text(), locale); | 412 field.first->text(), locale); | 
| 336 } | 413 } | 
| 337 LOG_IF(ERROR, !success && !ignore_errors) | 414 LOG_IF(ERROR, !success && !ignore_errors) | 
| 338 << "Can't setinfo(" << field.second.type << ", " << field.first->text(); | 415 << "Can't setinfo(" << field.second.type << ", " << field.first->text(); | 
| 339 if (!success && !ignore_errors) | 416 if (!success && !ignore_errors) | 
| 340 return false; | 417 return false; | 
| 341 } | 418 } | 
| 342 for (const auto& field : comboboxes()) { | 419 for (const auto& field : comboboxes()) { | 
| 343 // ValidatingCombobox* is the key, EditorField is the value. | 420 // ValidatingCombobox* is the key, EditorField is the value. | 
| 344 ValidatingCombobox* combobox = field.first; | 421 ValidatingCombobox* combobox = field.first; | 
| 422 // The country has already been dealt with. | |
| 423 if (combobox->id() == autofill::ADDRESS_HOME_COUNTRY) | |
| 424 continue; | |
| 345 if (combobox->invalid()) { | 425 if (combobox->invalid()) { | 
| 346 success = false; | 426 success = false; | 
| 347 } else { | 427 } else { | 
| 348 if (combobox->id() == autofill::ADDRESS_HOME_COUNTRY) { | 428 success = profile->SetInfo( | 
| 349 success = profile->SetInfo( | 429 autofill::AutofillType(field.second.type), | 
| 350 autofill::AutofillType(field.second.type), | 430 combobox->GetTextForRow(combobox->selected_index()), locale); | 
| 351 base::UTF8ToUTF16(country_codes_[combobox->selected_index()]), | |
| 352 locale); | |
| 353 } else { | |
| 354 success = profile->SetInfo( | |
| 355 autofill::AutofillType(field.second.type), | |
| 356 combobox->GetTextForRow(combobox->selected_index()), locale); | |
| 357 } | |
| 358 } | 431 } | 
| 359 LOG_IF(ERROR, !success && !ignore_errors) | 432 LOG_IF(ERROR, !success && !ignore_errors) | 
| 360 << "Can't setinfo(" << field.second.type << ", " | 433 << "Can't setinfo(" << field.second.type << ", " | 
| 361 << combobox->GetTextForRow(combobox->selected_index()); | 434 << combobox->GetTextForRow(combobox->selected_index()); | 
| 362 if (!success && !ignore_errors) | 435 if (!success && !ignore_errors) | 
| 363 return false; | 436 return false; | 
| 364 } | 437 } | 
| 365 return success; | 438 return success; | 
| 366 } | 439 } | 
| 367 | 440 | 
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 407 | 480 | 
| 408 void ShippingAddressEditorViewController::ShippingAddressValidationDelegate:: | 481 void ShippingAddressEditorViewController::ShippingAddressValidationDelegate:: | 
| 409 ComboboxModelChanged(views::Combobox* combobox) { | 482 ComboboxModelChanged(views::Combobox* combobox) { | 
| 410 controller_->OnComboboxModelChanged(combobox); | 483 controller_->OnComboboxModelChanged(combobox); | 
| 411 } | 484 } | 
| 412 | 485 | 
| 413 bool ShippingAddressEditorViewController::ShippingAddressValidationDelegate:: | 486 bool ShippingAddressEditorViewController::ShippingAddressValidationDelegate:: | 
| 414 ValidateValue(const base::string16& value) { | 487 ValidateValue(const base::string16& value) { | 
| 415 if (!value.empty()) { | 488 if (!value.empty()) { | 
| 416 if (field_.type == autofill::PHONE_HOME_WHOLE_NUMBER && | 489 if (field_.type == autofill::PHONE_HOME_WHOLE_NUMBER && | 
| 490 controller_->chosen_country_index_ < controller_->countries_.size() && | |
| 417 !autofill::IsValidPhoneNumber( | 491 !autofill::IsValidPhoneNumber( | 
| 418 value, | 492 value, controller_->countries_[controller_->chosen_country_index_] | 
| 419 controller_->country_codes_[controller_->chosen_country_index_])) { | 493 .first)) { | 
| 420 controller_->DisplayErrorMessageForField( | 494 controller_->DisplayErrorMessageForField( | 
| 421 field_, l10n_util::GetStringUTF16( | 495 field_, l10n_util::GetStringUTF16( | 
| 422 IDS_PAYMENTS_PHONE_INVALID_VALIDATION_MESSAGE)); | 496 IDS_PAYMENTS_PHONE_INVALID_VALIDATION_MESSAGE)); | 
| 423 return false; | 497 return false; | 
| 424 } | 498 } | 
| 425 // As long as other field types are non-empty, they are valid. | 499 // As long as other field types are non-empty, they are valid. | 
| 426 controller_->DisplayErrorMessageForField(field_, base::ASCIIToUTF16("")); | 500 controller_->DisplayErrorMessageForField(field_, base::ASCIIToUTF16("")); | 
| 427 return true; | 501 return true; | 
| 428 } | 502 } | 
| 429 bool is_required_valid = !field_.required; | 503 bool is_required_valid = !field_.required; | 
| 430 const base::string16 displayed_message = | 504 const base::string16 displayed_message = | 
| 431 is_required_valid ? base::ASCIIToUTF16("") | 505 is_required_valid ? base::ASCIIToUTF16("") | 
| 432 : l10n_util::GetStringUTF16( | 506 : l10n_util::GetStringUTF16( | 
| 433 IDS_PAYMENTS_FIELD_REQUIRED_VALIDATION_MESSAGE); | 507 IDS_PAYMENTS_FIELD_REQUIRED_VALIDATION_MESSAGE); | 
| 434 controller_->DisplayErrorMessageForField(field_, displayed_message); | 508 controller_->DisplayErrorMessageForField(field_, displayed_message); | 
| 435 return is_required_valid; | 509 return is_required_valid; | 
| 436 } | 510 } | 
| 437 | 511 | 
| 438 } // namespace payments | 512 } // namespace payments | 
| OLD | NEW |