xmpp.chapril.org-conversejs/src/i18n.js

171 lines
5.9 KiB
JavaScript

// Converse.js (A browser based XMPP chat client)
// http://conversejs.org
//
// This is the internationalization module.
//
// Copyright (c) 2012-2017, Jan-Carel Brand <jc@opkode.com>
// Licensed under the Mozilla Public License (MPLv2)
//
/*global define */
(function (root, factory) {
define([
"es6-promise",
"jed",
"lodash.noconflict",
"moment",
'moment/locale/af',
'moment/locale/ar',
'moment/locale/bg',
'moment/locale/ca',
'moment/locale/de',
'moment/locale/es',
'moment/locale/eu',
'moment/locale/fr',
'moment/locale/he',
'moment/locale/hu',
'moment/locale/id',
'moment/locale/it',
'moment/locale/ja',
'moment/locale/nb',
'moment/locale/nl',
'moment/locale/pl',
'moment/locale/pt-br',
'moment/locale/ru',
'moment/locale/tr',
'moment/locale/uk',
'moment/locale/zh-cn',
'moment/locale/zh-tw'
], factory);
}(this, function (Promise, Jed, _, moment) {
'use strict';
function detectLocale (library_check) {
/* Determine which locale is supported by the user's system as well
* as by the relevant library (e.g. converse.js or moment.js).
*
* Parameters:
* (Function) library_check - Returns a boolean indicating whether
* the locale is supported.
*/
var locale, i;
if (window.navigator.userLanguage) {
locale = isLocaleAvailable(window.navigator.userLanguage, library_check);
}
if (window.navigator.languages && !locale) {
for (i=0; i<window.navigator.languages.length && !locale; i++) {
locale = isLocaleAvailable(window.navigator.languages[i], library_check);
}
}
if (window.navigator.browserLanguage && !locale) {
locale = isLocaleAvailable(window.navigator.browserLanguage, library_check);
}
if (window.navigator.language && !locale) {
locale = isLocaleAvailable(window.navigator.language, library_check);
}
if (window.navigator.systemLanguage && !locale) {
locale = isLocaleAvailable(window.navigator.systemLanguage, library_check);
}
return locale || 'en';
}
function isMomentLocale (locale) {
return _.isString(locale) && moment.locale() === moment.locale(locale);
}
function isConverseLocale (locale, supported_locales) {
return _.isString(locale) && _.includes(supported_locales, locale);
}
function getLocale (preferred_locale, isSupportedByLibrary) {
if (_.isString(preferred_locale)) {
if (preferred_locale === 'en' || isSupportedByLibrary(preferred_locale)) {
return preferred_locale;
}
}
return detectLocale(isSupportedByLibrary) || 'en';
}
function isLocaleAvailable (locale, available) {
/* Check whether the locale or sub locale (e.g. en-US, en) is supported.
*
* Parameters:
* (String) locale - The locale to check for
* (Function) available - returns a boolean indicating whether the locale is supported
*/
if (available(locale)) {
return locale;
} else {
var sublocale = locale.split("-")[0];
if (sublocale !== locale && available(sublocale)) {
return sublocale;
}
}
}
let jed_instance;
return {
setLocales (preferred_locale, _converse) {
_converse.locale = getLocale(
preferred_locale,
_.partial(isConverseLocale, _, _converse.locales)
);
moment.locale(getLocale(preferred_locale, isMomentLocale));
},
translate (str) {
if (_.isNil(jed_instance)) {
return Jed.sprintf.apply(Jed, arguments);
}
var t = jed_instance.translate(str);
if (arguments.length>1) {
return t.fetch.apply(t, [].slice.call(arguments, 1));
} else {
return t.fetch();
}
},
fetchTranslations (locale, supported_locales, locale_url) {
/* Fetch the translations for the given local at the given URL.
*
* Parameters:
* (String) locale: The given i18n locale
* (Array) supported_locales: List of locales supported
* (String) locale_url: The URL from which the translations
* should be fetched.
*/
return new Promise((resolve, reject) => {
if (!isConverseLocale(locale, supported_locales) || locale === 'en') {
return resolve();
}
const xhr = new XMLHttpRequest();
xhr.open('GET', locale_url, true);
xhr.setRequestHeader(
'Accept',
"application/json, text/javascript"
);
xhr.onload = function () {
if (xhr.status >= 200 && xhr.status < 400) {
try {
const data = window.JSON.parse(xhr.responseText);
jed_instance = new Jed(data);
resolve();
} catch (e) {
xhr.onerror(e);
}
} else {
xhr.onerror();
}
};
xhr.onerror = (e) => {
const err_message = e ? ` Error: ${e.message}` : '';
reject(new Error(`Could not fetch translations. Status: ${xhr.statusText}. ${err_message}`));
}
xhr.send();
});
}
};
}));