/
i18n.js
154 lines (126 loc) · 3.65 KB
/
i18n.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
/** MIT License (c) copyright 2010-2013 B Cavalier & J Hann */
/**
* curl i18n! cram plugin
*/
define(['../plugin/i18n', '../plugin/locale'], function (i18n, getLocale) {
var tos, stringifiers, beenThereFlag;
tos = Object.prototype.toString;
stringifiers = {
Array: arrayAsString,
Boolean: asString,
Date: dateAsString,
Function: asString,
Null: nullAsString,
Number: asString,
Object: objectAsString,
RegExp: asString,
String: stringAsString,
Undefined: undefinedAsString
};
beenThereFlag = '__cram_i18n_flag__';
function bundleToString (thing) {
return thingToString(thing);
}
bundleToString.compile = function (pluginId, resId, req, io, config) {
var i18nId, localeId, locales, output, count, toId;
i18nId = pluginId + '!' + resId;
localeId = 'curl/plugin/locale!' + resId;
locales = config.locales || [];
if (locales.indexOf('') < 0) locales.push(''); // add default bundle
output = [];
count = locales.length;
toId = config['localeToModuleId'] || getLocale.toModuleId;
// use the load method of the run-time plugin, capturing bundles.
locales.forEach(function (locale, i) {
loaded.error = stop;
i18n.load(toId(resId, locale), req, loaded, config);
function loaded (bundle) {
// each bundle captured is output as a locale!id module, e.g.:
// define("locale!foo/en-us", function () {
// return {/*...*/};
// });
output[i] = amdDefine(
toId(localeId, locale), '', '', bundleToString(bundle)
);
if (--count == 0) done();
}
});
if (!locales.length) done();
function stop (ex) {
count = 0; // prevents done() from executing
io.error(ex);
}
function done () {
// add the default i18n bundle module which uses the locale!
// plugin to require() or fetch the correct bundle. e.g.
// define("i18n!foo/en", ["locale!foo/en"], function (bundle) {
// return bundle;
// });
output.push(amdDefine(i18nId, [localeId], ['bundle'], 'bundle'));
io.write(output.join(''));
}
};
return bundleToString;
function thingToString (thing) {
var t, stringifier;
t = type(thing);
stringifier = stringifiers[t];
if (!stringifier) throw new Error('Can\'t encode i18n item of type ' + t);
return stringifier(thing);
}
function asString (thing) {
return thing.toString();
}
function nullAsString () {
return 'null';
}
function stringAsString (s) {
return '"' + s + '"';
}
function undefinedAsString () {
return 'undefined';
}
function dateAsString (date) {
return 'new Date("' + date + '")';
}
function arrayAsString (arr) {
var i, len, items, item;
arr[beenThereFlag] = true;
items = [];
for (i = 0, len = arr.length; i < len; i++) {
item = arr[i];
if (typeof item == 'object' && beenThereFlag in item) {
throw new Error('Recursive object graphs not supported in i18n bundles.');
}
items.push(thingToString(item));
}
delete arr[beenThereFlag];
return '[' + items.join(',') + ']';
}
function objectAsString (obj) {
var p, items, item;
obj[beenThereFlag] = true;
items = [];
for (p in obj) {
if (p != beenThereFlag) {
item = obj[p];
if (typeof item == 'object' && beenThereFlag in item) {
throw new Error('Recursive object graphs not supported in i18n bundles.');
}
items.push('"' + p + '":' + thingToString(item));
}
}
delete obj[beenThereFlag];
return '{' + items.join(',') + '}';
}
function type (thing) {
return tos.call(thing).slice(8, -1);
}
function amdDefine (id, deps, args, exports) {
return 'define("' + id + '", '
+ (deps && deps.length ? arrayAsString(deps) + ', ' : '')
+ 'function (' + (args && args.join(',')) + ') {\nreturn '
+ exports
+ ';\n});\n';
}
});