OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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/autofill/autofill_dialog_controller_impl.h" | 5 #include "chrome/browser/ui/autofill/autofill_dialog_controller_impl.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <map> | 8 #include <map> |
9 #include <string> | 9 #include <string> |
10 | 10 |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
149 // Equivalent billing field type is used to support UseBillingAsShipping | 149 // Equivalent billing field type is used to support UseBillingAsShipping |
150 // usecase. | 150 // usecase. |
151 ServerFieldType field_type = | 151 ServerFieldType field_type = |
152 AutofillType::GetEquivalentBillingFieldType( | 152 AutofillType::GetEquivalentBillingFieldType( |
153 field.Type().GetStorableType()); | 153 field.Type().GetStorableType()); |
154 | 154 |
155 return common::InputTypeMatchesFieldType(input, AutofillType(field_type)); | 155 return common::InputTypeMatchesFieldType(input, AutofillType(field_type)); |
156 } | 156 } |
157 | 157 |
158 // Initializes |form_group| from user-entered data. | 158 // Initializes |form_group| from user-entered data. |
159 void FillFormGroupFromOutputs(const DetailOutputMap& detail_outputs, | 159 void FillFormGroupFromOutputs(const FieldValueMap& detail_outputs, |
160 FormGroup* form_group) { | 160 FormGroup* form_group) { |
161 for (DetailOutputMap::const_iterator iter = detail_outputs.begin(); | 161 for (FieldValueMap::const_iterator iter = detail_outputs.begin(); |
162 iter != detail_outputs.end(); ++iter) { | 162 iter != detail_outputs.end(); ++iter) { |
163 ServerFieldType type = iter->first->type; | 163 ServerFieldType type = iter->first; |
164 if (!iter->second.empty()) { | 164 if (!iter->second.empty()) { |
165 if (type == ADDRESS_HOME_COUNTRY || type == ADDRESS_BILLING_COUNTRY) { | 165 if (type == ADDRESS_HOME_COUNTRY || type == ADDRESS_BILLING_COUNTRY) { |
166 form_group->SetInfo(AutofillType(type), | 166 form_group->SetInfo(AutofillType(type), |
167 iter->second, | 167 iter->second, |
168 g_browser_process->GetApplicationLocale()); | 168 g_browser_process->GetApplicationLocale()); |
169 } else { | 169 } else { |
170 form_group->SetRawInfo( | 170 form_group->SetRawInfo( |
171 AutofillType(type).GetStorableType(), iter->second); | 171 AutofillType(type).GetStorableType(), iter->second); |
172 } | 172 } |
173 } | 173 } |
174 } | 174 } |
175 } | 175 } |
176 | 176 |
177 // Get billing info from |output| and put it into |card|, |cvc|, and |profile|. | 177 // Get billing info from |output| and put it into |card|, |cvc|, and |profile|. |
178 // These outparams are required because |card|/|profile| accept different types | 178 // These outparams are required because |card|/|profile| accept different types |
179 // of raw info, and CreditCard doesn't save CVCs. | 179 // of raw info, and CreditCard doesn't save CVCs. |
180 void GetBillingInfoFromOutputs(const DetailOutputMap& output, | 180 void GetBillingInfoFromOutputs(const FieldValueMap& output, |
181 CreditCard* card, | 181 CreditCard* card, |
182 string16* cvc, | 182 base::string16* cvc, |
183 AutofillProfile* profile) { | 183 AutofillProfile* profile) { |
184 for (DetailOutputMap::const_iterator it = output.begin(); | 184 for (FieldValueMap::const_iterator it = output.begin(); |
185 it != output.end(); ++it) { | 185 it != output.end(); ++it) { |
186 string16 trimmed; | 186 const ServerFieldType type = it->first; |
| 187 base::string16 trimmed; |
187 TrimWhitespace(it->second, TRIM_ALL, &trimmed); | 188 TrimWhitespace(it->second, TRIM_ALL, &trimmed); |
188 | 189 |
189 // Special case CVC as CreditCard just swallows it. | 190 // Special case CVC as CreditCard just swallows it. |
190 if (it->first->type == CREDIT_CARD_VERIFICATION_CODE) { | 191 if (type == CREDIT_CARD_VERIFICATION_CODE) { |
191 if (cvc) | 192 if (cvc) |
192 cvc->assign(trimmed); | 193 cvc->assign(trimmed); |
193 } else if (it->first->type == ADDRESS_HOME_COUNTRY || | 194 } else if (type == ADDRESS_HOME_COUNTRY || |
194 it->first->type == ADDRESS_BILLING_COUNTRY) { | 195 type == ADDRESS_BILLING_COUNTRY) { |
195 if (profile) { | 196 if (profile) { |
196 profile->SetInfo(AutofillType(it->first->type), | 197 profile->SetInfo(AutofillType(type), |
197 trimmed, | 198 trimmed, |
198 g_browser_process->GetApplicationLocale()); | 199 g_browser_process->GetApplicationLocale()); |
199 } | 200 } |
200 } else { | 201 } else { |
201 // Copy the credit card name to |profile| in addition to |card| as | 202 // Copy the credit card name to |profile| in addition to |card| as |
202 // wallet::Instrument requires a recipient name for its billing address. | 203 // wallet::Instrument requires a recipient name for its billing address. |
203 if (card && it->first->type == NAME_FULL) | 204 if (card && type == NAME_FULL) |
204 card->SetRawInfo(CREDIT_CARD_NAME, trimmed); | 205 card->SetRawInfo(CREDIT_CARD_NAME, trimmed); |
205 | 206 |
206 if (common::IsCreditCardType(it->first->type)) { | 207 if (common::IsCreditCardType(type)) { |
207 if (card) | 208 if (card) |
208 card->SetRawInfo(it->first->type, trimmed); | 209 card->SetRawInfo(type, trimmed); |
209 } else if (profile) { | 210 } else if (profile) { |
210 profile->SetRawInfo( | 211 profile->SetRawInfo(AutofillType(type).GetStorableType(), trimmed); |
211 AutofillType(it->first->type).GetStorableType(), trimmed); | |
212 } | 212 } |
213 } | 213 } |
214 } | 214 } |
215 } | 215 } |
216 | 216 |
217 // Returns the containing window for the given |web_contents|. The containing | 217 // Returns the containing window for the given |web_contents|. The containing |
218 // window might be a browser window for a Chrome tab, or it might be a shell | 218 // window might be a browser window for a Chrome tab, or it might be a shell |
219 // window for a platform app. | 219 // window for a platform app. |
220 ui::BaseWindow* GetBaseWindowForWebContents( | 220 ui::BaseWindow* GetBaseWindowForWebContents( |
221 const content::WebContents* web_contents) { | 221 const content::WebContents* web_contents) { |
222 Browser* browser = chrome::FindBrowserWithWebContents(web_contents); | 222 Browser* browser = chrome::FindBrowserWithWebContents(web_contents); |
223 if (browser) | 223 if (browser) |
224 return browser->window(); | 224 return browser->window(); |
225 | 225 |
226 gfx::NativeWindow native_window = | 226 gfx::NativeWindow native_window = |
227 web_contents->GetView()->GetTopLevelNativeWindow(); | 227 web_contents->GetView()->GetTopLevelNativeWindow(); |
228 apps::ShellWindow* shell_window = | 228 apps::ShellWindow* shell_window = |
229 apps::ShellWindowRegistry:: | 229 apps::ShellWindowRegistry:: |
230 GetShellWindowForNativeWindowAnyProfile(native_window); | 230 GetShellWindowForNativeWindowAnyProfile(native_window); |
231 return shell_window->GetBaseWindow(); | 231 return shell_window->GetBaseWindow(); |
232 } | 232 } |
233 | 233 |
234 // Extracts the string value of a field with |type| from |output|. This is | |
235 // useful when you only need the value of 1 input from a section of view inputs. | |
236 string16 GetValueForType(const DetailOutputMap& output, | |
237 ServerFieldType type) { | |
238 for (DetailOutputMap::const_iterator it = output.begin(); | |
239 it != output.end(); ++it) { | |
240 if (it->first->type == type) | |
241 return it->second; | |
242 } | |
243 return string16(); | |
244 } | |
245 | |
246 // Returns a string descriptor for a DialogSection, for use with prefs (do not | 234 // Returns a string descriptor for a DialogSection, for use with prefs (do not |
247 // change these values). | 235 // change these values). |
248 std::string SectionToPrefString(DialogSection section) { | 236 std::string SectionToPrefString(DialogSection section) { |
249 switch (section) { | 237 switch (section) { |
250 case SECTION_CC: | 238 case SECTION_CC: |
251 return "cc"; | 239 return "cc"; |
252 | 240 |
253 case SECTION_BILLING: | 241 case SECTION_BILLING: |
254 return "billing"; | 242 return "billing"; |
255 | 243 |
(...skipping 877 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1133 return false; | 1121 return false; |
1134 | 1122 |
1135 // If this is a combobox at the default value, don't preserve it. | 1123 // If this is a combobox at the default value, don't preserve it. |
1136 ui::ComboboxModel* model = ComboboxModelForAutofillType(type); | 1124 ui::ComboboxModel* model = ComboboxModelForAutofillType(type); |
1137 if (model && model->GetItemAt(model->GetDefaultIndex()) == value) | 1125 if (model && model->GetItemAt(model->GetDefaultIndex()) == value) |
1138 return false; | 1126 return false; |
1139 | 1127 |
1140 return true; | 1128 return true; |
1141 } | 1129 } |
1142 | 1130 |
1143 DetailOutputMap AutofillDialogControllerImpl::TakeUserInputSnapshot() { | 1131 FieldValueMap AutofillDialogControllerImpl::TakeUserInputSnapshot() { |
1144 DetailOutputMap snapshot; | 1132 FieldValueMap snapshot; |
1145 if (!view_) | 1133 if (!view_) |
1146 return snapshot; | 1134 return snapshot; |
1147 | 1135 |
1148 for (size_t i = SECTION_MIN; i <= SECTION_MAX; ++i) { | 1136 for (size_t i = SECTION_MIN; i <= SECTION_MAX; ++i) { |
1149 DialogSection section = static_cast<DialogSection>(i); | 1137 DialogSection section = static_cast<DialogSection>(i); |
1150 SuggestionsMenuModel* model = SuggestionsMenuModelForSection(section); | 1138 SuggestionsMenuModel* model = SuggestionsMenuModelForSection(section); |
1151 if (model->GetItemKeyForCheckedItem() != kAddNewItemKey) | 1139 if (model->GetItemKeyForCheckedItem() != kAddNewItemKey) |
1152 continue; | 1140 continue; |
1153 | 1141 |
1154 DetailOutputMap outputs; | 1142 FieldValueMap outputs; |
1155 view_->GetUserInput(section, &outputs); | 1143 view_->GetUserInput(section, &outputs); |
1156 // Remove fields that are empty, at their default values, or invalid. | 1144 // Remove fields that are empty, at their default values, or invalid. |
1157 for (DetailOutputMap::iterator it = outputs.begin(); it != outputs.end(); | 1145 for (FieldValueMap::iterator it = outputs.begin(); it != outputs.end(); |
1158 ++it) { | 1146 ++it) { |
1159 if (InputWasEdited(it->first->type, it->second) && | 1147 if (InputWasEdited(it->first, it->second) && |
1160 InputValidityMessage(section, it->first->type, it->second).empty()) { | 1148 InputValidityMessage(section, it->first, it->second).empty()) { |
1161 snapshot.insert(std::make_pair(it->first, it->second)); | 1149 snapshot.insert(std::make_pair(it->first, it->second)); |
1162 } | 1150 } |
1163 } | 1151 } |
1164 } | 1152 } |
1165 | 1153 |
1166 return snapshot; | 1154 return snapshot; |
1167 } | 1155 } |
1168 | 1156 |
1169 void AutofillDialogControllerImpl::RestoreUserInputFromSnapshot( | 1157 void AutofillDialogControllerImpl::RestoreUserInputFromSnapshot( |
1170 const DetailOutputMap& snapshot) { | 1158 const FieldValueMap& snapshot) { |
1171 if (snapshot.empty()) | 1159 if (snapshot.empty()) |
1172 return; | 1160 return; |
1173 | 1161 |
1174 DetailOutputWrapper wrapper(snapshot); | 1162 FieldMapWrapper wrapper(snapshot); |
1175 for (size_t i = SECTION_MIN; i <= SECTION_MAX; ++i) { | 1163 for (size_t i = SECTION_MIN; i <= SECTION_MAX; ++i) { |
1176 DialogSection section = static_cast<DialogSection>(i); | 1164 DialogSection section = static_cast<DialogSection>(i); |
1177 if (!SectionIsActive(section)) | 1165 if (!SectionIsActive(section)) |
1178 continue; | 1166 continue; |
1179 | 1167 |
1180 DetailInputs* inputs = MutableRequestedFieldsForSection(section); | 1168 DetailInputs* inputs = MutableRequestedFieldsForSection(section); |
1181 wrapper.FillInputs(inputs); | 1169 wrapper.FillInputs(inputs); |
1182 | 1170 |
1183 for (size_t i = 0; i < inputs->size(); ++i) { | 1171 for (size_t i = 0; i < inputs->size(); ++i) { |
1184 if (InputWasEdited((*inputs)[i].type, (*inputs)[i].initial_value)) { | 1172 if (InputWasEdited((*inputs)[i].type, (*inputs)[i].initial_value)) { |
(...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1425 } | 1413 } |
1426 | 1414 |
1427 string16 AutofillDialogControllerImpl::RequiredActionTextForSection( | 1415 string16 AutofillDialogControllerImpl::RequiredActionTextForSection( |
1428 DialogSection section) const { | 1416 DialogSection section) const { |
1429 if (section == SECTION_CC_BILLING && IsSubmitPausedOn(wallet::VERIFY_CVV)) { | 1417 if (section == SECTION_CC_BILLING && IsSubmitPausedOn(wallet::VERIFY_CVV)) { |
1430 const wallet::WalletItems::MaskedInstrument* current_instrument = | 1418 const wallet::WalletItems::MaskedInstrument* current_instrument = |
1431 wallet_items_->GetInstrumentById(active_instrument_id_); | 1419 wallet_items_->GetInstrumentById(active_instrument_id_); |
1432 if (current_instrument) | 1420 if (current_instrument) |
1433 return current_instrument->TypeAndLastFourDigits(); | 1421 return current_instrument->TypeAndLastFourDigits(); |
1434 | 1422 |
1435 DetailOutputMap output; | 1423 FieldValueMap output; |
1436 view_->GetUserInput(section, &output); | 1424 view_->GetUserInput(section, &output); |
1437 CreditCard card; | 1425 CreditCard card; |
1438 GetBillingInfoFromOutputs(output, &card, NULL, NULL); | 1426 GetBillingInfoFromOutputs(output, &card, NULL, NULL); |
1439 return card.TypeAndLastFourDigits(); | 1427 return card.TypeAndLastFourDigits(); |
1440 } | 1428 } |
1441 | 1429 |
1442 return string16(); | 1430 return string16(); |
1443 } | 1431 } |
1444 | 1432 |
1445 string16 AutofillDialogControllerImpl::ExtraSuggestionTextForSection( | 1433 string16 AutofillDialogControllerImpl::ExtraSuggestionTextForSection( |
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1608 if (section != SECTION_CC_BILLING) | 1596 if (section != SECTION_CC_BILLING) |
1609 return true; | 1597 return true; |
1610 | 1598 |
1611 if (input.type == CREDIT_CARD_NUMBER) | 1599 if (input.type == CREDIT_CARD_NUMBER) |
1612 return !IsEditingExistingData(section); | 1600 return !IsEditingExistingData(section); |
1613 | 1601 |
1614 // For CVC, only require (allow) input if the user has edited some other | 1602 // For CVC, only require (allow) input if the user has edited some other |
1615 // aspect of the card. | 1603 // aspect of the card. |
1616 if (input.type == CREDIT_CARD_VERIFICATION_CODE && | 1604 if (input.type == CREDIT_CARD_VERIFICATION_CODE && |
1617 IsEditingExistingData(section)) { | 1605 IsEditingExistingData(section)) { |
1618 DetailOutputMap output; | 1606 FieldValueMap output; |
1619 view_->GetUserInput(section, &output); | 1607 view_->GetUserInput(section, &output); |
1620 WalletInstrumentWrapper wrapper(ActiveInstrument()); | 1608 WalletInstrumentWrapper wrapper(ActiveInstrument()); |
1621 | 1609 |
1622 for (DetailOutputMap::iterator iter = output.begin(); iter != output.end(); | 1610 for (FieldValueMap::iterator iter = output.begin(); iter != output.end(); |
1623 ++iter) { | 1611 ++iter) { |
1624 if (iter->first->type == input.type) | 1612 if (iter->first == input.type) |
1625 continue; | 1613 continue; |
1626 | 1614 |
1627 AutofillType type(iter->first->type); | 1615 AutofillType type(iter->first); |
1628 if (type.group() == CREDIT_CARD && | 1616 if (type.group() == CREDIT_CARD && |
1629 iter->second != wrapper.GetInfo(type)) { | 1617 iter->second != wrapper.GetInfo(type)) { |
1630 return true; | 1618 return true; |
1631 } | 1619 } |
1632 } | 1620 } |
1633 | 1621 |
1634 return false; | 1622 return false; |
1635 } | 1623 } |
1636 | 1624 |
1637 return true; | 1625 return true; |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1739 } | 1727 } |
1740 | 1728 |
1741 return value.empty() ? | 1729 return value.empty() ? |
1742 l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_VALIDATION_MISSING_VALUE) : | 1730 l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_VALIDATION_MISSING_VALUE) : |
1743 base::string16(); | 1731 base::string16(); |
1744 } | 1732 } |
1745 | 1733 |
1746 // TODO(groby): Also add tests. | 1734 // TODO(groby): Also add tests. |
1747 ValidityMessages AutofillDialogControllerImpl::InputsAreValid( | 1735 ValidityMessages AutofillDialogControllerImpl::InputsAreValid( |
1748 DialogSection section, | 1736 DialogSection section, |
1749 const DetailOutputMap& inputs) { | 1737 const FieldValueMap& inputs) { |
1750 ValidityMessages messages; | 1738 ValidityMessages messages; |
1751 std::map<ServerFieldType, string16> field_values; | 1739 std::map<ServerFieldType, string16> field_values; |
1752 for (DetailOutputMap::const_iterator iter = inputs.begin(); | 1740 for (FieldValueMap::const_iterator iter = inputs.begin(); |
1753 iter != inputs.end(); ++iter) { | 1741 iter != inputs.end(); ++iter) { |
1754 const ServerFieldType type = iter->first->type; | 1742 const ServerFieldType type = iter->first; |
1755 | 1743 |
1756 base::string16 text = InputValidityMessage(section, type, iter->second); | 1744 base::string16 text = InputValidityMessage(section, type, iter->second); |
1757 | 1745 |
1758 // Skip empty/unchanged fields in edit mode. Ignore country code as it | 1746 // Skip empty/unchanged fields in edit mode. Ignore country code as it |
1759 // always has a value. If the individual field does not have validation | 1747 // always has a value. If the individual field does not have validation |
1760 // errors, assume it to be valid unless later proven otherwise. | 1748 // errors, assume it to be valid unless later proven otherwise. |
1761 bool sure = InputWasEdited(type, iter->second) || | 1749 bool sure = InputWasEdited(type, iter->second) || |
1762 ComboboxModelForAutofillType(type) == &country_combobox_model_; | 1750 ComboboxModelForAutofillType(type) == &country_combobox_model_; |
1763 | 1751 |
1764 // Consider only individually valid fields for inter-field validation. | 1752 // Consider only individually valid fields for inter-field validation. |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1842 IDS_AUTOFILL_DIALOG_VALIDATION_INVALID_PHONE_NUMBER); | 1830 IDS_AUTOFILL_DIALOG_VALIDATION_INVALID_PHONE_NUMBER); |
1843 } | 1831 } |
1844 messages.Set(PHONE_BILLING_WHOLE_NUMBER, phone_message); | 1832 messages.Set(PHONE_BILLING_WHOLE_NUMBER, phone_message); |
1845 } | 1833 } |
1846 | 1834 |
1847 return messages; | 1835 return messages; |
1848 } | 1836 } |
1849 | 1837 |
1850 void AutofillDialogControllerImpl::UserEditedOrActivatedInput( | 1838 void AutofillDialogControllerImpl::UserEditedOrActivatedInput( |
1851 DialogSection section, | 1839 DialogSection section, |
1852 const DetailInput* input, | 1840 ServerFieldType type, |
1853 gfx::NativeView parent_view, | 1841 gfx::NativeView parent_view, |
1854 const gfx::Rect& content_bounds, | 1842 const gfx::Rect& content_bounds, |
1855 const string16& field_contents, | 1843 const string16& field_contents, |
1856 bool was_edit) { | 1844 bool was_edit) { |
1857 // If the field is edited down to empty, don't show a popup. | 1845 // If the field is edited down to empty, don't show a popup. |
1858 if (was_edit && field_contents.empty()) { | 1846 if (was_edit && field_contents.empty()) { |
1859 HidePopup(); | 1847 HidePopup(); |
1860 return; | 1848 return; |
1861 } | 1849 } |
1862 | 1850 |
1863 // If the user clicks while the popup is already showing, be sure to hide | 1851 // If the user clicks while the popup is already showing, be sure to hide |
1864 // it. | 1852 // it. |
1865 if (!was_edit && popup_controller_.get()) { | 1853 if (!was_edit && popup_controller_.get()) { |
1866 HidePopup(); | 1854 HidePopup(); |
1867 return; | 1855 return; |
1868 } | 1856 } |
1869 | 1857 |
1870 std::vector<string16> popup_values, popup_labels, popup_icons; | 1858 std::vector<string16> popup_values, popup_labels, popup_icons; |
1871 if (common::IsCreditCardType(input->type)) { | 1859 if (common::IsCreditCardType(type)) { |
1872 GetManager()->GetCreditCardSuggestions(AutofillType(input->type), | 1860 GetManager()->GetCreditCardSuggestions(AutofillType(type), |
1873 field_contents, | 1861 field_contents, |
1874 &popup_values, | 1862 &popup_values, |
1875 &popup_labels, | 1863 &popup_labels, |
1876 &popup_icons, | 1864 &popup_icons, |
1877 &popup_guids_); | 1865 &popup_guids_); |
1878 } else { | 1866 } else { |
1879 std::vector<ServerFieldType> field_types; | 1867 std::vector<ServerFieldType> field_types; |
1880 const DetailInputs& inputs = RequestedFieldsForSection(section); | 1868 const DetailInputs& inputs = RequestedFieldsForSection(section); |
1881 for (DetailInputs::const_iterator iter = inputs.begin(); | 1869 for (DetailInputs::const_iterator iter = inputs.begin(); |
1882 iter != inputs.end(); ++iter) { | 1870 iter != inputs.end(); ++iter) { |
1883 field_types.push_back(iter->type); | 1871 field_types.push_back(iter->type); |
1884 } | 1872 } |
1885 GetManager()->GetProfileSuggestions(AutofillType(input->type), | 1873 GetManager()->GetProfileSuggestions(AutofillType(type), |
1886 field_contents, | 1874 field_contents, |
1887 false, | 1875 false, |
1888 field_types, | 1876 field_types, |
1889 &popup_values, | 1877 &popup_values, |
1890 &popup_labels, | 1878 &popup_labels, |
1891 &popup_icons, | 1879 &popup_icons, |
1892 &popup_guids_); | 1880 &popup_guids_); |
1893 } | 1881 } |
1894 | 1882 |
1895 if (popup_values.empty()) { | 1883 if (popup_values.empty()) { |
1896 HidePopup(); | 1884 HidePopup(); |
1897 return; | 1885 return; |
1898 } | 1886 } |
1899 | 1887 |
| 1888 // |input_showing_popup_| must be set before calling |Show()|. |
| 1889 const DetailInputs& inputs = RequestedFieldsForSection(section); |
| 1890 for (DetailInputs::const_iterator iter = inputs.begin(); |
| 1891 iter != inputs.end(); ++iter) { |
| 1892 if (iter->type == type) { |
| 1893 input_showing_popup_ = &(*iter); |
| 1894 break; |
| 1895 } |
| 1896 } |
| 1897 |
| 1898 if (!input_showing_popup_) |
| 1899 return; |
| 1900 |
1900 // TODO(estade): do we need separators and control rows like 'Clear | 1901 // TODO(estade): do we need separators and control rows like 'Clear |
1901 // Form'? | 1902 // Form'? |
1902 std::vector<int> popup_ids; | 1903 std::vector<int> popup_ids; |
1903 for (size_t i = 0; i < popup_guids_.size(); ++i) { | 1904 for (size_t i = 0; i < popup_guids_.size(); ++i) { |
1904 popup_ids.push_back(i); | 1905 popup_ids.push_back(i); |
1905 } | 1906 } |
1906 | 1907 |
1907 popup_controller_ = AutofillPopupControllerImpl::GetOrCreate( | 1908 popup_controller_ = AutofillPopupControllerImpl::GetOrCreate( |
1908 popup_controller_, | 1909 popup_controller_, |
1909 weak_ptr_factory_.GetWeakPtr(), | 1910 weak_ptr_factory_.GetWeakPtr(), |
1910 NULL, | 1911 NULL, |
1911 parent_view, | 1912 parent_view, |
1912 content_bounds, | 1913 content_bounds, |
1913 base::i18n::IsRTL() ? | 1914 base::i18n::IsRTL() ? |
1914 base::i18n::RIGHT_TO_LEFT : base::i18n::LEFT_TO_RIGHT); | 1915 base::i18n::RIGHT_TO_LEFT : base::i18n::LEFT_TO_RIGHT); |
1915 popup_controller_->set_hide_on_outside_click(true); | 1916 popup_controller_->set_hide_on_outside_click(true); |
1916 | |
1917 // |input_showing_popup_| must be set before calling |Show()|. | |
1918 input_showing_popup_ = input; | |
1919 | |
1920 popup_controller_->Show(popup_values, | 1917 popup_controller_->Show(popup_values, |
1921 popup_labels, | 1918 popup_labels, |
1922 popup_icons, | 1919 popup_icons, |
1923 popup_ids); | 1920 popup_ids); |
1924 } | 1921 } |
1925 | 1922 |
1926 void AutofillDialogControllerImpl::FocusMoved() { | 1923 void AutofillDialogControllerImpl::FocusMoved() { |
1927 HidePopup(); | 1924 HidePopup(); |
1928 } | 1925 } |
1929 | 1926 |
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2080 // name. | 2077 // name. |
2081 if (!IsSubmitPausedOn(wallet::VERIFY_CVV)) { | 2078 if (!IsSubmitPausedOn(wallet::VERIFY_CVV)) { |
2082 submitted_cardholder_name_ = | 2079 submitted_cardholder_name_ = |
2083 GetValueFromSection(SECTION_CC_BILLING, NAME_BILLING_FULL); | 2080 GetValueFromSection(SECTION_CC_BILLING, NAME_BILLING_FULL); |
2084 | 2081 |
2085 // Snag the last four digits of the backing card now as it could be wiped | 2082 // Snag the last four digits of the backing card now as it could be wiped |
2086 // out if a CVC challenge happens. | 2083 // out if a CVC challenge happens. |
2087 if (ActiveInstrument()) { | 2084 if (ActiveInstrument()) { |
2088 backing_card_last_four_ = ActiveInstrument()->TypeAndLastFourDigits(); | 2085 backing_card_last_four_ = ActiveInstrument()->TypeAndLastFourDigits(); |
2089 } else { | 2086 } else { |
2090 DetailOutputMap output; | 2087 FieldValueMap output; |
2091 view_->GetUserInput(SECTION_CC_BILLING, &output); | 2088 view_->GetUserInput(SECTION_CC_BILLING, &output); |
2092 CreditCard card; | 2089 CreditCard card; |
2093 GetBillingInfoFromOutputs(output, &card, NULL, NULL); | 2090 GetBillingInfoFromOutputs(output, &card, NULL, NULL); |
2094 backing_card_last_four_ = card.TypeAndLastFourDigits(); | 2091 backing_card_last_four_ = card.TypeAndLastFourDigits(); |
2095 } | 2092 } |
2096 } | 2093 } |
2097 DCHECK(!submitted_cardholder_name_.empty()); | 2094 DCHECK(!submitted_cardholder_name_.empty()); |
2098 DCHECK(!backing_card_last_four_.empty()); | 2095 DCHECK(!backing_card_last_four_.empty()); |
2099 } | 2096 } |
2100 | 2097 |
(...skipping 536 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2637 wallet_errors_.clear(); | 2634 wallet_errors_.clear(); |
2638 GetWalletClient()->CancelRequests(); | 2635 GetWalletClient()->CancelRequests(); |
2639 SetIsSubmitting(false); | 2636 SetIsSubmitting(false); |
2640 wallet_error_notification_ = GetWalletError(error_type); | 2637 wallet_error_notification_ = GetWalletError(error_type); |
2641 account_chooser_model_.SetHadWalletError(); | 2638 account_chooser_model_.SetHadWalletError(); |
2642 } | 2639 } |
2643 | 2640 |
2644 void AutofillDialogControllerImpl::SuggestionsUpdated() { | 2641 void AutofillDialogControllerImpl::SuggestionsUpdated() { |
2645 ScopedViewUpdates updates(view_.get()); | 2642 ScopedViewUpdates updates(view_.get()); |
2646 | 2643 |
2647 const DetailOutputMap snapshot = TakeUserInputSnapshot(); | 2644 const FieldValueMap snapshot = TakeUserInputSnapshot(); |
2648 | 2645 |
2649 suggested_cc_.Reset(); | 2646 suggested_cc_.Reset(); |
2650 suggested_billing_.Reset(); | 2647 suggested_billing_.Reset(); |
2651 suggested_cc_billing_.Reset(); | 2648 suggested_cc_billing_.Reset(); |
2652 suggested_shipping_.Reset(); | 2649 suggested_shipping_.Reset(); |
2653 HidePopup(); | 2650 HidePopup(); |
2654 | 2651 |
2655 suggested_shipping_.AddKeyedItem( | 2652 suggested_shipping_.AddKeyedItem( |
2656 kSameAsBillingKey, | 2653 kSameAsBillingKey, |
2657 l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_USE_BILLING_FOR_SHIPPING)); | 2654 l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_USE_BILLING_FOR_SHIPPING)); |
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2853 // When filling from Wallet data, use the email address associated with the | 2850 // When filling from Wallet data, use the email address associated with the |
2854 // account. There is no other email address stored as part of a Wallet | 2851 // account. There is no other email address stored as part of a Wallet |
2855 // address. | 2852 // address. |
2856 if (section == SECTION_CC_BILLING) { | 2853 if (section == SECTION_CC_BILLING) { |
2857 SetOutputForFieldsOfType( | 2854 SetOutputForFieldsOfType( |
2858 EMAIL_ADDRESS, account_chooser_model_.GetActiveWalletAccountName()); | 2855 EMAIL_ADDRESS, account_chooser_model_.GetActiveWalletAccountName()); |
2859 } | 2856 } |
2860 } else { | 2857 } else { |
2861 // The user manually input data. If using Autofill, save the info as new or | 2858 // The user manually input data. If using Autofill, save the info as new or |
2862 // edited data. Always fill local data into |form_structure_|. | 2859 // edited data. Always fill local data into |form_structure_|. |
2863 DetailOutputMap output; | 2860 FieldValueMap output; |
2864 view_->GetUserInput(section, &output); | 2861 view_->GetUserInput(section, &output); |
2865 | 2862 |
2866 if (section == SECTION_CC) { | 2863 if (section == SECTION_CC) { |
2867 CreditCard card; | 2864 CreditCard card; |
2868 card.set_origin(kAutofillDialogOrigin); | 2865 card.set_origin(kAutofillDialogOrigin); |
2869 FillFormGroupFromOutputs(output, &card); | 2866 FillFormGroupFromOutputs(output, &card); |
2870 | 2867 |
2871 // The card holder name comes from the billing address section. | 2868 // The card holder name comes from the billing address section. |
2872 card.SetRawInfo(CREDIT_CARD_NAME, | 2869 card.SetRawInfo(CREDIT_CARD_NAME, |
2873 GetValueFromSection(SECTION_BILLING, NAME_BILLING_FULL)); | 2870 GetValueFromSection(SECTION_BILLING, NAME_BILLING_FULL)); |
2874 | 2871 |
2875 if (ShouldSaveDetailsLocally()) { | 2872 if (ShouldSaveDetailsLocally()) { |
2876 std::string guid = GetManager()->SaveImportedCreditCard(card); | 2873 std::string guid = GetManager()->SaveImportedCreditCard(card); |
2877 newly_saved_data_model_guids_[section] = guid; | 2874 newly_saved_data_model_guids_[section] = guid; |
2878 DCHECK(!profile()->IsOffTheRecord()); | 2875 DCHECK(!profile()->IsOffTheRecord()); |
2879 newly_saved_card_.reset(new CreditCard(card)); | 2876 newly_saved_card_.reset(new CreditCard(card)); |
2880 } | 2877 } |
2881 | 2878 |
2882 AutofillCreditCardWrapper card_wrapper(&card); | 2879 AutofillCreditCardWrapper card_wrapper(&card); |
2883 card_wrapper.FillFormStructure(inputs, compare, &form_structure_); | 2880 card_wrapper.FillFormStructure(inputs, compare, &form_structure_); |
2884 | 2881 |
2885 // Again, CVC needs special-casing. Fill it in directly from |output|. | 2882 // Again, CVC needs special-casing. Fill it in directly from |output|. |
2886 SetOutputForFieldsOfType( | 2883 SetOutputForFieldsOfType( |
2887 CREDIT_CARD_VERIFICATION_CODE, | 2884 CREDIT_CARD_VERIFICATION_CODE, |
2888 GetValueForType(output, CREDIT_CARD_VERIFICATION_CODE)); | 2885 output[CREDIT_CARD_VERIFICATION_CODE]); |
2889 } else { | 2886 } else { |
2890 AutofillProfile profile; | 2887 AutofillProfile profile; |
2891 profile.set_origin(kAutofillDialogOrigin); | 2888 profile.set_origin(kAutofillDialogOrigin); |
2892 FillFormGroupFromOutputs(output, &profile); | 2889 FillFormGroupFromOutputs(output, &profile); |
2893 | 2890 |
2894 if (ShouldSaveDetailsLocally()) { | 2891 if (ShouldSaveDetailsLocally()) { |
2895 std::string guid = GetManager()->SaveImportedProfile(profile); | 2892 std::string guid = GetManager()->SaveImportedProfile(profile); |
2896 newly_saved_data_model_guids_[section] = guid; | 2893 newly_saved_data_model_guids_[section] = guid; |
2897 } | 2894 } |
2898 | 2895 |
(...skipping 30 matching lines...) Expand all Loading... |
2929 | 2926 |
2930 string16 AutofillDialogControllerImpl::GetValueFromSection( | 2927 string16 AutofillDialogControllerImpl::GetValueFromSection( |
2931 DialogSection section, | 2928 DialogSection section, |
2932 ServerFieldType type) { | 2929 ServerFieldType type) { |
2933 DCHECK(SectionIsActive(section)); | 2930 DCHECK(SectionIsActive(section)); |
2934 | 2931 |
2935 scoped_ptr<DataModelWrapper> wrapper = CreateWrapper(section); | 2932 scoped_ptr<DataModelWrapper> wrapper = CreateWrapper(section); |
2936 if (wrapper) | 2933 if (wrapper) |
2937 return wrapper->GetInfo(AutofillType(type)); | 2934 return wrapper->GetInfo(AutofillType(type)); |
2938 | 2935 |
2939 DetailOutputMap output; | 2936 FieldValueMap output; |
2940 view_->GetUserInput(section, &output); | 2937 view_->GetUserInput(section, &output); |
2941 return GetValueForType(output, type); | 2938 return output[type]; |
2942 } | 2939 } |
2943 | 2940 |
2944 SuggestionsMenuModel* AutofillDialogControllerImpl:: | 2941 SuggestionsMenuModel* AutofillDialogControllerImpl:: |
2945 SuggestionsMenuModelForSection(DialogSection section) { | 2942 SuggestionsMenuModelForSection(DialogSection section) { |
2946 switch (section) { | 2943 switch (section) { |
2947 case SECTION_CC: | 2944 case SECTION_CC: |
2948 return &suggested_cc_; | 2945 return &suggested_cc_; |
2949 case SECTION_BILLING: | 2946 case SECTION_BILLING: |
2950 return &suggested_billing_; | 2947 return &suggested_billing_; |
2951 case SECTION_SHIPPING: | 2948 case SECTION_SHIPPING: |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3035 return false; | 3032 return false; |
3036 } | 3033 } |
3037 return true; | 3034 return true; |
3038 } | 3035 } |
3039 | 3036 |
3040 bool AutofillDialogControllerImpl::SectionIsValid( | 3037 bool AutofillDialogControllerImpl::SectionIsValid( |
3041 DialogSection section) { | 3038 DialogSection section) { |
3042 if (!IsManuallyEditingSection(section)) | 3039 if (!IsManuallyEditingSection(section)) |
3043 return true; | 3040 return true; |
3044 | 3041 |
3045 DetailOutputMap detail_outputs; | 3042 FieldValueMap detail_outputs; |
3046 view_->GetUserInput(section, &detail_outputs); | 3043 view_->GetUserInput(section, &detail_outputs); |
3047 return !InputsAreValid(section, detail_outputs).HasSureErrors(); | 3044 return !InputsAreValid(section, detail_outputs).HasSureErrors(); |
3048 } | 3045 } |
3049 | 3046 |
3050 bool AutofillDialogControllerImpl::IsCreditCardExpirationValid( | 3047 bool AutofillDialogControllerImpl::IsCreditCardExpirationValid( |
3051 const base::string16& year, | 3048 const base::string16& year, |
3052 const base::string16& month) const { | 3049 const base::string16& month) const { |
3053 // If the expiration is in the past as per the local clock, it's invalid. | 3050 // If the expiration is in the past as per the local clock, it's invalid. |
3054 base::Time now = base::Time::Now(); | 3051 base::Time now = base::Time::Now(); |
3055 if (!autofill::IsValidCreditCardExpirationDate(year, month, now)) | 3052 if (!autofill::IsValidCreditCardExpirationDate(year, month, now)) |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3190 | 3187 |
3191 GetWalletClient()->SaveToWallet(inputted_instrument.Pass(), | 3188 GetWalletClient()->SaveToWallet(inputted_instrument.Pass(), |
3192 inputted_address.Pass()); | 3189 inputted_address.Pass()); |
3193 } | 3190 } |
3194 | 3191 |
3195 scoped_ptr<wallet::Instrument> AutofillDialogControllerImpl:: | 3192 scoped_ptr<wallet::Instrument> AutofillDialogControllerImpl:: |
3196 CreateTransientInstrument() { | 3193 CreateTransientInstrument() { |
3197 if (!active_instrument_id_.empty()) | 3194 if (!active_instrument_id_.empty()) |
3198 return scoped_ptr<wallet::Instrument>(); | 3195 return scoped_ptr<wallet::Instrument>(); |
3199 | 3196 |
3200 DetailOutputMap output; | 3197 FieldValueMap output; |
3201 view_->GetUserInput(SECTION_CC_BILLING, &output); | 3198 view_->GetUserInput(SECTION_CC_BILLING, &output); |
3202 | 3199 |
3203 CreditCard card; | 3200 CreditCard card; |
3204 AutofillProfile profile; | 3201 AutofillProfile profile; |
3205 string16 cvc; | 3202 string16 cvc; |
3206 GetBillingInfoFromOutputs(output, &card, &cvc, &profile); | 3203 GetBillingInfoFromOutputs(output, &card, &cvc, &profile); |
3207 | 3204 |
3208 return scoped_ptr<wallet::Instrument>( | 3205 return scoped_ptr<wallet::Instrument>( |
3209 new wallet::Instrument(card, cvc, profile)); | 3206 new wallet::Instrument(card, cvc, profile)); |
3210 } | 3207 } |
3211 | 3208 |
3212 scoped_ptr<wallet::Address>AutofillDialogControllerImpl:: | 3209 scoped_ptr<wallet::Address>AutofillDialogControllerImpl:: |
3213 CreateTransientAddress() { | 3210 CreateTransientAddress() { |
3214 // If not using billing for shipping, just scrape the view. | 3211 // If not using billing for shipping, just scrape the view. |
3215 DetailOutputMap output; | 3212 FieldValueMap output; |
3216 view_->GetUserInput(SECTION_SHIPPING, &output); | 3213 view_->GetUserInput(SECTION_SHIPPING, &output); |
3217 | 3214 |
3218 AutofillProfile profile; | 3215 AutofillProfile profile; |
3219 FillFormGroupFromOutputs(output, &profile); | 3216 FillFormGroupFromOutputs(output, &profile); |
3220 | 3217 |
3221 return scoped_ptr<wallet::Address>(new wallet::Address(profile)); | 3218 return scoped_ptr<wallet::Address>(new wallet::Address(profile)); |
3222 } | 3219 } |
3223 | 3220 |
3224 void AutofillDialogControllerImpl::GetFullWallet() { | 3221 void AutofillDialogControllerImpl::GetFullWallet() { |
3225 DCHECK(is_submitting_); | 3222 DCHECK(is_submitting_); |
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3483 } | 3480 } |
3484 | 3481 |
3485 void AutofillDialogControllerImpl::MaybeShowCreditCardBubble() { | 3482 void AutofillDialogControllerImpl::MaybeShowCreditCardBubble() { |
3486 if (!data_was_passed_back_) | 3483 if (!data_was_passed_back_) |
3487 return; | 3484 return; |
3488 | 3485 |
3489 if (newly_saved_card_) { | 3486 if (newly_saved_card_) { |
3490 scoped_ptr<AutofillProfile> billing_profile; | 3487 scoped_ptr<AutofillProfile> billing_profile; |
3491 if (IsManuallyEditingSection(SECTION_BILLING)) { | 3488 if (IsManuallyEditingSection(SECTION_BILLING)) { |
3492 // Scrape the view as the user's entering or updating information. | 3489 // Scrape the view as the user's entering or updating information. |
3493 DetailOutputMap outputs; | 3490 FieldValueMap outputs; |
3494 view_->GetUserInput(SECTION_BILLING, &outputs); | 3491 view_->GetUserInput(SECTION_BILLING, &outputs); |
3495 billing_profile.reset(new AutofillProfile); | 3492 billing_profile.reset(new AutofillProfile); |
3496 FillFormGroupFromOutputs(outputs, billing_profile.get()); | 3493 FillFormGroupFromOutputs(outputs, billing_profile.get()); |
3497 } else { | 3494 } else { |
3498 // Just snag the currently suggested profile. | 3495 // Just snag the currently suggested profile. |
3499 std::string item_key = SuggestionsMenuModelForSection(SECTION_BILLING)-> | 3496 std::string item_key = SuggestionsMenuModelForSection(SECTION_BILLING)-> |
3500 GetItemKeyForCheckedItem(); | 3497 GetItemKeyForCheckedItem(); |
3501 AutofillProfile* profile = GetManager()->GetProfileByGUID(item_key); | 3498 AutofillProfile* profile = GetManager()->GetProfileByGUID(item_key); |
3502 billing_profile.reset(new AutofillProfile(*profile)); | 3499 billing_profile.reset(new AutofillProfile(*profile)); |
3503 } | 3500 } |
(...skipping 21 matching lines...) Expand all Loading... |
3525 view_->UpdateButtonStrip(); | 3522 view_->UpdateButtonStrip(); |
3526 } | 3523 } |
3527 | 3524 |
3528 void AutofillDialogControllerImpl::FetchWalletCookie() { | 3525 void AutofillDialogControllerImpl::FetchWalletCookie() { |
3529 net::URLRequestContextGetter* request_context = profile_->GetRequestContext(); | 3526 net::URLRequestContextGetter* request_context = profile_->GetRequestContext(); |
3530 signin_helper_.reset(new wallet::WalletSigninHelper(this, request_context)); | 3527 signin_helper_.reset(new wallet::WalletSigninHelper(this, request_context)); |
3531 signin_helper_->StartWalletCookieValueFetch(); | 3528 signin_helper_->StartWalletCookieValueFetch(); |
3532 } | 3529 } |
3533 | 3530 |
3534 } // namespace autofill | 3531 } // namespace autofill |
OLD | NEW |