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
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");
12 dojo.getObject("i18n", true, dojo);
16 // summary: Utility classes to enable loading of resources for internationalization (i18n)
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){
23 // Returns an Object containing the localization for a given resource
24 // bundle in a package, matching the specified locale.
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.
37 // package which is associated with this resource
39 // the base filename of the resource bundle (without the ".js" suffix)
41 // the variant to load (optional). By default, the locale defined by
42 // the host environment: dojo.locale
44 locale = dojo.i18n.normalizeLocale(locale);
46 // look for nearest locale match
47 var elements = locale.split('-');
48 var module = [packageName,"nls",bundleName].join('.');
49 var bundle = dojo._loadedModules[module];
52 for(var i = elements.length; i > 0; i--){
53 var loc = elements.slice(0, i).join('_');
55 localization = bundle[loc];
60 localization = bundle.ROOT;
63 // make a singleton prototype so that the caller won't accidentally change the values globally
65 var clazz = function(){};
66 clazz.prototype = localization;
67 return new clazz(); // Object
71 throw new Error("Bundle not found: " + bundleName + " in " + packageName+" , locale=" + locale);
74 dojo.i18n.normalizeLocale = function(/*String?*/locale){
76 // Returns canonical form of locale, as used by Dojo.
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.
83 var result = locale ? locale.toLowerCase() : dojo.locale;
87 return result; // String
90 dojo.i18n._requireLocalization = function(/*String*/moduleName, /*String*/bundleName, /*String?*/locale, /*String?*/availableFlatLocales){
92 // See dojo.requireLocalization()
94 // Called by the bootstrap, but factored out so that it is only
95 // included in the build when needed.
97 var targetLocale = dojo.i18n.normalizeLocale(locale);
98 var bundlePackage = [moduleName, "nls", bundleName].join(".");
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.
110 //Find the best-match locale to load if we have available flat locales.
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];
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;
134 if(dojo.config.localizationComplete && bundle._built){return;}
135 var jsLoc = tempLocale.replace(/-/g, '_');
136 var translationPackage = bundlePackage+"."+jsLoc;
137 localizedBundle = dojo._loadedModules[translationPackage];
140 if(!localizedBundle){
141 bundle = dojo["provide"](bundlePackage);
142 var syms = dojo._getModuleSymbols(moduleName);
143 var modpath = syms.concat("nls").join("/");
146 dojo.i18n._searchLocalePath(tempLocale, availableFlatLocales, function(loc){
147 var jsLoc = loc.replace(/-/g, '_');
148 var translationPackage = bundlePackage + "." + jsLoc;
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]; }
168 if(loaded && bundle[jsLoc]){
169 parent = bundle[jsLoc];
171 bundle[jsLoc] = parent;
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.
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, '_')];
190 // If other locales are used, dojo.requireLocalization should load them as
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.
197 var extra = dojo.config.extraLocale;
199 if(!extra instanceof Array){
203 var req = dojo.i18n._requireLocalization;
204 dojo.i18n._requireLocalization = function(m, b, locale, availableFlatLocales){
205 req(m,b,locale, availableFlatLocales);
207 for(var i=0; i<extra.length; i++){
208 req(m,b,extra[i], availableFlatLocales);
214 dojo.i18n._searchLocalePath = function(/*String*/locale, /*Boolean*/down, /*Function*/searchFunc){
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".
221 locale = dojo.i18n.normalizeLocale(locale);
223 var elements = locale.split('-');
225 for(var i = elements.length; i > 0; i--){
226 searchlist.push(elements.slice(0, i).join('-'));
228 searchlist.push(false);
229 if(down){searchlist.reverse();}
231 for(var j = searchlist.length - 1; j >= 0; j--){
232 var loc = searchlist[j] || "ROOT";
233 var stop = searchFunc(loc);
238 dojo.i18n._preloadLocalizations = function(/*String*/bundlePrefix, /*Array*/localesGenerated){
240 // Load built, flattened resource bundles, if available for all
241 // locales used in the page. Only called by built layer files.
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
252 return false; // Boolean
256 var extra = dojo.config.extraLocale||[];
257 for(var i=0; i<extra.length; i++){