Upstream version 6.35.121.0
[platform/framework/web/crosswalk.git] / src / third_party / libaddressinput / chromium / cpp / src / address_ui.cc
1 // Copyright (C) 2013 Google Inc.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include <libaddressinput/address_ui.h>
16
17 #include <libaddressinput/address_field.h>
18 #include <libaddressinput/address_ui_component.h>
19
20 #include <algorithm>
21 #include <cassert>
22 #include <cstddef>
23 #include <set>
24 #include <string>
25 #include <vector>
26
27 #include "grit.h"
28 #include "grit/libaddressinput_strings.h"
29 #include "region_data_constants.h"
30 #include "rule.h"
31 #include "util/string_util.h"
32
33 namespace i18n {
34 namespace addressinput {
35
36 namespace {
37
38 int GetMessageIdForField(AddressField field,
39                          int admin_area_name_message_id,
40                          int postal_code_name_message_id) {
41   switch (field) {
42     case COUNTRY:
43       return IDS_LIBADDRESSINPUT_I18N_COUNTRY_LABEL;
44     case ADMIN_AREA:
45       return admin_area_name_message_id;
46     case LOCALITY:
47       return IDS_LIBADDRESSINPUT_I18N_LOCALITY_LABEL;
48     case DEPENDENT_LOCALITY:
49       return IDS_LIBADDRESSINPUT_I18N_DEPENDENT_LOCALITY_LABEL;
50     case SORTING_CODE:
51       return IDS_LIBADDRESSINPUT_I18N_CEDEX_LABEL;
52     case POSTAL_CODE:
53       return postal_code_name_message_id;
54     case STREET_ADDRESS:
55       return IDS_LIBADDRESSINPUT_I18N_ADDRESS_LINE1_LABEL;
56     case ORGANIZATION:
57       return IDS_LIBADDRESSINPUT_I18N_ORGANIZATION_LABEL;
58     case RECIPIENT:
59       return IDS_LIBADDRESSINPUT_I18N_RECIPIENT_LABEL;
60     default:
61       return INVALID_MESSAGE_ID;
62   }
63 }
64
65 // Returns the BCP 47 language code that should be used to format the address
66 // that the user entered.
67 //
68 // If the rule does not contain information about languages, then returns the
69 // UI language.
70 //
71 // If the UI language is either the default language for the country, one of the
72 // languages for rules, or one of the languages for address input, then returns
73 // this UI language. If there're no matches, then picks one of the languages in
74 // the rule and returns it.
75 //
76 // If latinized rules are available and the UI language code is not the primary
77 // language code for this region, then returns the primary language with "-latn"
78 // appended.
79 std::string GetComponentsLanguageCode(const Rule& rule,
80                                       const std::string& ui_language_code) {
81   // Select the default language code for the region.
82   std::string default_language_code;
83   if (!rule.GetLanguage().empty()) {
84     default_language_code = rule.GetLanguage();
85   } else if (!rule.GetLanguages().empty()) {
86     default_language_code = rule.GetLanguages()[0];
87   } else if (!rule.GetInputLanguages().empty()) {
88     default_language_code = rule.GetInputLanguages()[0];
89   } else {
90     // Region does not have any language information (e.g. Antarctica). Use the
91     // UI language code as is.
92     return ui_language_code;
93   }
94
95   // If the UI language code is not set, then use default language code.
96   if (ui_language_code.empty()) {
97     return default_language_code;
98   }
99
100   const std::string& normalized_ui_language_code =
101       NormalizeLanguageCode(ui_language_code);
102   const std::string& normalized_default_language_code =
103       NormalizeLanguageCode(default_language_code);
104
105   // Check whether UI language code matches any language codes in the rule,
106   // normalized or as is.
107   if (normalized_default_language_code == normalized_ui_language_code ||
108       std::find(
109           rule.GetLanguages().begin(),
110           rule.GetLanguages().end(),
111           ui_language_code) != rule.GetLanguages().end() ||
112       std::find(
113           rule.GetLanguages().begin(),
114           rule.GetLanguages().end(),
115           normalized_ui_language_code) != rule.GetLanguages().end() ||
116       std::find(
117           rule.GetInputLanguages().begin(),
118           rule.GetInputLanguages().end(),
119           ui_language_code) != rule.GetInputLanguages().end() ||
120       std::find(
121           rule.GetInputLanguages().begin(),
122           rule.GetInputLanguages().end(),
123           normalized_ui_language_code) != rule.GetInputLanguages().end()) {
124     return ui_language_code;
125   }
126
127   // The UI language code does not match any language information in the rule.
128   return rule.GetLatinFormat().empty()
129              ? default_language_code
130              : normalized_default_language_code + "-latn";
131 }
132
133 }  // namespace
134
135 const std::vector<std::string>& GetRegionCodes() {
136   return RegionDataConstants::GetRegionCodes();
137 }
138
139 std::vector<AddressUiComponent> BuildComponents(
140     const std::string& region_code,
141     const std::string& ui_language_code,
142     std::string* components_language_code) {
143   std::vector<AddressUiComponent> result;
144
145   Rule rule;
146   rule.CopyFrom(Rule::GetDefault());
147   if (!rule.ParseSerializedRule(
148            RegionDataConstants::GetRegionData(region_code))) {
149     return result;
150   }
151
152   if (components_language_code != NULL) {
153     *components_language_code =
154         GetComponentsLanguageCode(rule, ui_language_code);
155   }
156
157   // For avoiding showing an input field twice, when the field is displayed
158   // twice on an envelope.
159   std::set<AddressField> fields;
160
161   // If latinized rules are available and the |ui_language_code| is not the
162   // primary language code for the region, then use the latinized formatting
163   // rules.
164   const std::vector<std::vector<FormatElement> >& format =
165       rule.GetLatinFormat().empty() ||
166       ui_language_code.empty() ||
167       NormalizeLanguageCode(ui_language_code) ==
168           NormalizeLanguageCode(rule.GetLanguage())
169               ? rule.GetFormat() : rule.GetLatinFormat();
170
171   for (std::vector<std::vector<FormatElement> >::const_iterator
172            line_it = format.begin();
173        line_it != format.end();
174        ++line_it) {
175     int num_fields_this_row = 0;
176     for (std::vector<FormatElement>::const_iterator element_it =
177              line_it->begin();
178          element_it != line_it->end();
179          ++element_it) {
180       if (element_it->IsField()) {
181         ++num_fields_this_row;
182       }
183     }
184
185     for (std::vector<FormatElement>::const_iterator element_it =
186              line_it->begin();
187          element_it != line_it->end();
188          ++element_it) {
189       AddressField field = element_it->field;
190       if (!element_it->IsField() || fields.find(field) != fields.end()) {
191         continue;
192       }
193       fields.insert(field);
194
195       AddressUiComponent component;
196       component.length_hint =
197           num_fields_this_row == 1 ? AddressUiComponent::HINT_LONG
198                                    : AddressUiComponent::HINT_SHORT;
199       component.field = field;
200       component.name_id =
201           GetMessageIdForField(field,
202                                rule.GetAdminAreaNameMessageId(),
203                                rule.GetPostalCodeNameMessageId());
204       result.push_back(component);
205     }
206   }
207
208   return result;
209 }
210
211 std::vector<AddressField> GetRequiredFields(const std::string& region_code) {
212   Rule rule;
213   rule.CopyFrom(Rule::GetDefault());
214   if (!rule.ParseSerializedRule(
215            RegionDataConstants::GetRegionData(region_code))) {
216     return std::vector<AddressField>();
217   }
218
219   return rule.GetRequired();
220 }
221
222 const std::string& GetCompactAddressLinesSeparator(
223     const std::string& language_code) {
224   return RegionDataConstants::GetLanguageCompactLineSeparator(language_code);
225 }
226
227 }  // namespace addressinput
228 }  // namespace i18n