Chromium Code Reviews| Index: chrome/browser/ui/autofill/autofill_dialog_controller_impl.cc |
| diff --git a/chrome/browser/ui/autofill/autofill_dialog_controller_impl.cc b/chrome/browser/ui/autofill/autofill_dialog_controller_impl.cc |
| index 05b1c243f25f596af7249c08fb4506d0f19e4610..3e931396cf6385408d7a53a86e602ae2d77baf82 100644 |
| --- a/chrome/browser/ui/autofill/autofill_dialog_controller_impl.cc |
| +++ b/chrome/browser/ui/autofill/autofill_dialog_controller_impl.cc |
| @@ -604,21 +604,10 @@ void AutofillDialogControllerImpl::Show() { |
| AutofillMetrics::SECURITY_METRIC_CROSS_ORIGIN_FRAME); |
| } |
| - // TODO(dbeam): use GetManager()->GetDefaultCountryCodeForNewAddress() |
| - // instead when the country combobox is visible. http://crbug.com/331544 |
| - std::string country_code = "US"; |
| - common::BuildInputsForSection(SECTION_CC, |
| - country_code, |
| - &requested_cc_fields_); |
| - common::BuildInputsForSection(SECTION_BILLING, |
| - country_code, |
| - &requested_billing_fields_); |
| - common::BuildInputsForSection(SECTION_CC_BILLING, |
| - country_code, |
| - &requested_cc_billing_fields_); |
| - common::BuildInputsForSection(SECTION_SHIPPING, |
| - country_code, |
| - &requested_shipping_fields_); |
| + // TODO(dbeam): does SECTION_CC need to be internationalized? |
|
Evan Stade
2014/01/15 23:12:29
I don't think so. I think you can leave out this T
Dan Beam
2014/01/16 01:39:13
Done.
|
| + common::BuildInputsForSection(SECTION_CC, "US", &requested_cc_fields_); |
|
Evan Stade
2014/01/15 23:12:29
pass an empty country code to make it clear it's n
Dan Beam
2014/01/16 01:39:13
Done.
|
| + OnComboboxModelChanged(&billing_country_combobox_model_); |
| + OnComboboxModelChanged(&shipping_country_combobox_model_); |
| // Test whether we need to show the shipping section. If filling that section |
| // would be a no-op, don't show it. |
| @@ -643,7 +632,10 @@ void AutofillDialogControllerImpl::Show() { |
| SubmitButtonDelayBegin(); |
| view_.reset(CreateView()); |
| view_->Show(); |
| + |
| GetManager()->AddObserver(this); |
| + billing_country_combobox_model_.AddObserver(this); |
| + shipping_country_combobox_model_.AddObserver(this); |
| if (!account_chooser_model_->WalletIsSelected()) |
| LogDialogLatencyToShow(); |
| @@ -1098,8 +1090,6 @@ void AutofillDialogControllerImpl::ConstructLegalDocumentsText() { |
| } |
| void AutofillDialogControllerImpl::ResetSectionInput(DialogSection section) { |
| - SetEditingExistingData(section, false); |
| - |
| DetailInputs* inputs = MutableRequestedFieldsForSection(section); |
| for (DetailInputs::iterator it = inputs->begin(); it != inputs->end(); ++it) { |
| it->initial_value = common::GetHardcodedValueForType(it->type); |
| @@ -1170,6 +1160,20 @@ void AutofillDialogControllerImpl::RestoreUserInputFromSnapshot( |
| if (snapshot.empty()) |
| return; |
| + FieldValueMap::const_iterator it = snapshot.find(ADDRESS_BILLING_COUNTRY); |
| + if (it != snapshot.end()) { |
| + billing_country_combobox_model_.SetDefaultCountry( |
| + AutofillCountry::GetCountryCode( |
| + it->second, g_browser_process->GetApplicationLocale())); |
| + } |
| + |
| + FieldValueMap::const_iterator ship_it = snapshot.find(ADDRESS_HOME_COUNTRY); |
| + if (ship_it != snapshot.end()) { |
| + shipping_country_combobox_model_.SetDefaultCountry( |
| + AutofillCountry::GetCountryCode( |
| + ship_it->second, g_browser_process->GetApplicationLocale())); |
| + } |
| + |
| FieldMapWrapper wrapper(snapshot); |
| for (size_t i = SECTION_MIN; i <= SECTION_MAX; ++i) { |
| DialogSection section = static_cast<DialogSection>(i); |
| @@ -1303,9 +1307,11 @@ ui::ComboboxModel* AutofillDialogControllerImpl::ComboboxModelForAutofillType( |
| case CREDIT_CARD_EXP_4_DIGIT_YEAR: |
| return &cc_exp_year_combobox_model_; |
| - case ADDRESS_HOME_COUNTRY: |
| case ADDRESS_BILLING_COUNTRY: |
| - return &country_combobox_model_; |
| + return &billing_country_combobox_model_; |
| + |
| + case ADDRESS_HOME_COUNTRY: |
| + return &shipping_country_combobox_model_; |
| default: |
| return NULL; |
| @@ -1699,23 +1705,29 @@ base::string16 AutofillDialogControllerImpl::InputValidityMessage( |
| return base::string16(); // Line 2 is optional - always valid. |
| case ADDRESS_HOME_CITY: |
| + case ADDRESS_HOME_DEPENDENT_LOCALITY: |
| case ADDRESS_HOME_COUNTRY: |
| break; |
| case ADDRESS_HOME_STATE: |
| - if (!value.empty() && !autofill::IsValidState(value)) { |
| + if (!value.empty() && !autofill::IsValidState(value) && |
| + CountryCodeForSection(section) == "US") { |
| return l10n_util::GetStringUTF16( |
| IDS_AUTOFILL_DIALOG_VALIDATION_INVALID_REGION); |
| } |
| break; |
| case ADDRESS_HOME_ZIP: |
| - if (!value.empty() && !autofill::IsValidZip(value)) { |
| + if (!value.empty() && !autofill::IsValidZip(value) && |
| + CountryCodeForSection(section) == "US") { |
| return l10n_util::GetStringUTF16( |
| IDS_AUTOFILL_DIALOG_VALIDATION_INVALID_ZIP_CODE); |
| } |
| break; |
| + case ADDRESS_HOME_SORTING_CODE: |
| + break; |
| + |
| case NAME_FULL: |
| // Wallet requires a first and last billing name. |
| if (section == SECTION_CC_BILLING && !value.empty() && |
| @@ -1747,18 +1759,18 @@ ValidityMessages AutofillDialogControllerImpl::InputsAreValid( |
| DialogSection section, |
| const FieldValueMap& inputs) { |
| ValidityMessages messages; |
| - std::map<ServerFieldType, base::string16> field_values; |
| + FieldValueMap field_values; |
| for (FieldValueMap::const_iterator iter = inputs.begin(); |
| iter != inputs.end(); ++iter) { |
| const ServerFieldType type = iter->first; |
| base::string16 text = InputValidityMessage(section, type, iter->second); |
| - // Skip empty/unchanged fields in edit mode. Ignore country code as it |
| - // always has a value. If the individual field does not have validation |
| - // errors, assume it to be valid unless later proven otherwise. |
| + // Skip empty/unchanged fields in edit mode. Ignore country as it always has |
| + // a value. If the individual field does not have validation errors, assume |
| + // it to be valid unless later proven otherwise. |
| bool sure = InputWasEdited(type, iter->second) || |
| - ComboboxModelForAutofillType(type) == &country_combobox_model_; |
| + AutofillType(type).GetStorableType() == ADDRESS_HOME_COUNTRY; |
| // Consider only individually valid fields for inter-field validation. |
| if (text.empty()) { |
| @@ -1853,6 +1865,20 @@ void AutofillDialogControllerImpl::UserEditedOrActivatedInput( |
| const gfx::Rect& content_bounds, |
| const base::string16& field_contents, |
| bool was_edit) { |
| + ScopedViewUpdates updates(view_.get()); |
| + |
| + if (type == ADDRESS_BILLING_COUNTRY || type == ADDRESS_HOME_COUNTRY) { |
| + FieldValueMap snapshot = TakeUserInputSnapshot(); |
| + snapshot[type] = field_contents; |
| + RestoreUserInputFromSnapshot(snapshot); |
| + const bool is_billing = type == ADDRESS_BILLING_COUNTRY; |
| + UpdateSection(is_billing ? ActiveBillingSection() : SECTION_SHIPPING); |
| + } |
| + |
| + // The rest of this method applies only to textfields. If a combobox, bail. |
| + if (ComboboxModelForAutofillType(type)) |
| + return; |
| + |
| // If the field is edited down to empty, don't show a popup. |
| if (was_edit && field_contents.empty()) { |
| HidePopup(); |
| @@ -1931,6 +1957,8 @@ bool AutofillDialogControllerImpl::ShouldShowErrorBubble() const { |
| void AutofillDialogControllerImpl::ViewClosed() { |
| GetManager()->RemoveObserver(this); |
|
Evan Stade
2014/01/15 23:12:29
why is this here and not in the destructor?
why a
Dan Beam
2014/01/16 01:39:13
Done.
|
| + billing_country_combobox_model_.RemoveObserver(this); |
| + shipping_country_combobox_model_.RemoveObserver(this); |
| // Called from here rather than in ~AutofillDialogControllerImpl as this |
| // relies on virtual methods that change to their base class in the dtor. |
| @@ -2158,6 +2186,35 @@ void AutofillDialogControllerImpl::DidAcceptSuggestion( |
| pair.second)); |
| } |
| + if (i18ninput::Enabled()) { |
| + // If country will change while filling, rebuild inputs now. |
|
Evan Stade
2014/01/15 23:12:29
I can't make sense of this sentence.
Dan Beam
2014/01/16 01:39:13
Removed.
|
| + base::string16 billing_country; |
| + if (!billing_country_combobox_model_.GetDefaultIndex()) |
| + billing_country = wrapper->GetInfo(AutofillType(ADDRESS_BILLING_COUNTRY)); |
| + |
| + base::string16 shipping_country; |
| + if (!shipping_country_combobox_model_.GetDefaultIndex()) |
| + shipping_country = wrapper->GetInfo(AutofillType(ADDRESS_HOME_COUNTRY)); |
| + |
| + if (!billing_country.empty() || !shipping_country.empty()) { |
| + FieldValueMap snapshot = TakeUserInputSnapshot(); |
| + |
| + if (!billing_country.empty()) |
| + snapshot[ADDRESS_BILLING_COUNTRY] = billing_country; |
| + |
| + if (!shipping_country.empty()) |
| + snapshot[ADDRESS_HOME_COUNTRY] = shipping_country; |
| + |
| + RestoreUserInputFromSnapshot(snapshot); |
| + |
| + if (!billing_country.empty()) |
| + UpdateSection(ActiveBillingSection()); |
| + |
| + if (!shipping_country.empty()) |
| + UpdateSection(SECTION_SHIPPING); |
| + } |
| + } |
| + |
| for (size_t i = SECTION_MIN; i <= SECTION_MAX; ++i) { |
| DialogSection section = static_cast<DialogSection>(i); |
| wrapper->FillInputs(MutableRequestedFieldsForSection(section)); |
| @@ -2237,8 +2294,19 @@ void AutofillDialogControllerImpl::SuggestionItemSelected( |
| } |
| model->SetCheckedIndex(index); |
| + |
| DialogSection section = SectionForSuggestionsMenuModel(*model); |
| + SetEditingExistingData(section, false); |
| + |
| + if (i18ninput::Enabled()) { |
| + if (section == SECTION_SHIPPING) |
| + shipping_country_combobox_model_.ResetDefault(); |
| + else if (section == SECTION_BILLING || section == SECTION_CC_BILLING) |
| + billing_country_combobox_model_.ResetDefault(); |
| + } |
| + |
| ResetSectionInput(section); |
| + |
| ShowEditUiIfBadSuggestion(section); |
| UpdateSection(section); |
| view_->UpdateNotificationArea(); |
| @@ -2521,7 +2589,8 @@ AutofillDialogControllerImpl::AutofillDialogControllerImpl( |
| wallet_items_requested_(false), |
| handling_use_wallet_link_click_(false), |
| passive_failed_(false), |
| - country_combobox_model_(*GetManager()), |
| + billing_country_combobox_model_(*GetManager()), |
| + shipping_country_combobox_model_(*GetManager()), |
| suggested_cc_(this), |
| suggested_billing_(this), |
| suggested_cc_billing_(this), |
| @@ -2609,6 +2678,10 @@ void AutofillDialogControllerImpl::OpenTabWithUrl(const GURL& url) { |
| chrome::Navigate(¶ms); |
| } |
| +DialogSection AutofillDialogControllerImpl::ActiveBillingSection() const { |
| + return IsPayingWithWallet() ? SECTION_CC_BILLING : SECTION_BILLING; |
| +} |
| + |
| bool AutofillDialogControllerImpl::IsEditingExistingData( |
| DialogSection section) const { |
| return section_editing_state_.count(section) > 0; |
| @@ -2821,7 +2894,9 @@ void AutofillDialogControllerImpl::SuggestionsUpdated() { |
| view_->ModelChanged(); |
| for (size_t i = SECTION_MIN; i <= SECTION_MAX; ++i) { |
| - ResetSectionInput(static_cast<DialogSection>(i)); |
| + DialogSection section = static_cast<DialogSection>(i); |
| + SetEditingExistingData(section, false); |
| + ResetSectionInput(section); |
| } |
| RestoreUserInputFromSnapshot(snapshot); |
| @@ -2844,11 +2919,13 @@ void AutofillDialogControllerImpl::FillOutputForSectionWithComparator( |
| if (!SectionIsActive(section)) |
| return; |
| - const DetailInputs& inputs = RequestedFieldsForSection(section); |
| + DetailInputs inputs; |
| + std::string country_code = CountryCodeForSection(section); |
| + common::BuildInputsForSection(section, country_code, &inputs); |
| + |
| scoped_ptr<DataModelWrapper> wrapper = CreateWrapper(section); |
| if (wrapper) { |
| // Only fill in data that is associated with this section. |
| - const DetailInputs& inputs = RequestedFieldsForSection(section); |
| wrapper->FillFormStructure(inputs, compare, &form_structure_); |
| // CVC needs special-casing because the CreditCard class doesn't store or |
| @@ -2991,6 +3068,51 @@ DetailInputs* AutofillDialogControllerImpl::MutableRequestedFieldsForSection( |
| return const_cast<DetailInputs*>(&RequestedFieldsForSection(section)); |
| } |
| +void AutofillDialogControllerImpl::OnComboboxModelChanged( |
| + ui::ComboboxModel* model) { |
| + DCHECK(model == &billing_country_combobox_model_ || |
| + model == &shipping_country_combobox_model_); |
| + |
| + const bool is_shipping = model == &shipping_country_combobox_model_; |
| + const std::string country_code = AutofillCountry::GetCountryCode( |
| + model->GetItemAt(model->GetDefaultIndex()), |
| + g_browser_process->GetApplicationLocale()); |
| + |
| + for (size_t i = SECTION_MIN; i <= SECTION_MAX; ++i) { |
| + DialogSection section = static_cast<DialogSection>(i); |
| + |
| + if ((is_shipping && section != SECTION_SHIPPING) || |
|
Evan Stade
2014/01/15 23:12:29
this is the second place in this CL I've seen so f
Dan Beam
2014/01/16 01:39:13
Done.
|
| + (!is_shipping && (section != SECTION_BILLING && |
| + section != SECTION_CC_BILLING))) { |
| + continue; |
| + } |
| + |
| + DetailInputs* inputs = MutableRequestedFieldsForSection(section); |
| + inputs->clear(); |
| + |
| + common::BuildInputsForSection(section, country_code, inputs); |
| + } |
| +} |
| + |
| +std::string AutofillDialogControllerImpl::CountryCodeForSection( |
| + DialogSection section) { |
| + if (section == SECTION_CC) |
| + return "US"; |
|
Evan Stade
2014/01/15 23:12:29
ditto -- return "" as it's international.
Dan Beam
2014/01/16 01:39:13
Done.
|
| + |
| + base::string16 country_name; |
| + if (IsEditingExistingData(section)) { |
| + ServerFieldType type = SECTION_SHIPPING ? ADDRESS_HOME_COUNTRY : |
| + ADDRESS_BILLING_COUNTRY; |
| + return AutofillCountry::GetCountryCode( |
| + CreateWrapper(section)->GetInfo(AutofillType(type)), |
| + g_browser_process->GetApplicationLocale()); |
| + } |
| + |
| + CountryComboboxModel* model = section == SECTION_SHIPPING ? |
|
Evan Stade
2014/01/15 23:12:29
third place
Dan Beam
2014/01/16 01:39:13
Done.
|
| + &shipping_country_combobox_model_ : &billing_country_combobox_model_; |
| + return model->countries()[model->GetDefaultIndex()]->country_code(); |
| +} |
| + |
| void AutofillDialogControllerImpl::HidePopup() { |
| if (popup_controller_.get()) |
| popup_controller_->Hide(); |