From 92cebd5802d3a98871070bb6fab925290e79fa0f Mon Sep 17 00:00:00 2001 From: Christoph Reiter <reiter.christoph@gmail.com> Date: Thu, 8 Aug 2019 14:11:41 +0200 Subject: [PATCH] Add a i18next wrapper --- packages/common/i18next.js | 59 +++++++++++++++++++++++++++++++++ packages/common/package.json | 3 ++ packages/common/test/i18next.js | 49 +++++++++++++++++++++++++++ packages/common/test/unit.js | 2 +- 4 files changed, 112 insertions(+), 1 deletion(-) create mode 100644 packages/common/i18next.js create mode 100644 packages/common/test/i18next.js diff --git a/packages/common/i18next.js b/packages/common/i18next.js new file mode 100644 index 00000000..7dc135f0 --- /dev/null +++ b/packages/common/i18next.js @@ -0,0 +1,59 @@ +import i18next from 'i18next'; + +/** + * Like Intl.DateTimeFormat().format() but uses the current language as locale. + * + * A i18next instance can be created with createInstance() + * + * @param {i18next.i18n} i18n - The i18next instance + * @param {Date} date - The date to format + * @param options - Options passed to Intl.DateTimeFormat + * @returns {string} + */ +export function dateTimeFormat(i18n, date, options) { + return new Intl.DateTimeFormat(i18n.languages, options).format(date); +} + +/** + * Like Intl.NumberFormat().format() but uses the current language as locale. + * + * A i18next instance can be created with createInstance() + * + * @param {i18next.i18n} i18n - The i18next instance + * @param {Number} number - The number to format + * @param {Object} options - Options passed to Intl.NumberFormat + * @returns {string} + */ +export function numberFormat(i18n, number, options) { + return new Intl.NumberFormat(i18n.languages, options).format(number); +} + +/** + * Creates a new i18next instance that is fully initialized. + * + * Call changeLanguage() on the returned object to change the language. + * + * @param {Object} languages - Mapping from languages to translation objects + * @param {string} lng - The default language + * @param {string} fallback - The fallback language to use for unknown languages or untranslated keys + * @returns {i18next.i18n} + */ +export function createInstance(languages, lng, fallback) { + var options = { + lng: lng, + fallbackLng: fallback, + debug: false, + initImmediate: false, // Don't init async + resources: {}, + }; + + Object.keys(languages).forEach(function(key) { + options['resources'][key] = {translation: languages[key]}; + }); + + var i18n = i18next.createInstance(); + i18n.init(options); + console.assert(i18n.isInitialized); + + return i18n; +} \ No newline at end of file diff --git a/packages/common/package.json b/packages/common/package.json index 6f014fd5..125be379 100644 --- a/packages/common/package.json +++ b/packages/common/package.json @@ -21,5 +21,8 @@ "build": "npm run build-local", "build-test": "rollup -c --environment BUILD:test", "test": "npm run build-test && karma start --singleRun" + }, + "dependencies": { + "i18next": "^17.0.9" } } diff --git a/packages/common/test/i18next.js b/packages/common/test/i18next.js new file mode 100644 index 00000000..d5b6512b --- /dev/null +++ b/packages/common/test/i18next.js @@ -0,0 +1,49 @@ +import * as i18next from '../i18next.js'; + +describe('i18next', () => { + it('createInstance', () => { + var inst = i18next.createInstance({de: {}}, 'de', 'en'); + assert.exists(inst); + assert.deepEqual(inst.languages, ['de', 'en']); + }); + + it('translations', () => { + var inst = i18next.createInstance({de: {foo: 'bar'}, en: {foo: 'baz', extra: 'quux'}}, 'de', 'en'); + assert.deepEqual(inst.languages, ['de', 'en']); + assert.equal( inst.t('foo'), 'bar'); + assert.equal( inst.t('nope'), 'nope'); + assert.equal( inst.t('extra'), 'quux'); + inst.changeLanguage('en'); + assert.deepEqual(inst.languages, ['en']); + assert.equal( inst.t('foo'), 'baz'); + assert.equal( inst.t('nope'), 'nope'); + inst.changeLanguage('nope'); + assert.deepEqual(inst.languages, ['nope', 'en']); + assert.equal( inst.t('foo'), 'baz'); + assert.equal( inst.t('nope'), 'nope'); + }); + + it('date format', () => { + var inst = i18next.createInstance({de: {}}, 'de', 'en'); + assert.deepEqual(inst.languages, ['de', 'en']); + + var date = new Date('1995-12-17T03:24:00'); + assert.equal(i18next.dateTimeFormat(inst, date), '17.12.1995'); + inst.changeLanguage('en'); + // TODO: not sure it's a good idea to use the english format even if english is selected because it's just confusing + assert.equal(i18next.dateTimeFormat(inst, date), '12/17/1995'); + }); + + it('number format', () => { + var inst = i18next.createInstance({de: {}}, 'de', 'en'); + assert.deepEqual(inst.languages, ['de', 'en']); + + assert.equal(i18next.numberFormat(inst, 42), '42'); + assert.equal(i18next.numberFormat(inst, 1.25), '1,25'); + assert.equal(i18next.numberFormat(inst, 1234), '1.234'); + inst.changeLanguage('en'); + assert.equal(i18next.numberFormat(inst, 42), '42'); + assert.equal(i18next.numberFormat(inst, 1.25), '1.25'); + assert.equal(i18next.numberFormat(inst, 1234), '1,234'); + }); +}); diff --git a/packages/common/test/unit.js b/packages/common/test/unit.js index a7849e10..e800730c 100644 --- a/packages/common/test/unit.js +++ b/packages/common/test/unit.js @@ -18,7 +18,7 @@ describe('utils', () => { var res = utils.defineCustomElement("test-some-element", SomeElement); expect(res).to.equal(true); - node = document.createElement('test-some-element'); + var node = document.createElement('test-some-element'); expect(node.foo).to.equal(42); }); }); -- GitLab