Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(762)

Side by Side Diff: chrome/browser/ui/autofill/autofill_dialog_i18n_input.cc

Issue 63053003: Ask libaddressinput for address components to use in requestAutocomplete(). (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4 //
5 // A stub implementation of internationalized address input fields for
6 // interactive autofill dialog. The implementation always returns the same
7 // address fields until libaddressinput library is integrated.
8 //
9 // Also, GetI18nFields() will call libaddressinput library to determine the
10 // address fields instead of always returning US address fields.
11 //
12 // GuessCountry() uses only the application locale and should be improved to use
13 // the timezone and possibly geolocation.
14
15 #include "chrome/browser/ui/autofill/autofill_dialog_i18n_input.h"
16
17 #include <algorithm>
18
19 #include "base/command_line.h"
20 #include "chrome/browser/browser_process.h"
21 #include "chrome/common/chrome_switches.h"
22 #include "components/autofill/core/browser/autofill_country.h"
23 #include "grit/component_strings.h"
24 #include "grit/generated_resources.h"
25 #include "third_party/libaddressinput/src/cpp/include/libaddressinput/address_fi eld.h"
26 #include "third_party/libaddressinput/src/cpp/include/libaddressinput/address_ui .h"
27 #include "third_party/libaddressinput/src/cpp/include/libaddressinput/address_ui _component.h"
28 #include "third_party/libaddressinput/src/cpp/include/libaddressinput/localizati on.h"
29 #include "ui/base/l10n/l10n_util.h"
30
31 namespace autofill {
32 namespace i18ninput {
33
34 namespace {
35
36 using i18n::addressinput::AddressField;
37 using i18n::addressinput::AddressUiComponent;
38
39 // Indexes into arrays of address field data.
40 enum AddressFieldIndex {
41 COUNTRY_INDEX,
42 ADMIN_AREA_INDEX,
43 LOCALITY_INDEX,
44 DEPENDENT_LOCALITY_INDEX,
45 POSTAL_CODE_INDEX,
46 SORTING_CODE_INDEX,
47 STREET_ADDRESS_1_INDEX,
48 STREET_ADDRESS_2_INDEX,
49 RECIPIENT_INDEX,
50 ORGANIZATION_INDEX,
51 ADDRESS_FIELD_INVALID_INDEX,
52 };
53
54 // Indexes into arrays of street address line data.
55 enum StreetAddressLine {
56 STREET_ADDRESS_LINE_1,
57 STREET_ADDRESS_LINE_2,
58 };
59
60 // The number of address types.
61 const int kNumberOfAddressTypes = ADDRESS_TYPE_BILLING + 1;
62
63 // The maximum number of input fields.
64 const int kMaxNumberOfInputFields = ADDRESS_FIELD_INVALID_INDEX;
65
66 // The maximum number of street address lines.
67 const int kMaxNumberOfStreetAddressLines = STREET_ADDRESS_LINE_2 + 1;
68
69 // A mapping of StreetAddressLine to corresponding values in AddressFieldIndex.
70 // Used to lookup address field data for street address lines.
71 const AddressFieldIndex kStreetAddressLineIndex
72 [kMaxNumberOfStreetAddressLines] = {
73 STREET_ADDRESS_1_INDEX,
74 STREET_ADDRESS_2_INDEX,
75 };
76
77 // A mapping of AddressFieldIndex and AddressType to autofill field types.
78 const ServerFieldType kServerFields[kMaxNumberOfInputFields]
79 [kNumberOfAddressTypes] = {
80 {ADDRESS_HOME_COUNTRY, ADDRESS_BILLING_COUNTRY},
Evan Stade 2013/11/25 20:35:45 there should be spaces inside the {} throughout th
Dan Beam 2013/11/28 02:52:45 Done.
81 {ADDRESS_HOME_STATE, ADDRESS_BILLING_STATE},
82 {ADDRESS_HOME_CITY, ADDRESS_BILLING_CITY},
83 {ADDRESS_HOME_DEPENDENT_LOCALITY, ADDRESS_BILLING_DEPENDENT_LOCALITY},
84 {ADDRESS_HOME_ZIP, ADDRESS_BILLING_ZIP},
85 {ADDRESS_HOME_SORTING_CODE, ADDRESS_BILLING_SORTING_CODE},
86 {ADDRESS_HOME_LINE1, ADDRESS_BILLING_LINE1},
87 {ADDRESS_HOME_LINE2, ADDRESS_BILLING_LINE2},
88 {NAME_FULL, NAME_BILLING_FULL},
89 {COMPANY_NAME, COMPANY_NAME},
90 };
91
92 // A mapping of AddressFieldIndex and AddressType to string identifiers for
93 // placeholder text.
94 const int kPlaceHolderStringIds[kMaxNumberOfInputFields]
95 [kNumberOfAddressTypes] = {
96 {IDS_AUTOFILL_FIELD_LABEL_COUNTRY, IDS_AUTOFILL_FIELD_LABEL_COUNTRY},
97 {IDS_AUTOFILL_FIELD_LABEL_STATE, IDS_AUTOFILL_FIELD_LABEL_STATE},
98 {IDS_AUTOFILL_DIALOG_PLACEHOLDER_LOCALITY,
99 IDS_AUTOFILL_DIALOG_PLACEHOLDER_LOCALITY},
100 {IDS_AUTOFILL_DIALOG_PLACEHOLDER_DEPENDENT_LOCALITY,
101 IDS_AUTOFILL_DIALOG_PLACEHOLDER_DEPENDENT_LOCALITY},
102 {IDS_AUTOFILL_DIALOG_PLACEHOLDER_POSTAL_CODE,
103 IDS_AUTOFILL_DIALOG_PLACEHOLDER_POSTAL_CODE},
104 {IDS_AUTOFILL_DIALOG_PLACEHOLDER_SORTING_CODE,
105 IDS_AUTOFILL_DIALOG_PLACEHOLDER_SORTING_CODE},
106 {IDS_AUTOFILL_DIALOG_PLACEHOLDER_ADDRESS_LINE_1,
107 IDS_AUTOFILL_DIALOG_PLACEHOLDER_ADDRESS_LINE_1},
108 {IDS_AUTOFILL_DIALOG_PLACEHOLDER_ADDRESS_LINE_2,
109 IDS_AUTOFILL_DIALOG_PLACEHOLDER_ADDRESS_LINE_2},
110 {IDS_AUTOFILL_DIALOG_PLACEHOLDER_ADDRESSEE_NAME,
111 IDS_AUTOFILL_DIALOG_PLACEHOLDER_CARDHOLDER_NAME},
112 {IDS_AUTOFILL_DIALOG_PLACEHOLDER_ORGANIZATION,
113 IDS_AUTOFILL_DIALOG_PLACEHOLDER_ORGANIZATION},
114 };
115
116 // Returns the AddressFieldIndex for the given i18n::addressinput::AddressField.
117 // If the address field is STREET_ADDRESS, then uses the given StreetAddressLine
118 // to determine whether to return STREET_ADDRESS_1_INDEX or
119 // STREET_ADDRESS_2_INDEX.
120 AddressFieldIndex AddressFieldToIndex(AddressField field_type,
121 StreetAddressLine street_address_line) {
122 switch (field_type) {
123 case i18n::addressinput::COUNTRY:
124 return COUNTRY_INDEX;
125 case i18n::addressinput::ADMIN_AREA:
126 return ADMIN_AREA_INDEX;
127 case i18n::addressinput::LOCALITY:
128 return LOCALITY_INDEX;
129 case i18n::addressinput::DEPENDENT_LOCALITY:
130 return DEPENDENT_LOCALITY_INDEX;
131 case i18n::addressinput::POSTAL_CODE:
132 return POSTAL_CODE_INDEX;
133 case i18n::addressinput::SORTING_CODE:
134 return SORTING_CODE_INDEX;
135 case i18n::addressinput::STREET_ADDRESS:
136 return kStreetAddressLineIndex[street_address_line];
137 case i18n::addressinput::RECIPIENT:
138 return RECIPIENT_INDEX;
139 case i18n::addressinput::ORGANIZATION:
140 return ORGANIZATION_INDEX;
141 }
142 NOTREACHED();
143 return ADDRESS_FIELD_INVALID_INDEX;
144 }
145
146 // Sets the address field types and length hints for the given |country_region|
147 // and |language|.
148 void GetI18nFields(const std::string country_region,
Evan Stade 2013/11/25 20:35:45 const ref
Dan Beam 2013/11/28 02:52:45 Done.
149 const std::string& language,
150 std::vector<AddressField>* field_types,
151 std::vector<AddressUiComponent::LengthHint>* length_hints) {
152 i18n::addressinput::Localization localization;
153 // TODO(dbeam): do we need to call |localization.SetGetter()| here?
154 std::vector<AddressUiComponent> components(
155 i18n::addressinput::BuildComponents(country_region, localization));
156 for (size_t i = 0; i < components.size(); ++i) {
157 if (components[i].field == i18n::addressinput::ORGANIZATION)
158 continue;
159 field_types->push_back(components[i].field);
160 length_hints->push_back(components[i].length_hint);
161 }
162
163 // If |field_types| does not contain a country field, add one at the end so
164 // the user can still switch countries.
165 if (std::find(field_types->begin(), field_types->end(),
166 i18n::addressinput::COUNTRY) == field_types->end()) {
167 field_types->push_back(i18n::addressinput::COUNTRY);
168 length_hints->push_back(AddressUiComponent::HINT_LONG);
169 }
170 }
171
172 // Returns an incremented |row_index| if |length_hint| and |prev_length_hint|
173 // indicate that the current input should start on a new line.
174 int IncrementRowIndexBasedOnLengthHint(
175 AddressUiComponent::LengthHint prev_length_hint,
176 AddressUiComponent::LengthHint length_hint,
177 int row_index) {
178 if (length_hint == AddressUiComponent::HINT_LONG ||
179 prev_length_hint != length_hint) {
180 return row_index + 1;
181 }
182 return row_index;
183 }
184
185 // Appends the |field_type| input to |inputs|. Appends
186 // kMaxNumberOfStreetAddressLines inputs if |field_type| is STREET_ADDRESS.
187 int BuildI18nInput(int row_index,
Evan Stade 2013/11/25 20:35:45 this doesn't seem like something that should be a
Dan Beam 2013/11/28 02:52:45 Done.
188 AddressField field_type,
189 AddressUiComponent::LengthHint prev_length_hint,
190 AddressUiComponent::LengthHint length_hint,
191 AddressType address_type,
192 DetailInputs* inputs) {
193 int field_index = AddressFieldToIndex(field_type, STREET_ADDRESS_LINE_1);
194 if (field_index == ADDRESS_FIELD_INVALID_INDEX)
195 return row_index;
196
197 row_index = IncrementRowIndexBasedOnLengthHint(
198 prev_length_hint, length_hint, row_index);
199 DetailInput input = {row_index, kServerFields[field_index][address_type],
200 kPlaceHolderStringIds[field_index][address_type]};
201 inputs->push_back(input);
202
203 if (field_type == i18n::addressinput::STREET_ADDRESS) {
204 field_index = AddressFieldToIndex(field_type, STREET_ADDRESS_LINE_2);
205 row_index = IncrementRowIndexBasedOnLengthHint(
206 prev_length_hint, length_hint, row_index);
207 DetailInput input = {row_index, kServerFields[field_index][address_type],
208 kPlaceHolderStringIds[field_index][address_type]};
209 inputs->push_back(input);
210 }
211
212 return row_index;
213 }
214
215 // Returns the language of the current application locale.
216 std::string GetLocaleLanguage() {
217 return AutofillCountry::CountryCodeForLocale(
218 g_browser_process->GetApplicationLocale());
219 }
220
221 } // namespace
222
223 bool IsI18nAddressInputEnabled() {
224 return CommandLine::ForCurrentProcess()->HasSwitch(
225 ::switches::kEnableAutofillAddressInternationalization);
226 }
227
228 std::string GuessCountry() {
229 if (!IsI18nAddressInputEnabled())
230 return "US";
231
232 // TODO(rouslan): Improve on this rudimentary implementation of guessing the
233 // current country code.
234 return GetLocaleLanguage();
235 }
236
237 void BuildI18nInputs(AddressType address_type,
238 const std::string& country_region,
239 int row_index,
240 DetailInputs* inputs) {
241 std::vector<AddressField> field_types;
242 std::vector<AddressUiComponent::LengthHint> length_hints;
243 GetI18nFields(
244 country_region, GetLocaleLanguage(), &field_types, &length_hints);
245 AddressUiComponent::LengthHint prev_length_hint =
246 AddressUiComponent::HINT_LONG;
247 for (size_t i = 0; i < field_types.size() && i < length_hints.size(); ++i) {
248 row_index = BuildI18nInput(row_index,
249 field_types[i],
250 prev_length_hint,
251 length_hints[i],
252 address_type,
253 inputs);
254 prev_length_hint = length_hints[i];
255 }
256 }
257
258 } // namespace i18ninput
259 } // namespace autofill
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698