UNPKG

@iobroker/adapter-react-v5

Version:

React components to develop ioBroker interfaces with react.

224 lines 8.34 kB
/** * Copyright 2018-2024 Denis Haev (bluefox) <dogafox@gmail.com> * * MIT License * */ /** * Translation string management. */ export class I18n { /** List of all languages with their translations. */ static translations = {}; /** List of unknown translations during development. */ static unknownTranslations = []; /** The currently displayed language. */ static lang = window.sysLang || 'en'; static _disableWarning = false; /** * Set the language to display * * @param lang The default language for translations. */ static setLanguage(lang) { if (lang) { I18n.lang = lang; } } /** * Add translations * User can provide two types of structures: * - {"word1": "translated word1", "word2": "translated word2"}, but in this case the lang must be provided * - {"word1": {"en": "translated en word1", "de": "translated de word1"}, "word2": {"en": "translated en word2", "de": "translated de word2"}}, but no lang must be provided * * @param words additional words for specific language * @param lang language for the words */ static extendTranslations(words, lang) { // automatically extend all languages with prefix if (words.prefix) { const wordsWithPrefix = words; if (typeof wordsWithPrefix.prefix === 'string') { const prefix = wordsWithPrefix.prefix; delete wordsWithPrefix.prefix; Object.keys(wordsWithPrefix).forEach(key => { const _lang = key; const _words = {}; const wordsOfOneLanguage = wordsWithPrefix[_lang]; Object.keys(wordsOfOneLanguage).forEach(word => { if (!word) { return; } if (wordsOfOneLanguage) { if (!word.startsWith(prefix)) { _words[`${prefix}${word}`] = wordsOfOneLanguage[word]; } else { _words[word] = wordsOfOneLanguage[word]; } } }); words[_lang] = _words; }); } else { console.warn('Found prefix in translations, but it is not a string'); } } try { if (!lang) { // if it is a dictionary with all/many languages if (words.en && words.de && words.ru) { Object.keys(words).forEach(key => { const _lang = key; I18n.translations[_lang] = I18n.translations[_lang] || {}; const wordsOfOneLang = I18n.translations[_lang]; Object.assign(wordsOfOneLang, words[_lang]); }); } else { // It could be vice versa: words.word1 = {en: 'translated word1', de: 'übersetztes Wort2'} Object.keys(words).forEach(word => { const _word = words[word]; Object.keys(_word).forEach(key => { const _lang = key; const languageDictionary = I18n.translations[_lang]; if (!languageDictionary) { console.warn(`Used unknown language: ${_lang}`); } else if (!languageDictionary[word]) { languageDictionary[word] = _word[_lang]; } else if (languageDictionary[word] !== _word[_lang]) { console.warn(`Translation for word "${word}" in "${_lang}" was ignored: existing = "${languageDictionary[word]}", new = ${_word[_lang]}`); } }); }); } } else { // translations for one language if (!I18n.translations[lang]) { console.warn(`Used unknown language: ${lang}`); } I18n.translations[lang] = I18n.translations[lang] || {}; const languageDictionary = I18n.translations[lang]; if (languageDictionary) { Object.keys(words).forEach(word => { if (!languageDictionary[word]) { languageDictionary[word] = words[word]; } else if (languageDictionary[word] !== words[word]) { console.warn(`Translation for word "${word}" in "${lang}" was ignored: existing = "${languageDictionary[word]}", new = ${words[word]}`); } }); } } } catch (e) { console.error(`Cannot apply translations: ${e}`); } } /** * Sets all translations (in all languages). * * @param translations The translations to add. */ static setTranslations(translations) { if (translations) { I18n.translations = translations; } } /** * Get the currently chosen language. * * @returns The current language. */ static getLanguage() { return I18n.lang; } /** * Translate the given string to the selected language * * @param word The (key) word to look up the string. * @param args Optional arguments which will replace the first (second, third, ...) occurrences of %s */ static t(word, ...args) { const translation = I18n.translations[I18n.lang]; if (translation) { const w = translation[word]; if (w) { word = w; } else { if (!I18n.unknownTranslations.includes(word)) { I18n.unknownTranslations.push(word); !I18n._disableWarning && console.log(`Translate: ${word}`); } // fallback to english if (I18n.lang !== 'en' && I18n.translations.en) { const wordEn = I18n.translations.en[word]; if (wordEn) { word = wordEn; } } } } for (const arg of args) { word = word.replace('%s', arg); } return word; } /** * Show non-translated words * Required during development * * @param filter The filter to apply to the list of non-translated words. */ static i18nShow(filter) { /** List words with their translations. */ const result = {}; if (!filter) { I18n.unknownTranslations.forEach(word => (result[word] = word)); console.log(JSON.stringify(result, null, 2)); } else if (typeof filter === 'string') { I18n.unknownTranslations.forEach(word => { if (word.startsWith(filter)) { result[word] = word.replace(filter, ''); } }); console.log(JSON.stringify(result, null, 2)); } else if (typeof filter === 'object') { I18n.unknownTranslations.forEach(word => { if (filter.test(word)) { result[word] = word; } }); console.log(JSON.stringify(result, null, 2)); } } /** * Disable warning about non-translated words * Required during development * * @param disable Whether to disable the warning */ static disableWarning(disable) { I18n._disableWarning = !!disable; } } // install global handlers window.i18nShow = I18n.i18nShow; window.i18nDisableWarning = I18n.disableWarning; /* I18n.translations = { 'en': require('./i18n/en'), 'ru': require('./i18n/ru'), 'de': require('./i18n/de'), }; I18n.fallbacks = true; I18n.t = function () {}; */ //# sourceMappingURL=i18n.js.map