PageSourceSearch

https://app.belegebox.de/statics/core/js/l10n.js

js belegebox.de collected 2026-10-07 17:36:19 UTC 9,190 bytes, 348 lines download raw bytes

1/**
2 * Copyright (c) 2014 Vincent Petry <[email protected]>
3 *
4 * This file is licensed under the Affero General Public License version 3
5 * or later.
6 *
7 * See the COPYING-README file.
8 *
9 */
10
11/**
12 * L10N namespace with localization functions.
13 *
14 * @namespace
15 */
16OC.L10N = {
17	/**
18	 * String bundles with app name as key.
19	 * @type {Object.<String,String>}
20	 */
21	_bundles: {},
22
23	/**
24	 * Plural functions, key is app name and value is function.
25	 * @type {Object.<String,Function>}
26	 */
27	_pluralFunctions: {},
28
29	/**
30	 * Load an app's translation bundle if not loaded already.
31	 *
32	 * @param {String} appName name of the app
33	 * @param {Function} callback callback to be called when
34	 * the translations are loaded
35	 * @return {Promise} promise
36	 */
37	load: function(appName, callback) {
38		// already available ?
39		if (this._bundles[appName] || OC.getLocale() === 'en') {
40			var deferred = $.Deferred();
41			var promise = deferred.promise();
42			promise.then(callback);
43			deferred.resolve();
44			return promise;
45		}
46
47		var self = this;
48		var url = OC.filePath(appName, 'l10n', OC.getLocale() + '.json');
49
50		// load JSON translation bundle per AJAX
51		return $.get(url)
52			.then(
53				function(result) {
54					if (result.translations) {
55						self.register(appName, result.translations, result.pluralForm);
56					}
57				})
58			.then(callback);
59	},
60
61	/**
62	 * Register an app's translation bundle.
63	 *
64	 * @param {String} appName name of the app
65	 * @param {Object<String,String>} bundle
66	 * @param {Function|String} [pluralForm] optional plural function or plural string
67	 */
68	register: function(appName, bundle, pluralForm) {
69		var self = this;
70		if (_.isUndefined(this._bundles[appName])) {
71			this._bundles[appName] = bundle || {};
72
73			// generate plural function based on form
74			this._pluralFunctions[appName] = this._getPlural;
75		} else {
76			// Theme overwriting the default language
77			_.extend(self._bundles[appName], bundle);
78		}
79	},
80
81	/**
82	 * Translate a string
83	 * @param {string} app the id of the app for which to translate the string
84	 * @param {string} text the string to translate
85	 * @param [vars] map of placeholder key to value
86	 * @param {number} [count] number to replace %n with
87	 * @param {array} [options] options array
88	 * @param {bool} [options.escape=true] enable/disable auto escape of placeholders (by default enabled)
89	 * @return {string}
90	 */
91	translate: function(app, text, vars, count, options) {
92		var defaultOptions = {
93				escape: true
94			},
95			allOptions = options || {};
96		_.defaults(allOptions, defaultOptions);
97
98		// TODO: cache this function to avoid inline recreation
99		// of the same function over and over again in case
100		// translate() is used in a loop
101		var _build = function (text, vars, count) {
102			return text.replace(/%n/g, count).replace(/{([^{}]*)}/g,
103				function (a, b) {
104					var r = vars[b];
105					if(typeof r === 'string' || typeof r === 'number') {
106						if(allOptions.escape) {
107							return DOMPurify.sanitize(escapeHTML(r));
108						} else {
109							return DOMPurify.sanitize(r);
110						}
111					} else {
112						return DOMPurify.sanitize(a);
113					}
114				}
115			);
116		};
117		var translation = text;
118		var bundle = this._bundles[app] || {};
119		var value = bundle[text];
120		if( typeof(value) !== 'undefined' ){
121			translation = value;
122		}
123
124		if(typeof vars === 'object' || count !== undefined ) {
125			return DOMPurify.sanitize(_build(translation, vars, count));
126		} else {
127			return DOMPurify.sanitize(translation);
128		}
129	},
130
131	/**
132	 * Translate a plural string
133	 * @param {string} app the id of the app for which to translate the string
134	 * @param {string} textSingular the string to translate for exactly one object
135	 * @param {string} textPlural the string to translate for n objects
136	 * @param {number} count number to determine whether to use singular or plural
137	 * @param [vars] map of placeholder key to value
138	 * @param {array} [options] options array
139	 * @param {bool} [options.escape=true] enable/disable auto escape of placeholders (by default enabled)
140	 * @return {string} Translated string
141	 */
142	translatePlural: function(app, textSingular, textPlural, count, vars, options) {
143		var identifier = '_' + textSingular + '_::_' + textPlural + '_';
144		var bundle = this._bundles[app] || {};
145		var value = bundle[identifier];
146		if( typeof(value) !== 'undefined' ){
147			var translation = value;
148			if ($.isArray(translation)) {
149				var plural = this._pluralFunctions[app](count);
150				return this.translate(app, translation[plural], vars, count, options);
151			}
152		}
153
154		if(count === 1) {
155			return this.translate(app, textSingular, vars, count, options);
156		}
157		else{
158			return this.translate(app, textPlural, vars, count, options);
159		}
160	},
161
162	/**
163	 * The plural function taken from symfony
164	 *
165	 * @param {number} number
166	 * @returns {number}
167	 * @private
168	 */
169	_getPlural: function(number) {
170		var locale = OC.getLocale();
171		if ('pt_BR' === locale) {
172			// temporary set a locale for brazilian
173			locale = 'xbr';
174		}
175
176		if (typeof locale === 'undefined') {
177			return (1 == number) ? 0 : 1;
178		}
179
180		if (locale.length > 3) {
181			locale = locale.substring(0, locale.lastIndexOf('_'));
182		}
183
184		/*
185		 * The plural rules are derived from code of the Zend Framework (2010-09-25),
186		 * which is subject to the new BSD license (http://framework.zend.com/license/new-bsd).
187		 * Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
188		 */
189		switch (locale) {
190			case 'az':
191			case 'bo':
192			case 'dz':
193			case 'id':
194			case 'ja':
195			case 'jv':
196			case 'ka':
197			case 'km':
198			case 'kn':
199			case 'ko':
200			case 'ms':
201			case 'th':
202			case 'tr':
203			case 'vi':
204			case 'zh':
205				return 0;
206
207			case 'af':
208			case 'bn':
209			case 'bg':
210			case 'ca':
211			case 'da':
212			case 'de':
213			case 'el':
214			case 'en':
215			case 'eo':
216			case 'es':
217			case 'et':
218			case 'eu':
219			case 'fa':
220			case 'fi':
221			case 'fo':
222			case 'fur':
223			case 'fy':
224			case 'gl':
225			case 'gu':
226			case 'ha':
227			case 'he':
228			case 'hu':
229			case 'is':
230			case 'it':
231			case 'ku':
232			case 'lb':
233			case 'ml':
234			case 'mn':
235			case 'mr':
236			case 'nah':
237			case 'nb':
238			case 'ne':
239			case 'nl':
240			case 'nn':
241			case 'no':
242			case 'oc':
243			case 'om':
244			case 'or':
245			case 'pa':
246			case 'pap':
247			case 'ps':
248			case 'pt':
249			case 'so':
250			case 'sq':
251			case 'sv':
252			case 'sw':
253			case 'ta':
254			case 'te':
255			case 'tk':
256			case 'ur':
257			case 'zu':
258				return (1 == number) ? 0 : 1;
259
260			case 'am':
261			case 'bh':
262			case 'fil':
263			case 'fr':
264			case 'gun':
265			case 'hi':
266			case 'hy':
267			case 'ln':
268			case 'mg':
269			case 'nso':
270			case 'xbr':
271			case 'ti':
272			case 'wa':
273				return ((0 == number) || (1 == number)) ? 0 : 1;
274
275			case 'be':
276			case 'bs':
277			case 'hr':
278			case 'ru':
279			case 'sh':
280			case 'sr':
281			case 'uk':
282				return ((1 == number % 10) && (11 != number % 100)) ? 0 : (((number % 10 >= 2) && (number % 10 <= 4) && ((number % 100 < 10) || (number % 100 >= 20))) ? 1 : 2);
283
284			case 'cs':
285			case 'sk':
286				return (1 == number) ? 0 : (((number >= 2) && (number <= 4)) ? 1 : 2);
287
288			case 'ga':
289				return (1 == number) ? 0 : ((2 == number) ? 1 : 2);
290
291			case 'lt':
292				return ((1 == number % 10) && (11 != number % 100)) ? 0 : (((number % 10 >= 2) && ((number % 100 < 10) || (number % 100 >= 20))) ? 1 : 2);
293
294			case 'sl':
295				return (1 == number % 100) ? 0 : ((2 == number % 100) ? 1 : (((3 == number % 100) || (4 == number % 100)) ? 2 : 3));
296
297			case 'mk':
298				return (1 == number % 10) ? 0 : 1;
299
300			case 'mt':
301				return (1 == number) ? 0 : (((0 == number) || ((number % 100 > 1) && (number % 100 < 11))) ? 1 : (((number % 100 > 10) && (number % 100 < 20)) ? 2 : 3));
302
303			case 'lv':
304				return (0 == number) ? 0 : (((1 == number % 10) && (11 != number % 100)) ? 1 : 2);
305
306			case 'pl':
307				return (1 == number) ? 0 : (((number % 10 >= 2) && (number % 10 <= 4) && ((number % 100 < 12) || (number % 100 > 14))) ? 1 : 2);
308
309			case 'cy':
310				return (1 == number) ? 0 : ((2 == number) ? 1 : (((8 == number) || (11 == number)) ? 2 : 3));
311
312			case 'ro':
313				return (1 == number) ? 0 : (((0 == number) || ((number % 100 > 0) && (number % 100 < 20))) ? 1 : 2);
314
315			case 'ar':
316				return (0 == number) ? 0 : ((1 == number) ? 1 : ((2 == number) ? 2 : (((number % 100 >= 3) && (number % 100 <= 10)) ? 3 : (((number % 100 >= 11) && (number % 100 <= 99)) ? 4 : 5))));
317
318			default:
319				return 0;
320		}
321	}
322};
323
324/**
325 * translate a string
326 * @param {string} app the id of the app for which to translate the string
327 * @param {string} text the string to translate
328 * @param [vars] map of placeholder key to value
329 * @param {number} [count] number to replace %n with
330 * @return {string}
331 */
332window.t = _.bind(OC.L10N.translate, OC.L10N);
333
334/**
335 * translate a string
336 * @param {string} app the id of the app for which to translate the string
337 * @param {string} text_singular the string to translate for exactly one object
338 * @param {string} text_plural the string to translate for n objects
339 * @param {number} count number to determine whether to use singular or plural
340 * @param [vars] map of placeholder key to value
341 * @return {string} Translated string
342 */
343window.n = _.bind(OC.L10N.translatePlural, OC.L10N);
344
345Handlebars.registerHelper('t', function(app, text) {
346	return OC.L10N.translate(app, text);
347});
348

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.