From 05c3a5cad69c548cdedefb8fe1bc75fc625d078a Mon Sep 17 00:00:00 2001 From: JC Brand Date: Tue, 24 Oct 2017 12:56:35 +0200 Subject: [PATCH] Move translation machinery into a separate module --- 3rdparty/moment_locales.js | 1 + CHANGES.md | 1 + src/config.js | 1 + src/converse-core.js | 151 +++++-------------------------------- src/i18n.js | 142 ++++++++++++++++++++++++++++++++++ src/utils.js | 2 - 6 files changed, 165 insertions(+), 133 deletions(-) create mode 100644 src/i18n.js diff --git a/3rdparty/moment_locales.js b/3rdparty/moment_locales.js index c68e376c9..f393bd003 100644 --- a/3rdparty/moment_locales.js +++ b/3rdparty/moment_locales.js @@ -10,6 +10,7 @@ define("moment_with_locales", [ 'moment', // Everything below can be removed except for moment itself. 'moment/locale/af', + 'moment/locale/ca', 'moment/locale/de', 'moment/locale/es', 'moment/locale/fr', diff --git a/CHANGES.md b/CHANGES.md index eb409f8e8..c3969d04e 100755 --- a/CHANGES.md +++ b/CHANGES.md @@ -25,6 +25,7 @@ smaller filesize but means that the translations you want to provide need to be available. See the [locales_url](https://conversejs.org/docs/html/configurations.html#locales-url) configuration setting for more info. +- The translation machinery has now been moved to a separate module in `src/i18n.js`. ## 3.2.1 (2017-08-29) diff --git a/src/config.js b/src/config.js index c482bb719..131925002 100644 --- a/src/config.js +++ b/src/config.js @@ -26,6 +26,7 @@ require.config({ "es6-promise": "node_modules/es6-promise/dist/es6-promise.auto", "eventemitter": "node_modules/otr/build/dep/eventemitter", "form-utils": "src/form-utils", + "i18n": "src/i18n", "jed": "node_modules/jed/jed", "jquery": "node_modules/jquery/dist/jquery", "jquery.browser": "node_modules/jquery.browser/dist/jquery.browser", diff --git a/src/converse-core.js b/src/converse-core.js index 974b58e35..df3b0d812 100755 --- a/src/converse-core.js +++ b/src/converse-core.js @@ -10,7 +10,7 @@ "es6-promise", "lodash.noconflict", "polyfill", - "jed", + "i18n", "utils", "moment_with_locales", "strophe", @@ -19,7 +19,7 @@ "backbone.browserStorage", "backbone.overview", ], factory); -}(this, function (sizzle, Promise, _, polyfill, Jed, utils, moment, Strophe, pluggable, Backbone) { +}(this, function (sizzle, Promise, _, polyfill, i18n, utils, moment, Strophe, pluggable, Backbone) { /* Cannot use this due to Safari bug. * See https://github.com/jcbrand/converse.js/issues/196 @@ -137,11 +137,11 @@ * (String) message - The message to be logged. * (Integer) level - The loglevel which allows for filtering of log * messages. - * + * * Available loglevels are 0 for 'debug', 1 for 'info', 2 for 'warn', * 3 for 'error' and 4 for 'fatal'. * - * When using the 'error' or 'warn' loglevels, a full stacktrace will be + * When using the 'error' or 'warn' loglevels, a full stacktrace will be * logged as well. */ if (message instanceof Error) { @@ -176,133 +176,19 @@ } }; - // --------------------- - // Translation machinery - // --------------------- _converse.__ = function (str) { /* Translate the given string based on the current locale. * * Parameters: * (String) str - The string to translate. */ - if (_.isUndefined(Jed)) { + if (_.isUndefined(i18n)) { return str; } - if (_.isUndefined(_converse.jed)) { - return Jed.sprintf.apply(Jed, arguments); - } - var t = _converse.jed.translate(str); - if (arguments.length>1) { - return t.fetch.apply(t, [].slice.call(arguments, 1)); - } else { - return t.fetch(); - } + return i18n.translate.apply(i18n, arguments); } - 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 { - if (!isLocaleSupported(locale) || 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) { - resolve(new Jed(window.JSON.parse(xhr.responseText))); - } else { - xhr.onerror(); - } - }; - xhr.onerror = function () { - reject(xhr.statusText); - }; - xhr.send(); - }); - } - // -------------------------- - // END: Translation machinery - // -------------------------- - + const __ = _converse.__; const PROMISES = [ 'initialized', @@ -445,10 +331,12 @@ } } - /* Internationalization */ - moment.locale(getLocale(settings.i18n, isMomentLocale)); - _converse.locale = getLocale(settings.i18n, isLocaleSupported); - const __ = _converse.__; + /* Localisation */ + if (!_.isUndefined(i18n)) { + i18n.setLocales(settings.i18n, _converse); + } else { + _converse.locale = 'en'; + } // Module-level variables // ---------------------- @@ -2026,23 +1914,24 @@ } if (!_.isUndefined(_converse.connection) && - _converse.connection.service === 'jasmine tests') { - + _converse.connection.service === 'jasmine tests') { finishInitialization(); return _converse; + } else if (_.isUndefined(i18n)) { + finishInitialization(); } else { - fetchTranslations( + i18n.fetchTranslations( _converse.locale, + _converse.locales, _.template(_converse.locales_url)({'locale': _converse.locale}) - ).then((jed) => { - _converse.jed = jed; + ).then(() => { finishInitialization(); }).catch((reason) => { finishInitialization(); _converse.log(reason, Strophe.LogLevel.ERROR); }); - return init_promise.promise; } + return init_promise.promise; }; // API methods only available to plugins diff --git a/src/i18n.js b/src/i18n.js new file mode 100644 index 000000000..8982328e0 --- /dev/null +++ b/src/i18n.js @@ -0,0 +1,142 @@ +// Converse.js (A browser based XMPP chat client) +// http://conversejs.org +// +// This is the internationalization module. +// +// Copyright (c) 2012-2017, Jan-Carel Brand +// Licensed under the Mozilla Public License (MPLv2) +// +/*global define */ + +(function (root, factory) { + define([ + "es6-promise", + "jed", + "lodash.noconflict", + "moment_with_locales" + ], 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; i1) { + 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) { + jed_instance = new Jed(window.JSON.parse(xhr.responseText)); + resolve(); + } else { + xhr.onerror(); + } + }; + xhr.onerror = function () { + reject(xhr.statusText); + }; + xhr.send(); + }); + } + }; +})); diff --git a/src/utils.js b/src/utils.js index 261202c9a..e6f5b2a19 100755 --- a/src/utils.js +++ b/src/utils.js @@ -13,7 +13,6 @@ "es6-promise", "jquery.browser", "lodash.noconflict", - "moment_with_locales", "strophe", ], factory); }(this, function ( @@ -21,7 +20,6 @@ Promise, jQBrowser, _, - moment, Strophe ) { "use strict";