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

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

Issue 10952004: Change intl to use new pub layout (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 | « pkg/intl/example/basic/messages_th_th.dart ('k') | 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
(Empty)
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
3 // BSD-style license that can be found in the LICENSE file.
4
5 /**
6 * Internationalization object providing access to message formatting objects,
7 * date formatting, parsing, bidirectional text relative to a specific locale.
8 */
9 #library('intl');
10
11 // TODO(rnystrom): Use "package:" import when test.dart supports it (#4968).
12 #import('../htmlescape/lib/htmlescape.dart');
13
14 #import('date_format.dart');
15 #import('lib/intl_helpers.dart');
16
17 #source('bidi_formatter.dart');
18 #source('bidi_utils.dart');
19
20 class Intl {
21 /**
22 * String indicating the locale code with which the message is to be
23 * formatted (such as en-CA).
24 */
25 String _locale;
26
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 */
31 static String _defaultLocale;
32
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 /**
44 * Return a new date format using the specified [pattern].
45 * If [desiredLocale] is not specified, then we default to [locale].
46 */
47 DateFormat date([String pattern, String desiredLocale]) {
48 var actualLocale = (desiredLocale == null) ? locale : desiredLocale;
49 return new DateFormat(pattern, actualLocale);
50 }
51
52 /**
53 * Constructor optionally [aLocale] for specifics of the language
54 * locale to be used, otherwise, we will attempt to infer it (acceptable if
55 * Dart is running on the client, we can infer from the browser/client
56 * preferences).
57 */
58 Intl([String aLocale]) {
59 if (aLocale != null) {
60 _locale = aLocale;
61 } else {
62 _locale = getCurrentLocale();
63 }
64 }
65
66 /**
67 * Returns a message that can be internationalized. It takes a
68 * [message_str] that will be translated, which may be interpolated
69 * based on one or more variables, a [desc] providing a description of usage
70 * for the [message_str], and a map of [examples] for each data element to be
71 * substituted into the message. For example, if message="Hello, $name", then
72 * examples = {'name': 'Sparky'}. If not using the user's default locale, or
73 * if the locale is not easily detectable, explicitly pass [locale].
74 * The values of [desc] and [examples] are not used at run-time but are only
75 * made available to the translators, so they MUST be simple Strings available
76 * at compile time: no String interpolation or concatenation.
77 * The expected usage of this is inside a function that takes as parameters
78 * the variables used in the interpolated string, and additionally also a
79 * locale (optional).
80 * Ultimately, the information about the enclosing function and its arguments
81 * will be extracted automatically but for the time being it must be passed
82 * explicitly in the [name] and [args] arguments.
83 */
84 static String message(String message_str, [final String desc='',
85 final Map examples=const {}, String locale, String name,
86 List<String> args]) {
87 return _messageLookup.lookupMessage(
88 message_str, desc, examples, locale, name, args);
89 }
90
91 /**
92 * Return the locale for this instance. If none was set, the locale will
93 * be the default.
94 */
95 String get locale => _locale;
96
97 /**
98 * Return true if the locale exists, or if it is null. The null case
99 * is interpreted to mean that we use the default locale.
100 */
101 static bool _localeExists(localeName) {
102 return DateFormat.localeExists(localeName);
103 }
104
105 /**
106 * Given [newLocale] return a locale that we have data for that is similar
107 * to it, if possible.
108 * If [newLocale] is found directly, return it. If it can't be found, look up
109 * based on just the language (e.g. 'en_CA' -> 'en'). Also accepts '-'
110 * as a separator and changes it into '_' for lookup, and changes the
111 * country to uppercase.
112 * Note that null is interpreted as meaning the default locale, so if
113 * [newLocale] is null it will be returned.
114 */
115 static String verifiedLocale(String newLocale) {
116 // TODO(alanknight): This is specific to DateFormat, and only used there
117 // now. This should be moved, renamed, or generalized.
118 if (newLocale == null) return systemLocale;
119 if (_localeExists(newLocale)) {
120 return newLocale;
121 }
122 for (var each in [canonicalizedLocale(newLocale), _shortLocale(newLocale)]) {
123 if (_localeExists(each)) {
124 return each;
125 }
126 }
127 throw new IllegalArgumentException("Invalid locale '$newLocale'");
128 }
129
130 /** Return the short version of a locale name, e.g. 'en_US' => 'en' */
131 static String _shortLocale(String aLocale) {
132 if (aLocale.length < 2) return aLocale;
133 return aLocale.substring(0, 2).toLowerCase();
134 }
135
136 /**
137 * Return a locale name turned into xx_YY where it might possibly be
138 * in the wrong case or with a hyphen instead of an underscore.
139 */
140 static String canonicalizedLocale(String aLocale) {
141 // Locales of length < 5 are presumably two-letter forms, or else malformed.
142 // Locales of length > 6 are likely to be malformed. In either case we
143 // return them unmodified and if correct they will be found.
144 // We treat C as a special case, and assume it wants en_ISO for formatting.
145 // TODO(alanknight): en_ISO is probably not quite right for the C/Posix
146 // locale for formatting. Consider adding C to the formats database.
147 if (aLocale == "C") return "en_ISO";
148 if ((aLocale.length < 5) || (aLocale.length > 6)) return aLocale;
149 if (aLocale[2] != '-' && (aLocale[2] != '_')) return aLocale;
150 var lastRegionLetter = aLocale.length == 5 ? "" : aLocale[5].toUpperCase();
151 return '${aLocale[0]}${aLocale[1]}_${aLocale[3].toUpperCase()}'
152 '${aLocale[4].toUpperCase()}$lastRegionLetter';
153 }
154
155 /**
156 * Support method for message formatting. Select the correct plural form from
157 * [cases] given [howMany].
158 */
159 static String plural(var howMany, Map cases, [num offset=0]) {
160 // TODO(efortuna): Deal with "few" and "many" cases, offset, and others!
161 return select(howMany.toString(), cases);
162 }
163
164 /**
165 * Format the given function with a specific [locale], given a
166 * [msg_function] that takes no parameters and returns a String. We
167 * basically delay calling the message function proper until after the proper
168 * locale has been set.
169 */
170 static String withLocale(String locale, Function msg_function) {
171 // We have to do this silliness because Locale is not known at compile time,
172 // but must be a static variable.
173 if (_defaultLocale == null) _defaultLocale = systemLocale;
174 var oldLocale = _defaultLocale;
175 _defaultLocale = locale;
176 var result = msg_function();
177 _defaultLocale = oldLocale;
178 return result;
179 }
180
181 /**
182 * Support method for message formatting. Select the correct exact (gender,
183 * usually) form from [cases] given the user [choice].
184 */
185 static String select(String choice, Map cases) {
186 if (cases.containsKey(choice)) {
187 return cases[choice];
188 } else if (cases.containsKey('other')){
189 return cases['other'];
190 } else {
191 return '';
192 }
193 }
194
195 /**
196 * Accessor for the current locale. This should always == the default locale,
197 * unless for some reason this gets called inside a message that resets the
198 * locale.
199 */
200 static String getCurrentLocale() {
201 if (_defaultLocale == null) _defaultLocale = systemLocale;
202 return _defaultLocale;
203 }
204 }
205
206 /**
207 * The internal mechanism for looking up messages. We expect this to be set
208 * by the implementing package so that we're not dependent on its
209 * implementation.
210 */
211 var _messageLookup = const
212 UninitializedLocaleData('initializeMessages(<locale>)');
213
214 /**
215 * Initialize the message lookup mechanism. This is for internal use only.
216 * User applications should import message_lookup_local.dart and call
217 * initializeMessages
218 */
219 void initializeInternalMessageLookup(Function lookupFunction) {
220 if (_messageLookup is UninitializedLocaleData) {
221 _messageLookup = lookupFunction();
222 }
223 }
OLDNEW
« no previous file with comments | « pkg/intl/example/basic/messages_th_th.dart ('k') | pkg/intl/intl_browser.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698