@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
JavaScript
'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;