]>
Commit | Line | Data |
---|---|---|
2f01fe57 | 1 | /* |
81bea17a | 2 | Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved. |
2f01fe57 AD |
3 | Available via Academic Free License >= 2.1 OR the modified BSD license. |
4 | see: http://dojotoolkit.org/license for details | |
5 | */ | |
6 | ||
7 | ||
a089699c AD |
8 | if(!dojo._hasResource["dojo.i18n"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. |
9 | dojo._hasResource["dojo.i18n"] = true; | |
2f01fe57 | 10 | dojo.provide("dojo.i18n"); |
a089699c | 11 | |
81bea17a AD |
12 | dojo.getObject("i18n", true, dojo); |
13 | ||
a089699c AD |
14 | /*===== |
15 | dojo.i18n = { | |
16 | // summary: Utility classes to enable loading of resources for internationalization (i18n) | |
2f01fe57 | 17 | }; |
a089699c AD |
18 | =====*/ |
19 | ||
81bea17a AD |
20 | // when using a real AMD loader, dojo.i18n.getLocalization is already defined by dojo/lib/backCompat |
21 | dojo.i18n.getLocalization = dojo.i18n.getLocalization || function(/*String*/packageName, /*String*/bundleName, /*String?*/locale){ | |
a089699c AD |
22 | // summary: |
23 | // Returns an Object containing the localization for a given resource | |
24 | // bundle in a package, matching the specified locale. | |
25 | // description: | |
26 | // Returns a hash containing name/value pairs in its prototypesuch | |
27 | // that values can be easily overridden. Throws an exception if the | |
28 | // bundle is not found. Bundle must have already been loaded by | |
29 | // `dojo.requireLocalization()` or by a build optimization step. NOTE: | |
30 | // try not to call this method as part of an object property | |
31 | // definition (`var foo = { bar: dojo.i18n.getLocalization() }`). In | |
32 | // some loading situations, the bundle may not be available in time | |
33 | // for the object definition. Instead, call this method inside a | |
34 | // function that is run after all modules load or the page loads (like | |
35 | // in `dojo.addOnLoad()`), or in a widget lifecycle method. | |
36 | // packageName: | |
37 | // package which is associated with this resource | |
38 | // bundleName: | |
39 | // the base filename of the resource bundle (without the ".js" suffix) | |
40 | // locale: | |
41 | // the variant to load (optional). By default, the locale defined by | |
42 | // the host environment: dojo.locale | |
43 | ||
44 | locale = dojo.i18n.normalizeLocale(locale); | |
45 | ||
46 | // look for nearest locale match | |
47 | var elements = locale.split('-'); | |
48 | var module = [packageName,"nls",bundleName].join('.'); | |
81bea17a | 49 | var bundle = dojo._loadedModules[module]; |
a089699c AD |
50 | if(bundle){ |
51 | var localization; | |
52 | for(var i = elements.length; i > 0; i--){ | |
53 | var loc = elements.slice(0, i).join('_'); | |
54 | if(bundle[loc]){ | |
55 | localization = bundle[loc]; | |
56 | break; | |
57 | } | |
58 | } | |
59 | if(!localization){ | |
60 | localization = bundle.ROOT; | |
61 | } | |
62 | ||
63 | // make a singleton prototype so that the caller won't accidentally change the values globally | |
64 | if(localization){ | |
65 | var clazz = function(){}; | |
66 | clazz.prototype = localization; | |
67 | return new clazz(); // Object | |
68 | } | |
69 | } | |
70 | ||
71 | throw new Error("Bundle not found: " + bundleName + " in " + packageName+" , locale=" + locale); | |
2f01fe57 | 72 | }; |
a089699c AD |
73 | |
74 | dojo.i18n.normalizeLocale = function(/*String?*/locale){ | |
75 | // summary: | |
76 | // Returns canonical form of locale, as used by Dojo. | |
77 | // | |
78 | // description: | |
79 | // All variants are case-insensitive and are separated by '-' as specified in [RFC 3066](http://www.ietf.org/rfc/rfc3066.txt). | |
80 | // If no locale is specified, the dojo.locale is returned. dojo.locale is defined by | |
81 | // the user agent's locale unless overridden by djConfig. | |
82 | ||
83 | var result = locale ? locale.toLowerCase() : dojo.locale; | |
84 | if(result == "root"){ | |
85 | result = "ROOT"; | |
86 | } | |
87 | return result; // String | |
2f01fe57 | 88 | }; |
a089699c AD |
89 | |
90 | dojo.i18n._requireLocalization = function(/*String*/moduleName, /*String*/bundleName, /*String?*/locale, /*String?*/availableFlatLocales){ | |
91 | // summary: | |
92 | // See dojo.requireLocalization() | |
93 | // description: | |
94 | // Called by the bootstrap, but factored out so that it is only | |
95 | // included in the build when needed. | |
96 | ||
97 | var targetLocale = dojo.i18n.normalizeLocale(locale); | |
98 | var bundlePackage = [moduleName, "nls", bundleName].join("."); | |
81bea17a | 99 | // NOTE: |
a089699c AD |
100 | // When loading these resources, the packaging does not match what is |
101 | // on disk. This is an implementation detail, as this is just a | |
102 | // private data structure to hold the loaded resources. e.g. | |
103 | // `tests/hello/nls/en-us/salutations.js` is loaded as the object | |
104 | // `tests.hello.nls.salutations.en_us={...}` The structure on disk is | |
105 | // intended to be most convenient for developers and translators, but | |
106 | // in memory it is more logical and efficient to store in a different | |
107 | // order. Locales cannot use dashes, since the resulting path will | |
108 | // not evaluate as valid JS, so we translate them to underscores. | |
81bea17a | 109 | |
a089699c AD |
110 | //Find the best-match locale to load if we have available flat locales. |
111 | var bestLocale = ""; | |
112 | if(availableFlatLocales){ | |
113 | var flatLocales = availableFlatLocales.split(","); | |
114 | for(var i = 0; i < flatLocales.length; i++){ | |
115 | //Locale must match from start of string. | |
116 | //Using ["indexOf"] so customBase builds do not see | |
117 | //this as a dojo._base.array dependency. | |
118 | if(targetLocale["indexOf"](flatLocales[i]) == 0){ | |
119 | if(flatLocales[i].length > bestLocale.length){ | |
120 | bestLocale = flatLocales[i]; | |
121 | } | |
122 | } | |
123 | } | |
124 | if(!bestLocale){ | |
125 | bestLocale = "ROOT"; | |
81bea17a | 126 | } |
a089699c AD |
127 | } |
128 | ||
129 | //See if the desired locale is already loaded. | |
130 | var tempLocale = availableFlatLocales ? bestLocale : targetLocale; | |
131 | var bundle = dojo._loadedModules[bundlePackage]; | |
132 | var localizedBundle = null; | |
133 | if(bundle){ | |
134 | if(dojo.config.localizationComplete && bundle._built){return;} | |
135 | var jsLoc = tempLocale.replace(/-/g, '_'); | |
136 | var translationPackage = bundlePackage+"."+jsLoc; | |
137 | localizedBundle = dojo._loadedModules[translationPackage]; | |
138 | } | |
139 | ||
140 | if(!localizedBundle){ | |
141 | bundle = dojo["provide"](bundlePackage); | |
142 | var syms = dojo._getModuleSymbols(moduleName); | |
143 | var modpath = syms.concat("nls").join("/"); | |
144 | var parent; | |
145 | ||
146 | dojo.i18n._searchLocalePath(tempLocale, availableFlatLocales, function(loc){ | |
147 | var jsLoc = loc.replace(/-/g, '_'); | |
148 | var translationPackage = bundlePackage + "." + jsLoc; | |
149 | var loaded = false; | |
150 | if(!dojo._loadedModules[translationPackage]){ | |
151 | // Mark loaded whether it's found or not, so that further load attempts will not be made | |
152 | dojo["provide"](translationPackage); | |
153 | var module = [modpath]; | |
154 | if(loc != "ROOT"){module.push(loc);} | |
155 | module.push(bundleName); | |
156 | var filespec = module.join("/") + '.js'; | |
157 | loaded = dojo._loadPath(filespec, null, function(hash){ | |
81bea17a | 158 | hash = hash.root || hash; |
a089699c AD |
159 | // Use singleton with prototype to point to parent bundle, then mix-in result from loadPath |
160 | var clazz = function(){}; | |
161 | clazz.prototype = parent; | |
162 | bundle[jsLoc] = new clazz(); | |
163 | for(var j in hash){ bundle[jsLoc][j] = hash[j]; } | |
164 | }); | |
165 | }else{ | |
166 | loaded = true; | |
167 | } | |
168 | if(loaded && bundle[jsLoc]){ | |
169 | parent = bundle[jsLoc]; | |
170 | }else{ | |
171 | bundle[jsLoc] = parent; | |
172 | } | |
81bea17a | 173 | |
a089699c AD |
174 | if(availableFlatLocales){ |
175 | //Stop the locale path searching if we know the availableFlatLocales, since | |
176 | //the first call to this function will load the only bundle that is needed. | |
177 | return true; | |
178 | } | |
179 | }); | |
180 | } | |
181 | ||
182 | //Save the best locale bundle as the target locale bundle when we know the | |
183 | //the available bundles. | |
184 | if(availableFlatLocales && targetLocale != bestLocale){ | |
185 | bundle[targetLocale.replace(/-/g, '_')] = bundle[bestLocale.replace(/-/g, '_')]; | |
186 | } | |
2f01fe57 | 187 | }; |
a089699c | 188 | |
2f01fe57 | 189 | (function(){ |
a089699c | 190 | // If other locales are used, dojo.requireLocalization should load them as |
81bea17a AD |
191 | // well, by default. |
192 | // | |
a089699c AD |
193 | // Override dojo.requireLocalization to do load the default bundle, then |
194 | // iterate through the extraLocale list and load those translations as | |
195 | // well, unless a particular locale was requested. | |
196 | ||
197 | var extra = dojo.config.extraLocale; | |
198 | if(extra){ | |
199 | if(!extra instanceof Array){ | |
200 | extra = [extra]; | |
201 | } | |
202 | ||
203 | var req = dojo.i18n._requireLocalization; | |
204 | dojo.i18n._requireLocalization = function(m, b, locale, availableFlatLocales){ | |
205 | req(m,b,locale, availableFlatLocales); | |
206 | if(locale){return;} | |
207 | for(var i=0; i<extra.length; i++){ | |
208 | req(m,b,extra[i], availableFlatLocales); | |
209 | } | |
210 | }; | |
211 | } | |
2f01fe57 | 212 | })(); |
a089699c AD |
213 | |
214 | dojo.i18n._searchLocalePath = function(/*String*/locale, /*Boolean*/down, /*Function*/searchFunc){ | |
215 | // summary: | |
216 | // A helper method to assist in searching for locale-based resources. | |
217 | // Will iterate through the variants of a particular locale, either up | |
218 | // or down, executing a callback function. For example, "en-us" and | |
219 | // true will try "en-us" followed by "en" and finally "ROOT". | |
220 | ||
221 | locale = dojo.i18n.normalizeLocale(locale); | |
222 | ||
223 | var elements = locale.split('-'); | |
224 | var searchlist = []; | |
225 | for(var i = elements.length; i > 0; i--){ | |
226 | searchlist.push(elements.slice(0, i).join('-')); | |
227 | } | |
228 | searchlist.push(false); | |
229 | if(down){searchlist.reverse();} | |
230 | ||
231 | for(var j = searchlist.length - 1; j >= 0; j--){ | |
232 | var loc = searchlist[j] || "ROOT"; | |
233 | var stop = searchFunc(loc); | |
234 | if(stop){ break; } | |
235 | } | |
2f01fe57 | 236 | }; |
a089699c AD |
237 | |
238 | dojo.i18n._preloadLocalizations = function(/*String*/bundlePrefix, /*Array*/localesGenerated){ | |
239 | // summary: | |
240 | // Load built, flattened resource bundles, if available for all | |
241 | // locales used in the page. Only called by built layer files. | |
242 | ||
243 | function preload(locale){ | |
244 | locale = dojo.i18n.normalizeLocale(locale); | |
245 | dojo.i18n._searchLocalePath(locale, true, function(loc){ | |
246 | for(var i=0; i<localesGenerated.length;i++){ | |
247 | if(localesGenerated[i] == loc){ | |
248 | dojo["require"](bundlePrefix+"_"+loc); | |
249 | return true; // Boolean | |
250 | } | |
251 | } | |
252 | return false; // Boolean | |
253 | }); | |
254 | } | |
255 | preload(); | |
256 | var extra = dojo.config.extraLocale||[]; | |
257 | for(var i=0; i<extra.length; i++){ | |
258 | preload(extra[i]); | |
259 | } | |
2f01fe57 | 260 | }; |
a089699c | 261 | |
2f01fe57 | 262 | } |