| 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..1e7bfafc6ca34bcfd8429746c15cd44063832169 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?
|
| + common::BuildInputsForSection(SECTION_CC, "US", &requested_cc_fields_);
|
| + OnCountryComboboxModelChanged(&billing_country_combobox_model_);
|
| + OnCountryComboboxModelChanged(&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_.AddCountryComboboxObserver(this);
|
| + shipping_country_combobox_model_.AddCountryComboboxObserver(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_.SelectCountry(
|
| + 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_.SelectCountry(
|
| + 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);
|
| + billing_country_combobox_model_.RemoveCountryComboboxObserver(this);
|
| + shipping_country_combobox_model_.RemoveCountryComboboxObserver(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.
|
| + base::string16 billing_country;
|
| + if (billing_country_combobox_model_.IsDefaultIndexSelected())
|
| + billing_country = wrapper->GetInfo(AutofillType(ADDRESS_BILLING_COUNTRY));
|
| +
|
| + base::string16 shipping_country;
|
| + if (shipping_country_combobox_model_.IsDefaultIndexSelected())
|
| + 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_.SelectDefaultIndex();
|
| + else if (section == SECTION_BILLING || section == SECTION_CC_BILLING)
|
| + billing_country_combobox_model_.SelectDefaultIndex();
|
| + }
|
| +
|
| 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,50 @@ DetailInputs* AutofillDialogControllerImpl::MutableRequestedFieldsForSection(
|
| return const_cast<DetailInputs*>(&RequestedFieldsForSection(section));
|
| }
|
|
|
| +void AutofillDialogControllerImpl::OnCountryComboboxModelChanged(
|
| + CountryComboboxModel* 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 = model->GetSelectedCountryCode();
|
| +
|
| + for (size_t i = SECTION_MIN; i <= SECTION_MAX; ++i) {
|
| + DialogSection section = static_cast<DialogSection>(i);
|
| +
|
| + if ((is_shipping && section != SECTION_SHIPPING) ||
|
| + (!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";
|
| +
|
| + scoped_ptr<DataModelWrapper> wrapper = CreateWrapper(section);
|
| + if (wrapper) {
|
| + return AutofillCountry::GetCountryCode(
|
| + wrapper->GetInfo(AutofillType(section == SECTION_SHIPPING ?
|
| + ADDRESS_HOME_COUNTRY : ADDRESS_BILLING_COUNTRY)),
|
| + g_browser_process->GetApplicationLocale());
|
| + }
|
| +
|
| + if (section == SECTION_BILLING || section == SECTION_CC_BILLING)
|
| + return billing_country_combobox_model_.GetSelectedCountryCode();
|
| +
|
| + DCHECK_EQ(SECTION_SHIPPING, section);
|
| + return shipping_country_combobox_model_.GetSelectedCountryCode();
|
| +}
|
| +
|
| void AutofillDialogControllerImpl::HidePopup() {
|
| if (popup_controller_.get())
|
| popup_controller_->Hide();
|
|
|