UNPKG

@gctools-components/i18n-translation-webpack-plugin

Version:

Complete i18n translation solution for webpack, including code-splitting and automatic generation of translation files

255 lines (222 loc) 13 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.Localizer = undefined; var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); /* * Author: National Research Council Canada * Website: http://www.nrc-cnrc.gc.ca/eng/rd/ict/ * * License: MIT * Copyright: Her Majesty the Queen in Right of Canada, as represented by * the Minister of National Research Council, 2017 */ var _jed = require('jed'); var _jed2 = _interopRequireDefault(_jed); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } var _require = require('es6-promise'), Promise = _require.Promise; var objectAssign = require('object-assign'); var hasWndw = function hasWndw() { return typeof window !== 'undefined'; }; /** * Javascript in-browser object reponsible for loading language files, * switching languages, and language change notification. * * By default this object binds to the global window object as window.localizer * so it can interact with other libraries that may have been bundled using * this plugin. */ var Localizer = exports.Localizer = function () { function Localizer(config) { _classCallCheck(this, Localizer); this.lang = null; this.domains = {}; this.ready = {}; this.languageChangeCallbacks = []; var defaultAvailableLanguages = ['en_CA']; var defaultConfig = { window_global: 'localizer', availableLanguages: defaultAvailableLanguages, language: (hasWndw() ? window.navigator.userLanguage || window.navigator.language : false) || defaultAvailableLanguages[0] }; defaultConfig.language = defaultConfig.language.replace('-', '_'); this.config = defaultConfig; this.domainsReady = this.domainsReady.bind(this); this.applyConfig(config); } _createClass(Localizer, [{ key: 'applyConfig', value: function applyConfig(config) { this.config = objectAssign(this.config, config); if (this.config.availableLanguages.length === 0) { throw new Error('Localizer needs some languages.'); } if (!this.hasLanguage(this.config.language)) { var _config$availableLang = _slicedToArray(this.config.availableLanguages, 1); this.config.language = _config$availableLang[0]; } this.setLanguage(this.config.language); } /** * Determines if the speicifed language is supported. * @param lang 'en_US' | 'fr_CA' | ... */ }, { key: 'hasLanguage', value: function hasLanguage(lang) { return this.config.availableLanguages.indexOf(lang) !== -1; } /** * Sets the current language. * @param lang Locale code 'en_US' | 'fr_CA' | ... */ }, { key: 'setLanguage', value: function setLanguage(lang) { var _this = this; var language = lang.replace('-', '_'); if (this.hasLanguage(language)) { this.lang = language; Object.keys(this.domains).forEach(function (l) { if (l !== language) { Object.keys(_this.domains[l]).forEach(function (d) { if ({}.hasOwnProperty.call(_this.domains[l], d)) { _this.registerDomain(d); } }); } }); this.callLanguageChangeCallbacks(); } else { throw new Error('Specified language is not available.'); } } /** * Internal method used to initialize Jed with the currently known domains * and languages. * * @private */ }, { key: '_initializeJed', value: function _initializeJed() { this.i18n = new _jed2.default({ // This callback is called when a key is missing missing_key_callback: function missingKeyCallback(key) { throw new Error('ERROR: specified key does not exists: ' + key); }, locale_data: this.domains[this.lang] }); } /** * Register the given domain with the localizer. The appropriate translation * files will be automatically loaded. * * @param domain The filename that uses the term. */ }, { key: 'registerDomain', value: function registerDomain(domain) { if (this.ready[domain]) return this.ready[domain]; var self = this; this.ready[domain] = new Promise(function (resolve, reject) { // eslint-disable-next-line require('./language.loader.js!./<I18nWebpackPlugin>')(self.lang, domain, function (translations) { if (translations && translations.locale_data && translations.locale_data.messages) { if (!self.domains[self.lang]) { self.domains[self.lang] = {}; } // eslint-disable-next-line no-param-reassign translations.locale_data.messages[''].domain = domain; self.domains[self.lang][domain] = translations.locale_data.messages; self._initializeJed(); // eslint-disable-line no-underscore-dangle resolve(); } else { reject(); } delete self.ready[domain]; }); }); return this.ready[domain]; } }, { key: 'domainsReady', value: function domainsReady() { var _this2 = this; var ar = []; Object.keys(this.ready).forEach(function (i) { if ({}.hasOwnProperty.call(_this2.ready, i)) { ar.push(_this2.ready[i]); } }); return Promise.all(ar); } }, { key: 'onLanguageChange', value: function onLanguageChange(callback) { var _this3 = this; if (this.languageChangeCallbacks.indexOf(callback) < 0) { this.languageChangeCallbacks.push(callback); } return { remove: function remove() { var idx = _this3.languageChangeCallbacks.indexOf(callback); if (idx >= 0) { _this3.languageChangeCallbacks.splice(idx, 1); } } }; } }, { key: 'callLanguageChangeCallbacks', value: function callLanguageChangeCallbacks() { for (var x = 0; x < this.languageChangeCallbacks.length; x += 1) { this.languageChangeCallbacks[x](this.lang); } } }, { key: 'translate', value: function translate(domain, str, val) { if (!this.domains[this.lang] || !this.domains[this.lang][domain]) { return str; } if (typeof val !== 'undefined') { var num = val * 1; return this.i18n.translate.apply(this.i18n, [str]).onDomain(domain || 'messages').ifPlural(num, '').fetch(num); } return this.i18n.translate.apply(this.i18n, [str]).onDomain(domain || 'messages').fetch(); } }, { key: 'interpolate', value: function interpolate(domain, str) { var _i18n$translate$apply; if (!this.domains[this.lang] || !this.domains[this.lang][domain]) { return str; } for (var _len = arguments.length, args = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) { args[_key - 2] = arguments[_key]; } return (_i18n$translate$apply = this.i18n.translate.apply(this.i18n, [str]).onDomain(domain || 'messages')).fetch.apply(_i18n$translate$apply, args); } }]); return Localizer; }(); var localizerInstance = null; var localizer = function localizer(config) { if (localizerInstance !== null) { return localizerInstance; } if (hasWndw() && window.localizer && window.localizer instanceof Localizer) { return window.localizer; } localizerInstance = new Localizer(config); if (hasWndw() && config.window_global) { window[config.window_global] = localizerInstance; } return localizerInstance; }; exports.default = localizer;