const yaml = require('js-yaml'); const locales = {}; let fallbackLang = 'en'; let lang = null; /** * Class to manage the internationalization. */ module.exports = { init() { if (lang) return; this.loads = {}; this.locales = locales; this.fallbackLang = fallbackLang; const languages = navigator.languages; if (languages && languages.length > 0) lang = languages[0]; else if (navigator.language) lang = navigator.language; lang = lang ? lang.substr(0, 2) : fallbackLang; this.language = lang; }, async load(path) { this.init(); await Promise.all([ this.loadLang(path, fallbackLang), this.loadLang(path, lang) ]); }, /** * @returns {Promise} */ loadLang(path, lang) { let langLoad = this.loads[lang]; if (!langLoad) langLoad = this.loads[lang] = {}; if (langLoad[path]) return Promise.resolve(); langLoad[path] = true; const langFile = `${path}/locale/${lang}.yml${Vn.getVersion()}`; const request = new XMLHttpRequest(); request.open('get', langFile, true); return new Promise( (resolve, reject) => { request.onreadystatechange = () => this.onRequestReady(request, resolve, reject); request.send(); }) .then(translations => { this.add(translations, lang); }) .catch(err => { langLoad[path] = false; console.warn(err); }); }, onRequestReady(request, resolve, reject) { if (request.readyState != 4) return; if (request.status < 200 || request.status >= 400) return reject(new Error(`HTTP ${request.status}: ${request.statusText}`)); resolve(yaml.safeLoad(request.responseText)); }, add(translations, myLang) { if (!translations) return; myLang = myLang || lang; let langLocales = locales[myLang]; if (!langLocales) langLocales = locales[myLang] = {}; for (const str in translations) langLocales[str] = translations[str]; } } function getString(stringId, lang) { return locales[lang] ? locales[lang][stringId] : null; } window._ = function(stringId) { let string = getString(stringId, lang); if (!string) string = getString(stringId, fallbackLang); return string || stringId; }