1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/ui/webui/options/autofill_options_handler.h"
10 #include "base/bind_helpers.h"
11 #include "base/guid.h"
12 #include "base/logging.h"
13 #include "base/strings/string16.h"
14 #include "base/strings/string_number_conversions.h"
15 #include "base/strings/utf_string_conversions.h"
16 #include "base/values.h"
17 #include "chrome/browser/autofill/personal_data_manager_factory.h"
18 #include "chrome/browser/browser_process.h"
19 #include "chrome/browser/profiles/profile.h"
20 #include "chrome/browser/ui/autofill/country_combobox_model.h"
21 #include "chrome/common/url_constants.h"
22 #include "components/autofill/core/browser/autofill_country.h"
23 #include "components/autofill/core/browser/autofill_profile.h"
24 #include "components/autofill/core/browser/credit_card.h"
25 #include "components/autofill/core/browser/personal_data_manager.h"
26 #include "components/autofill/core/browser/phone_number_i18n.h"
27 #include "components/autofill/core/common/autofill_constants.h"
28 #include "content/public/browser/web_ui.h"
29 #include "grit/components_strings.h"
30 #include "grit/generated_resources.h"
31 #include "third_party/libaddressinput/messages.h"
32 #include "third_party/libaddressinput/src/cpp/include/libaddressinput/address_ui.h"
33 #include "third_party/libaddressinput/src/cpp/include/libaddressinput/address_ui_component.h"
34 #include "third_party/libaddressinput/src/cpp/include/libaddressinput/localization.h"
35 #include "ui/base/l10n/l10n_util.h"
36 #include "ui/base/webui/web_ui_util.h"
38 using autofill::AutofillCountry
;
39 using autofill::AutofillType
;
40 using autofill::ServerFieldType
;
41 using autofill::AutofillProfile
;
42 using autofill::CreditCard
;
43 using autofill::PersonalDataManager
;
44 using i18n::addressinput::AddressUiComponent
;
48 const char kSettingsOrigin
[] = "Chrome settings";
50 static const char kFullNameField
[] = "fullName";
51 static const char kCompanyNameField
[] = "companyName";
52 static const char kAddressLineField
[] = "addrLines";
53 static const char kDependentLocalityField
[] = "dependentLocality";
54 static const char kCityField
[] = "city";
55 static const char kStateField
[] = "state";
56 static const char kPostalCodeField
[] = "postalCode";
57 static const char kSortingCodeField
[] = "sortingCode";
58 static const char kCountryField
[] = "country";
60 static const char kComponents
[] = "components";
61 static const char kLanguageCode
[] = "languageCode";
63 // Fills |components| with the address UI components that should be used to
64 // input an address for |country_code| when UI BCP 47 language code is
65 // |ui_language_code|. If |components_language_code| is not NULL, then sets it
66 // to the BCP 47 language code that should be used to format the address for
68 void GetAddressComponents(const std::string
& country_code
,
69 const std::string
& ui_language_code
,
70 base::ListValue
* address_components
,
71 std::string
* components_language_code
) {
72 DCHECK(address_components
);
74 i18n::addressinput::Localization localization
;
75 localization
.SetGetter(l10n_util::GetStringUTF8
);
77 std::vector
<AddressUiComponent
> components
=
78 i18n::addressinput::BuildComponents(
82 components_language_code
== NULL
?
83 ¬_used
: components_language_code
);
84 if (components
.empty()) {
85 static const char kDefaultCountryCode
[] = "US";
86 components
= i18n::addressinput::BuildComponents(
90 components_language_code
== NULL
?
91 ¬_used
: components_language_code
);
93 DCHECK(!components
.empty());
95 base::ListValue
* line
= NULL
;
96 static const char kField
[] = "field";
97 static const char kLength
[] = "length";
98 for (size_t i
= 0; i
< components
.size(); ++i
) {
100 components
[i
- 1].length_hint
== AddressUiComponent::HINT_LONG
||
101 components
[i
].length_hint
== AddressUiComponent::HINT_LONG
) {
102 line
= new base::ListValue
;
103 address_components
->Append(line
);
106 scoped_ptr
<base::DictionaryValue
> component(new base::DictionaryValue
);
107 component
->SetString("name", components
[i
].name
);
109 switch (components
[i
].field
) {
110 case i18n::addressinput::COUNTRY
:
111 component
->SetString(kField
, kCountryField
);
113 case i18n::addressinput::ADMIN_AREA
:
114 component
->SetString(kField
, kStateField
);
116 case i18n::addressinput::LOCALITY
:
117 component
->SetString(kField
, kCityField
);
119 case i18n::addressinput::DEPENDENT_LOCALITY
:
120 component
->SetString(kField
, kDependentLocalityField
);
122 case i18n::addressinput::SORTING_CODE
:
123 component
->SetString(kField
, kSortingCodeField
);
125 case i18n::addressinput::POSTAL_CODE
:
126 component
->SetString(kField
, kPostalCodeField
);
128 case i18n::addressinput::STREET_ADDRESS
:
129 component
->SetString(kField
, kAddressLineField
);
131 case i18n::addressinput::RECIPIENT
:
132 component
->SetString(kField
, kFullNameField
);
133 component
->SetString(
135 l10n_util::GetStringUTF16(IDS_AUTOFILL_FIELD_LABEL_ADD_NAME
));
139 switch (components
[i
].length_hint
) {
140 case AddressUiComponent::HINT_LONG
:
141 component
->SetString(kLength
, "long");
143 case AddressUiComponent::HINT_SHORT
:
144 component
->SetString(kLength
, "short");
148 line
->Append(component
.release());
152 // Sets data related to the country <select>.
153 void SetCountryData(const PersonalDataManager
& manager
,
154 base::DictionaryValue
* localized_strings
) {
155 autofill::CountryComboboxModel model
;
156 model
.SetCountries(manager
, base::Callback
<bool(const std::string
&)>());
157 const std::vector
<AutofillCountry
*>& countries
= model
.countries();
158 localized_strings
->SetString("defaultCountryCode",
159 countries
.front()->country_code());
161 // An ordered list of options to show in the <select>.
162 scoped_ptr
<base::ListValue
> country_list(new base::ListValue());
163 for (size_t i
= 0; i
< countries
.size(); ++i
) {
164 scoped_ptr
<base::DictionaryValue
> option_details(
165 new base::DictionaryValue());
166 option_details
->SetString("name", model
.GetItemAt(i
));
167 option_details
->SetString(
169 countries
[i
] ? countries
[i
]->country_code() : "separator");
170 country_list
->Append(option_details
.release());
172 localized_strings
->Set("autofillCountrySelectList", country_list
.release());
174 scoped_ptr
<base::ListValue
> default_country_components(new base::ListValue
);
175 std::string default_country_language_code
;
176 GetAddressComponents(countries
.front()->country_code(),
177 g_browser_process
->GetApplicationLocale(),
178 default_country_components
.get(),
179 &default_country_language_code
);
180 localized_strings
->Set("autofillDefaultCountryComponents",
181 default_country_components
.release());
182 localized_strings
->SetString("autofillDefaultCountryLanguageCode",
183 default_country_language_code
);
186 // Get the multi-valued element for |type| and return it in |ListValue| form.
187 // Buyer beware: the type of data affects whether GetRawInfo or GetInfo is used.
188 void GetValueList(const AutofillProfile
& profile
,
189 ServerFieldType type
,
190 scoped_ptr
<base::ListValue
>* list
) {
191 list
->reset(new base::ListValue
);
193 std::vector
<base::string16
> values
;
194 if (AutofillType(type
).group() == autofill::NAME
) {
195 profile
.GetMultiInfo(
196 AutofillType(type
), g_browser_process
->GetApplicationLocale(), &values
);
198 profile
.GetRawMultiInfo(type
, &values
);
201 // |Get[Raw]MultiInfo()| always returns at least one, potentially empty, item.
202 if (values
.size() == 1 && values
.front().empty())
205 for (size_t i
= 0; i
< values
.size(); ++i
) {
206 (*list
)->Set(i
, new base::StringValue(values
[i
]));
210 // Converts a ListValue of StringValues to a vector of string16s.
211 void ListValueToStringVector(const base::ListValue
& list
,
212 std::vector
<base::string16
>* output
) {
213 output
->resize(list
.GetSize());
214 for (size_t i
= 0; i
< list
.GetSize(); ++i
) {
215 base::string16 value
;
216 if (list
.GetString(i
, &value
))
217 (*output
)[i
].swap(value
);
221 // Pulls the phone number |index|, |phone_number_list|, and |country_code| from
223 void ExtractPhoneNumberInformation(const base::ListValue
* args
,
225 const base::ListValue
** phone_number_list
,
226 std::string
* country_code
) {
227 // Retrieve index as a |double|, as that is how it comes across from
230 if (!args
->GetDouble(0, &number
)) {
236 if (!args
->GetList(1, phone_number_list
)) {
241 if (!args
->GetString(2, country_code
)) {
247 // Searches the |list| for the value at |index|. If this value is present
248 // in any of the rest of the list, then the item (at |index|) is removed.
249 // The comparison of phone number values is done on normalized versions of the
250 // phone number values.
251 void RemoveDuplicatePhoneNumberAtIndex(size_t index
,
252 const std::string
& country_code
,
253 base::ListValue
* list
) {
254 base::string16 new_value
;
255 if (!list
->GetString(index
, &new_value
)) {
256 NOTREACHED() << "List should have a value at index " << index
;
260 bool is_duplicate
= false;
261 std::string app_locale
= g_browser_process
->GetApplicationLocale();
262 for (size_t i
= 0; i
< list
->GetSize() && !is_duplicate
; ++i
) {
266 base::string16 existing_value
;
267 if (!list
->GetString(i
, &existing_value
)) {
268 NOTREACHED() << "List should have a value at index " << i
;
271 is_duplicate
= autofill::i18n::PhoneNumbersMatch(
272 new_value
, existing_value
, country_code
, app_locale
);
276 list
->Remove(index
, NULL
);
279 scoped_ptr
<base::ListValue
> ValidatePhoneArguments(
280 const base::ListValue
* args
) {
282 std::string country_code
;
283 const base::ListValue
* extracted_list
= NULL
;
284 ExtractPhoneNumberInformation(args
, &index
, &extracted_list
, &country_code
);
286 scoped_ptr
<base::ListValue
> list(extracted_list
->DeepCopy());
287 RemoveDuplicatePhoneNumberAtIndex(index
, country_code
, list
.get());
295 AutofillOptionsHandler::AutofillOptionsHandler()
296 : personal_data_(NULL
) {}
298 AutofillOptionsHandler::~AutofillOptionsHandler() {
300 personal_data_
->RemoveObserver(this);
303 /////////////////////////////////////////////////////////////////////////////
304 // OptionsPageUIHandler implementation:
305 void AutofillOptionsHandler::GetLocalizedValues(
306 base::DictionaryValue
* localized_strings
) {
307 DCHECK(localized_strings
);
309 static OptionsStringResource resources
[] = {
310 { "autofillAddresses", IDS_AUTOFILL_ADDRESSES_GROUP_NAME
},
311 { "autofillCreditCards", IDS_AUTOFILL_CREDITCARDS_GROUP_NAME
},
312 { "autofillAddAddress", IDS_AUTOFILL_ADD_ADDRESS_BUTTON
},
313 { "autofillAddCreditCard", IDS_AUTOFILL_ADD_CREDITCARD_BUTTON
},
314 { "autofillEditProfileButton", IDS_AUTOFILL_EDIT_PROFILE_BUTTON
},
315 { "helpButton", IDS_AUTOFILL_HELP_LABEL
},
316 { "addAddressTitle", IDS_AUTOFILL_ADD_ADDRESS_CAPTION
},
317 { "editAddressTitle", IDS_AUTOFILL_EDIT_ADDRESS_CAPTION
},
318 { "addCreditCardTitle", IDS_AUTOFILL_ADD_CREDITCARD_CAPTION
},
319 { "editCreditCardTitle", IDS_AUTOFILL_EDIT_CREDITCARD_CAPTION
},
320 #if defined(OS_MACOSX)
321 { "auxiliaryProfilesEnabled", IDS_AUTOFILL_USE_MAC_ADDRESS_BOOK
},
322 #endif // defined(OS_MACOSX)
325 RegisterStrings(localized_strings
, resources
, arraysize(resources
));
326 RegisterTitle(localized_strings
, "autofillOptionsPage",
327 IDS_AUTOFILL_OPTIONS_TITLE
);
329 localized_strings
->SetString("helpUrl", autofill::kHelpURL
);
330 SetAddressOverlayStrings(localized_strings
);
331 SetCreditCardOverlayStrings(localized_strings
);
334 void AutofillOptionsHandler::InitializeHandler() {
335 // personal_data_ is NULL in guest mode on Chrome OS.
337 personal_data_
->AddObserver(this);
340 void AutofillOptionsHandler::InitializePage() {
345 void AutofillOptionsHandler::RegisterMessages() {
346 personal_data_
= autofill::PersonalDataManagerFactory::GetForProfile(
347 Profile::FromWebUI(web_ui()));
349 #if defined(OS_MACOSX) && !defined(OS_IOS)
350 web_ui()->RegisterMessageCallback(
352 base::Bind(&AutofillOptionsHandler::AccessAddressBook
,
353 base::Unretained(this)));
354 #endif // defined(OS_MACOSX) && !defined(OS_IOS)
355 web_ui()->RegisterMessageCallback(
357 base::Bind(&AutofillOptionsHandler::RemoveData
,
358 base::Unretained(this)));
359 web_ui()->RegisterMessageCallback(
361 base::Bind(&AutofillOptionsHandler::LoadAddressEditor
,
362 base::Unretained(this)));
363 web_ui()->RegisterMessageCallback(
364 "loadAddressEditorComponents",
365 base::Bind(&AutofillOptionsHandler::LoadAddressEditorComponents
,
366 base::Unretained(this)));
367 web_ui()->RegisterMessageCallback(
368 "loadCreditCardEditor",
369 base::Bind(&AutofillOptionsHandler::LoadCreditCardEditor
,
370 base::Unretained(this)));
371 web_ui()->RegisterMessageCallback(
373 base::Bind(&AutofillOptionsHandler::SetAddress
, base::Unretained(this)));
374 web_ui()->RegisterMessageCallback(
376 base::Bind(&AutofillOptionsHandler::SetCreditCard
,
377 base::Unretained(this)));
378 web_ui()->RegisterMessageCallback(
379 "validatePhoneNumbers",
380 base::Bind(&AutofillOptionsHandler::ValidatePhoneNumbers
,
381 base::Unretained(this)));
384 /////////////////////////////////////////////////////////////////////////////
385 // PersonalDataManagerObserver implementation:
386 void AutofillOptionsHandler::OnPersonalDataChanged() {
390 void AutofillOptionsHandler::SetAddressOverlayStrings(
391 base::DictionaryValue
* localized_strings
) {
392 localized_strings
->SetString("autofillEditAddressTitle",
393 l10n_util::GetStringUTF16(IDS_AUTOFILL_EDIT_ADDRESS_CAPTION
));
394 localized_strings
->SetString("autofillCountryLabel",
395 l10n_util::GetStringUTF16(IDS_LIBADDRESSINPUT_COUNTRY_OR_REGION_LABEL
));
396 localized_strings
->SetString("autofillPhoneLabel",
397 l10n_util::GetStringUTF16(IDS_AUTOFILL_FIELD_LABEL_PHONE
));
398 localized_strings
->SetString("autofillEmailLabel",
399 l10n_util::GetStringUTF16(IDS_AUTOFILL_FIELD_LABEL_EMAIL
));
400 localized_strings
->SetString("autofillAddPhonePlaceholder",
401 l10n_util::GetStringUTF16(IDS_AUTOFILL_FIELD_LABEL_ADD_PHONE
));
402 localized_strings
->SetString("autofillAddEmailPlaceholder",
403 l10n_util::GetStringUTF16(IDS_AUTOFILL_FIELD_LABEL_ADD_EMAIL
));
404 SetCountryData(*personal_data_
, localized_strings
);
407 void AutofillOptionsHandler::SetCreditCardOverlayStrings(
408 base::DictionaryValue
* localized_strings
) {
409 localized_strings
->SetString("autofillEditCreditCardTitle",
410 l10n_util::GetStringUTF16(IDS_AUTOFILL_EDIT_CREDITCARD_CAPTION
));
411 localized_strings
->SetString("nameOnCardLabel",
412 l10n_util::GetStringUTF16(IDS_AUTOFILL_FIELD_LABEL_NAME_ON_CARD
));
413 localized_strings
->SetString("creditCardNumberLabel",
414 l10n_util::GetStringUTF16(IDS_AUTOFILL_FIELD_LABEL_CREDIT_CARD_NUMBER
));
415 localized_strings
->SetString("creditCardExpirationDateLabel",
416 l10n_util::GetStringUTF16(IDS_AUTOFILL_FIELD_LABEL_EXPIRATION_DATE
));
419 void AutofillOptionsHandler::LoadAutofillData() {
420 if (!IsPersonalDataLoaded())
423 const std::vector
<AutofillProfile
*>& profiles
=
424 personal_data_
->web_profiles();
425 std::vector
<base::string16
> labels
;
426 AutofillProfile::CreateDifferentiatingLabels(
428 g_browser_process
->GetApplicationLocale(),
430 DCHECK_EQ(labels
.size(), profiles
.size());
432 base::ListValue addresses
;
433 for (size_t i
= 0; i
< profiles
.size(); ++i
) {
434 base::ListValue
* entry
= new base::ListValue();
435 entry
->Append(new base::StringValue(profiles
[i
]->guid()));
436 entry
->Append(new base::StringValue(labels
[i
]));
437 addresses
.Append(entry
);
440 web_ui()->CallJavascriptFunction("AutofillOptions.setAddressList", addresses
);
442 base::ListValue credit_cards
;
443 const std::vector
<CreditCard
*>& cards
= personal_data_
->GetCreditCards();
444 for (std::vector
<CreditCard
*>::const_iterator iter
= cards
.begin();
445 iter
!= cards
.end(); ++iter
) {
446 const CreditCard
* card
= *iter
;
447 // TODO(estade): this should be a dictionary.
448 base::ListValue
* entry
= new base::ListValue();
449 entry
->Append(new base::StringValue(card
->guid()));
450 entry
->Append(new base::StringValue(card
->Label()));
451 entry
->Append(new base::StringValue(
452 webui::GetBitmapDataUrlFromResource(
453 CreditCard::IconResourceId(card
->type()))));
454 entry
->Append(new base::StringValue(card
->TypeForDisplay()));
455 credit_cards
.Append(entry
);
458 web_ui()->CallJavascriptFunction("AutofillOptions.setCreditCardList",
462 #if defined(OS_MACOSX) && !defined(OS_IOS)
463 void AutofillOptionsHandler::AccessAddressBook(const base::ListValue
* args
) {
464 personal_data_
->AccessAddressBook();
466 #endif // defined(OS_MACOSX) && !defined(OS_IOS)
468 void AutofillOptionsHandler::RemoveData(const base::ListValue
* args
) {
469 DCHECK(IsPersonalDataLoaded());
472 if (!args
->GetString(0, &guid
)) {
477 personal_data_
->RemoveByGUID(guid
);
480 void AutofillOptionsHandler::LoadAddressEditor(const base::ListValue
* args
) {
481 DCHECK(IsPersonalDataLoaded());
484 if (!args
->GetString(0, &guid
)) {
489 AutofillProfile
* profile
= personal_data_
->GetProfileByGUID(guid
);
491 // There is a race where a user can click once on the close button and
492 // quickly click again on the list item before the item is removed (since
493 // the list is not updated until the model tells the list an item has been
494 // removed). This will activate the editor for a profile that has been
495 // removed. Do nothing in that case.
499 base::DictionaryValue address
;
500 AutofillProfileToDictionary(*profile
, &address
);
502 web_ui()->CallJavascriptFunction("AutofillOptions.editAddress", address
);
505 void AutofillOptionsHandler::LoadAddressEditorComponents(
506 const base::ListValue
* args
) {
507 std::string country_code
;
508 if (!args
->GetString(0, &country_code
)) {
513 base::DictionaryValue input
;
514 scoped_ptr
<base::ListValue
> components(new base::ListValue
);
515 std::string language_code
;
516 GetAddressComponents(country_code
, g_browser_process
->GetApplicationLocale(),
517 components
.get(), &language_code
);
518 input
.Set(kComponents
, components
.release());
519 input
.SetString(kLanguageCode
, language_code
);
521 web_ui()->CallJavascriptFunction(
522 "AutofillEditAddressOverlay.loadAddressComponents", input
);
525 void AutofillOptionsHandler::LoadCreditCardEditor(const base::ListValue
* args
) {
526 DCHECK(IsPersonalDataLoaded());
529 if (!args
->GetString(0, &guid
)) {
534 CreditCard
* credit_card
= personal_data_
->GetCreditCardByGUID(guid
);
536 // There is a race where a user can click once on the close button and
537 // quickly click again on the list item before the item is removed (since
538 // the list is not updated until the model tells the list an item has been
539 // removed). This will activate the editor for a profile that has been
540 // removed. Do nothing in that case.
544 base::DictionaryValue credit_card_data
;
545 credit_card_data
.SetString("guid", credit_card
->guid());
546 credit_card_data
.SetString(
548 credit_card
->GetRawInfo(autofill::CREDIT_CARD_NAME
));
549 credit_card_data
.SetString(
551 credit_card
->GetRawInfo(autofill::CREDIT_CARD_NUMBER
));
552 credit_card_data
.SetString(
554 credit_card
->GetRawInfo(autofill::CREDIT_CARD_EXP_MONTH
));
555 credit_card_data
.SetString(
557 credit_card
->GetRawInfo(autofill::CREDIT_CARD_EXP_4_DIGIT_YEAR
));
559 web_ui()->CallJavascriptFunction("AutofillOptions.editCreditCard",
563 void AutofillOptionsHandler::SetAddress(const base::ListValue
* args
) {
564 if (!IsPersonalDataLoaded())
569 if (!args
->GetString(arg_counter
++, &guid
)) {
574 AutofillProfile
profile(guid
, kSettingsOrigin
);
576 base::string16 value
;
577 const base::ListValue
* list_value
;
578 if (args
->GetList(arg_counter
++, &list_value
)) {
579 std::vector
<base::string16
> values
;
580 ListValueToStringVector(*list_value
, &values
);
581 profile
.SetMultiInfo(AutofillType(autofill::NAME_FULL
),
583 g_browser_process
->GetApplicationLocale());
586 if (args
->GetString(arg_counter
++, &value
))
587 profile
.SetRawInfo(autofill::COMPANY_NAME
, value
);
589 if (args
->GetString(arg_counter
++, &value
))
590 profile
.SetRawInfo(autofill::ADDRESS_HOME_STREET_ADDRESS
, value
);
592 if (args
->GetString(arg_counter
++, &value
))
593 profile
.SetRawInfo(autofill::ADDRESS_HOME_DEPENDENT_LOCALITY
, value
);
595 if (args
->GetString(arg_counter
++, &value
))
596 profile
.SetRawInfo(autofill::ADDRESS_HOME_CITY
, value
);
598 if (args
->GetString(arg_counter
++, &value
))
599 profile
.SetRawInfo(autofill::ADDRESS_HOME_STATE
, value
);
601 if (args
->GetString(arg_counter
++, &value
))
602 profile
.SetRawInfo(autofill::ADDRESS_HOME_ZIP
, value
);
604 if (args
->GetString(arg_counter
++, &value
))
605 profile
.SetRawInfo(autofill::ADDRESS_HOME_SORTING_CODE
, value
);
607 if (args
->GetString(arg_counter
++, &value
))
608 profile
.SetRawInfo(autofill::ADDRESS_HOME_COUNTRY
, value
);
610 if (args
->GetList(arg_counter
++, &list_value
)) {
611 std::vector
<base::string16
> values
;
612 ListValueToStringVector(*list_value
, &values
);
613 profile
.SetRawMultiInfo(autofill::PHONE_HOME_WHOLE_NUMBER
, values
);
616 if (args
->GetList(arg_counter
++, &list_value
)) {
617 std::vector
<base::string16
> values
;
618 ListValueToStringVector(*list_value
, &values
);
619 profile
.SetRawMultiInfo(autofill::EMAIL_ADDRESS
, values
);
622 if (args
->GetString(arg_counter
++, &value
))
623 profile
.set_language_code(base::UTF16ToUTF8(value
));
625 if (!base::IsValidGUID(profile
.guid())) {
626 profile
.set_guid(base::GenerateGUID());
627 personal_data_
->AddProfile(profile
);
629 personal_data_
->UpdateProfile(profile
);
633 void AutofillOptionsHandler::SetCreditCard(const base::ListValue
* args
) {
634 if (!IsPersonalDataLoaded())
638 if (!args
->GetString(0, &guid
)) {
643 CreditCard
credit_card(guid
, kSettingsOrigin
);
645 base::string16 value
;
646 if (args
->GetString(1, &value
))
647 credit_card
.SetRawInfo(autofill::CREDIT_CARD_NAME
, value
);
649 if (args
->GetString(2, &value
))
650 credit_card
.SetRawInfo(autofill::CREDIT_CARD_NUMBER
, value
);
652 if (args
->GetString(3, &value
))
653 credit_card
.SetRawInfo(autofill::CREDIT_CARD_EXP_MONTH
, value
);
655 if (args
->GetString(4, &value
))
656 credit_card
.SetRawInfo(autofill::CREDIT_CARD_EXP_4_DIGIT_YEAR
, value
);
658 if (!base::IsValidGUID(credit_card
.guid())) {
659 credit_card
.set_guid(base::GenerateGUID());
660 personal_data_
->AddCreditCard(credit_card
);
662 personal_data_
->UpdateCreditCard(credit_card
);
666 void AutofillOptionsHandler::ValidatePhoneNumbers(const base::ListValue
* args
) {
667 if (!IsPersonalDataLoaded())
670 scoped_ptr
<base::ListValue
> list_value
= ValidatePhoneArguments(args
);
672 web_ui()->CallJavascriptFunction(
673 "AutofillEditAddressOverlay.setValidatedPhoneNumbers", *list_value
);
676 bool AutofillOptionsHandler::IsPersonalDataLoaded() const {
677 return personal_data_
&& personal_data_
->IsDataLoaded();
681 void AutofillOptionsHandler::AutofillProfileToDictionary(
682 const autofill::AutofillProfile
& profile
,
683 base::DictionaryValue
* address
) {
684 address
->SetString("guid", profile
.guid());
685 scoped_ptr
<base::ListValue
> list
;
686 GetValueList(profile
, autofill::NAME_FULL
, &list
);
687 address
->Set(kFullNameField
, list
.release());
688 address
->SetString(kCompanyNameField
,
689 profile
.GetRawInfo(autofill::COMPANY_NAME
));
690 address
->SetString(kAddressLineField
,
691 profile
.GetRawInfo(autofill::ADDRESS_HOME_STREET_ADDRESS
));
692 address
->SetString(kCityField
,
693 profile
.GetRawInfo(autofill::ADDRESS_HOME_CITY
));
694 address
->SetString(kStateField
,
695 profile
.GetRawInfo(autofill::ADDRESS_HOME_STATE
));
697 kDependentLocalityField
,
698 profile
.GetRawInfo(autofill::ADDRESS_HOME_DEPENDENT_LOCALITY
));
699 address
->SetString(kSortingCodeField
,
700 profile
.GetRawInfo(autofill::ADDRESS_HOME_SORTING_CODE
));
701 address
->SetString(kPostalCodeField
,
702 profile
.GetRawInfo(autofill::ADDRESS_HOME_ZIP
));
703 address
->SetString(kCountryField
,
704 profile
.GetRawInfo(autofill::ADDRESS_HOME_COUNTRY
));
705 GetValueList(profile
, autofill::PHONE_HOME_WHOLE_NUMBER
, &list
);
706 address
->Set("phone", list
.release());
707 GetValueList(profile
, autofill::EMAIL_ADDRESS
, &list
);
708 address
->Set("email", list
.release());
709 address
->SetString(kLanguageCode
, profile
.language_code());
711 scoped_ptr
<base::ListValue
> components(new base::ListValue
);
712 GetAddressComponents(
713 base::UTF16ToUTF8(profile
.GetRawInfo(autofill::ADDRESS_HOME_COUNTRY
)),
714 profile
.language_code(),
717 address
->Set(kComponents
, components
.release());
720 } // namespace options