]> git.wh0rd.org Git - tt-rss.git/blob - lib/dojo/i18n.js
upgrade Dojo to 1.6.1
[tt-rss.git] / lib / dojo / i18n.js
1 /*
2         Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
3         Available via Academic Free License >= 2.1 OR the modified BSD license.
4         see: http://dojotoolkit.org/license for details
5 */
6
7
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;
10 dojo.provide("dojo.i18n");
11
12 dojo.getObject("i18n", true, dojo);
13
14 /*=====
15 dojo.i18n = {
16         // summary: Utility classes to enable loading of resources for internationalization (i18n)
17 };
18 =====*/
19
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){
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('.');
49                 var bundle = dojo._loadedModules[module];
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);
72 };
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
88 };
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(".");
99         // NOTE:
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.
109
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";
126                 }
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){
158                                         hash = hash.root || hash;
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                         }
173
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         }
187 };
188
189 (function(){
190         // If other locales are used, dojo.requireLocalization should load them as
191         // well, by default.
192         //
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         }
212 })();
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         }
236 };
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         }
260 };
261
262 }