diff --git a/bower.json b/bower.json index a5d79103..ec33453e 100644 --- a/bower.json +++ b/bower.json @@ -16,5 +16,5 @@ "type": "git", "url": "http://github.com/aurelia/i18n" }, - "dependencies": { } + "dependencies": {} } diff --git a/dist/amd/base-i18n.js b/dist/amd/base-i18n.js new file mode 100644 index 00000000..cde138f4 --- /dev/null +++ b/dist/amd/base-i18n.js @@ -0,0 +1,43 @@ +define(['exports', 'babel-runtime/helpers/create-class', 'babel-runtime/helpers/class-call-check', './i18n', 'aurelia-event-aggregator'], function (exports, _babelRuntimeHelpersCreateClass, _babelRuntimeHelpersClassCallCheck, _i18n, _aureliaEventAggregator) { + 'use strict'; + + Object.defineProperty(exports, '__esModule', { + value: true + }); + + var BaseI18N = (function () { + (0, _babelRuntimeHelpersCreateClass['default'])(BaseI18N, null, [{ + key: 'inject', + value: [_i18n.I18N, Element, _aureliaEventAggregator.EventAggregator], + enumerable: true + }]); + + function BaseI18N(i18n, element, ea) { + var _this = this; + + (0, _babelRuntimeHelpersClassCallCheck['default'])(this, BaseI18N); + + this.i18n = i18n; + this.element = element; + + this.__i18nDisposer = ea.subscribe('i18n:locale:changed', function (payload) { + _this.i18n.updateTranslations(_this.element); + }); + } + + (0, _babelRuntimeHelpersCreateClass['default'])(BaseI18N, [{ + key: 'attached', + value: function attached() { + this.i18n.updateTranslations(this.element); + } + }, { + key: 'detached', + value: function detached() { + this.__i18nDisposer(); + } + }]); + return BaseI18N; + })(); + + exports.BaseI18N = BaseI18N; +}); \ No newline at end of file diff --git a/dist/amd/defaultTranslations/relative.time.js b/dist/amd/defaultTranslations/relative.time.js new file mode 100644 index 00000000..5c70ac88 --- /dev/null +++ b/dist/amd/defaultTranslations/relative.time.js @@ -0,0 +1,232 @@ +define(["exports", "module"], function (exports, module) { + "use strict"; + + module.exports = { + ar: { + translation: { + "now": "الآن", + "second_ago": "منذ __count__ ثانية", + "second_ago_plural": "منذ __count__ ثواني", + "second_in": "في __count__ ثانية", + "second_in_plural": "في __count__ ثواني", + "minute_ago": "منذ __count__ دقيقة", + "minute_ago_plural": "منذ __count__ دقائق", + "minute_in": "في __count__ دقيقة", + "minute_in_plural": "في __count__ دقائق", + "hour_ago": "منذ __count__ ساعة", + "hour_ago_plural": "منذ __count__ ساعات", + "hour_in": "في __count__ ساعة", + "hour_in_plural": "في __count__ ساعات", + "day_ago": "منذ __count__ يوم", + "day_ago_plural": "منذ __count__ أيام", + "day_in": "في __count__ يوم", + "day_in_plural": "في __count__ أيام" + } + }, + en: { + translation: { + "now": "just now", + "second_ago": "__count__ second ago", + "second_ago_plural": "__count__ seconds ago", + "second_in": "in __count__ second", + "second_in_plural": "in __count__ seconds", + "minute_ago": "__count__ minute ago", + "minute_ago_plural": "__count__ minutes ago", + "minute_in": "in __count__ minute", + "minute_in_plural": "in __count__ minutes", + "hour_ago": "__count__ hour ago", + "hour_ago_plural": "__count__ hours ago", + "hour_in": "in __count__ hour", + "hour_in_plural": "in __count__ hours", + "day_ago": "__count__ day ago", + "day_ago_plural": "__count__ days ago", + "day_in": "in __count__ day", + "day_in_plural": "in __count__ days", + "month_ago": "__count__ month ago", + "month_ago_plural": "__count__ months ago", + "month_in": "in __count__ month", + "month_in_plural": "in __count__ months", + "year_ago": "__count__ year ago", + "year_ago_plural": "__count__ years ago", + "year_in": "in __count__ year", + "year_in_plural": "in __count__ years" + } + }, + de: { + translation: { + "now": "jetzt gerade", + "second_ago": "vor __count__ Sekunde", + "second_ago_plural": "vor __count__ Sekunden", + "second_in": "in __count__ Sekunde", + "second_in_plural": "in __count__ Sekunden", + "minute_ago": "vor __count__ Minute", + "minute_ago_plural": "vor __count__ Minuten", + "minute_in": "in __count__ Minute", + "minute_in_plural": "in __count__ Minuten", + "hour_ago": "vor __count__ Stunde", + "hour_ago_plural": "vor __count__ Stunden", + "hour_in": "in __count__ Stunde", + "hour_in_plural": "in __count__ Stunden", + "day_ago": "vor __count__ Tag", + "day_ago_plural": "vor __count__ Tagen", + "day_in": "in __count__ Tag", + "day_in_plural": "in __count__ Tagen", + "month_ago": "vor __count__ Monat", + "month_ago_plural": "vor __count__ Monaten", + "month_in": "in __count__ Monat", + "month_in_plural": "in __count__ Monaten", + "year_ago": "vor __count__ Jahr", + "year_ago_plural": "vor __count__ Jahren", + "year_in": "in __count__ Jahr", + "year_in_plural": "in __count__ Jahren" + } + }, + nl: { + translation: { + "now": "zonet", + "second_ago": "__count__ seconde geleden", + "second_ago_plural": "__count__ seconden geleden", + "second_in": "in __count__ seconde", + "second_in_plural": "in __count__ seconden", + "minute_ago": "__count__ minuut geleden", + "minute_ago_plural": "__count__ minuten geleden", + "minute_in": "in __count__ minuut", + "minute_in_plural": "in __count__ minuten", + "hour_ago": "__count__ uur geleden", + "hour_ago_plural": "__count__ uren geleden", + "hour_in": "in __count__ uur", + "hour_in_plural": "in __count__ uren", + "day_ago": "__count__ dag geleden", + "day_ago_plural": "__count__ dagen geleden", + "day_in": "in __count__ dag", + "day_in_plural": "in __count__ dagen" + } + }, + fr: { + translation: { + "now": "juste", + "second_ago": "__count__ seconde passé", + "second_ago_plural": "__count__ secondes passé", + "second_in": "en __count__ seconde", + "second_in_plural": "en __count__ secondes", + "minute_ago": "__count__ minute passé", + "minute_ago_plural": "__count__ minutes passé", + "minute_in": "en __count__ minute", + "minute_in_plural": "en __count__ minutes", + "hour_ago": "__count__ heure passé", + "hour_ago_plural": "__count__ heures passé", + "hour_in": "en __count__ heure", + "hour_in_plural": "en __count__ heures", + "day_ago": "__count__ jour passé", + "day_ago_plural": "__count__ jours passé", + "day_in": "en __count__ jour", + "day_in_plural": "en __count__ jours" + } + }, + th: { + translation: { + "now": "เมื่อกี้", + "second_ago": "__count__ วินาที ที่ผ่านมา", + "second_ago_plural": "__count__ วินาที ที่ผ่านมา", + "second_in": "อีก __count__ วินาที", + "second_in_plural": "อีก __count__ วินาที", + "minute_ago": "__count__ นาที ที่ผ่านมา", + "minute_ago_plural": "__count__ นาที ที่ผ่านมา", + "minute_in": "อีก __count__ นาที", + "minute_in_plural": "อีก __count__ นาที", + "hour_ago": "__count__ ชั่วโมง ที่ผ่านมา", + "hour_ago_plural": "__count__ ชั่วโมง ที่ผ่านมา", + "hour_in": "อีก __count__ ชั่วโมง", + "hour_in_plural": "อีก __count__ ชั่วโมง", + "day_ago": "__count__ วัน ที่ผ่านมา", + "day_ago_plural": "__count__ วัน ที่ผ่านมา", + "day_in": "อีก __count__ วัน", + "day_in_plural": "อีก __count__ วัน" + } + }, + sv: { + translation: { + "now": "just nu", + "second_ago": "__count__ sekund sedan", + "second_ago_plural": "__count__ sekunder sedan", + "second_in": "om __count__ sekund", + "second_in_plural": "om __count__ sekunder", + "minute_ago": "__count__ minut sedan", + "minute_ago_plural": "__count__ minuter sedan", + "minute_in": "om __count__ minut", + "minute_in_plural": "om __count__ minuter", + "hour_ago": "__count__ timme sedan", + "hour_ago_plural": "__count__ timmar sedan", + "hour_in": "om __count__ timme", + "hour_in_plural": "om __count__ timmar", + "day_ago": "__count__ dag sedan", + "day_ago_plural": "__count__ dagar sedan", + "day_in": "om __count__ dag", + "day_in_plural": "om __count__ dagar" + } + }, + da: { + translation: { + "now": "lige nu", + "second_ago": "__count__ sekunder siden", + "second_ago_plural": "__count__ sekunder siden", + "second_in": "om __count__ sekund", + "second_in_plural": "om __count__ sekunder", + "minute_ago": "__count__ minut siden", + "minute_ago_plural": "__count__ minutter siden", + "minute_in": "om __count__ minut", + "minute_in_plural": "om __count__ minutter", + "hour_ago": "__count__ time siden", + "hour_ago_plural": "__count__ timer siden", + "hour_in": "om __count__ time", + "hour_in_plural": "om __count__ timer", + "day_ago": "__count__ dag siden", + "day_ago_plural": "__count__ dage siden", + "day_in": "om __count__ dag", + "day_in_plural": "om __count__ dage" + } + }, + no: { + translation: { + "now": "akkurat nå", + "second_ago": "__count__ sekund siden", + "second_ago_plural": "__count__ sekunder siden", + "second_in": "om __count__ sekund", + "second_in_plural": "om __count__ sekunder", + "minute_ago": "__count__ minutt siden", + "minute_ago_plural": "__count__ minutter siden", + "minute_in": "om __count__ minutt", + "minute_in_plural": "om __count__ minutter", + "hour_ago": "__count__ time siden", + "hour_ago_plural": "__count__ timer siden", + "hour_in": "om __count__ time", + "hour_in_plural": "om __count__ timer", + "day_ago": "__count__ dag siden", + "day_ago_plural": "__count__ dager siden", + "day_in": "om __count__ dag", + "day_in_plural": "om __count__ dager" + } + }, + jp: { + translation: { + "now": "たった今", + "second_ago": "__count__ 秒前", + "second_ago_plural": "__count__ 秒前", + "second_in": "あと __count__ 秒", + "second_in_plural": "あと __count__ 秒", + "minute_ago": "__count__ 分前", + "minute_ago_plural": "__count__ 分前", + "minute_in": "あと __count__ 分", + "minute_in_plural": "あと __count__ 分", + "hour_ago": "__count__ 時間前", + "hour_ago_plural": "__count__ 時間前", + "hour_in": "あと __count__ 時間", + "hour_in_plural": "あと __count__ 時間", + "day_ago": "__count__ 日間前", + "day_ago_plural": "__count__ 日間前", + "day_in": "あと __count__ 日間", + "day_in_plural": "あと __count__ 日間" + } + } + }; +}); \ No newline at end of file diff --git a/dist/amd/df.js b/dist/amd/df.js new file mode 100644 index 00000000..86abde97 --- /dev/null +++ b/dist/amd/df.js @@ -0,0 +1,34 @@ +define(['exports', 'babel-runtime/helpers/create-class', 'babel-runtime/helpers/class-call-check', './i18n'], function (exports, _babelRuntimeHelpersCreateClass, _babelRuntimeHelpersClassCallCheck, _i18n) { + 'use strict'; + + Object.defineProperty(exports, '__esModule', { + value: true + }); + + var DfValueConverter = (function () { + (0, _babelRuntimeHelpersCreateClass['default'])(DfValueConverter, null, [{ + key: 'inject', + value: function inject() { + return [_i18n.I18N]; + } + }]); + + function DfValueConverter(i18n) { + (0, _babelRuntimeHelpersClassCallCheck['default'])(this, DfValueConverter); + + this.service = i18n; + } + + (0, _babelRuntimeHelpersCreateClass['default'])(DfValueConverter, [{ + key: 'toView', + value: function toView(value, formatOptions, locale, dateFormat) { + var df = dateFormat || this.service.df(formatOptions, locale || this.service.getLocale()); + + return df.format(value); + } + }]); + return DfValueConverter; + })(); + + exports.DfValueConverter = DfValueConverter; +}); \ No newline at end of file diff --git a/dist/amd/i18n.js b/dist/amd/i18n.js new file mode 100644 index 00000000..e75ec876 --- /dev/null +++ b/dist/amd/i18n.js @@ -0,0 +1,184 @@ +define(['exports', 'babel-runtime/helpers/create-class', 'babel-runtime/helpers/class-call-check', 'babel-runtime/core-js/promise', 'babel-runtime/core-js/object/assign', 'babel-runtime/core-js/get-iterator', 'i18next', 'babel-runtime/helpers/interop-require-default', './utils'], function (exports, _babelRuntimeHelpersCreateClass, _babelRuntimeHelpersClassCallCheck, _babelRuntimeCoreJsPromise, _babelRuntimeCoreJsObjectAssign, _babelRuntimeCoreJsGetIterator, _i18next, _babelRuntimeHelpersInteropRequireDefault, _utils) { + 'use strict'; + + Object.defineProperty(exports, '__esModule', { + value: true + }); + + var _i18n = (0, _babelRuntimeHelpersInteropRequireDefault['default'])(_i18next); + + var I18N = (function () { + function I18N(ea) { + (0, _babelRuntimeHelpersClassCallCheck['default'])(this, I18N); + this.globalVars = {}; + + this.i18next = _i18n['default']; + this.ea = ea; + this.Intl = window.Intl; + + if (window.Intl === undefined) { + System['import']('Intl').then(function (poly) { + window.Intl = poly; + }); + } + } + + (0, _babelRuntimeHelpersCreateClass['default'])(I18N, [{ + key: 'setup', + value: function setup(options) { + var defaultOptions = { + resGetPath: 'locale/__lng__/__ns__.json', + lng: 'en', + getAsync: false, + sendMissing: false, + attributes: ['t', 'i18n'], + fallbackLng: 'en', + debug: false + }; + + _i18n['default'].init(options || defaultOptions); + + if (_i18n['default'].options.attributes instanceof String) { + _i18n['default'].options.attributes = [_i18n['default'].options.attributes]; + } + } + }, { + key: 'setLocale', + value: function setLocale(locale) { + var _this = this; + + return new _babelRuntimeCoreJsPromise['default'](function (resolve) { + var oldLocale = _this.getLocale(); + _this.i18next.setLng(locale, function (tr) { + _this.ea.publish("i18n:locale:changed", { oldValue: oldLocale, newValue: locale }); + resolve(tr); + }); + }); + } + }, { + key: 'getLocale', + value: function getLocale() { + return this.i18next.lng(); + } + }, { + key: 'nf', + value: function nf(options, locales) { + return new this.Intl.NumberFormat(locales || this.getLocale(), options); + } + }, { + key: 'df', + value: function df(options, locales) { + return new this.Intl.DateTimeFormat(locales || this.getLocale(), options); + } + }, { + key: 'tr', + value: function tr(key, options) { + var fullOptions = this.globalVars; + + if (options !== undefined) { + fullOptions = (0, _babelRuntimeCoreJsObjectAssign['default'])((0, _babelRuntimeCoreJsObjectAssign['default'])({}, this.globalVars), options); + } + + return this.i18next.t(key, (0, _utils.assignObjectToKeys)('', fullOptions)); + } + }, { + key: 'registerGlobalVariable', + value: function registerGlobalVariable(key, value) { + this.globalVars[key] = value; + } + }, { + key: 'unregisterGlobalVariable', + value: function unregisterGlobalVariable(key) { + delete this.globalVars[key]; + } + }, { + key: 'updateTranslations', + value: function updateTranslations(el) { + + var i, l; + + var selector = [].concat(this.i18next.options.attributes); + for (i = 0, l = selector.length; i < l; i++) selector[i] = "[" + selector[i] + "]"; + selector = selector.join(","); + + var nodes = el.querySelectorAll(selector); + for (i = 0, l = nodes.length; i < l; i++) { + var node = nodes[i]; + var keys; + + for (var i2 = 0, l2 = this.i18next.options.attributes.length; i2 < l2; i2++) { + keys = node.getAttribute(this.i18next.options.attributes[i2]); + if (keys) break; + } + + if (!keys) continue; + + keys = keys.split(";"); + var _iteratorNormalCompletion = true; + var _didIteratorError = false; + var _iteratorError = undefined; + + try { + for (var _iterator = (0, _babelRuntimeCoreJsGetIterator['default'])(keys), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + var key = _step.value; + + var re = /\[([a-z]*)\]/g; + + var m; + var attr = "text"; + + if (node.nodeName == "IMG") attr = "src"; + + while ((m = re.exec(key)) !== null) { + if (m.index === re.lastIndex) { + re.lastIndex++; + } + if (m) { + key = key.replace(m[0], ''); + attr = m[1]; + } + } + + if (!node._textContent) node._textContent = node.textContent; + if (!node._innerHTML) node._innerHTML = node.innerHTML; + + switch (attr) { + case 'text': + node.textContent = this.tr(key); + break; + case 'prepend': + node.innerHTML = this.tr(key) + node._innerHTML.trim(); + break; + case 'append': + node.innerHTML = node._innerHTML.trim() + this.tr(key); + break; + case 'html': + node.innerHTML = this.tr(key); + break; + default: + node.setAttribute(attr, this.tr(key)); + break; + } + } + } catch (err) { + _didIteratorError = true; + _iteratorError = err; + } finally { + try { + if (!_iteratorNormalCompletion && _iterator['return']) { + _iterator['return'](); + } + } finally { + if (_didIteratorError) { + throw _iteratorError; + } + } + } + } + } + }]); + return I18N; + })(); + + exports.I18N = I18N; +}); \ No newline at end of file diff --git a/dist/amd/index.js b/dist/amd/index.js new file mode 100644 index 00000000..9ef49d7e --- /dev/null +++ b/dist/amd/index.js @@ -0,0 +1,88 @@ +define(['exports', './i18n', 'aurelia-event-aggregator', 'aurelia-templating', './relativeTime', './df', './nf', './rt', './t', './base-i18n'], function (exports, _i18n, _aureliaEventAggregator, _aureliaTemplating, _relativeTime, _df, _nf, _rt, _t, _baseI18n) { + 'use strict'; + + Object.defineProperty(exports, '__esModule', { + value: true + }); + exports.configure = configure; + Object.defineProperty(exports, 'I18N', { + enumerable: true, + get: function get() { + return _i18n.I18N; + } + }); + Object.defineProperty(exports, 'RelativeTime', { + enumerable: true, + get: function get() { + return _relativeTime.RelativeTime; + } + }); + Object.defineProperty(exports, 'DfValueConverter', { + enumerable: true, + get: function get() { + return _df.DfValueConverter; + } + }); + Object.defineProperty(exports, 'NfValueConverter', { + enumerable: true, + get: function get() { + return _nf.NfValueConverter; + } + }); + Object.defineProperty(exports, 'RtValueConverter', { + enumerable: true, + get: function get() { + return _rt.RtValueConverter; + } + }); + Object.defineProperty(exports, 'TValueConverter', { + enumerable: true, + get: function get() { + return _t.TValueConverter; + } + }); + Object.defineProperty(exports, 'TCustomAttribute', { + enumerable: true, + get: function get() { + return _t.TCustomAttribute; + } + }); + Object.defineProperty(exports, 'BaseI18N', { + enumerable: true, + get: function get() { + return _baseI18n.BaseI18N; + } + }); + Object.defineProperty(exports, 'EventAggregator', { + enumerable: true, + get: function get() { + return _aureliaEventAggregator.EventAggregator; + } + }); + + function configure(frameworkConfig, cb) { + if (cb === undefined || typeof cb !== 'function') { + throw 'You need to provide a callback method to properly configure the library'; + } + + frameworkConfig.globalResources('./t'); + frameworkConfig.globalResources('./nf'); + frameworkConfig.globalResources('./df'); + frameworkConfig.globalResources('./rt'); + var instance = new _i18n.I18N(frameworkConfig.container.get(_aureliaEventAggregator.EventAggregator)); + frameworkConfig.container.registerInstance(_i18n.I18N, instance); + + var ret = cb(instance); + + frameworkConfig.postTask(function () { + var resources = frameworkConfig.container.get(_aureliaTemplating.ViewResources); + var htmlBehaviorResource = resources.getAttribute('t'); + + instance.i18next.options.attributes.forEach(function (alias) { + return resources.registerAttribute(alias, htmlBehaviorResource, 't'); + }); + }); + + return ret; + } +}); \ No newline at end of file diff --git a/dist/amd/nf.js b/dist/amd/nf.js new file mode 100644 index 00000000..72793a91 --- /dev/null +++ b/dist/amd/nf.js @@ -0,0 +1,34 @@ +define(['exports', 'babel-runtime/helpers/create-class', 'babel-runtime/helpers/class-call-check', './i18n'], function (exports, _babelRuntimeHelpersCreateClass, _babelRuntimeHelpersClassCallCheck, _i18n) { + 'use strict'; + + Object.defineProperty(exports, '__esModule', { + value: true + }); + + var NfValueConverter = (function () { + (0, _babelRuntimeHelpersCreateClass['default'])(NfValueConverter, null, [{ + key: 'inject', + value: function inject() { + return [_i18n.I18N]; + } + }]); + + function NfValueConverter(i18n) { + (0, _babelRuntimeHelpersClassCallCheck['default'])(this, NfValueConverter); + + this.service = i18n; + } + + (0, _babelRuntimeHelpersCreateClass['default'])(NfValueConverter, [{ + key: 'toView', + value: function toView(value, formatOptions, locale, numberFormat) { + var nf = numberFormat || this.service.nf(formatOptions, locale || this.service.getLocale()); + + return nf.format(value); + } + }]); + return NfValueConverter; + })(); + + exports.NfValueConverter = NfValueConverter; +}); \ No newline at end of file diff --git a/dist/amd/relativeTime.js b/dist/amd/relativeTime.js new file mode 100644 index 00000000..1391901b --- /dev/null +++ b/dist/amd/relativeTime.js @@ -0,0 +1,85 @@ +define(['exports', 'babel-runtime/helpers/create-class', 'babel-runtime/helpers/class-call-check', 'babel-runtime/core-js/object/keys', './i18n', './defaultTranslations/relative.time'], function (exports, _babelRuntimeHelpersCreateClass, _babelRuntimeHelpersClassCallCheck, _babelRuntimeCoreJsObjectKeys, _i18n, _defaultTranslationsRelativeTime) { + 'use strict'; + + Object.defineProperty(exports, '__esModule', { + value: true + }); + + var RelativeTime = (function () { + (0, _babelRuntimeHelpersCreateClass['default'])(RelativeTime, null, [{ + key: 'inject', + value: function inject() { + return [_i18n.I18N]; + } + }]); + + function RelativeTime(i18n) { + var _this = this; + + (0, _babelRuntimeHelpersClassCallCheck['default'])(this, RelativeTime); + + this.service = i18n; + + var trans = _defaultTranslationsRelativeTime['default'] || _defaultTranslationsRelativeTime; + + (0, _babelRuntimeCoreJsObjectKeys['default'])(trans).map(function (key) { + var translation = trans[key]['translation']; + var options = i18n.i18next.options; + + if (options.interpolationPrefix !== '__' || options.interpolationSuffix !== '__') { + for (var subkey in translation) { + translation[subkey] = translation[subkey].replace('__count__', options.interpolationPrefix + 'count' + options.interpolationSuffix); + } + } + + _this.service.i18next.addResources(key, 'translation', translation); + }); + } + + (0, _babelRuntimeHelpersCreateClass['default'])(RelativeTime, [{ + key: 'getRelativeTime', + value: function getRelativeTime(time) { + var now = new Date(); + var diff = now.getTime() - time.getTime(); + + var timeDiff = this.getTimeDiffDescription(diff, 'year', 31104000000); + if (!timeDiff) { + var timeDiff = this.getTimeDiffDescription(diff, 'month', 2592000000); + if (!timeDiff) { + var timeDiff = this.getTimeDiffDescription(diff, 'day', 86400000); + if (!timeDiff) { + timeDiff = this.getTimeDiffDescription(diff, 'hour', 3600000); + if (!timeDiff) { + timeDiff = this.getTimeDiffDescription(diff, 'minute', 60000); + if (!timeDiff) { + timeDiff = this.getTimeDiffDescription(diff, 'second', 1000); + if (!timeDiff) { + timeDiff = this.service.tr('now'); + } + } + } + } + } + } + + return timeDiff; + } + }, { + key: 'getTimeDiffDescription', + value: function getTimeDiffDescription(diff, unit, timeDivisor) { + var unitAmount = (diff / timeDivisor).toFixed(0); + if (unitAmount > 0) { + return this.service.tr(unit, { count: parseInt(unitAmount), context: 'ago' }); + } else if (unitAmount < 0) { + var abs = Math.abs(unitAmount); + return this.service.tr(unit, { count: abs, context: 'in' }); + } else { + return null; + } + } + }]); + return RelativeTime; + })(); + + exports.RelativeTime = RelativeTime; +}); \ No newline at end of file diff --git a/dist/amd/rt.js b/dist/amd/rt.js new file mode 100644 index 00000000..7d885326 --- /dev/null +++ b/dist/amd/rt.js @@ -0,0 +1,32 @@ +define(['exports', 'babel-runtime/helpers/create-class', 'babel-runtime/helpers/class-call-check', './relativeTime'], function (exports, _babelRuntimeHelpersCreateClass, _babelRuntimeHelpersClassCallCheck, _relativeTime) { + 'use strict'; + + Object.defineProperty(exports, '__esModule', { + value: true + }); + + var RtValueConverter = (function () { + (0, _babelRuntimeHelpersCreateClass['default'])(RtValueConverter, null, [{ + key: 'inject', + value: function inject() { + return [_relativeTime.RelativeTime]; + } + }]); + + function RtValueConverter(relativeTime) { + (0, _babelRuntimeHelpersClassCallCheck['default'])(this, RtValueConverter); + + this.service = relativeTime; + } + + (0, _babelRuntimeHelpersCreateClass['default'])(RtValueConverter, [{ + key: 'toView', + value: function toView(value) { + return this.service.getRelativeTime(value); + } + }]); + return RtValueConverter; + })(); + + exports.RtValueConverter = RtValueConverter; +}); \ No newline at end of file diff --git a/dist/amd/t.js b/dist/amd/t.js new file mode 100644 index 00000000..467b6c26 --- /dev/null +++ b/dist/amd/t.js @@ -0,0 +1,61 @@ +define(['exports', 'babel-runtime/helpers/create-class', 'babel-runtime/helpers/class-call-check', './i18n', 'aurelia-templating'], function (exports, _babelRuntimeHelpersCreateClass, _babelRuntimeHelpersClassCallCheck, _i18n, _aureliaTemplating) { + 'use strict'; + + Object.defineProperty(exports, '__esModule', { + value: true + }); + + var TValueConverter = (function () { + (0, _babelRuntimeHelpersCreateClass['default'])(TValueConverter, null, [{ + key: 'inject', + value: function inject() { + return [_i18n.I18N]; + } + }]); + + function TValueConverter(i18n) { + (0, _babelRuntimeHelpersClassCallCheck['default'])(this, TValueConverter); + + this.service = i18n; + } + + (0, _babelRuntimeHelpersCreateClass['default'])(TValueConverter, [{ + key: 'toView', + value: function toView(value, options) { + return this.service.tr(value, options); + } + }]); + return TValueConverter; + })(); + + exports.TValueConverter = TValueConverter; + + var TCustomAttribute = (function () { + (0, _babelRuntimeHelpersCreateClass['default'])(TCustomAttribute, null, [{ + key: 'inject', + value: [Element, _i18n.I18N], + enumerable: true + }]); + + function TCustomAttribute(element, i18n) { + (0, _babelRuntimeHelpersClassCallCheck['default'])(this, _TCustomAttribute); + + this.element = element; + this.service = i18n; + } + + (0, _babelRuntimeHelpersCreateClass['default'])(TCustomAttribute, [{ + key: 'valueChanged', + value: function valueChanged() { + if (this.element.parentElement !== undefined && this.element.parentElement !== null) { + this.service.updateTranslations(this.element.parentElement); + } + } + }]); + var _TCustomAttribute = TCustomAttribute; + TCustomAttribute = (0, _aureliaTemplating.customAttribute)('t')(TCustomAttribute) || TCustomAttribute; + return TCustomAttribute; + })(); + + exports.TCustomAttribute = TCustomAttribute; +}); \ No newline at end of file diff --git a/dist/amd/utils.js b/dist/amd/utils.js new file mode 100644 index 00000000..c9cb6fac --- /dev/null +++ b/dist/amd/utils.js @@ -0,0 +1,29 @@ +define(['exports', 'babel-runtime/core-js/object/keys'], function (exports, _babelRuntimeCoreJsObjectKeys) { + 'use strict'; + + Object.defineProperty(exports, '__esModule', { + value: true + }); + var extend = function extend(destination, source) { + for (var property in source) destination[property] = source[property]; + return destination; + }; + + exports.extend = extend; + var assignObjectToKeys = function assignObjectToKeys(root, obj) { + if (obj === undefined || obj === null) return obj; + + var opts = {}; + + (0, _babelRuntimeCoreJsObjectKeys['default'])(obj).map(function (key) { + if (typeof obj[key] === 'object') { + extend(opts, assignObjectToKeys(key, obj[key])); + } else { + opts[root !== '' ? root + '.' + key : key] = obj[key]; + } + }); + + return opts; + }; + exports.assignObjectToKeys = assignObjectToKeys; +}); \ No newline at end of file diff --git a/dist/commonjs/base-i18n.js b/dist/commonjs/base-i18n.js new file mode 100644 index 00000000..2664b714 --- /dev/null +++ b/dist/commonjs/base-i18n.js @@ -0,0 +1,50 @@ +'use strict'; + +var _createClass = require('babel-runtime/helpers/create-class')['default']; + +var _classCallCheck = require('babel-runtime/helpers/class-call-check')['default']; + +Object.defineProperty(exports, '__esModule', { + value: true +}); + +var _i18n = require('./i18n'); + +var _aureliaEventAggregator = require('aurelia-event-aggregator'); + +var BaseI18N = (function () { + _createClass(BaseI18N, null, [{ + key: 'inject', + value: [_i18n.I18N, Element, _aureliaEventAggregator.EventAggregator], + enumerable: true + }]); + + function BaseI18N(i18n, element, ea) { + var _this = this; + + _classCallCheck(this, BaseI18N); + + this.i18n = i18n; + this.element = element; + + this.__i18nDisposer = ea.subscribe('i18n:locale:changed', function (payload) { + _this.i18n.updateTranslations(_this.element); + }); + } + + _createClass(BaseI18N, [{ + key: 'attached', + value: function attached() { + this.i18n.updateTranslations(this.element); + } + }, { + key: 'detached', + value: function detached() { + this.__i18nDisposer(); + } + }]); + + return BaseI18N; +})(); + +exports.BaseI18N = BaseI18N; \ No newline at end of file diff --git a/dist/commonjs/defaultTranslations/relative.time.js b/dist/commonjs/defaultTranslations/relative.time.js new file mode 100644 index 00000000..df97c20e --- /dev/null +++ b/dist/commonjs/defaultTranslations/relative.time.js @@ -0,0 +1,234 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports["default"] = { + ar: { + translation: { + "now": "الآن", + "second_ago": "منذ __count__ ثانية", + "second_ago_plural": "منذ __count__ ثواني", + "second_in": "في __count__ ثانية", + "second_in_plural": "في __count__ ثواني", + "minute_ago": "منذ __count__ دقيقة", + "minute_ago_plural": "منذ __count__ دقائق", + "minute_in": "في __count__ دقيقة", + "minute_in_plural": "في __count__ دقائق", + "hour_ago": "منذ __count__ ساعة", + "hour_ago_plural": "منذ __count__ ساعات", + "hour_in": "في __count__ ساعة", + "hour_in_plural": "في __count__ ساعات", + "day_ago": "منذ __count__ يوم", + "day_ago_plural": "منذ __count__ أيام", + "day_in": "في __count__ يوم", + "day_in_plural": "في __count__ أيام" + } + }, + en: { + translation: { + "now": "just now", + "second_ago": "__count__ second ago", + "second_ago_plural": "__count__ seconds ago", + "second_in": "in __count__ second", + "second_in_plural": "in __count__ seconds", + "minute_ago": "__count__ minute ago", + "minute_ago_plural": "__count__ minutes ago", + "minute_in": "in __count__ minute", + "minute_in_plural": "in __count__ minutes", + "hour_ago": "__count__ hour ago", + "hour_ago_plural": "__count__ hours ago", + "hour_in": "in __count__ hour", + "hour_in_plural": "in __count__ hours", + "day_ago": "__count__ day ago", + "day_ago_plural": "__count__ days ago", + "day_in": "in __count__ day", + "day_in_plural": "in __count__ days", + "month_ago": "__count__ month ago", + "month_ago_plural": "__count__ months ago", + "month_in": "in __count__ month", + "month_in_plural": "in __count__ months", + "year_ago": "__count__ year ago", + "year_ago_plural": "__count__ years ago", + "year_in": "in __count__ year", + "year_in_plural": "in __count__ years" + } + }, + de: { + translation: { + "now": "jetzt gerade", + "second_ago": "vor __count__ Sekunde", + "second_ago_plural": "vor __count__ Sekunden", + "second_in": "in __count__ Sekunde", + "second_in_plural": "in __count__ Sekunden", + "minute_ago": "vor __count__ Minute", + "minute_ago_plural": "vor __count__ Minuten", + "minute_in": "in __count__ Minute", + "minute_in_plural": "in __count__ Minuten", + "hour_ago": "vor __count__ Stunde", + "hour_ago_plural": "vor __count__ Stunden", + "hour_in": "in __count__ Stunde", + "hour_in_plural": "in __count__ Stunden", + "day_ago": "vor __count__ Tag", + "day_ago_plural": "vor __count__ Tagen", + "day_in": "in __count__ Tag", + "day_in_plural": "in __count__ Tagen", + "month_ago": "vor __count__ Monat", + "month_ago_plural": "vor __count__ Monaten", + "month_in": "in __count__ Monat", + "month_in_plural": "in __count__ Monaten", + "year_ago": "vor __count__ Jahr", + "year_ago_plural": "vor __count__ Jahren", + "year_in": "in __count__ Jahr", + "year_in_plural": "in __count__ Jahren" + } + }, + nl: { + translation: { + "now": "zonet", + "second_ago": "__count__ seconde geleden", + "second_ago_plural": "__count__ seconden geleden", + "second_in": "in __count__ seconde", + "second_in_plural": "in __count__ seconden", + "minute_ago": "__count__ minuut geleden", + "minute_ago_plural": "__count__ minuten geleden", + "minute_in": "in __count__ minuut", + "minute_in_plural": "in __count__ minuten", + "hour_ago": "__count__ uur geleden", + "hour_ago_plural": "__count__ uren geleden", + "hour_in": "in __count__ uur", + "hour_in_plural": "in __count__ uren", + "day_ago": "__count__ dag geleden", + "day_ago_plural": "__count__ dagen geleden", + "day_in": "in __count__ dag", + "day_in_plural": "in __count__ dagen" + } + }, + fr: { + translation: { + "now": "juste", + "second_ago": "__count__ seconde passé", + "second_ago_plural": "__count__ secondes passé", + "second_in": "en __count__ seconde", + "second_in_plural": "en __count__ secondes", + "minute_ago": "__count__ minute passé", + "minute_ago_plural": "__count__ minutes passé", + "minute_in": "en __count__ minute", + "minute_in_plural": "en __count__ minutes", + "hour_ago": "__count__ heure passé", + "hour_ago_plural": "__count__ heures passé", + "hour_in": "en __count__ heure", + "hour_in_plural": "en __count__ heures", + "day_ago": "__count__ jour passé", + "day_ago_plural": "__count__ jours passé", + "day_in": "en __count__ jour", + "day_in_plural": "en __count__ jours" + } + }, + th: { + translation: { + "now": "เมื่อกี้", + "second_ago": "__count__ วินาที ที่ผ่านมา", + "second_ago_plural": "__count__ วินาที ที่ผ่านมา", + "second_in": "อีก __count__ วินาที", + "second_in_plural": "อีก __count__ วินาที", + "minute_ago": "__count__ นาที ที่ผ่านมา", + "minute_ago_plural": "__count__ นาที ที่ผ่านมา", + "minute_in": "อีก __count__ นาที", + "minute_in_plural": "อีก __count__ นาที", + "hour_ago": "__count__ ชั่วโมง ที่ผ่านมา", + "hour_ago_plural": "__count__ ชั่วโมง ที่ผ่านมา", + "hour_in": "อีก __count__ ชั่วโมง", + "hour_in_plural": "อีก __count__ ชั่วโมง", + "day_ago": "__count__ วัน ที่ผ่านมา", + "day_ago_plural": "__count__ วัน ที่ผ่านมา", + "day_in": "อีก __count__ วัน", + "day_in_plural": "อีก __count__ วัน" + } + }, + sv: { + translation: { + "now": "just nu", + "second_ago": "__count__ sekund sedan", + "second_ago_plural": "__count__ sekunder sedan", + "second_in": "om __count__ sekund", + "second_in_plural": "om __count__ sekunder", + "minute_ago": "__count__ minut sedan", + "minute_ago_plural": "__count__ minuter sedan", + "minute_in": "om __count__ minut", + "minute_in_plural": "om __count__ minuter", + "hour_ago": "__count__ timme sedan", + "hour_ago_plural": "__count__ timmar sedan", + "hour_in": "om __count__ timme", + "hour_in_plural": "om __count__ timmar", + "day_ago": "__count__ dag sedan", + "day_ago_plural": "__count__ dagar sedan", + "day_in": "om __count__ dag", + "day_in_plural": "om __count__ dagar" + } + }, + da: { + translation: { + "now": "lige nu", + "second_ago": "__count__ sekunder siden", + "second_ago_plural": "__count__ sekunder siden", + "second_in": "om __count__ sekund", + "second_in_plural": "om __count__ sekunder", + "minute_ago": "__count__ minut siden", + "minute_ago_plural": "__count__ minutter siden", + "minute_in": "om __count__ minut", + "minute_in_plural": "om __count__ minutter", + "hour_ago": "__count__ time siden", + "hour_ago_plural": "__count__ timer siden", + "hour_in": "om __count__ time", + "hour_in_plural": "om __count__ timer", + "day_ago": "__count__ dag siden", + "day_ago_plural": "__count__ dage siden", + "day_in": "om __count__ dag", + "day_in_plural": "om __count__ dage" + } + }, + no: { + translation: { + "now": "akkurat nå", + "second_ago": "__count__ sekund siden", + "second_ago_plural": "__count__ sekunder siden", + "second_in": "om __count__ sekund", + "second_in_plural": "om __count__ sekunder", + "minute_ago": "__count__ minutt siden", + "minute_ago_plural": "__count__ minutter siden", + "minute_in": "om __count__ minutt", + "minute_in_plural": "om __count__ minutter", + "hour_ago": "__count__ time siden", + "hour_ago_plural": "__count__ timer siden", + "hour_in": "om __count__ time", + "hour_in_plural": "om __count__ timer", + "day_ago": "__count__ dag siden", + "day_ago_plural": "__count__ dager siden", + "day_in": "om __count__ dag", + "day_in_plural": "om __count__ dager" + } + }, + jp: { + translation: { + "now": "たった今", + "second_ago": "__count__ 秒前", + "second_ago_plural": "__count__ 秒前", + "second_in": "あと __count__ 秒", + "second_in_plural": "あと __count__ 秒", + "minute_ago": "__count__ 分前", + "minute_ago_plural": "__count__ 分前", + "minute_in": "あと __count__ 分", + "minute_in_plural": "あと __count__ 分", + "hour_ago": "__count__ 時間前", + "hour_ago_plural": "__count__ 時間前", + "hour_in": "あと __count__ 時間", + "hour_in_plural": "あと __count__ 時間", + "day_ago": "__count__ 日間前", + "day_ago_plural": "__count__ 日間前", + "day_in": "あと __count__ 日間", + "day_in_plural": "あと __count__ 日間" + } + } +}; +module.exports = exports["default"]; \ No newline at end of file diff --git a/dist/commonjs/df.js b/dist/commonjs/df.js new file mode 100644 index 00000000..effeca47 --- /dev/null +++ b/dist/commonjs/df.js @@ -0,0 +1,39 @@ +'use strict'; + +var _createClass = require('babel-runtime/helpers/create-class')['default']; + +var _classCallCheck = require('babel-runtime/helpers/class-call-check')['default']; + +Object.defineProperty(exports, '__esModule', { + value: true +}); + +var _i18n = require('./i18n'); + +var DfValueConverter = (function () { + _createClass(DfValueConverter, null, [{ + key: 'inject', + value: function inject() { + return [_i18n.I18N]; + } + }]); + + function DfValueConverter(i18n) { + _classCallCheck(this, DfValueConverter); + + this.service = i18n; + } + + _createClass(DfValueConverter, [{ + key: 'toView', + value: function toView(value, formatOptions, locale, dateFormat) { + var df = dateFormat || this.service.df(formatOptions, locale || this.service.getLocale()); + + return df.format(value); + } + }]); + + return DfValueConverter; +})(); + +exports.DfValueConverter = DfValueConverter; \ No newline at end of file diff --git a/dist/commonjs/i18n.js b/dist/commonjs/i18n.js new file mode 100644 index 00000000..22bdef95 --- /dev/null +++ b/dist/commonjs/i18n.js @@ -0,0 +1,200 @@ +'use strict'; + +var _createClass = require('babel-runtime/helpers/create-class')['default']; + +var _classCallCheck = require('babel-runtime/helpers/class-call-check')['default']; + +var _Promise = require('babel-runtime/core-js/promise')['default']; + +var _Object$assign = require('babel-runtime/core-js/object/assign')['default']; + +var _getIterator = require('babel-runtime/core-js/get-iterator')['default']; + +var _interopRequireDefault = require('babel-runtime/helpers/interop-require-default')['default']; + +Object.defineProperty(exports, '__esModule', { + value: true +}); + +var _i18next = require('i18next'); + +var _i18next2 = _interopRequireDefault(_i18next); + +var _utils = require('./utils'); + +var I18N = (function () { + function I18N(ea) { + _classCallCheck(this, I18N); + + this.globalVars = {}; + + this.i18next = _i18next2['default']; + this.ea = ea; + this.Intl = window.Intl; + + if (window.Intl === undefined) { + System['import']('Intl').then(function (poly) { + window.Intl = poly; + }); + } + } + + _createClass(I18N, [{ + key: 'setup', + value: function setup(options) { + var defaultOptions = { + resGetPath: 'locale/__lng__/__ns__.json', + lng: 'en', + getAsync: false, + sendMissing: false, + attributes: ['t', 'i18n'], + fallbackLng: 'en', + debug: false + }; + + _i18next2['default'].init(options || defaultOptions); + + if (_i18next2['default'].options.attributes instanceof String) { + _i18next2['default'].options.attributes = [_i18next2['default'].options.attributes]; + } + } + }, { + key: 'setLocale', + value: function setLocale(locale) { + var _this = this; + + return new _Promise(function (resolve) { + var oldLocale = _this.getLocale(); + _this.i18next.setLng(locale, function (tr) { + _this.ea.publish("i18n:locale:changed", { oldValue: oldLocale, newValue: locale }); + resolve(tr); + }); + }); + } + }, { + key: 'getLocale', + value: function getLocale() { + return this.i18next.lng(); + } + }, { + key: 'nf', + value: function nf(options, locales) { + return new this.Intl.NumberFormat(locales || this.getLocale(), options); + } + }, { + key: 'df', + value: function df(options, locales) { + return new this.Intl.DateTimeFormat(locales || this.getLocale(), options); + } + }, { + key: 'tr', + value: function tr(key, options) { + var fullOptions = this.globalVars; + + if (options !== undefined) { + fullOptions = _Object$assign(_Object$assign({}, this.globalVars), options); + } + + return this.i18next.t(key, (0, _utils.assignObjectToKeys)('', fullOptions)); + } + }, { + key: 'registerGlobalVariable', + value: function registerGlobalVariable(key, value) { + this.globalVars[key] = value; + } + }, { + key: 'unregisterGlobalVariable', + value: function unregisterGlobalVariable(key) { + delete this.globalVars[key]; + } + }, { + key: 'updateTranslations', + value: function updateTranslations(el) { + + var i, l; + + var selector = [].concat(this.i18next.options.attributes); + for (i = 0, l = selector.length; i < l; i++) selector[i] = "[" + selector[i] + "]"; + selector = selector.join(","); + + var nodes = el.querySelectorAll(selector); + for (i = 0, l = nodes.length; i < l; i++) { + var node = nodes[i]; + var keys; + + for (var i2 = 0, l2 = this.i18next.options.attributes.length; i2 < l2; i2++) { + keys = node.getAttribute(this.i18next.options.attributes[i2]); + if (keys) break; + } + + if (!keys) continue; + + keys = keys.split(";"); + var _iteratorNormalCompletion = true; + var _didIteratorError = false; + var _iteratorError = undefined; + + try { + for (var _iterator = _getIterator(keys), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + var key = _step.value; + + var re = /\[([a-z]*)\]/g; + + var m; + var attr = "text"; + + if (node.nodeName == "IMG") attr = "src"; + + while ((m = re.exec(key)) !== null) { + if (m.index === re.lastIndex) { + re.lastIndex++; + } + if (m) { + key = key.replace(m[0], ''); + attr = m[1]; + } + } + + if (!node._textContent) node._textContent = node.textContent; + if (!node._innerHTML) node._innerHTML = node.innerHTML; + + switch (attr) { + case 'text': + node.textContent = this.tr(key); + break; + case 'prepend': + node.innerHTML = this.tr(key) + node._innerHTML.trim(); + break; + case 'append': + node.innerHTML = node._innerHTML.trim() + this.tr(key); + break; + case 'html': + node.innerHTML = this.tr(key); + break; + default: + node.setAttribute(attr, this.tr(key)); + break; + } + } + } catch (err) { + _didIteratorError = true; + _iteratorError = err; + } finally { + try { + if (!_iteratorNormalCompletion && _iterator['return']) { + _iterator['return'](); + } + } finally { + if (_didIteratorError) { + throw _iteratorError; + } + } + } + } + } + }]); + + return I18N; +})(); + +exports.I18N = I18N; \ No newline at end of file diff --git a/dist/commonjs/index.js b/dist/commonjs/index.js new file mode 100644 index 00000000..08df9e40 --- /dev/null +++ b/dist/commonjs/index.js @@ -0,0 +1,111 @@ +'use strict'; + +Object.defineProperty(exports, '__esModule', { + value: true +}); +exports.configure = configure; + +var _i18n = require('./i18n'); + +var _aureliaEventAggregator = require('aurelia-event-aggregator'); + +var _aureliaTemplating = require('aurelia-templating'); + +Object.defineProperty(exports, 'I18N', { + enumerable: true, + get: function get() { + return _i18n.I18N; + } +}); + +var _relativeTime = require('./relativeTime'); + +Object.defineProperty(exports, 'RelativeTime', { + enumerable: true, + get: function get() { + return _relativeTime.RelativeTime; + } +}); + +var _df = require('./df'); + +Object.defineProperty(exports, 'DfValueConverter', { + enumerable: true, + get: function get() { + return _df.DfValueConverter; + } +}); + +var _nf = require('./nf'); + +Object.defineProperty(exports, 'NfValueConverter', { + enumerable: true, + get: function get() { + return _nf.NfValueConverter; + } +}); + +var _rt = require('./rt'); + +Object.defineProperty(exports, 'RtValueConverter', { + enumerable: true, + get: function get() { + return _rt.RtValueConverter; + } +}); + +var _t = require('./t'); + +Object.defineProperty(exports, 'TValueConverter', { + enumerable: true, + get: function get() { + return _t.TValueConverter; + } +}); +Object.defineProperty(exports, 'TCustomAttribute', { + enumerable: true, + get: function get() { + return _t.TCustomAttribute; + } +}); + +var _baseI18n = require('./base-i18n'); + +Object.defineProperty(exports, 'BaseI18N', { + enumerable: true, + get: function get() { + return _baseI18n.BaseI18N; + } +}); +Object.defineProperty(exports, 'EventAggregator', { + enumerable: true, + get: function get() { + return _aureliaEventAggregator.EventAggregator; + } +}); + +function configure(frameworkConfig, cb) { + if (cb === undefined || typeof cb !== 'function') { + throw 'You need to provide a callback method to properly configure the library'; + } + + frameworkConfig.globalResources('./t'); + frameworkConfig.globalResources('./nf'); + frameworkConfig.globalResources('./df'); + frameworkConfig.globalResources('./rt'); + var instance = new _i18n.I18N(frameworkConfig.container.get(_aureliaEventAggregator.EventAggregator)); + frameworkConfig.container.registerInstance(_i18n.I18N, instance); + + var ret = cb(instance); + + frameworkConfig.postTask(function () { + var resources = frameworkConfig.container.get(_aureliaTemplating.ViewResources); + var htmlBehaviorResource = resources.getAttribute('t'); + + instance.i18next.options.attributes.forEach(function (alias) { + return resources.registerAttribute(alias, htmlBehaviorResource, 't'); + }); + }); + + return ret; +} \ No newline at end of file diff --git a/dist/commonjs/nf.js b/dist/commonjs/nf.js new file mode 100644 index 00000000..29153921 --- /dev/null +++ b/dist/commonjs/nf.js @@ -0,0 +1,39 @@ +'use strict'; + +var _createClass = require('babel-runtime/helpers/create-class')['default']; + +var _classCallCheck = require('babel-runtime/helpers/class-call-check')['default']; + +Object.defineProperty(exports, '__esModule', { + value: true +}); + +var _i18n = require('./i18n'); + +var NfValueConverter = (function () { + _createClass(NfValueConverter, null, [{ + key: 'inject', + value: function inject() { + return [_i18n.I18N]; + } + }]); + + function NfValueConverter(i18n) { + _classCallCheck(this, NfValueConverter); + + this.service = i18n; + } + + _createClass(NfValueConverter, [{ + key: 'toView', + value: function toView(value, formatOptions, locale, numberFormat) { + var nf = numberFormat || this.service.nf(formatOptions, locale || this.service.getLocale()); + + return nf.format(value); + } + }]); + + return NfValueConverter; +})(); + +exports.NfValueConverter = NfValueConverter; \ No newline at end of file diff --git a/dist/commonjs/relativeTime.js b/dist/commonjs/relativeTime.js new file mode 100644 index 00000000..ed1be190 --- /dev/null +++ b/dist/commonjs/relativeTime.js @@ -0,0 +1,98 @@ +'use strict'; + +var _createClass = require('babel-runtime/helpers/create-class')['default']; + +var _classCallCheck = require('babel-runtime/helpers/class-call-check')['default']; + +var _Object$keys = require('babel-runtime/core-js/object/keys')['default']; + +var _interopRequireWildcard = require('babel-runtime/helpers/interop-require-wildcard')['default']; + +Object.defineProperty(exports, '__esModule', { + value: true +}); + +var _i18n = require('./i18n'); + +var _defaultTranslationsRelativeTime = require('./defaultTranslations/relative.time'); + +var translations = _interopRequireWildcard(_defaultTranslationsRelativeTime); + +var RelativeTime = (function () { + _createClass(RelativeTime, null, [{ + key: 'inject', + value: function inject() { + return [_i18n.I18N]; + } + }]); + + function RelativeTime(i18n) { + var _this = this; + + _classCallCheck(this, RelativeTime); + + this.service = i18n; + + var trans = translations['default'] || translations; + + _Object$keys(trans).map(function (key) { + var translation = trans[key]['translation']; + var options = i18n.i18next.options; + + if (options.interpolationPrefix !== '__' || options.interpolationSuffix !== '__') { + for (var subkey in translation) { + translation[subkey] = translation[subkey].replace('__count__', options.interpolationPrefix + 'count' + options.interpolationSuffix); + } + } + + _this.service.i18next.addResources(key, 'translation', translation); + }); + } + + _createClass(RelativeTime, [{ + key: 'getRelativeTime', + value: function getRelativeTime(time) { + var now = new Date(); + var diff = now.getTime() - time.getTime(); + + var timeDiff = this.getTimeDiffDescription(diff, 'year', 31104000000); + if (!timeDiff) { + var timeDiff = this.getTimeDiffDescription(diff, 'month', 2592000000); + if (!timeDiff) { + var timeDiff = this.getTimeDiffDescription(diff, 'day', 86400000); + if (!timeDiff) { + timeDiff = this.getTimeDiffDescription(diff, 'hour', 3600000); + if (!timeDiff) { + timeDiff = this.getTimeDiffDescription(diff, 'minute', 60000); + if (!timeDiff) { + timeDiff = this.getTimeDiffDescription(diff, 'second', 1000); + if (!timeDiff) { + timeDiff = this.service.tr('now'); + } + } + } + } + } + } + + return timeDiff; + } + }, { + key: 'getTimeDiffDescription', + value: function getTimeDiffDescription(diff, unit, timeDivisor) { + var unitAmount = (diff / timeDivisor).toFixed(0); + if (unitAmount > 0) { + return this.service.tr(unit, { count: parseInt(unitAmount), context: 'ago' }); + } else if (unitAmount < 0) { + var abs = Math.abs(unitAmount); + return this.service.tr(unit, { count: abs, context: 'in' }); + } else { + return null; + } + } + }]); + + return RelativeTime; +})(); + +exports.RelativeTime = RelativeTime; \ No newline at end of file diff --git a/dist/commonjs/rt.js b/dist/commonjs/rt.js new file mode 100644 index 00000000..5406b0fe --- /dev/null +++ b/dist/commonjs/rt.js @@ -0,0 +1,37 @@ +'use strict'; + +var _createClass = require('babel-runtime/helpers/create-class')['default']; + +var _classCallCheck = require('babel-runtime/helpers/class-call-check')['default']; + +Object.defineProperty(exports, '__esModule', { + value: true +}); + +var _relativeTime = require('./relativeTime'); + +var RtValueConverter = (function () { + _createClass(RtValueConverter, null, [{ + key: 'inject', + value: function inject() { + return [_relativeTime.RelativeTime]; + } + }]); + + function RtValueConverter(relativeTime) { + _classCallCheck(this, RtValueConverter); + + this.service = relativeTime; + } + + _createClass(RtValueConverter, [{ + key: 'toView', + value: function toView(value) { + return this.service.getRelativeTime(value); + } + }]); + + return RtValueConverter; +})(); + +exports.RtValueConverter = RtValueConverter; \ No newline at end of file diff --git a/dist/commonjs/t.js b/dist/commonjs/t.js new file mode 100644 index 00000000..769a8335 --- /dev/null +++ b/dist/commonjs/t.js @@ -0,0 +1,69 @@ +'use strict'; + +var _createClass = require('babel-runtime/helpers/create-class')['default']; + +var _classCallCheck = require('babel-runtime/helpers/class-call-check')['default']; + +Object.defineProperty(exports, '__esModule', { + value: true +}); + +var _i18n = require('./i18n'); + +var _aureliaTemplating = require('aurelia-templating'); + +var TValueConverter = (function () { + _createClass(TValueConverter, null, [{ + key: 'inject', + value: function inject() { + return [_i18n.I18N]; + } + }]); + + function TValueConverter(i18n) { + _classCallCheck(this, TValueConverter); + + this.service = i18n; + } + + _createClass(TValueConverter, [{ + key: 'toView', + value: function toView(value, options) { + return this.service.tr(value, options); + } + }]); + + return TValueConverter; +})(); + +exports.TValueConverter = TValueConverter; + +var TCustomAttribute = (function () { + _createClass(TCustomAttribute, null, [{ + key: 'inject', + value: [Element, _i18n.I18N], + enumerable: true + }]); + + function TCustomAttribute(element, i18n) { + _classCallCheck(this, _TCustomAttribute); + + this.element = element; + this.service = i18n; + } + + _createClass(TCustomAttribute, [{ + key: 'valueChanged', + value: function valueChanged() { + if (this.element.parentElement !== undefined && this.element.parentElement !== null) { + this.service.updateTranslations(this.element.parentElement); + } + } + }]); + + var _TCustomAttribute = TCustomAttribute; + TCustomAttribute = (0, _aureliaTemplating.customAttribute)('t')(TCustomAttribute) || TCustomAttribute; + return TCustomAttribute; +})(); + +exports.TCustomAttribute = TCustomAttribute; \ No newline at end of file diff --git a/dist/commonjs/utils.js b/dist/commonjs/utils.js new file mode 100644 index 00000000..305b5121 --- /dev/null +++ b/dist/commonjs/utils.js @@ -0,0 +1,29 @@ +'use strict'; + +var _Object$keys = require('babel-runtime/core-js/object/keys')['default']; + +Object.defineProperty(exports, '__esModule', { + value: true +}); +var extend = function extend(destination, source) { + for (var property in source) destination[property] = source[property]; + return destination; +}; + +exports.extend = extend; +var assignObjectToKeys = function assignObjectToKeys(root, obj) { + if (obj === undefined || obj === null) return obj; + + var opts = {}; + + _Object$keys(obj).map(function (key) { + if (typeof obj[key] === 'object') { + extend(opts, assignObjectToKeys(key, obj[key])); + } else { + opts[root !== '' ? root + '.' + key : key] = obj[key]; + } + }); + + return opts; +}; +exports.assignObjectToKeys = assignObjectToKeys; \ No newline at end of file diff --git a/dist/es6/base-i18n.js b/dist/es6/base-i18n.js new file mode 100644 index 00000000..4de2c7d6 --- /dev/null +++ b/dist/es6/base-i18n.js @@ -0,0 +1,24 @@ +import {I18N} from './i18n'; +import {EventAggregator} from 'aurelia-event-aggregator'; + +export class BaseI18N { + + static inject = [I18N,Element,EventAggregator]; + + constructor(i18n,element,ea) { + this.i18n = i18n; + this.element = element; + + this.__i18nDisposer = ea.subscribe('i18n:locale:changed', payload => { + this.i18n.updateTranslations(this.element); + }); + } + + attached(){ + this.i18n.updateTranslations(this.element); + } + + detached() { + this.__i18nDisposer(); + } +} diff --git a/dist/es6/defaultTranslations/relative.time.js b/dist/es6/defaultTranslations/relative.time.js new file mode 100644 index 00000000..9f94e90f --- /dev/null +++ b/dist/es6/defaultTranslations/relative.time.js @@ -0,0 +1,228 @@ +export default { + ar: { + translation: { + "now": "الآن", + "second_ago": "منذ __count__ ثانية", + "second_ago_plural": "منذ __count__ ثواني", + "second_in": "في __count__ ثانية", + "second_in_plural": "في __count__ ثواني", + "minute_ago": "منذ __count__ دقيقة", + "minute_ago_plural": "منذ __count__ دقائق", + "minute_in": "في __count__ دقيقة", + "minute_in_plural": "في __count__ دقائق", + "hour_ago": "منذ __count__ ساعة", + "hour_ago_plural": "منذ __count__ ساعات", + "hour_in": "في __count__ ساعة", + "hour_in_plural": "في __count__ ساعات", + "day_ago": "منذ __count__ يوم", + "day_ago_plural": "منذ __count__ أيام", + "day_in": "في __count__ يوم", + "day_in_plural": "في __count__ أيام" + } + }, + en: { + translation: { + "now": "just now", + "second_ago": "__count__ second ago", + "second_ago_plural": "__count__ seconds ago", + "second_in": "in __count__ second", + "second_in_plural": "in __count__ seconds", + "minute_ago": "__count__ minute ago", + "minute_ago_plural": "__count__ minutes ago", + "minute_in": "in __count__ minute", + "minute_in_plural": "in __count__ minutes", + "hour_ago": "__count__ hour ago", + "hour_ago_plural": "__count__ hours ago", + "hour_in": "in __count__ hour", + "hour_in_plural": "in __count__ hours", + "day_ago": "__count__ day ago", + "day_ago_plural": "__count__ days ago", + "day_in": "in __count__ day", + "day_in_plural": "in __count__ days", + "month_ago": "__count__ month ago", + "month_ago_plural": "__count__ months ago", + "month_in": "in __count__ month", + "month_in_plural": "in __count__ months", + "year_ago": "__count__ year ago", + "year_ago_plural": "__count__ years ago", + "year_in": "in __count__ year", + "year_in_plural": "in __count__ years" + } + }, + de: { + translation: { + "now": "jetzt gerade", + "second_ago": "vor __count__ Sekunde", + "second_ago_plural": "vor __count__ Sekunden", + "second_in": "in __count__ Sekunde", + "second_in_plural": "in __count__ Sekunden", + "minute_ago": "vor __count__ Minute", + "minute_ago_plural": "vor __count__ Minuten", + "minute_in": "in __count__ Minute", + "minute_in_plural": "in __count__ Minuten", + "hour_ago": "vor __count__ Stunde", + "hour_ago_plural": "vor __count__ Stunden", + "hour_in": "in __count__ Stunde", + "hour_in_plural": "in __count__ Stunden", + "day_ago": "vor __count__ Tag", + "day_ago_plural": "vor __count__ Tagen", + "day_in": "in __count__ Tag", + "day_in_plural": "in __count__ Tagen", + "month_ago": "vor __count__ Monat", + "month_ago_plural": "vor __count__ Monaten", + "month_in": "in __count__ Monat", + "month_in_plural": "in __count__ Monaten", + "year_ago": "vor __count__ Jahr", + "year_ago_plural": "vor __count__ Jahren", + "year_in": "in __count__ Jahr", + "year_in_plural": "in __count__ Jahren" + } + }, + nl: { + translation: { + "now": "zonet", + "second_ago": "__count__ seconde geleden", + "second_ago_plural": "__count__ seconden geleden", + "second_in": "in __count__ seconde", + "second_in_plural": "in __count__ seconden", + "minute_ago": "__count__ minuut geleden", + "minute_ago_plural": "__count__ minuten geleden", + "minute_in": "in __count__ minuut", + "minute_in_plural": "in __count__ minuten", + "hour_ago": "__count__ uur geleden", + "hour_ago_plural": "__count__ uren geleden", + "hour_in": "in __count__ uur", + "hour_in_plural": "in __count__ uren", + "day_ago": "__count__ dag geleden", + "day_ago_plural": "__count__ dagen geleden", + "day_in": "in __count__ dag", + "day_in_plural": "in __count__ dagen" + } + }, + fr: { + translation: { + "now": "juste", + "second_ago": "__count__ seconde passé", + "second_ago_plural": "__count__ secondes passé", + "second_in": "en __count__ seconde", + "second_in_plural": "en __count__ secondes", + "minute_ago": "__count__ minute passé", + "minute_ago_plural": "__count__ minutes passé", + "minute_in": "en __count__ minute", + "minute_in_plural": "en __count__ minutes", + "hour_ago": "__count__ heure passé", + "hour_ago_plural": "__count__ heures passé", + "hour_in": "en __count__ heure", + "hour_in_plural": "en __count__ heures", + "day_ago": "__count__ jour passé", + "day_ago_plural": "__count__ jours passé", + "day_in": "en __count__ jour", + "day_in_plural": "en __count__ jours" + } + }, + th: { + translation: { + "now": "เมื่อกี้", + "second_ago": "__count__ วินาที ที่ผ่านมา", + "second_ago_plural": "__count__ วินาที ที่ผ่านมา", + "second_in": "อีก __count__ วินาที", + "second_in_plural": "อีก __count__ วินาที", + "minute_ago": "__count__ นาที ที่ผ่านมา", + "minute_ago_plural": "__count__ นาที ที่ผ่านมา", + "minute_in": "อีก __count__ นาที", + "minute_in_plural": "อีก __count__ นาที", + "hour_ago": "__count__ ชั่วโมง ที่ผ่านมา", + "hour_ago_plural": "__count__ ชั่วโมง ที่ผ่านมา", + "hour_in": "อีก __count__ ชั่วโมง", + "hour_in_plural": "อีก __count__ ชั่วโมง", + "day_ago": "__count__ วัน ที่ผ่านมา", + "day_ago_plural": "__count__ วัน ที่ผ่านมา", + "day_in": "อีก __count__ วัน", + "day_in_plural": "อีก __count__ วัน" + } + }, + sv: { + translation: { + "now": "just nu", + "second_ago": "__count__ sekund sedan", + "second_ago_plural": "__count__ sekunder sedan", + "second_in": "om __count__ sekund", + "second_in_plural": "om __count__ sekunder", + "minute_ago": "__count__ minut sedan", + "minute_ago_plural": "__count__ minuter sedan", + "minute_in": "om __count__ minut", + "minute_in_plural": "om __count__ minuter", + "hour_ago": "__count__ timme sedan", + "hour_ago_plural": "__count__ timmar sedan", + "hour_in": "om __count__ timme", + "hour_in_plural": "om __count__ timmar", + "day_ago": "__count__ dag sedan", + "day_ago_plural": "__count__ dagar sedan", + "day_in": "om __count__ dag", + "day_in_plural": "om __count__ dagar" + } + }, + da: { + translation: { + "now": "lige nu", + "second_ago": "__count__ sekunder siden", + "second_ago_plural": "__count__ sekunder siden", + "second_in": "om __count__ sekund", + "second_in_plural": "om __count__ sekunder", + "minute_ago": "__count__ minut siden", + "minute_ago_plural": "__count__ minutter siden", + "minute_in": "om __count__ minut", + "minute_in_plural": "om __count__ minutter", + "hour_ago": "__count__ time siden", + "hour_ago_plural": "__count__ timer siden", + "hour_in": "om __count__ time", + "hour_in_plural": "om __count__ timer", + "day_ago": "__count__ dag siden", + "day_ago_plural": "__count__ dage siden", + "day_in": "om __count__ dag", + "day_in_plural": "om __count__ dage" + } + }, + no: { + translation: { + "now": "akkurat nå", + "second_ago": "__count__ sekund siden", + "second_ago_plural": "__count__ sekunder siden", + "second_in": "om __count__ sekund", + "second_in_plural": "om __count__ sekunder", + "minute_ago": "__count__ minutt siden", + "minute_ago_plural": "__count__ minutter siden", + "minute_in": "om __count__ minutt", + "minute_in_plural": "om __count__ minutter", + "hour_ago": "__count__ time siden", + "hour_ago_plural": "__count__ timer siden", + "hour_in": "om __count__ time", + "hour_in_plural": "om __count__ timer", + "day_ago": "__count__ dag siden", + "day_ago_plural": "__count__ dager siden", + "day_in": "om __count__ dag", + "day_in_plural": "om __count__ dager" + } + }, + jp: { + translation: { + "now": "たった今", + "second_ago": "__count__ 秒前", + "second_ago_plural": "__count__ 秒前", + "second_in": "あと __count__ 秒", + "second_in_plural": "あと __count__ 秒", + "minute_ago": "__count__ 分前", + "minute_ago_plural": "__count__ 分前", + "minute_in": "あと __count__ 分", + "minute_in_plural": "あと __count__ 分", + "hour_ago": "__count__ 時間前", + "hour_ago_plural": "__count__ 時間前", + "hour_in": "あと __count__ 時間", + "hour_in_plural": "あと __count__ 時間", + "day_ago": "__count__ 日間前", + "day_ago_plural": "__count__ 日間前", + "day_in": "あと __count__ 日間", + "day_in_plural": "あと __count__ 日間" + } + } +}; diff --git a/dist/es6/df.js b/dist/es6/df.js new file mode 100644 index 00000000..003b88bf --- /dev/null +++ b/dist/es6/df.js @@ -0,0 +1,14 @@ +import {I18N} from './i18n'; + +export class DfValueConverter { + static inject() { return [I18N]; } + constructor(i18n) { + this.service = i18n; + } + + toView(value, formatOptions, locale, dateFormat) { + var df = dateFormat || this.service.df(formatOptions, locale || this.service.getLocale()); + + return df.format(value); + } +} diff --git a/dist/es6/i18n.js b/dist/es6/i18n.js new file mode 100644 index 00000000..ecf48931 --- /dev/null +++ b/dist/es6/i18n.js @@ -0,0 +1,158 @@ +import i18n from 'i18next'; +import {assignObjectToKeys} from './utils'; + +export class I18N { + + globalVars = {}; + + constructor(ea) { + this.i18next = i18n; + this.ea = ea; + this.Intl = window.Intl; + + // check whether Intl is available, otherwise load the polyfill + if(window.Intl === undefined) { + System.import('Intl').then( (poly) => { + window.Intl = poly; + }); + } + } + + setup(options) { + var defaultOptions = { + resGetPath : 'locale/__lng__/__ns__.json', + lng : 'en', + getAsync : false, + sendMissing : false, + attributes : ['t','i18n'], //attributes that will be searched for when searching for keys the html + fallbackLng : 'en', + debug : false + }; + + i18n.init(options || defaultOptions); + + //make sure attributes is an array in case a string was provided + if(i18n.options.attributes instanceof String) { + i18n.options.attributes = [i18n.options.attributes]; + } + } + + setLocale(locale) { + return new Promise( resolve => { + var oldLocale = this.getLocale(); + this.i18next.setLng(locale, tr=>{ + this.ea.publish("i18n:locale:changed", { oldValue:oldLocale, newValue:locale }); + resolve(tr); + }); + }); + } + + getLocale() { + return this.i18next.lng(); + } + + nf(options, locales) { + return new this.Intl.NumberFormat(locales || this.getLocale(), options); + } + + df(options, locales) { + return new this.Intl.DateTimeFormat(locales || this.getLocale(), options); + } + + tr(key, options) { + let fullOptions = this.globalVars; + + if(options !== undefined) { + fullOptions = Object.assign(Object.assign({}, this.globalVars), options); + } + + return this.i18next.t(key, assignObjectToKeys('', fullOptions)); + } + + registerGlobalVariable(key, value) { + this.globalVars[key] = value; + } + + unregisterGlobalVariable(key) { + delete this.globalVars[key]; + } + + /** + * Scans an element for children that have a translation attribute and + * updates their innerHTML with the current translation values. + * + * If an image is encountered the translated value will be applied to the src attribute. + * + * @param el HTMLElement to search within + */ + updateTranslations(el){ + + var i,l; + + //create a selector from the specified attributes to look for + //var selector = [].concat(this.i18next.options.attributes); + var selector = [].concat(this.i18next.options.attributes); + for(i = 0, l = selector.length; i < l; i++) selector[i] = "["+selector[i]+"]"; + selector = selector.join(","); + + //get the nodes + var nodes = el.querySelectorAll(selector); + for(i = 0, l = nodes.length; i < l; i++){ + var node = nodes[i]; + var keys; + //test every attribute and get the first one that has a value + for(var i2 = 0, l2 = this.i18next.options.attributes.length; i2 < l2; i2++){ + keys = node.getAttribute(this.i18next.options.attributes[i2]); + if(keys) break; + } + //skip if nothing was found + if(!keys) continue; + + //split the keys into multiple keys separated by a ; + keys = keys.split(";"); + for(let key of keys){ + // remove the optional attribute + var re = /\[([a-z]*)\]/g; + + var m; + var attr = "text"; + //set default attribute to src if this is an image node + if(node.nodeName=="IMG") attr = "src"; + + //check if a attribute was specified in the key + while ((m = re.exec(key)) !== null) { + if (m.index === re.lastIndex) { + re.lastIndex++; + } + if(m){ + key = key.replace(m[0],''); + attr = m[1]; + } + } + + if(!node._textContent) node._textContent = node.textContent; + if(!node._innerHTML) node._innerHTML = node.innerHTML; + + //handle various attributes + //anything other than text,prepend,append or html will be added as an attribute on the element. + switch(attr){ + case 'text': + node.textContent = this.tr(key); + break; + case 'prepend': + node.innerHTML = this.tr(key) + node._innerHTML.trim(); + break; + case 'append': + node.innerHTML = node._innerHTML.trim() + this.tr(key); + break; + case 'html': + node.innerHTML = this.tr(key); + break; + default: //normal html attribute + node.setAttribute(attr, this.tr(key)); + break; + } + } + } + } +} diff --git a/dist/es6/index.js b/dist/es6/index.js new file mode 100644 index 00000000..322e813f --- /dev/null +++ b/dist/es6/index.js @@ -0,0 +1,37 @@ +import {I18N} from './i18n'; +import {EventAggregator} from 'aurelia-event-aggregator'; +import {ViewResources} from 'aurelia-templating'; + +export {I18N} from './i18n'; +export {RelativeTime} from './relativeTime'; +export {DfValueConverter} from './df'; +export {NfValueConverter} from './nf'; +export {RtValueConverter} from './rt'; +export {TValueConverter} from './t'; +export {TCustomAttribute} from './t'; +export {BaseI18N} from './base-i18n' +export {EventAggregator} from 'aurelia-event-aggregator'; + +export function configure(frameworkConfig, cb){ + if(cb === undefined || typeof cb !== 'function') { + throw 'You need to provide a callback method to properly configure the library'; + } + + frameworkConfig.globalResources('./t'); + frameworkConfig.globalResources('./nf'); + frameworkConfig.globalResources('./df'); + frameworkConfig.globalResources('./rt'); + var instance = new I18N(frameworkConfig.container.get(EventAggregator)); + frameworkConfig.container.registerInstance(I18N, instance); + + var ret = cb(instance); + + frameworkConfig.postTask(() => { + let resources = frameworkConfig.container.get(ViewResources); + let htmlBehaviorResource = resources.getAttribute('t'); + + instance.i18next.options.attributes.forEach(alias => resources.registerAttribute(alias, htmlBehaviorResource, 't')); + }); + + return ret; +} diff --git a/dist/es6/nf.js b/dist/es6/nf.js new file mode 100644 index 00000000..3d690c2f --- /dev/null +++ b/dist/es6/nf.js @@ -0,0 +1,14 @@ +import {I18N} from './i18n'; + +export class NfValueConverter { + static inject() { return [I18N]; } + constructor(i18n) { + this.service = i18n; + } + + toView(value, formatOptions, locale, numberFormat) { + var nf = numberFormat || this.service.nf(formatOptions, locale || this.service.getLocale()); + + return nf.format(value); + } +} diff --git a/dist/es6/relativeTime.js b/dist/es6/relativeTime.js new file mode 100644 index 00000000..697f0989 --- /dev/null +++ b/dist/es6/relativeTime.js @@ -0,0 +1,65 @@ +import {I18N} from './i18n'; +import * as translations from './defaultTranslations/relative.time'; + +export class RelativeTime { + static inject() { return [I18N]; } + constructor(i18n) { + this.service = i18n; + + let trans = translations.default || translations; + + Object.keys(trans).map( (key) => { + let translation = trans[key]['translation']; + let options = i18n.i18next.options; + + if(options.interpolationPrefix !== '__' || options.interpolationSuffix !== '__') { + for(let subkey in translation) { + translation[subkey] = translation[subkey].replace('__count__', options.interpolationPrefix + 'count' + options.interpolationSuffix); + } + } + + this.service.i18next.addResources(key, 'translation', translation); + }); + } + + getRelativeTime(time) + { + var now = new Date(); + var diff = now.getTime() - time.getTime(); + + var timeDiff = this.getTimeDiffDescription(diff, 'year', 31104000000); + if (!timeDiff) { + var timeDiff = this.getTimeDiffDescription(diff, 'month', 2592000000); + if (!timeDiff) { + var timeDiff = this.getTimeDiffDescription(diff, 'day', 86400000); + if (!timeDiff) { + timeDiff = this.getTimeDiffDescription(diff, 'hour', 3600000); + if (!timeDiff) { + timeDiff = this.getTimeDiffDescription(diff, 'minute', 60000); + if (!timeDiff) { + timeDiff = this.getTimeDiffDescription(diff, 'second', 1000); + if (!timeDiff) { + timeDiff = this.service.tr('now'); + } + } + } + } + } + } + + return timeDiff; + } + + getTimeDiffDescription(diff, unit, timeDivisor) + { + var unitAmount = (diff / timeDivisor).toFixed(0); + if (unitAmount > 0) { + return this.service.tr(unit, { count: parseInt(unitAmount), context: 'ago' }); + } else if (unitAmount < 0) { + var abs = Math.abs(unitAmount); + return this.service.tr(unit, { count: abs, context: 'in'}); + } else { + return null; + } + } +} diff --git a/dist/es6/rt.js b/dist/es6/rt.js new file mode 100644 index 00000000..7977a112 --- /dev/null +++ b/dist/es6/rt.js @@ -0,0 +1,12 @@ +import {RelativeTime} from './relativeTime'; + +export class RtValueConverter { + static inject() { return [RelativeTime]; } + constructor(relativeTime) { + this.service = relativeTime; + } + + toView(value) { + return this.service.getRelativeTime(value); + } +} diff --git a/dist/es6/t.js b/dist/es6/t.js new file mode 100644 index 00000000..f9254c3c --- /dev/null +++ b/dist/es6/t.js @@ -0,0 +1,31 @@ +import {I18N} from './i18n'; +import {customAttribute} from 'aurelia-templating'; + + +export class TValueConverter { + static inject() { return [I18N]; } + constructor(i18n) { + this.service = i18n; + } + + toView(value, options) { + return this.service.tr(value, options); + } +} + +@customAttribute('t') +export class TCustomAttribute { + + static inject = [Element, I18N]; + + constructor(element, i18n) { + this.element = element; + this.service = i18n; + } + + valueChanged(){ + if(this.element.parentElement !== undefined && this.element.parentElement !== null) { + this.service.updateTranslations(this.element.parentElement); + } + } +} diff --git a/dist/es6/utils.js b/dist/es6/utils.js new file mode 100644 index 00000000..a73d41c2 --- /dev/null +++ b/dist/es6/utils.js @@ -0,0 +1,22 @@ +export var extend = (destination,source) => { + for (var property in source) + destination[property] = source[property]; + return destination; +}; + +export var assignObjectToKeys = (root, obj) => { + if(obj === undefined || obj === null) + return obj; + + var opts = {}; + + Object.keys(obj).map( (key) => { + if(typeof obj[key] === 'object') { + extend(opts, assignObjectToKeys(key, obj[key])); + } else { + opts[root !== '' ? root + '.' + key : key] = obj[key]; + } + }); + + return opts; +}; diff --git a/dist/system/base-i18n.js b/dist/system/base-i18n.js new file mode 100644 index 00000000..3e732cc9 --- /dev/null +++ b/dist/system/base-i18n.js @@ -0,0 +1,55 @@ +System.register(['babel-runtime/helpers/create-class', 'babel-runtime/helpers/class-call-check', './i18n', 'aurelia-event-aggregator'], function (_export) { + var _createClass, _classCallCheck, I18N, EventAggregator, BaseI18N; + + return { + setters: [function (_babelRuntimeHelpersCreateClass) { + _createClass = _babelRuntimeHelpersCreateClass['default']; + }, function (_babelRuntimeHelpersClassCallCheck) { + _classCallCheck = _babelRuntimeHelpersClassCallCheck['default']; + }, function (_i18n) { + I18N = _i18n.I18N; + }, function (_aureliaEventAggregator) { + EventAggregator = _aureliaEventAggregator.EventAggregator; + }], + execute: function () { + 'use strict'; + + BaseI18N = (function () { + _createClass(BaseI18N, null, [{ + key: 'inject', + value: [I18N, Element, EventAggregator], + enumerable: true + }]); + + function BaseI18N(i18n, element, ea) { + var _this = this; + + _classCallCheck(this, BaseI18N); + + this.i18n = i18n; + this.element = element; + + this.__i18nDisposer = ea.subscribe('i18n:locale:changed', function (payload) { + _this.i18n.updateTranslations(_this.element); + }); + } + + _createClass(BaseI18N, [{ + key: 'attached', + value: function attached() { + this.i18n.updateTranslations(this.element); + } + }, { + key: 'detached', + value: function detached() { + this.__i18nDisposer(); + } + }]); + + return BaseI18N; + })(); + + _export('BaseI18N', BaseI18N); + } + }; +}); \ No newline at end of file diff --git a/dist/system/defaultTranslations/relative.time.js b/dist/system/defaultTranslations/relative.time.js new file mode 100644 index 00000000..a1344773 --- /dev/null +++ b/dist/system/defaultTranslations/relative.time.js @@ -0,0 +1,237 @@ +System.register([], function (_export) { + "use strict"; + + return { + setters: [], + execute: function () { + _export("default", { + ar: { + translation: { + "now": "الآن", + "second_ago": "منذ __count__ ثانية", + "second_ago_plural": "منذ __count__ ثواني", + "second_in": "في __count__ ثانية", + "second_in_plural": "في __count__ ثواني", + "minute_ago": "منذ __count__ دقيقة", + "minute_ago_plural": "منذ __count__ دقائق", + "minute_in": "في __count__ دقيقة", + "minute_in_plural": "في __count__ دقائق", + "hour_ago": "منذ __count__ ساعة", + "hour_ago_plural": "منذ __count__ ساعات", + "hour_in": "في __count__ ساعة", + "hour_in_plural": "في __count__ ساعات", + "day_ago": "منذ __count__ يوم", + "day_ago_plural": "منذ __count__ أيام", + "day_in": "في __count__ يوم", + "day_in_plural": "في __count__ أيام" + } + }, + en: { + translation: { + "now": "just now", + "second_ago": "__count__ second ago", + "second_ago_plural": "__count__ seconds ago", + "second_in": "in __count__ second", + "second_in_plural": "in __count__ seconds", + "minute_ago": "__count__ minute ago", + "minute_ago_plural": "__count__ minutes ago", + "minute_in": "in __count__ minute", + "minute_in_plural": "in __count__ minutes", + "hour_ago": "__count__ hour ago", + "hour_ago_plural": "__count__ hours ago", + "hour_in": "in __count__ hour", + "hour_in_plural": "in __count__ hours", + "day_ago": "__count__ day ago", + "day_ago_plural": "__count__ days ago", + "day_in": "in __count__ day", + "day_in_plural": "in __count__ days", + "month_ago": "__count__ month ago", + "month_ago_plural": "__count__ months ago", + "month_in": "in __count__ month", + "month_in_plural": "in __count__ months", + "year_ago": "__count__ year ago", + "year_ago_plural": "__count__ years ago", + "year_in": "in __count__ year", + "year_in_plural": "in __count__ years" + } + }, + de: { + translation: { + "now": "jetzt gerade", + "second_ago": "vor __count__ Sekunde", + "second_ago_plural": "vor __count__ Sekunden", + "second_in": "in __count__ Sekunde", + "second_in_plural": "in __count__ Sekunden", + "minute_ago": "vor __count__ Minute", + "minute_ago_plural": "vor __count__ Minuten", + "minute_in": "in __count__ Minute", + "minute_in_plural": "in __count__ Minuten", + "hour_ago": "vor __count__ Stunde", + "hour_ago_plural": "vor __count__ Stunden", + "hour_in": "in __count__ Stunde", + "hour_in_plural": "in __count__ Stunden", + "day_ago": "vor __count__ Tag", + "day_ago_plural": "vor __count__ Tagen", + "day_in": "in __count__ Tag", + "day_in_plural": "in __count__ Tagen", + "month_ago": "vor __count__ Monat", + "month_ago_plural": "vor __count__ Monaten", + "month_in": "in __count__ Monat", + "month_in_plural": "in __count__ Monaten", + "year_ago": "vor __count__ Jahr", + "year_ago_plural": "vor __count__ Jahren", + "year_in": "in __count__ Jahr", + "year_in_plural": "in __count__ Jahren" + } + }, + nl: { + translation: { + "now": "zonet", + "second_ago": "__count__ seconde geleden", + "second_ago_plural": "__count__ seconden geleden", + "second_in": "in __count__ seconde", + "second_in_plural": "in __count__ seconden", + "minute_ago": "__count__ minuut geleden", + "minute_ago_plural": "__count__ minuten geleden", + "minute_in": "in __count__ minuut", + "minute_in_plural": "in __count__ minuten", + "hour_ago": "__count__ uur geleden", + "hour_ago_plural": "__count__ uren geleden", + "hour_in": "in __count__ uur", + "hour_in_plural": "in __count__ uren", + "day_ago": "__count__ dag geleden", + "day_ago_plural": "__count__ dagen geleden", + "day_in": "in __count__ dag", + "day_in_plural": "in __count__ dagen" + } + }, + fr: { + translation: { + "now": "juste", + "second_ago": "__count__ seconde passé", + "second_ago_plural": "__count__ secondes passé", + "second_in": "en __count__ seconde", + "second_in_plural": "en __count__ secondes", + "minute_ago": "__count__ minute passé", + "minute_ago_plural": "__count__ minutes passé", + "minute_in": "en __count__ minute", + "minute_in_plural": "en __count__ minutes", + "hour_ago": "__count__ heure passé", + "hour_ago_plural": "__count__ heures passé", + "hour_in": "en __count__ heure", + "hour_in_plural": "en __count__ heures", + "day_ago": "__count__ jour passé", + "day_ago_plural": "__count__ jours passé", + "day_in": "en __count__ jour", + "day_in_plural": "en __count__ jours" + } + }, + th: { + translation: { + "now": "เมื่อกี้", + "second_ago": "__count__ วินาที ที่ผ่านมา", + "second_ago_plural": "__count__ วินาที ที่ผ่านมา", + "second_in": "อีก __count__ วินาที", + "second_in_plural": "อีก __count__ วินาที", + "minute_ago": "__count__ นาที ที่ผ่านมา", + "minute_ago_plural": "__count__ นาที ที่ผ่านมา", + "minute_in": "อีก __count__ นาที", + "minute_in_plural": "อีก __count__ นาที", + "hour_ago": "__count__ ชั่วโมง ที่ผ่านมา", + "hour_ago_plural": "__count__ ชั่วโมง ที่ผ่านมา", + "hour_in": "อีก __count__ ชั่วโมง", + "hour_in_plural": "อีก __count__ ชั่วโมง", + "day_ago": "__count__ วัน ที่ผ่านมา", + "day_ago_plural": "__count__ วัน ที่ผ่านมา", + "day_in": "อีก __count__ วัน", + "day_in_plural": "อีก __count__ วัน" + } + }, + sv: { + translation: { + "now": "just nu", + "second_ago": "__count__ sekund sedan", + "second_ago_plural": "__count__ sekunder sedan", + "second_in": "om __count__ sekund", + "second_in_plural": "om __count__ sekunder", + "minute_ago": "__count__ minut sedan", + "minute_ago_plural": "__count__ minuter sedan", + "minute_in": "om __count__ minut", + "minute_in_plural": "om __count__ minuter", + "hour_ago": "__count__ timme sedan", + "hour_ago_plural": "__count__ timmar sedan", + "hour_in": "om __count__ timme", + "hour_in_plural": "om __count__ timmar", + "day_ago": "__count__ dag sedan", + "day_ago_plural": "__count__ dagar sedan", + "day_in": "om __count__ dag", + "day_in_plural": "om __count__ dagar" + } + }, + da: { + translation: { + "now": "lige nu", + "second_ago": "__count__ sekunder siden", + "second_ago_plural": "__count__ sekunder siden", + "second_in": "om __count__ sekund", + "second_in_plural": "om __count__ sekunder", + "minute_ago": "__count__ minut siden", + "minute_ago_plural": "__count__ minutter siden", + "minute_in": "om __count__ minut", + "minute_in_plural": "om __count__ minutter", + "hour_ago": "__count__ time siden", + "hour_ago_plural": "__count__ timer siden", + "hour_in": "om __count__ time", + "hour_in_plural": "om __count__ timer", + "day_ago": "__count__ dag siden", + "day_ago_plural": "__count__ dage siden", + "day_in": "om __count__ dag", + "day_in_plural": "om __count__ dage" + } + }, + no: { + translation: { + "now": "akkurat nå", + "second_ago": "__count__ sekund siden", + "second_ago_plural": "__count__ sekunder siden", + "second_in": "om __count__ sekund", + "second_in_plural": "om __count__ sekunder", + "minute_ago": "__count__ minutt siden", + "minute_ago_plural": "__count__ minutter siden", + "minute_in": "om __count__ minutt", + "minute_in_plural": "om __count__ minutter", + "hour_ago": "__count__ time siden", + "hour_ago_plural": "__count__ timer siden", + "hour_in": "om __count__ time", + "hour_in_plural": "om __count__ timer", + "day_ago": "__count__ dag siden", + "day_ago_plural": "__count__ dager siden", + "day_in": "om __count__ dag", + "day_in_plural": "om __count__ dager" + } + }, + jp: { + translation: { + "now": "たった今", + "second_ago": "__count__ 秒前", + "second_ago_plural": "__count__ 秒前", + "second_in": "あと __count__ 秒", + "second_in_plural": "あと __count__ 秒", + "minute_ago": "__count__ 分前", + "minute_ago_plural": "__count__ 分前", + "minute_in": "あと __count__ 分", + "minute_in_plural": "あと __count__ 分", + "hour_ago": "__count__ 時間前", + "hour_ago_plural": "__count__ 時間前", + "hour_in": "あと __count__ 時間", + "hour_in_plural": "あと __count__ 時間", + "day_ago": "__count__ 日間前", + "day_ago_plural": "__count__ 日間前", + "day_in": "あと __count__ 日間", + "day_in_plural": "あと __count__ 日間" + } + } + }); + } + }; +}); \ No newline at end of file diff --git a/dist/system/df.js b/dist/system/df.js new file mode 100644 index 00000000..53c728ab --- /dev/null +++ b/dist/system/df.js @@ -0,0 +1,44 @@ +System.register(['babel-runtime/helpers/create-class', 'babel-runtime/helpers/class-call-check', './i18n'], function (_export) { + var _createClass, _classCallCheck, I18N, DfValueConverter; + + return { + setters: [function (_babelRuntimeHelpersCreateClass) { + _createClass = _babelRuntimeHelpersCreateClass['default']; + }, function (_babelRuntimeHelpersClassCallCheck) { + _classCallCheck = _babelRuntimeHelpersClassCallCheck['default']; + }, function (_i18n) { + I18N = _i18n.I18N; + }], + execute: function () { + 'use strict'; + + DfValueConverter = (function () { + _createClass(DfValueConverter, null, [{ + key: 'inject', + value: function inject() { + return [I18N]; + } + }]); + + function DfValueConverter(i18n) { + _classCallCheck(this, DfValueConverter); + + this.service = i18n; + } + + _createClass(DfValueConverter, [{ + key: 'toView', + value: function toView(value, formatOptions, locale, dateFormat) { + var df = dateFormat || this.service.df(formatOptions, locale || this.service.getLocale()); + + return df.format(value); + } + }]); + + return DfValueConverter; + })(); + + _export('DfValueConverter', DfValueConverter); + } + }; +}); \ No newline at end of file diff --git a/dist/system/i18n.js b/dist/system/i18n.js new file mode 100644 index 00000000..7cd18fed --- /dev/null +++ b/dist/system/i18n.js @@ -0,0 +1,201 @@ +System.register(['babel-runtime/helpers/create-class', 'babel-runtime/helpers/class-call-check', 'babel-runtime/core-js/promise', 'babel-runtime/core-js/object/assign', 'babel-runtime/core-js/get-iterator', 'i18next', './utils'], function (_export) { + var _createClass, _classCallCheck, _Promise, _Object$assign, _getIterator, i18n, assignObjectToKeys, I18N; + + return { + setters: [function (_babelRuntimeHelpersCreateClass) { + _createClass = _babelRuntimeHelpersCreateClass['default']; + }, function (_babelRuntimeHelpersClassCallCheck) { + _classCallCheck = _babelRuntimeHelpersClassCallCheck['default']; + }, function (_babelRuntimeCoreJsPromise) { + _Promise = _babelRuntimeCoreJsPromise['default']; + }, function (_babelRuntimeCoreJsObjectAssign) { + _Object$assign = _babelRuntimeCoreJsObjectAssign['default']; + }, function (_babelRuntimeCoreJsGetIterator) { + _getIterator = _babelRuntimeCoreJsGetIterator['default']; + }, function (_i18next) { + i18n = _i18next['default']; + }, function (_utils) { + assignObjectToKeys = _utils.assignObjectToKeys; + }], + execute: function () { + 'use strict'; + + I18N = (function () { + function I18N(ea) { + _classCallCheck(this, I18N); + + this.globalVars = {}; + + this.i18next = i18n; + this.ea = ea; + this.Intl = window.Intl; + + if (window.Intl === undefined) { + System['import']('Intl').then(function (poly) { + window.Intl = poly; + }); + } + } + + _createClass(I18N, [{ + key: 'setup', + value: function setup(options) { + var defaultOptions = { + resGetPath: 'locale/__lng__/__ns__.json', + lng: 'en', + getAsync: false, + sendMissing: false, + attributes: ['t', 'i18n'], + fallbackLng: 'en', + debug: false + }; + + i18n.init(options || defaultOptions); + + if (i18n.options.attributes instanceof String) { + i18n.options.attributes = [i18n.options.attributes]; + } + } + }, { + key: 'setLocale', + value: function setLocale(locale) { + var _this = this; + + return new _Promise(function (resolve) { + var oldLocale = _this.getLocale(); + _this.i18next.setLng(locale, function (tr) { + _this.ea.publish("i18n:locale:changed", { oldValue: oldLocale, newValue: locale }); + resolve(tr); + }); + }); + } + }, { + key: 'getLocale', + value: function getLocale() { + return this.i18next.lng(); + } + }, { + key: 'nf', + value: function nf(options, locales) { + return new this.Intl.NumberFormat(locales || this.getLocale(), options); + } + }, { + key: 'df', + value: function df(options, locales) { + return new this.Intl.DateTimeFormat(locales || this.getLocale(), options); + } + }, { + key: 'tr', + value: function tr(key, options) { + var fullOptions = this.globalVars; + + if (options !== undefined) { + fullOptions = _Object$assign(_Object$assign({}, this.globalVars), options); + } + + return this.i18next.t(key, assignObjectToKeys('', fullOptions)); + } + }, { + key: 'registerGlobalVariable', + value: function registerGlobalVariable(key, value) { + this.globalVars[key] = value; + } + }, { + key: 'unregisterGlobalVariable', + value: function unregisterGlobalVariable(key) { + delete this.globalVars[key]; + } + }, { + key: 'updateTranslations', + value: function updateTranslations(el) { + + var i, l; + + var selector = [].concat(this.i18next.options.attributes); + for (i = 0, l = selector.length; i < l; i++) selector[i] = "[" + selector[i] + "]"; + selector = selector.join(","); + + var nodes = el.querySelectorAll(selector); + for (i = 0, l = nodes.length; i < l; i++) { + var node = nodes[i]; + var keys; + + for (var i2 = 0, l2 = this.i18next.options.attributes.length; i2 < l2; i2++) { + keys = node.getAttribute(this.i18next.options.attributes[i2]); + if (keys) break; + } + + if (!keys) continue; + + keys = keys.split(";"); + var _iteratorNormalCompletion = true; + var _didIteratorError = false; + var _iteratorError = undefined; + + try { + for (var _iterator = _getIterator(keys), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + var key = _step.value; + + var re = /\[([a-z]*)\]/g; + + var m; + var attr = "text"; + + if (node.nodeName == "IMG") attr = "src"; + + while ((m = re.exec(key)) !== null) { + if (m.index === re.lastIndex) { + re.lastIndex++; + } + if (m) { + key = key.replace(m[0], ''); + attr = m[1]; + } + } + + if (!node._textContent) node._textContent = node.textContent; + if (!node._innerHTML) node._innerHTML = node.innerHTML; + + switch (attr) { + case 'text': + node.textContent = this.tr(key); + break; + case 'prepend': + node.innerHTML = this.tr(key) + node._innerHTML.trim(); + break; + case 'append': + node.innerHTML = node._innerHTML.trim() + this.tr(key); + break; + case 'html': + node.innerHTML = this.tr(key); + break; + default: + node.setAttribute(attr, this.tr(key)); + break; + } + } + } catch (err) { + _didIteratorError = true; + _iteratorError = err; + } finally { + try { + if (!_iteratorNormalCompletion && _iterator['return']) { + _iterator['return'](); + } + } finally { + if (_didIteratorError) { + throw _iteratorError; + } + } + } + } + } + }]); + + return I18N; + })(); + + _export('I18N', I18N); + } + }; +}); \ No newline at end of file diff --git a/dist/system/index.js b/dist/system/index.js new file mode 100644 index 00000000..50df13fd --- /dev/null +++ b/dist/system/index.js @@ -0,0 +1,62 @@ +System.register(['./i18n', 'aurelia-event-aggregator', 'aurelia-templating', './relativeTime', './df', './nf', './rt', './t', './base-i18n'], function (_export) { + 'use strict'; + + var I18N, EventAggregator, ViewResources; + + _export('configure', configure); + + function configure(frameworkConfig, cb) { + if (cb === undefined || typeof cb !== 'function') { + throw 'You need to provide a callback method to properly configure the library'; + } + + frameworkConfig.globalResources('./t'); + frameworkConfig.globalResources('./nf'); + frameworkConfig.globalResources('./df'); + frameworkConfig.globalResources('./rt'); + var instance = new I18N(frameworkConfig.container.get(EventAggregator)); + frameworkConfig.container.registerInstance(I18N, instance); + + var ret = cb(instance); + + frameworkConfig.postTask(function () { + var resources = frameworkConfig.container.get(ViewResources); + var htmlBehaviorResource = resources.getAttribute('t'); + + instance.i18next.options.attributes.forEach(function (alias) { + return resources.registerAttribute(alias, htmlBehaviorResource, 't'); + }); + }); + + return ret; + } + + return { + setters: [function (_i18n) { + I18N = _i18n.I18N; + + _export('I18N', _i18n.I18N); + }, function (_aureliaEventAggregator) { + EventAggregator = _aureliaEventAggregator.EventAggregator; + + _export('EventAggregator', _aureliaEventAggregator.EventAggregator); + }, function (_aureliaTemplating) { + ViewResources = _aureliaTemplating.ViewResources; + }, function (_relativeTime) { + _export('RelativeTime', _relativeTime.RelativeTime); + }, function (_df) { + _export('DfValueConverter', _df.DfValueConverter); + }, function (_nf) { + _export('NfValueConverter', _nf.NfValueConverter); + }, function (_rt) { + _export('RtValueConverter', _rt.RtValueConverter); + }, function (_t) { + _export('TValueConverter', _t.TValueConverter); + + _export('TCustomAttribute', _t.TCustomAttribute); + }, function (_baseI18n) { + _export('BaseI18N', _baseI18n.BaseI18N); + }], + execute: function () {} + }; +}); \ No newline at end of file diff --git a/dist/system/nf.js b/dist/system/nf.js new file mode 100644 index 00000000..7c5c4d7b --- /dev/null +++ b/dist/system/nf.js @@ -0,0 +1,44 @@ +System.register(['babel-runtime/helpers/create-class', 'babel-runtime/helpers/class-call-check', './i18n'], function (_export) { + var _createClass, _classCallCheck, I18N, NfValueConverter; + + return { + setters: [function (_babelRuntimeHelpersCreateClass) { + _createClass = _babelRuntimeHelpersCreateClass['default']; + }, function (_babelRuntimeHelpersClassCallCheck) { + _classCallCheck = _babelRuntimeHelpersClassCallCheck['default']; + }, function (_i18n) { + I18N = _i18n.I18N; + }], + execute: function () { + 'use strict'; + + NfValueConverter = (function () { + _createClass(NfValueConverter, null, [{ + key: 'inject', + value: function inject() { + return [I18N]; + } + }]); + + function NfValueConverter(i18n) { + _classCallCheck(this, NfValueConverter); + + this.service = i18n; + } + + _createClass(NfValueConverter, [{ + key: 'toView', + value: function toView(value, formatOptions, locale, numberFormat) { + var nf = numberFormat || this.service.nf(formatOptions, locale || this.service.getLocale()); + + return nf.format(value); + } + }]); + + return NfValueConverter; + })(); + + _export('NfValueConverter', NfValueConverter); + } + }; +}); \ No newline at end of file diff --git a/dist/system/relativeTime.js b/dist/system/relativeTime.js new file mode 100644 index 00000000..f8dcce57 --- /dev/null +++ b/dist/system/relativeTime.js @@ -0,0 +1,99 @@ +System.register(['babel-runtime/helpers/create-class', 'babel-runtime/helpers/class-call-check', 'babel-runtime/core-js/object/keys', './i18n', './defaultTranslations/relative.time'], function (_export) { + var _createClass, _classCallCheck, _Object$keys, I18N, translations, RelativeTime; + + return { + setters: [function (_babelRuntimeHelpersCreateClass) { + _createClass = _babelRuntimeHelpersCreateClass['default']; + }, function (_babelRuntimeHelpersClassCallCheck) { + _classCallCheck = _babelRuntimeHelpersClassCallCheck['default']; + }, function (_babelRuntimeCoreJsObjectKeys) { + _Object$keys = _babelRuntimeCoreJsObjectKeys['default']; + }, function (_i18n) { + I18N = _i18n.I18N; + }, function (_defaultTranslationsRelativeTime) { + translations = _defaultTranslationsRelativeTime; + }], + execute: function () { + 'use strict'; + + RelativeTime = (function () { + _createClass(RelativeTime, null, [{ + key: 'inject', + value: function inject() { + return [I18N]; + } + }]); + + function RelativeTime(i18n) { + var _this = this; + + _classCallCheck(this, RelativeTime); + + this.service = i18n; + + var trans = translations['default'] || translations; + + _Object$keys(trans).map(function (key) { + var translation = trans[key]['translation']; + var options = i18n.i18next.options; + + if (options.interpolationPrefix !== '__' || options.interpolationSuffix !== '__') { + for (var subkey in translation) { + translation[subkey] = translation[subkey].replace('__count__', options.interpolationPrefix + 'count' + options.interpolationSuffix); + } + } + + _this.service.i18next.addResources(key, 'translation', translation); + }); + } + + _createClass(RelativeTime, [{ + key: 'getRelativeTime', + value: function getRelativeTime(time) { + var now = new Date(); + var diff = now.getTime() - time.getTime(); + + var timeDiff = this.getTimeDiffDescription(diff, 'year', 31104000000); + if (!timeDiff) { + var timeDiff = this.getTimeDiffDescription(diff, 'month', 2592000000); + if (!timeDiff) { + var timeDiff = this.getTimeDiffDescription(diff, 'day', 86400000); + if (!timeDiff) { + timeDiff = this.getTimeDiffDescription(diff, 'hour', 3600000); + if (!timeDiff) { + timeDiff = this.getTimeDiffDescription(diff, 'minute', 60000); + if (!timeDiff) { + timeDiff = this.getTimeDiffDescription(diff, 'second', 1000); + if (!timeDiff) { + timeDiff = this.service.tr('now'); + } + } + } + } + } + } + + return timeDiff; + } + }, { + key: 'getTimeDiffDescription', + value: function getTimeDiffDescription(diff, unit, timeDivisor) { + var unitAmount = (diff / timeDivisor).toFixed(0); + if (unitAmount > 0) { + return this.service.tr(unit, { count: parseInt(unitAmount), context: 'ago' }); + } else if (unitAmount < 0) { + var abs = Math.abs(unitAmount); + return this.service.tr(unit, { count: abs, context: 'in' }); + } else { + return null; + } + } + }]); + + return RelativeTime; + })(); + + _export('RelativeTime', RelativeTime); + } + }; +}); \ No newline at end of file diff --git a/dist/system/rt.js b/dist/system/rt.js new file mode 100644 index 00000000..59a9fcd4 --- /dev/null +++ b/dist/system/rt.js @@ -0,0 +1,42 @@ +System.register(['babel-runtime/helpers/create-class', 'babel-runtime/helpers/class-call-check', './relativeTime'], function (_export) { + var _createClass, _classCallCheck, RelativeTime, RtValueConverter; + + return { + setters: [function (_babelRuntimeHelpersCreateClass) { + _createClass = _babelRuntimeHelpersCreateClass['default']; + }, function (_babelRuntimeHelpersClassCallCheck) { + _classCallCheck = _babelRuntimeHelpersClassCallCheck['default']; + }, function (_relativeTime) { + RelativeTime = _relativeTime.RelativeTime; + }], + execute: function () { + 'use strict'; + + RtValueConverter = (function () { + _createClass(RtValueConverter, null, [{ + key: 'inject', + value: function inject() { + return [RelativeTime]; + } + }]); + + function RtValueConverter(relativeTime) { + _classCallCheck(this, RtValueConverter); + + this.service = relativeTime; + } + + _createClass(RtValueConverter, [{ + key: 'toView', + value: function toView(value) { + return this.service.getRelativeTime(value); + } + }]); + + return RtValueConverter; + })(); + + _export('RtValueConverter', RtValueConverter); + } + }; +}); \ No newline at end of file diff --git a/dist/system/t.js b/dist/system/t.js new file mode 100644 index 00000000..df08d9db --- /dev/null +++ b/dist/system/t.js @@ -0,0 +1,74 @@ +System.register(['babel-runtime/helpers/create-class', 'babel-runtime/helpers/class-call-check', './i18n', 'aurelia-templating'], function (_export) { + var _createClass, _classCallCheck, I18N, customAttribute, TValueConverter, TCustomAttribute; + + return { + setters: [function (_babelRuntimeHelpersCreateClass) { + _createClass = _babelRuntimeHelpersCreateClass['default']; + }, function (_babelRuntimeHelpersClassCallCheck) { + _classCallCheck = _babelRuntimeHelpersClassCallCheck['default']; + }, function (_i18n) { + I18N = _i18n.I18N; + }, function (_aureliaTemplating) { + customAttribute = _aureliaTemplating.customAttribute; + }], + execute: function () { + 'use strict'; + + TValueConverter = (function () { + _createClass(TValueConverter, null, [{ + key: 'inject', + value: function inject() { + return [I18N]; + } + }]); + + function TValueConverter(i18n) { + _classCallCheck(this, TValueConverter); + + this.service = i18n; + } + + _createClass(TValueConverter, [{ + key: 'toView', + value: function toView(value, options) { + return this.service.tr(value, options); + } + }]); + + return TValueConverter; + })(); + + _export('TValueConverter', TValueConverter); + + TCustomAttribute = (function () { + _createClass(TCustomAttribute, null, [{ + key: 'inject', + value: [Element, I18N], + enumerable: true + }]); + + function TCustomAttribute(element, i18n) { + _classCallCheck(this, _TCustomAttribute); + + this.element = element; + this.service = i18n; + } + + _createClass(TCustomAttribute, [{ + key: 'valueChanged', + value: function valueChanged() { + if (this.element.parentElement !== undefined && this.element.parentElement !== null) { + this.service.updateTranslations(this.element.parentElement); + } + } + }]); + + var _TCustomAttribute = TCustomAttribute; + TCustomAttribute = customAttribute('t')(TCustomAttribute) || TCustomAttribute; + return TCustomAttribute; + })(); + + _export('TCustomAttribute', TCustomAttribute); + } + }; +}); \ No newline at end of file diff --git a/dist/system/utils.js b/dist/system/utils.js new file mode 100644 index 00000000..ee667f0b --- /dev/null +++ b/dist/system/utils.js @@ -0,0 +1,37 @@ +System.register(['babel-runtime/core-js/object/keys'], function (_export) { + var _Object$keys, extend, assignObjectToKeys; + + return { + setters: [function (_babelRuntimeCoreJsObjectKeys) { + _Object$keys = _babelRuntimeCoreJsObjectKeys['default']; + }], + execute: function () { + 'use strict'; + + extend = function extend(destination, source) { + for (var property in source) destination[property] = source[property]; + return destination; + }; + + _export('extend', extend); + + assignObjectToKeys = function assignObjectToKeys(root, obj) { + if (obj === undefined || obj === null) return obj; + + var opts = {}; + + _Object$keys(obj).map(function (key) { + if (typeof obj[key] === 'object') { + extend(opts, assignObjectToKeys(key, obj[key])); + } else { + opts[root !== '' ? root + '.' + key : key] = obj[key]; + } + }); + + return opts; + }; + + _export('assignObjectToKeys', assignObjectToKeys); + } + }; +}); \ No newline at end of file diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md new file mode 100644 index 00000000..53aea7ad --- /dev/null +++ b/doc/CHANGELOG.md @@ -0,0 +1,7 @@ +### 0.1.0 (2015-08-27) + + +#### Bug Fixes + +* **attribute:** fix null check ([f14e4cc0](http://github.com/aurelia/i18n/commit/f14e4cc03eb5e3683659f7fca94d9200c70a5a8b)) + diff --git a/doc/api.json b/doc/api.json new file mode 100644 index 00000000..6de3c0a9 --- /dev/null +++ b/doc/api.json @@ -0,0 +1 @@ +{"classes":[],"methods":[],"properties":[],"events":[]} \ No newline at end of file