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

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

Issue 25620002: [rac] Use i18n address inputs with --enable-autofill-address-i18n flag (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Separate i18n input file Created 7 years, 2 months 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 // After libaddressinput library is integrated, these enums will removed below:
10 // i18n::addressinput::AddressField
11 // i18n::addressinput::LengthHint
12 // Also, GetI18nFields() will call libaddressinput library to determine the
13 // address fields instead of always returning US address fields.
14 //
15 // GuessCountry() uses only the application locale and should be improved to use
Evan Stade 2013/10/08 23:44:51 link to the bug also, we should probably look at
Evan Stade 2013/11/18 19:39:47 note that I've been working on this, the code is L
16 // the timezone and possibly geolocation.
17
18 #include "chrome/browser/ui/autofill/autofill_dialog_i18n_input.h"
19
20 #include "base/command_line.h"
21 #include "chrome/browser/browser_process.h"
22 #include "chrome/common/chrome_switches.h"
23 #include "components/autofill/core/browser/autofill_country.h"
24 #include "grit/component_strings.h"
25 #include "grit/generated_resources.h"
26
27 namespace autofill {
28 namespace i18ninput {
29
30 namespace {
31
32 // TODO(rouslan): Use the enums from libaddressinput instead after the library
33 // has been integrated.
34 namespace i18n {
35 namespace addressinput {
36
37 enum AddressField {
38 COUNTRY,
39 ADMIN_AREA,
40 LOCALITY,
41 DEPENDENT_LOCALITY,
42 POSTAL_CODE,
43 SORTING_CODE,
44 STREET_ADDRESS,
45 ORGANIZATION,
46 RECIPIENT,
47 };
48
49 enum LengthHint {
50 LENGTH_HINT_SHORT,
51 LENGTH_HINT_LONG,
52 };
53
54 } // namespace addressinput
55 } // namespace i18n
56
57 // Indexes into arrays of address field data. The values in
58 // i18n::addressinput::AddressField enum cannot be used directly because they
59 // are not sequential.
60 enum AddressFieldIndex {
61 COUNTRY_INDEX,
62 ADMIN_AREA_INDEX,
63 LOCALITY_INDEX,
64 POSTAL_CODE_INDEX,
65 STREET_ADDRESS_1_INDEX,
66 STREET_ADDRESS_2_INDEX,
67 RECIPIENT_INDEX,
68 };
69
70 // Indexes into arrays of street address line data.
71 enum StreetAddressLine {
72 STREET_ADDRESS_LINE_1,
73 STREET_ADDRESS_LINE_2,
74 };
75
76 // The number of address types.
77 const int kNumberOfAddressTypes = ADDRESS_TYPE_BILLING + 1;
78
79 // The maximum number of input fields.
80 const int kMaxNumberOfInputFields = RECIPIENT_INDEX + 1;
81
82 // The maximum number of street address lines.
83 const int kMaxNumberOfStreetAddressLines = STREET_ADDRESS_LINE_2 + 1;
84
85 // A mapping of StreetAddressLine to corresponding values in AddressFieldIndex.
86 // Used to lookup address field data for street address lines.
87 const AddressFieldIndex kStreetAddressLineIndex
88 [kMaxNumberOfStreetAddressLines] = {
89 STREET_ADDRESS_1_INDEX,
90 STREET_ADDRESS_2_INDEX,
91 };
92
93 // A mapping of AddressFieldIndex and AddressType to autofill field types.
94 const ServerFieldType kServerFields[kMaxNumberOfInputFields]
95 [kNumberOfAddressTypes] = {
96 {ADDRESS_HOME_COUNTRY, ADDRESS_BILLING_COUNTRY},
Evan Stade 2013/10/08 23:44:51 space after { and before } also, this seems to be
97 {ADDRESS_HOME_STATE, ADDRESS_BILLING_STATE},
98 {ADDRESS_HOME_CITY, ADDRESS_BILLING_CITY},
99 {ADDRESS_HOME_ZIP, ADDRESS_BILLING_ZIP},
100 {ADDRESS_HOME_LINE1, ADDRESS_BILLING_LINE1},
101 {ADDRESS_HOME_LINE2, ADDRESS_BILLING_LINE2},
102 {NAME_FULL, NAME_BILLING_FULL},
103 };
104
105 // A mapping of AddressFieldIndex and AddressType to string identifiers for
Evan Stade 2013/10/08 23:44:51 you should make this a map from autofill field typ
106 // placeholder text.
107 const int kPlaceHolderStringIds[kMaxNumberOfInputFields]
Evan Stade 2013/10/08 23:44:51 s/PlaceHolder/Placeholder
108 [kNumberOfAddressTypes] = {
109 {IDS_AUTOFILL_FIELD_LABEL_COUNTRY, IDS_AUTOFILL_FIELD_LABEL_COUNTRY},
110 {IDS_AUTOFILL_FIELD_LABEL_STATE, IDS_AUTOFILL_FIELD_LABEL_STATE},
111 {IDS_AUTOFILL_DIALOG_PLACEHOLDER_LOCALITY,
112 IDS_AUTOFILL_DIALOG_PLACEHOLDER_LOCALITY},
113 {IDS_AUTOFILL_DIALOG_PLACEHOLDER_POSTAL_CODE,
114 IDS_AUTOFILL_DIALOG_PLACEHOLDER_POSTAL_CODE},
115 {IDS_AUTOFILL_DIALOG_PLACEHOLDER_ADDRESS_LINE_1,
116 IDS_AUTOFILL_DIALOG_PLACEHOLDER_ADDRESS_LINE_1},
117 {IDS_AUTOFILL_DIALOG_PLACEHOLDER_ADDRESS_LINE_2,
118 IDS_AUTOFILL_DIALOG_PLACEHOLDER_ADDRESS_LINE_2},
119 {IDS_AUTOFILL_DIALOG_PLACEHOLDER_ADDRESSEE_NAME,
120 IDS_AUTOFILL_DIALOG_PLACEHOLDER_CARDHOLDER_NAME},
121 };
122
123 // Returns the AddressFieldIndex for the given i18n::addressinput::AddressField.
124 // If the address field is STREET_ADDRESS, then uses the given StreetAddressLine
125 // to determine whether to return STREET_ADDRESS_1_INDEX or
126 // STREET_ADDRESS_2_INDEX.
127 AddressFieldIndex AddressFieldToIndex(
128 i18n::addressinput::AddressField field_type,
129 StreetAddressLine street_address_line) {
130 switch (field_type) {
131 case i18n::addressinput::COUNTRY:
132 return COUNTRY_INDEX;
133 case i18n::addressinput::ADMIN_AREA:
134 return ADMIN_AREA_INDEX;
135 case i18n::addressinput::LOCALITY:
136 return LOCALITY_INDEX;
137 case i18n::addressinput::POSTAL_CODE:
138 return POSTAL_CODE_INDEX;
139 case i18n::addressinput::STREET_ADDRESS:
140 return kStreetAddressLineIndex[street_address_line];
Evan Stade 2013/10/08 23:44:51 2 returns in a row?
141 return POSTAL_CODE_INDEX;
142 case i18n::addressinput::RECIPIENT:
143 return RECIPIENT_INDEX;
144 default:
145 NOTREACHED();
146 return COUNTRY_INDEX;
147 }
148 }
149
150 // Sets the address field types and length hints for the given |country_region|
151 // and |language|.
152 void GetI18nFields(const std::string country_region,
Evan Stade 2013/10/08 23:44:51 const ref?
153 const std::string& language,
154 std::vector<i18n::addressinput::AddressField>* field_types,
155 std::vector<i18n::addressinput::LengthHint>* length_hints) {
Evan Stade 2013/10/08 23:44:51 I'd prefer if this were a single vector, of either
156 // TODO(rouslan): Use the country_region and language specific
157 // address input field types and names after libaddressinput is integrated.
158 field_types->push_back(i18n::addressinput::RECIPIENT);
159 length_hints->push_back(i18n::addressinput::LENGTH_HINT_LONG);
160
161 field_types->push_back(i18n::addressinput::STREET_ADDRESS);
162 length_hints->push_back(i18n::addressinput::LENGTH_HINT_LONG);
163
164 field_types->push_back(i18n::addressinput::LOCALITY);
165 length_hints->push_back(i18n::addressinput::LENGTH_HINT_LONG);
166
167 field_types->push_back(i18n::addressinput::ADMIN_AREA);
168 length_hints->push_back(i18n::addressinput::LENGTH_HINT_SHORT);
169
170 field_types->push_back(i18n::addressinput::POSTAL_CODE);
171 length_hints->push_back(i18n::addressinput::LENGTH_HINT_SHORT);
172
173 field_types->push_back(i18n::addressinput::COUNTRY);
174 length_hints->push_back(i18n::addressinput::LENGTH_HINT_LONG);
175
Evan Stade 2013/10/08 23:44:51 ^H
176 }
177
178 // Returns an incremented |row_index| if |length_hint| and |prev_length_hint|
179 // indicate that the current input should start on a new line.
180 int IncrementRowIndexBasedOnLengthHint(
181 i18n::addressinput::LengthHint prev_length_hint,
182 i18n::addressinput::LengthHint length_hint,
183 int row_index) {
184 if (length_hint == i18n::addressinput::LENGTH_HINT_LONG ||
185 prev_length_hint != length_hint) {
Evan Stade 2013/10/08 23:44:51 optional nit: imo, this is easier to grok as if (
186 return row_index + 1;
187 }
188 return row_index;
189 }
190
191 // Appends the |field_type| input to |inputs|. Appends
192 // kMaxNumberOfStreetAddressLines inputs if |field_type| is STREET_ADDRESS.
Evan Stade 2013/10/08 23:44:51 can you document the other params? I don't underst
193 int BuildI18nInput(int row_index,
Evan Stade 2013/10/08 23:44:51 instead of passing row_index around, I think you c
194 i18n::addressinput::AddressField field_type,
195 i18n::addressinput::LengthHint prev_length_hint,
196 i18n::addressinput::LengthHint length_hint,
197 AddressType address_type,
198 DetailInputs* inputs) {
199 int field_index = AddressFieldToIndex(field_type, STREET_ADDRESS_LINE_1);
Evan Stade 2013/10/08 23:44:51 this is confusing because most of the time STREET_
200 row_index = IncrementRowIndexBasedOnLengthHint(
201 prev_length_hint, length_hint, row_index);
202 inputs->push_back({row_index, kServerFields[field_index][address_type],
203 kPlaceHolderStringIds[field_index][address_type]});
204
205 if (field_type == i18n::addressinput::STREET_ADDRESS) {
206 field_index = AddressFieldToIndex(field_type, STREET_ADDRESS_LINE_2);
207 row_index = IncrementRowIndexBasedOnLengthHint(
208 prev_length_hint, length_hint, row_index);
209 inputs->push_back({row_index, kServerFields[field_index][address_type],
210 kPlaceHolderStringIds[field_index][address_type]});
211 }
212
213 return row_index;
214 }
215
216 // Returns the language of the current application locale.
217 std::string GetLocaleLanguage() {
218 const std::string& locale = g_browser_process->GetApplicationLocale();
219 return locale.substr(0, locale.find('-'));
Evan Stade 2013/10/08 23:44:51 AutofillCountry::CountryCodeForLocale
220 }
221
222 } // namespace
223
224 bool IsI18nAddressInputEnabled() {
225 return CommandLine::ForCurrentProcess()->HasSwitch(
226 ::switches::kEnableAutofillAddressInternationalization);
227 }
228
229 std::string GuessCountry() {
230 if (!IsI18nAddressInputEnabled())
231 return "US";
232
233 // TODO(rouslan): Improve on this rudimentary implementation of guessing the
234 // current country code.
235 return AutofillCountry::CountryCodeForLocale(
236 g_browser_process->GetApplicationLocale());
237 }
238
239 void BuildI18nInputs(AddressType address_type,
240 const std::string& country_region,
241 int row_index,
242 DetailInputs* inputs) {
243 std::vector<i18n::addressinput::AddressField> field_types;
244 std::vector<i18n::addressinput::LengthHint> length_hints;
245 GetI18nFields(
246 country_region, GetLocaleLanguage(), &field_types, &length_hints);
247 i18n::addressinput::LengthHint prev_length_hint =
248 i18n::addressinput::LENGTH_HINT_LONG;
249 for (size_t i = 0; i < field_types.size() && i < length_hints.size(); ++i) {
250 row_index = BuildI18nInput(row_index,
251 field_types[i],
252 prev_length_hint,
253 length_hints[i],
254 address_type,
255 inputs);
256 prev_length_hint = length_hints[i];
257 }
258 }
259
260 } // namespace i18ninput
261 } // namespace autofill
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698