source: Dev/trunk/src/client/dojo/i18n.js @ 531

Last change on this file since 531 was 483, checked in by hendrikvanantwerpen, 11 years ago

Added Dojo 1.9.3 release.

File size: 25.1 KB
Line 
1define(["./_base/kernel", "require", "./has", "./_base/array", "./_base/config", "./_base/lang", "./has!host-browser?./_base/xhr", "./json", "module"],
2        function(dojo, require, has, array, config, lang, xhr, json, module){
3
4        // module:
5        //              dojo/i18n
6
7        has.add("dojo-preload-i18n-Api",
8                // if true, define the preload localizations machinery
9                1
10        );
11
12        has.add("dojo-v1x-i18n-Api",
13                // if true, define the v1.x i18n functions
14                1
15        );
16
17        var
18                thisModule = dojo.i18n =
19                        {
20                                // summary:
21                                //              This module implements the dojo/i18n! plugin and the v1.6- i18n API
22                                // description:
23                                //              We choose to include our own plugin to leverage functionality already contained in dojo
24                                //              and thereby reduce the size of the plugin compared to various loader implementations. Also, this
25                                //              allows foreign AMD loaders to be used without their plugins.
26                        },
27
28                nlsRe =
29                        // regexp for reconstructing the master bundle name from parts of the regexp match
30                        // nlsRe.exec("foo/bar/baz/nls/en-ca/foo") gives:
31                        // ["foo/bar/baz/nls/en-ca/foo", "foo/bar/baz/nls/", "/", "/", "en-ca", "foo"]
32                        // nlsRe.exec("foo/bar/baz/nls/foo") gives:
33                        // ["foo/bar/baz/nls/foo", "foo/bar/baz/nls/", "/", "/", "foo", ""]
34                        // so, if match[5] is blank, it means this is the top bundle definition.
35                        // courtesy of http://requirejs.org
36                        /(^.*(^|\/)nls)(\/|$)([^\/]*)\/?([^\/]*)/,
37
38                getAvailableLocales = function(
39                        root,
40                        locale,
41                        bundlePath,
42                        bundleName
43                ){
44                        // summary:
45                        //              return a vector of module ids containing all available locales with respect to the target locale
46                        //              For example, assuming:
47                        //
48                        //              - the root bundle indicates specific bundles for "fr" and "fr-ca",
49                        //              -  bundlePath is "myPackage/nls"
50                        //              - bundleName is "myBundle"
51                        //
52                        //              Then a locale argument of "fr-ca" would return
53                        //
54                        //                      ["myPackage/nls/myBundle", "myPackage/nls/fr/myBundle", "myPackage/nls/fr-ca/myBundle"]
55                        //
56                        //              Notice that bundles are returned least-specific to most-specific, starting with the root.
57                        //
58                        //              If root===false indicates we're working with a pre-AMD i18n bundle that doesn't tell about the available locales;
59                        //              therefore, assume everything is available and get 404 errors that indicate a particular localization is not available
60
61                        for(var result = [bundlePath + bundleName], localeParts = locale.split("-"), current = "", i = 0; i<localeParts.length; i++){
62                                current += (current ? "-" : "") + localeParts[i];
63                                if(!root || root[current]){
64                                        result.push(bundlePath + current + "/" + bundleName);
65                                        result.specificity = current;
66                                }
67                        }
68                        return result;
69                },
70
71                cache = {},
72
73                getBundleName = function(moduleName, bundleName, locale){
74                        locale = locale ? locale.toLowerCase() : dojo.locale;
75                        moduleName = moduleName.replace(/\./g, "/");
76                        bundleName = bundleName.replace(/\./g, "/");
77                        return (/root/i.test(locale)) ?
78                                (moduleName + "/nls/" + bundleName) :
79                                (moduleName + "/nls/" + locale + "/" + bundleName);
80                },
81
82                getL10nName = dojo.getL10nName = function(moduleName, bundleName, locale){
83                        return moduleName = module.id + "!" + getBundleName(moduleName, bundleName, locale);
84                },
85
86                doLoad = function(require, bundlePathAndName, bundlePath, bundleName, locale, load){
87                        // summary:
88                        //              get the root bundle which instructs which other bundles are required to construct the localized bundle
89                        require([bundlePathAndName], function(root){
90                                var current = lang.clone(root.root || root.ROOT),// 1.6 built bundle defined ROOT
91                                        availableLocales = getAvailableLocales(!root._v1x && root, locale, bundlePath, bundleName);
92                                require(availableLocales, function(){
93                                        for (var i = 1; i<availableLocales.length; i++){
94                                                current = lang.mixin(lang.clone(current), arguments[i]);
95                                        }
96                                        // target may not have been resolve (e.g., maybe only "fr" exists when "fr-ca" was requested)
97                                        var target = bundlePathAndName + "/" + locale;
98                                        cache[target] = current;
99                                        current.$locale = availableLocales.specificity;
100                                        load();
101                                });
102                        });
103                },
104
105                normalize = function(id, toAbsMid){
106                        // summary:
107                        //              id may be relative.
108                        //              preload has form `*preload*<path>/nls/<module>*<flattened locales>` and
109                        //              therefore never looks like a relative
110                        return /^\./.test(id) ? toAbsMid(id) : id;
111                },
112
113                getLocalesToLoad = function(targetLocale){
114                        var list = config.extraLocale || [];
115                        list = lang.isArray(list) ? list : [list];
116                        list.push(targetLocale);
117                        return list;
118                },
119
120                load = function(id, require, load){
121                        // summary:
122                        //              id is in one of the following formats
123                        //
124                        //              1. <path>/nls/<bundle>
125                        //                      => load the bundle, localized to config.locale; load all bundles localized to
126                        //                      config.extraLocale (if any); return the loaded bundle localized to config.locale.
127                        //
128                        //              2. <path>/nls/<locale>/<bundle>
129                        //                      => load then return the bundle localized to <locale>
130                        //
131                        //              3. *preload*<path>/nls/<module>*<JSON array of available locales>
132                        //                      => for config.locale and all config.extraLocale, load all bundles found
133                        //                      in the best-matching bundle rollup. A value of 1 is returned, which
134                        //                      is meaningless other than to say the plugin is executing the requested
135                        //                      preloads
136                        //
137                        //              In cases 1 and 2, <path> is always normalized to an absolute module id upon entry; see
138                        //              normalize. In case 3, it <path> is assumed to be absolute; this is arranged by the builder.
139                        //
140                        //              To load a bundle means to insert the bundle into the plugin's cache and publish the bundle
141                        //              value to the loader. Given <path>, <bundle>, and a particular <locale>, the cache key
142                        //
143                        //                      <path>/nls/<bundle>/<locale>
144                        //
145                        //              will hold the value. Similarly, then plugin will publish this value to the loader by
146                        //
147                        //                      define("<path>/nls/<bundle>/<locale>", <bundle-value>);
148                        //
149                        //              Given this algorithm, other machinery can provide fast load paths be preplacing
150                        //              values in the plugin's cache, which is public. When a load is demanded the
151                        //              cache is inspected before starting any loading. Explicitly placing values in the plugin
152                        //              cache is an advanced/experimental feature that should not be needed; use at your own risk.
153                        //
154                        //              For the normal AMD algorithm, the root bundle is loaded first, which instructs the
155                        //              plugin what additional localized bundles are required for a particular locale. These
156                        //              additional locales are loaded and a mix of the root and each progressively-specific
157                        //              locale is returned. For example:
158                        //
159                        //              1. The client demands "dojo/i18n!some/path/nls/someBundle
160                        //
161                        //              2. The loader demands load(some/path/nls/someBundle)
162                        //
163                        //              3. This plugin require's "some/path/nls/someBundle", which is the root bundle.
164                        //
165                        //              4. Assuming config.locale is "ab-cd-ef" and the root bundle indicates that localizations
166                        //              are available for "ab" and "ab-cd-ef" (note the missing "ab-cd", then the plugin
167                        //              requires "some/path/nls/ab/someBundle" and "some/path/nls/ab-cd-ef/someBundle"
168                        //
169                        //              5. Upon receiving all required bundles, the plugin constructs the value of the bundle
170                        //              ab-cd-ef as...
171                        //
172                        //                              mixin(mixin(mixin({}, require("some/path/nls/someBundle"),
173                        //                                      require("some/path/nls/ab/someBundle")),
174                        //                                      require("some/path/nls/ab-cd-ef/someBundle"));
175                        //
176                        //              This value is inserted into the cache and published to the loader at the
177                        //              key/module-id some/path/nls/someBundle/ab-cd-ef.
178                        //
179                        //              The special preload signature (case 3) instructs the plugin to stop servicing all normal requests
180                        //              (further preload requests will be serviced) until all ongoing preloading has completed.
181                        //
182                        //              The preload signature instructs the plugin that a special rollup module is available that contains
183                        //              one or more flattened, localized bundles. The JSON array of available locales indicates which locales
184                        //              are available. Here is an example:
185                        //
186                        //                      *preload*some/path/nls/someModule*["root", "ab", "ab-cd-ef"]
187                        //
188                        //              This indicates the following rollup modules are available:
189                        //
190                        //                      some/path/nls/someModule_ROOT
191                        //                      some/path/nls/someModule_ab
192                        //                      some/path/nls/someModule_ab-cd-ef
193                        //
194                        //              Each of these modules is a normal AMD module that contains one or more flattened bundles in a hash.
195                        //              For example, assume someModule contained the bundles some/bundle/path/someBundle and
196                        //              some/bundle/path/someOtherBundle, then some/path/nls/someModule_ab would be expressed as follows:
197                        //
198                        //                      define({
199                        //                              some/bundle/path/someBundle:<value of someBundle, flattened with respect to locale ab>,
200                        //                              some/bundle/path/someOtherBundle:<value of someOtherBundle, flattened with respect to locale ab>,
201                        //                      });
202                        //
203                        //              E.g., given this design, preloading for locale=="ab" can execute the following algorithm:
204                        //
205                        //                      require(["some/path/nls/someModule_ab"], function(rollup){
206                        //                              for(var p in rollup){
207                        //                                      var id = p + "/ab",
208                        //                                      cache[id] = rollup[p];
209                        //                                      define(id, rollup[p]);
210                        //                              }
211                        //                      });
212                        //
213                        //              Similarly, if "ab-cd" is requested, the algorithm can determine that "ab" is the best available and
214                        //              load accordingly.
215                        //
216                        //              The builder will write such rollups for every layer if a non-empty localeList  profile property is
217                        //              provided. Further, the builder will include the following cache entry in the cache associated with
218                        //              any layer.
219                        //
220                        //                      "*now":function(r){r(['dojo/i18n!*preload*<path>/nls/<module>*<JSON array of available locales>']);}
221                        //
222                        //              The *now special cache module instructs the loader to apply the provided function to context-require
223                        //              with respect to the particular layer being defined. This causes the plugin to hold all normal service
224                        //              requests until all preloading is complete.
225                        //
226                        //              Notice that this algorithm is rarely better than the standard AMD load algorithm. Consider the normal case
227                        //              where the target locale has a single segment and a layer depends on a single bundle:
228                        //
229                        //              Without Preloads:
230                        //
231                        //              1. Layer loads root bundle.
232                        //              2. bundle is demanded; plugin loads single localized bundle.
233                        //
234                        //              With Preloads:
235                        //
236                        //              1. Layer causes preloading of target bundle.
237                        //              2. bundle is demanded; service is delayed until preloading complete; bundle is returned.
238                        //
239                        //              In each case a single transaction is required to load the target bundle. In cases where multiple bundles
240                        //              are required and/or the locale has multiple segments, preloads still requires a single transaction whereas
241                        //              the normal path requires an additional transaction for each additional bundle/locale-segment. However all
242                        //              of these additional transactions can be done concurrently. Owing to this analysis, the entire preloading
243                        //              algorithm can be discard during a build by setting the has feature dojo-preload-i18n-Api to false.
244
245                        if(has("dojo-preload-i18n-Api")){
246                                var split = id.split("*"),
247                                        preloadDemand = split[1] == "preload";
248                                if(preloadDemand){
249                                        if(!cache[id]){
250                                                // use cache[id] to prevent multiple preloads of the same preload; this shouldn't happen, but
251                                                // who knows what over-aggressive human optimizers may attempt
252                                                cache[id] = 1;
253                                                preloadL10n(split[2], json.parse(split[3]), 1, require);
254                                        }
255                                        // don't stall the loader!
256                                        load(1);
257                                }
258                                if(preloadDemand || waitForPreloads(id, require, load)){
259                                        return;
260                                }
261                        }
262
263                        var match = nlsRe.exec(id),
264                                bundlePath = match[1] + "/",
265                                bundleName = match[5] || match[4],
266                                bundlePathAndName = bundlePath + bundleName,
267                                localeSpecified = (match[5] && match[4]),
268                                targetLocale =  localeSpecified || dojo.locale || "",
269                                loadTarget = bundlePathAndName + "/" + targetLocale,
270                                loadList = localeSpecified ? [targetLocale] : getLocalesToLoad(targetLocale),
271                                remaining = loadList.length,
272                                finish = function(){
273                                        if(!--remaining){
274                                                load(lang.delegate(cache[loadTarget]));
275                                        }
276                                };
277                        array.forEach(loadList, function(locale){
278                                var target = bundlePathAndName + "/" + locale;
279                                if(has("dojo-preload-i18n-Api")){
280                                        checkForLegacyModules(target);
281                                }
282                                if(!cache[target]){
283                                        doLoad(require, bundlePathAndName, bundlePath, bundleName, locale, finish);
284                                }else{
285                                        finish();
286                                }
287                        });
288                };
289
290        if(has("dojo-unit-tests")){
291                var unitTests = thisModule.unitTests = [];
292        }
293
294        if(has("dojo-preload-i18n-Api") || has("dojo-v1x-i18n-Api")){
295                var normalizeLocale = thisModule.normalizeLocale = function(locale){
296                                var result = locale ? locale.toLowerCase() : dojo.locale;
297                                return result == "root" ? "ROOT" : result;
298                        },
299
300                        isXd = function(mid, contextRequire){
301                                return (has("dojo-sync-loader") && has("dojo-v1x-i18n-Api")) ?
302                                        contextRequire.isXdUrl(require.toUrl(mid + ".js")) :
303                                        true;
304                        },
305
306                        preloading = 0,
307
308                        preloadWaitQueue = [],
309
310                        preloadL10n = thisModule._preloadLocalizations = function(/*String*/bundlePrefix, /*Array*/localesGenerated, /*boolean?*/ guaranteedAmdFormat, /*function?*/ contextRequire){
311                                // summary:
312                                //              Load available flattened resource bundles associated with a particular module for dojo/locale and all dojo/config.extraLocale (if any)
313                                // description:
314                                //              Only called by built layer files. The entire locale hierarchy is loaded. For example,
315                                //              if locale=="ab-cd", then ROOT, "ab", and "ab-cd" are loaded. This is different than v1.6-
316                                //              in that the v1.6- would only load ab-cd...which was *always* flattened.
317                                //
318                                //              If guaranteedAmdFormat is true, then the module can be loaded with require thereby circumventing the detection algorithm
319                                //              and the extra possible extra transaction.
320
321                                // If this function is called from legacy code, then guaranteedAmdFormat and contextRequire will be undefined. Since the function
322                                // needs a require in order to resolve module ids, fall back to the context-require associated with this dojo/i18n module, which
323                                // itself may have been mapped.
324                                contextRequire = contextRequire || require;
325
326                                function doRequire(mid, callback){
327                                        if(isXd(mid, contextRequire) || guaranteedAmdFormat){
328                                                contextRequire([mid], callback);
329                                        }else{
330                                                syncRequire([mid], callback, contextRequire);
331                                        }
332                                }
333
334                                function forEachLocale(locale, func){
335                                        // given locale= "ab-cd-ef", calls func on "ab-cd-ef", "ab-cd", "ab", "ROOT"; stops calling the first time func returns truthy
336                                        var parts = locale.split("-");
337                                        while(parts.length){
338                                                if(func(parts.join("-"))){
339                                                        return;
340                                                }
341                                                parts.pop();
342                                        }
343                                        func("ROOT");
344                                }
345
346                                        function preloadingAddLock(){
347                                                preloading++;
348                                        }
349
350                                        function preloadingRelLock(){
351                                                --preloading;
352                                                while(!preloading && preloadWaitQueue.length){
353                                                        load.apply(null, preloadWaitQueue.shift());
354                                                }
355                                        }
356
357                                        function cacheId(path, name, loc, require){
358                                                // path is assumed to have a trailing "/"
359                                                return require.toAbsMid(path + name + "/" + loc)
360                                        }
361
362                                        function preload(locale){
363                                                locale = normalizeLocale(locale);
364                                                forEachLocale(locale, function(loc){
365                                                        if(array.indexOf(localesGenerated, loc) >= 0){
366                                                                var mid = bundlePrefix.replace(/\./g, "/") + "_" + loc;
367                                                                preloadingAddLock();
368                                                                doRequire(mid, function(rollup){
369                                                                        for(var p in rollup){
370                                                                                var bundle = rollup[p],
371                                                                                        match = p.match(/(.+)\/([^\/]+)$/),
372                                                                                        bundleName, bundlePath;
373                                                                                       
374                                                                                        // If there is no match, the bundle is not a regular bundle from an AMD layer.
375                                                                                        if (!match){continue;}
376
377                                                                                        bundleName = match[2];
378                                                                                        bundlePath = match[1] + "/";
379
380                                                                                // backcompat
381                                                                                bundle._localized = bundle._localized || {};
382
383                                                                                var localized;
384                                                                                if(loc === "ROOT"){
385                                                                                        var root = localized = bundle._localized;
386                                                                                        delete bundle._localized;
387                                                                                        root.root = bundle;
388                                                                                        cache[require.toAbsMid(p)] = root;
389                                                                                }else{
390                                                                                        localized = bundle._localized;
391                                                                                        cache[cacheId(bundlePath, bundleName, loc, require)] = bundle;
392                                                                                }
393
394                                                                                if(loc !== locale){
395                                                                                        // capture some locale variables
396                                                                                        function improveBundle(bundlePath, bundleName, bundle, localized){
397                                                                                                // locale was not flattened and we've fallen back to a less-specific locale that was flattened
398                                                                                                // for example, we had a flattened 'fr', a 'fr-ca' is available for at least this bundle, and
399                                                                                                // locale==='fr-ca'; therefore, we must improve the bundle as retrieved from the rollup by
400                                                                                                // manually loading the fr-ca version of the bundle and mixing this into the already-retrieved 'fr'
401                                                                                                // version of the bundle.
402                                                                                                //
403                                                                                                // Remember, different bundles may have different sets of locales available.
404                                                                                                //
405                                                                                                // we are really falling back on the regular algorithm here, but--hopefully--starting with most
406                                                                                                // of the required bundles already on board as given by the rollup and we need to "manually" load
407                                                                                                // only one locale from a few bundles...or even better...we won't find anything better to load.
408                                                                                                // This algorithm ensures there is nothing better to load even when we can only load a less-specific rollup.
409                                                                                                //
410                                                                                                // note: this feature is only available in async mode
411
412                                                                                                // inspect the loaded bundle that came from the rollup to see if something better is available
413                                                                                                // for any bundle in a rollup, more-specific available locales are given at localized.
414                                                                                                var requiredBundles = [],
415                                                                                                        cacheIds = [];
416                                                                                                forEachLocale(locale, function(loc){
417                                                                                                        if(localized[loc]){
418                                                                                                                requiredBundles.push(require.toAbsMid(bundlePath + loc + "/" + bundleName));
419                                                                                                                cacheIds.push(cacheId(bundlePath, bundleName, loc, require));
420                                                                                                        }
421                                                                                                });
422
423                                                                                                if(requiredBundles.length){
424                                                                                                        preloadingAddLock();
425                                                                                                        contextRequire(requiredBundles, function(){
426                                                                                                                for(var i = 0; i < requiredBundles.length; i++){
427                                                                                                                        bundle = lang.mixin(lang.clone(bundle), arguments[i]);
428                                                                                                                        cache[cacheIds[i]] = bundle;
429                                                                                                                }
430                                                                                                                // this is the best possible (maybe a perfect match, maybe not), accept it
431                                                                                                                cache[cacheId(bundlePath, bundleName, locale, require)] = lang.clone(bundle);
432                                                                                                                preloadingRelLock();
433                                                                                                        });
434                                                                                                }else{
435                                                                                                        // this is the best possible (definitely not a perfect match), accept it
436                                                                                                        cache[cacheId(bundlePath, bundleName, locale, require)] = bundle;
437                                                                                                }
438                                                                                        }
439                                                                                        improveBundle(bundlePath, bundleName, bundle, localized);
440                                                                                }
441                                                                        }
442                                                                        preloadingRelLock();
443                                                                });
444                                                                return true;
445                                                        }
446                                                        return false;
447                                                });
448                                        }
449
450                                preload();
451                                array.forEach(dojo.config.extraLocale, preload);
452                        },
453
454                        waitForPreloads = function(id, require, load){
455                                if(preloading){
456                                        preloadWaitQueue.push([id, require, load]);
457                                }
458                                return preloading;
459                        },
460
461                        checkForLegacyModules = function()
462                                {};
463        }
464
465        if(has("dojo-v1x-i18n-Api")){
466                // this code path assumes the dojo loader and won't work with a standard AMD loader
467                var amdValue = {},
468                        evalBundle =
469                                // use the function ctor to keep the minifiers away (also come close to global scope, but this is secondary)
470                                new Function(
471                                        "__bundle",                                // the bundle to evalutate
472                                        "__checkForLegacyModules", // a function that checks if __bundle defined __mid in the global space
473                                        "__mid",                                   // the mid that __bundle is intended to define
474                                        "__amdValue",
475
476                                        // returns one of:
477                                        //              1 => the bundle was an AMD bundle
478                                        //              a legacy bundle object that is the value of __mid
479                                        //              instance of Error => could not figure out how to evaluate bundle
480
481                                          // used to detect when __bundle calls define
482                                          "var define = function(mid, factory){define.called = 1; __amdValue.result = factory || mid;},"
483                                        + "        require = function(){define.called = 1;};"
484
485                                        + "try{"
486                                        +               "define.called = 0;"
487                                        +               "eval(__bundle);"
488                                        +               "if(define.called==1)"
489                                                                // bundle called define; therefore signal it's an AMD bundle
490                                        +                       "return __amdValue;"
491
492                                        +               "if((__checkForLegacyModules = __checkForLegacyModules(__mid)))"
493                                                                // bundle was probably a v1.6- built NLS flattened NLS bundle that defined __mid in the global space
494                                        +                       "return __checkForLegacyModules;"
495
496                                        + "}catch(e){}"
497                                        // evaulating the bundle was *neither* an AMD *nor* a legacy flattened bundle
498                                        // either way, re-eval *after* surrounding with parentheses
499
500                                        + "try{"
501                                        +               "return eval('('+__bundle+')');"
502                                        + "}catch(e){"
503                                        +               "return e;"
504                                        + "}"
505                                ),
506
507                        syncRequire = function(deps, callback, require){
508                                var results = [];
509                                array.forEach(deps, function(mid){
510                                        var url = require.toUrl(mid + ".js");
511
512                                        function load(text){
513                                                var result = evalBundle(text, checkForLegacyModules, mid, amdValue);
514                                                if(result===amdValue){
515                                                        // the bundle was an AMD module; re-inject it through the normal AMD path
516                                                        // we gotta do this since it could be an anonymous module and simply evaluating
517                                                        // the text here won't provide the loader with the context to know what
518                                                        // module is being defined()'d. With browser caching, this should be free; further
519                                                        // this entire code path can be circumvented by using the AMD format to begin with
520                                                        results.push(cache[url] = amdValue.result);
521                                                }else{
522                                                        if(result instanceof Error){
523                                                                console.error("failed to evaluate i18n bundle; url=" + url, result);
524                                                                result = {};
525                                                        }
526                                                        // nls/<locale>/<bundle-name> indicates not the root.
527                                                        results.push(cache[url] = (/nls\/[^\/]+\/[^\/]+$/.test(url) ? result : {root:result, _v1x:1}));
528                                                }
529                                        }
530
531                                        if(cache[url]){
532                                                results.push(cache[url]);
533                                        }else{
534                                                var bundle = require.syncLoadNls(mid);
535                                                // don't need to check for legacy since syncLoadNls returns a module if the module
536                                                // (1) was already loaded, or (2) was in the cache. In case 1, if syncRequire is called
537                                                // from getLocalization --> load, then load will have called checkForLegacyModules() before
538                                                // calling syncRequire; if syncRequire is called from preloadLocalizations, then we
539                                                // don't care about checkForLegacyModules() because that will be done when a particular
540                                                // bundle is actually demanded. In case 2, checkForLegacyModules() is never relevant
541                                                // because cached modules are always v1.7+ built modules.
542                                                if(bundle){
543                                                        results.push(bundle);
544                                                }else{
545                                                        if(!xhr){
546                                                                try{
547                                                                        require.getText(url, true, load);
548                                                                }catch(e){
549                                                                        results.push(cache[url] = {});
550                                                                }
551                                                        }else{
552                                                                xhr.get({
553                                                                        url:url,
554                                                                        sync:true,
555                                                                        load:load,
556                                                                        error:function(){
557                                                                                results.push(cache[url] = {});
558                                                                        }
559                                                                });
560                                                        }
561                                                }
562                                        }
563                                });
564                                callback && callback.apply(null, results);
565                        };
566
567                checkForLegacyModules = function(target){
568                        // legacy code may have already loaded [e.g] the raw bundle x/y/z at x.y.z; when true, push into the cache
569                        for(var result, names = target.split("/"), object = dojo.global[names[0]], i = 1; object && i<names.length-1; object = object[names[i++]]){}
570                        if(object){
571                                result = object[names[i]];
572                                if(!result){
573                                        // fallback for incorrect bundle build of 1.6
574                                        result = object[names[i].replace(/-/g,"_")];
575                                }
576                                if(result){
577                                        cache[target] = result;
578                                }
579                        }
580                        return result;
581                };
582
583                thisModule.getLocalization = function(moduleName, bundleName, locale){
584                        var result,
585                                l10nName = getBundleName(moduleName, bundleName, locale);
586                        load(
587                                l10nName,
588
589                                // isXd() and syncRequire() need a context-require in order to resolve the mid with respect to a reference module.
590                                // Since this legacy function does not have the concept of a reference module, resolve with respect to this
591                                // dojo/i18n module, which, itself may have been mapped.
592                                (!isXd(l10nName, require) ? function(deps, callback){ syncRequire(deps, callback, require); } : require),
593
594                                function(result_){ result = result_; }
595                        );
596                        return result;
597                };
598
599                if(has("dojo-unit-tests")){
600                        unitTests.push(function(doh){
601                                doh.register("tests.i18n.unit", function(t){
602                                        var check;
603
604                                        check = evalBundle("{prop:1}", checkForLegacyModules, "nonsense", amdValue);
605                                        t.is({prop:1}, check); t.is(undefined, check[1]);
606
607                                        check = evalBundle("({prop:1})", checkForLegacyModules, "nonsense", amdValue);
608                                        t.is({prop:1}, check); t.is(undefined, check[1]);
609
610                                        check = evalBundle("{'prop-x':1}", checkForLegacyModules, "nonsense", amdValue);
611                                        t.is({'prop-x':1}, check); t.is(undefined, check[1]);
612
613                                        check = evalBundle("({'prop-x':1})", checkForLegacyModules, "nonsense", amdValue);
614                                        t.is({'prop-x':1}, check); t.is(undefined, check[1]);
615
616                                        check = evalBundle("define({'prop-x':1})", checkForLegacyModules, "nonsense", amdValue);
617                                        t.is(amdValue, check); t.is({'prop-x':1}, amdValue.result);
618
619                                        check = evalBundle("define('some/module', {'prop-x':1})", checkForLegacyModules, "nonsense", amdValue);
620                                        t.is(amdValue, check); t.is({'prop-x':1}, amdValue.result);
621
622                                        check = evalBundle("this is total nonsense and should throw an error", checkForLegacyModules, "nonsense", amdValue);
623                                        t.is(check instanceof Error, true);
624                                });
625                        });
626                }
627        }
628
629        return lang.mixin(thisModule, {
630                dynamic:true,
631                normalize:normalize,
632                load:load,
633                cache:cache,
634                getL10nName: getL10nName
635        });
636});
Note: See TracBrowser for help on using the repository browser.