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

Side by Side Diff: pkg/intl/intl.dart

Issue 10907266: Find the system locale from the browser or OS (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 3 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
« no previous file with comments | « no previous file | pkg/intl/intl_browser.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 /** 5 /**
6 * Internationalization object providing access to message formatting objects, 6 * Internationalization object providing access to message formatting objects,
7 * date formatting, parsing, bidirectional text relative to a specific locale. 7 * date formatting, parsing, bidirectional text relative to a specific locale.
8 */ 8 */
9 #library('intl'); 9 #library('intl');
10 10
11 // TODO(rnystrom): Use "package:" import when test.dart supports it (#4968). 11 // TODO(rnystrom): Use "package:" import when test.dart supports it (#4968).
12 #import('../htmlescape/lib/htmlescape.dart'); 12 #import('../htmlescape/lib/htmlescape.dart');
13 13
14 #import('date_format.dart'); 14 #import('date_format.dart');
15 #import('lib/intl_helpers.dart'); 15 #import('lib/intl_helpers.dart');
16 16
17 #source('bidi_formatter.dart'); 17 #source('bidi_formatter.dart');
18 #source('bidi_utils.dart'); 18 #source('bidi_utils.dart');
19 19
20 class Intl { 20 class Intl {
21 /** 21 /**
22 * String indicating the locale code with which the message is to be 22 * String indicating the locale code with which the message is to be
23 * formatted (such as en-CA). 23 * formatted (such as en-CA).
24 */ 24 */
25 String _locale; 25 String _locale;
26 26
27 /** The default locale, which normally will be obtained from the browser. */ 27 /** The default locale. This defaults to being set from systemLocale, but
28 * can also be set explicitly, and will then apply to any new instances where
29 * the locale isn't specified.
30 */
28 static String _defaultLocale; 31 static String _defaultLocale;
29 32
30 /** 33 /**
34 * The system's locale, as obtained from the window.navigator.language
35 * or other operating system mechanism. Note that due to system limitations
36 * this is not automatically set, and must be set by importing one of
37 * intl_browser.dart or intl_standalone.dart and calling findSystemLocale().
38 */
39 // TODO(alanknight): Detect this without forcing the jump through hoops.
40 // Issue 5171.
41 static String systemLocale = 'en_US';
42
43 /**
31 * Return a new date format using the specified [pattern]. 44 * Return a new date format using the specified [pattern].
32 * If [desiredLocale] is not specified, then we default to [locale]. 45 * If [desiredLocale] is not specified, then we default to [locale].
33 */ 46 */
34 DateFormat date([String pattern, String desiredLocale]) { 47 DateFormat date([String pattern, String desiredLocale]) {
35 var actualLocale = (desiredLocale == null) ? locale : desiredLocale; 48 var actualLocale = (desiredLocale == null) ? locale : desiredLocale;
36 return new DateFormat(pattern, actualLocale); 49 return new DateFormat(pattern, actualLocale);
37 } 50 }
38 51
39 /** 52 /**
40 * Constructor optionally [aLocale] for specifics of the language 53 * Constructor optionally [aLocale] for specifics of the language
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
95 * If [newLocale] is found directly, return it. If it can't be found, look up 108 * If [newLocale] is found directly, return it. If it can't be found, look up
96 * based on just the language (e.g. 'en_CA' -> 'en'). Also accepts '-' 109 * based on just the language (e.g. 'en_CA' -> 'en'). Also accepts '-'
97 * as a separator and changes it into '_' for lookup, and changes the 110 * as a separator and changes it into '_' for lookup, and changes the
98 * country to uppercase. 111 * country to uppercase.
99 * Note that null is interpreted as meaning the default locale, so if 112 * Note that null is interpreted as meaning the default locale, so if
100 * [newLocale] is null it will be returned. 113 * [newLocale] is null it will be returned.
101 */ 114 */
102 static String verifiedLocale(String newLocale) { 115 static String verifiedLocale(String newLocale) {
103 // TODO(alanknight): This is specific to DateFormat, and only used there 116 // TODO(alanknight): This is specific to DateFormat, and only used there
104 // now. This should be moved, renamed, or generalized. 117 // now. This should be moved, renamed, or generalized.
105 if (newLocale == null) return _getDefaultLocale(); 118 if (newLocale == null) return systemLocale;
106 if (_localeExists(newLocale)) { 119 if (_localeExists(newLocale)) {
107 return newLocale; 120 return newLocale;
108 } 121 }
109 for (var each in [_canonicalized(newLocale), _shortLocale(newLocale)]) { 122 for (var each in [canonicalizedLocale(newLocale), _shortLocale(newLocale)]) {
110 if (_localeExists(each)) { 123 if (_localeExists(each)) {
111 return each; 124 return each;
112 } 125 }
113 } 126 }
114 throw new IllegalArgumentException("Invalid locale '$newLocale'"); 127 throw new IllegalArgumentException("Invalid locale '$newLocale'");
115 } 128 }
116 129
117 /** Return the short version of a locale name, e.g. 'en_US' => 'en' */ 130 /** Return the short version of a locale name, e.g. 'en_US' => 'en' */
118 static String _shortLocale(String aLocale) { 131 static String _shortLocale(String aLocale) {
119 if (aLocale.length < 2) return aLocale; 132 if (aLocale.length < 2) return aLocale;
120 return aLocale.substring(0, 2).toLowerCase(); 133 return aLocale.substring(0, 2).toLowerCase();
121 } 134 }
122 135
123 /** 136 /**
124 * Return a locale name turned into xx_YY where it might possibly be 137 * Return a locale name turned into xx_YY where it might possibly be
125 * in the wrong case or with a hyphen instead of an underscore. 138 * in the wrong case or with a hyphen instead of an underscore.
126 */ 139 */
127 static String _canonicalized(String aLocale) { 140 static String canonicalizedLocale(String aLocale) {
128 // Locales of length < 5 are presumably two-letter forms, or else malformed. 141 // Locales of length < 5 are presumably two-letter forms, or else malformed.
129 // Locales of length > 6 are likely to be malformed. In either case we 142 // Locales of length > 6 are likely to be malformed. In either case we
130 // return them unmodified and if correct they will be found. 143 // return them unmodified and if correct they will be found.
131 if ((aLocale.length < 5) || (aLocale.length > 6)) return aLocale; 144 if ((aLocale.length < 5) || (aLocale.length > 6)) return aLocale;
132 if (aLocale[2] != '-' && (aLocale[2] != '_')) return aLocale; 145 if (aLocale[2] != '-' && (aLocale[2] != '_')) return aLocale;
133 return '${aLocale[0]}${aLocale[1]}_${aLocale[3].toUpperCase()}' 146 return '${aLocale[0]}${aLocale[1]}_${aLocale[3].toUpperCase()}'
134 '${aLocale[4].toUpperCase()}'; 147 '${aLocale[4].toUpperCase()}';
135 } 148 }
136 149
137 /** 150 /**
138 * Support method for message formatting. Select the correct plural form from 151 * Support method for message formatting. Select the correct plural form from
139 * [cases] given [howMany]. 152 * [cases] given [howMany].
140 */ 153 */
141 static String plural(var howMany, Map cases, [num offset=0]) { 154 static String plural(var howMany, Map cases, [num offset=0]) {
142 // TODO(efortuna): Deal with "few" and "many" cases, offset, and others! 155 // TODO(efortuna): Deal with "few" and "many" cases, offset, and others!
143 return select(howMany.toString(), cases); 156 return select(howMany.toString(), cases);
144 } 157 }
145 158
146 /** 159 /**
147 * Format the given function with a specific [locale], given a 160 * Format the given function with a specific [locale], given a
148 * [msg_function] that takes no parameters and returns a String. We 161 * [msg_function] that takes no parameters and returns a String. We
149 * basically delay calling the message function proper until after the proper 162 * basically delay calling the message function proper until after the proper
150 * locale has been set. 163 * locale has been set.
151 */ 164 */
152 static String withLocale(String locale, Function msg_function) { 165 static String withLocale(String locale, Function msg_function) {
153 // We have to do this silliness because Locale is not known at compile time, 166 // We have to do this silliness because Locale is not known at compile time,
154 // but must be a static variable. 167 // but must be a static variable.
155 if (_defaultLocale == null) _defaultLocale = _getDefaultLocale(); 168 if (_defaultLocale == null) _defaultLocale = systemLocale;
156 var oldLocale = _defaultLocale; 169 var oldLocale = _defaultLocale;
157 _defaultLocale = locale; 170 _defaultLocale = locale;
158 var result = msg_function(); 171 var result = msg_function();
159 _defaultLocale = oldLocale; 172 _defaultLocale = oldLocale;
160 return result; 173 return result;
161 } 174 }
162 175
163 /** 176 /**
164 * Support method for message formatting. Select the correct exact (gender, 177 * Support method for message formatting. Select the correct exact (gender,
165 * usually) form from [cases] given the user [choice]. 178 * usually) form from [cases] given the user [choice].
166 */ 179 */
167 static String select(String choice, Map cases) { 180 static String select(String choice, Map cases) {
168 if (cases.containsKey(choice)) { 181 if (cases.containsKey(choice)) {
169 return cases[choice]; 182 return cases[choice];
170 } else if (cases.containsKey('other')){ 183 } else if (cases.containsKey('other')){
171 return cases['other']; 184 return cases['other'];
172 } else { 185 } else {
173 return ''; 186 return '';
174 } 187 }
175 } 188 }
176 189
177 /** 190 /**
178 * Helper to detect the locale as defined at runtime.
179 */
180 static String _getDefaultLocale() {
181 // TODO(efortuna): Detect the default locale given the user preferences.
182 // That would mean using window.navigator.language in a browser or
183 // an environment variable or other OS mechanism for the standalone VM.
184 // Yay, hard-coding for now!
185 return 'en_US';
186 }
187
188 /**
189 * Accessor for the current locale. This should always == the default locale, 191 * Accessor for the current locale. This should always == the default locale,
190 * unless for some reason this gets called inside a message that resets the 192 * unless for some reason this gets called inside a message that resets the
191 * locale. 193 * locale.
192 */ 194 */
193 static String getCurrentLocale() { 195 static String getCurrentLocale() {
194 if (_defaultLocale == null) _defaultLocale = _getDefaultLocale(); 196 if (_defaultLocale == null) _defaultLocale = systemLocale;
195 return _defaultLocale; 197 return _defaultLocale;
196 } 198 }
197 } 199 }
198 200
199 /** 201 /**
200 * The internal mechanism for looking up messages. We expect this to be set 202 * The internal mechanism for looking up messages. We expect this to be set
201 * by the implementing package so that we're not dependent on its 203 * by the implementing package so that we're not dependent on its
202 * implementation. 204 * implementation.
203 */ 205 */
204 var _messageLookup = const 206 var _messageLookup = const
205 UninitializedLocaleData('initializeMessages(<locale>)'); 207 UninitializedLocaleData('initializeMessages(<locale>)');
206 208
207 /** 209 /**
208 * Initialize the message lookup mechanism. This is for internal use only. 210 * Initialize the message lookup mechanism. This is for internal use only.
209 * User applications should import message_lookup_local.dart and call 211 * User applications should import message_lookup_local.dart and call
210 * initializeMessages 212 * initializeMessages
211 */ 213 */
212 void initializeInternalMessageLookup(Function lookupFunction) { 214 void initializeInternalMessageLookup(Function lookupFunction) {
213 if (_messageLookup is UninitializedLocaleData) { 215 if (_messageLookup is UninitializedLocaleData) {
214 _messageLookup = lookupFunction(); 216 _messageLookup = lookupFunction();
215 } 217 }
216 } 218 }
OLDNEW
« no previous file with comments | « no previous file | pkg/intl/intl_browser.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698