diff --git a/package.json b/package.json index a302bf59e3465f6d90b4a42b5797bad23c52f4ee..42030b6c9f35d1e1c4fcd6243464d99d233bf1d2 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,7 @@ "scripts": { "test": "lerna run test", "build": "lerna run build", + "i18next": "lerna run i18next", "version-patch": "lerna version patch", "version-minor": "lerna version minor", "version": "lerna version", diff --git a/packages/app-shell/i18next-scanner.config.js b/packages/app-shell/i18next-scanner.config.js new file mode 100644 index 0000000000000000000000000000000000000000..aeb8fdb6532e6c951401ba91424e2a256353d391 --- /dev/null +++ b/packages/app-shell/i18next-scanner.config.js @@ -0,0 +1,16 @@ +module.exports = { + input: [ + 'src/*.js', + ], + output: './', + options: { + debug: false, + removeUnusedKeys: true, + func: {list: ['i18n.t', '_i18n.t']}, + lngs: ['en','de'], + resource: { + loadPath: 'src/i18n/{{lng}}/{{ns}}.json', + savePath: 'src/i18n/{{lng}}/{{ns}}.json' + }, + }, +} diff --git a/packages/app-shell/package.json b/packages/app-shell/package.json index ccecb0392a24def4c5f0e2398abde21091ee7221..d31a609a71c61c7e877534f16d7c369c47e0e79f 100644 --- a/packages/app-shell/package.json +++ b/packages/app-shell/package.json @@ -31,7 +31,8 @@ "rollup-plugin-copy": "^3.1.0", "rollup-plugin-delete": "^2.0.0", "rollup-plugin-emit-ejs": "^3.1.0", - "rollup-plugin-serve": "^1.0.1" + "rollup-plugin-serve": "^1.0.1", + "i18next-scanner": "^3.0.0" }, "dependencies": { "@dbp-toolkit/auth": "^0.2.2", @@ -47,6 +48,7 @@ "universal-router": "^9.0.1" }, "scripts": { + "i18next": "i18next-scanner", "build": "npm run build-local", "build-local": "rollup -c", "build-test": "rollup -c --environment BUILD:test", diff --git a/packages/app-shell/src/app-shell.js b/packages/app-shell/src/app-shell.js index bf2bab5e86cee6158b619e9105c0aa600d3100cc..864ae5255ebe09aac5fa43f1b1446258b3398829 100644 --- a/packages/app-shell/src/app-shell.js +++ b/packages/app-shell/src/app-shell.js @@ -1,4 +1,4 @@ -import {createI18nInstance} from './i18n.js'; +import {createInstance} from './i18n.js'; import {html, css} from 'lit-element'; import {ScopedElementsMixin} from '@open-wc/scoped-elements'; import {LanguageSelect} from '@dbp-toolkit/language-select'; @@ -15,18 +15,16 @@ import {appWelcomeMeta} from './dbp-app-shell-welcome.js'; import {MatomoElement} from "@dbp-toolkit/matomo/src/matomo"; import DBPLitElement from "@dbp-toolkit/common/dbp-lit-element"; - -const i18n = createI18nInstance(); - /** * In case the application gets updated future dynamic imports might fail. * This sends a notification suggesting the user to reload the page. * - * uage: importNotify(import('<path>')); + * usage: importNotify(import('<path>')); * + * @param i18n * @param {Promise} promise */ -const importNotify = async (promise) => { +const importNotify = async (i18n, promise) => { try { return await promise; } catch (error) { @@ -43,7 +41,6 @@ const importNotify = async (promise) => { export class AppShell extends ScopedElementsMixin(DBPLitElement) { constructor() { super(); - this.lang = i18n.language; this.activeView = ''; this.entryPointUrl = ''; this.subtitle = ''; @@ -62,6 +59,8 @@ export class AppShell extends ScopedElementsMixin(DBPLitElement) { this.buildTime = ''; this._loginStatus = 'unknown'; this._roles = []; + this._i18n = createInstance(); + this.lang = this._i18n.language; this.matomoUrl = ''; this.matomoSiteId = -1; @@ -271,7 +270,7 @@ export class AppShell extends ScopedElementsMixin(DBPLitElement) { */ updateLangIfChanged(lang) { // in case the language is unknown, fall back to the default - if (!i18n.languages.includes(lang)) { + if (!this._i18n.languages.includes(lang)) { lang = this.lang; } if (this.lang !== lang) { @@ -287,10 +286,9 @@ export class AppShell extends ScopedElementsMixin(DBPLitElement) { changedProperties.forEach((oldValue, propName) => { switch (propName) { case 'lang': - i18n.changeLanguage(this.lang); + this._i18n.changeLanguage(this.lang); // For screen readers document.documentElement.setAttribute("lang", this.lang); - i18n.changeLanguage(this.lang); this.router.update(); this.subtitle = this.activeMetaDataText("short_name"); @@ -420,7 +418,7 @@ export class AppShell extends ScopedElementsMixin(DBPLitElement) { return; } - importNotify(import(metadata.module_src)).then(() => { + importNotify(this._i18n, import(metadata.module_src)).then(() => { updateFunc(); }).catch((e) => { console.error(`Error loading ${ metadata.element }`); @@ -836,6 +834,8 @@ export class AppShell extends ScopedElementsMixin(DBPLitElement) { } render() { + let i18n = this._i18n; + const getSelectClasses = (name => { return classMap({selected: this.activeView === name}); }); diff --git a/packages/app-shell/src/auth-menu-button.js b/packages/app-shell/src/auth-menu-button.js index ce8e9fc1b076d8d498548afd7dfb22c17c53568a..a122cb825ba6139db687d2a379e319b1d10c32b4 100644 --- a/packages/app-shell/src/auth-menu-button.js +++ b/packages/app-shell/src/auth-menu-button.js @@ -1,4 +1,4 @@ -import {createI18nInstance} from './i18n.js'; +import {createInstance} from './i18n.js'; import {html, css} from 'lit-element'; import {unsafeHTML} from 'lit-html/directives/unsafe-html.js'; import {ScopedElementsMixin} from '@open-wc/scoped-elements'; @@ -7,14 +7,12 @@ import {Icon} from '@dbp-toolkit/common'; import {AdapterLitElement} from "@dbp-toolkit/provider/src/adapter-lit-element"; import {LoginStatus} from "@dbp-toolkit/auth/src/util"; - -const i18n = createI18nInstance(); - export class AuthMenuButton extends ScopedElementsMixin(AdapterLitElement) { constructor() { super(); - this.lang = 'de'; + this._i18n = createInstance(); + this.lang = this._i18n.language; this.showImage = false; this.auth = {}; @@ -82,7 +80,7 @@ export class AuthMenuButton extends ScopedElementsMixin(AdapterLitElement) { update(changedProperties) { changedProperties.forEach((oldValue, propName) => { if (propName === "lang") { - i18n.changeLanguage(this.lang); + this._i18n.changeLanguage(this.lang); } }); @@ -246,6 +244,7 @@ export class AuthMenuButton extends ScopedElementsMixin(AdapterLitElement) { } renderLoggedIn() { + const i18n = this._i18n; const person = this.auth.person; const imageURL = (this.showImage && person && person.image) ? person.image : null; @@ -270,6 +269,7 @@ export class AuthMenuButton extends ScopedElementsMixin(AdapterLitElement) { } renderLoggedOut() { + const i18n = this._i18n; let loginSVG = ` <svg viewBox="0 0 100 100" diff --git a/packages/app-shell/src/dbp-activity-example.js b/packages/app-shell/src/dbp-activity-example.js index 850a73c289e514052d2fa347da420431a42a0a30..e126445bf47d4a4128e26348ce32b9dccaedd0b2 100644 --- a/packages/app-shell/src/dbp-activity-example.js +++ b/packages/app-shell/src/dbp-activity-example.js @@ -1,14 +1,13 @@ import {html , LitElement} from 'lit-element'; -import {createI18nInstance} from './i18n.js'; +import {createInstance} from './i18n.js'; import * as commonUtils from '@dbp-toolkit/common/utils'; -const i18n = createI18nInstance(); - class ActivityExample extends LitElement { constructor() { super(); - this.lang = i18n.language; + this._i18n = createInstance(); + this.lang = this._i18n.language; } static get properties() { @@ -21,7 +20,7 @@ class ActivityExample extends LitElement { changedProperties.forEach((oldValue, propName) => { switch (propName) { case "lang": - i18n.changeLanguage(this.lang); + this._i18n.changeLanguage(this.lang); break; } }); @@ -30,6 +29,7 @@ class ActivityExample extends LitElement { } render() { + const i18n = this._i18n; return html` <h3>${i18n.t('activity-example.hello-world')}</h3> <ul>${(Array.from(Array(100).keys())).map(i => html`<li>${i18n.t('activity-example.hello-world') + ' ' + i}</li>`)}</ul> diff --git a/packages/app-shell/src/dbp-app-shell-welcome.js b/packages/app-shell/src/dbp-app-shell-welcome.js index 2397905ba095d39b3bc977a694c1eb151e58a55c..52acdf77cb64ccf5472709e67e33a35d31dca400 100644 --- a/packages/app-shell/src/dbp-app-shell-welcome.js +++ b/packages/app-shell/src/dbp-app-shell-welcome.js @@ -1,16 +1,15 @@ -import {createI18nInstance} from './i18n.js'; +import {createInstance} from './i18n.js'; import {css, html, LitElement} from 'lit-element'; import {ScopedElementsMixin} from '@open-wc/scoped-elements'; import * as commonUtils from '@dbp-toolkit/common/utils'; import * as commonStyles from '@dbp-toolkit/common/styles'; -const i18n = createI18nInstance(); - class AppShellWelcome extends ScopedElementsMixin(LitElement) { constructor() { super(); - this.lang = i18n.language; + this._i18n = createInstance(); + this.lang = this._i18n.language; this._onVisibilityChanged = this._onVisibilityChanged.bind(this); } @@ -28,7 +27,7 @@ class AppShellWelcome extends ScopedElementsMixin(LitElement) { update(changedProperties) { changedProperties.forEach((oldValue, propName) => { if (propName === "lang") { - i18n.changeLanguage(this.lang); + this._i18n.changeLanguage(this.lang); } }); @@ -75,6 +74,7 @@ class AppShellWelcome extends ScopedElementsMixin(LitElement) { } render() { + const i18n = this._i18n; const app = AppShellWelcome._app; let itemTemplates = []; diff --git a/packages/app-shell/src/i18n.js b/packages/app-shell/src/i18n.js index 7bc3faba59eb4d9d4a7e1106ad44181b17d77ec4..0c6fedc883e4f02965df30acfb47fa37e11a268c 100644 --- a/packages/app-shell/src/i18n.js +++ b/packages/app-shell/src/i18n.js @@ -1,20 +1,8 @@ -import {createInstance} from '@dbp-toolkit/common/i18next.js'; +import {createInstance as _createInstance} from '@dbp-toolkit/common/i18next.js'; import de from './i18n/de/translation.json'; import en from './i18n/en/translation.json'; -const i18n = createInstance({en: en, de: de}, 'de', 'en'); - -export function createI18nInstance () { - return i18n.cloneInstance(); +export function createInstance() { + return _createInstance({en: en, de: de}, 'de', 'en'); } - -/** - * Dummy function to mark strings as i18next keys for i18next-scanner - * - * @param {string} key - * @returns {string} The key param as is - */ -export function i18nKey(key) { - return key; -} \ No newline at end of file diff --git a/packages/app-shell/src/i18n/de/translation.json b/packages/app-shell/src/i18n/de/translation.json index bac3fc0fb57a6b6e8ce32746ef1bd4556f5837cd..3b959a1aa025175012d775fab70761dd5dee28fc 100644 --- a/packages/app-shell/src/i18n/de/translation.json +++ b/packages/app-shell/src/i18n/de/translation.json @@ -12,10 +12,10 @@ "hello-world": "Hallo Welt" }, "welcome": { - "headline": "Willkommen bei der Applikation '{{appname}}'." + "headline": "Willkommen bei der Applikation '{{appname}}'." }, "login": "Einloggen", "logout": "Ausloggen", "page-not-found": "Die gewünschte Seite wurde nicht gefunden", "choose-from-menu": "Bitte wählen Sie eine Aktivität aus dem Menu." -} \ No newline at end of file +} diff --git a/packages/app-shell/src/i18n/en/translation.json b/packages/app-shell/src/i18n/en/translation.json index 5a5c20a43596e8d667e64f6647716b11e4c0207f..ae4a137d9eb84ebbad052f1c5564228fbdaf133e 100644 --- a/packages/app-shell/src/i18n/en/translation.json +++ b/packages/app-shell/src/i18n/en/translation.json @@ -12,7 +12,7 @@ "hello-world": "Hello World" }, "welcome": { - "headline": "Welcome to the '{{appname}}' application." + "headline": "Welcome to the '{{appname}}' application." }, "login": "Login", "logout": "Logout", diff --git a/packages/auth/i18next-scanner.config.js b/packages/auth/i18next-scanner.config.js index 0e6216b2e7dd8a8b3a0d95d9ef86f35c37ce5f5e..aeb8fdb6532e6c951401ba91424e2a256353d391 100644 --- a/packages/auth/i18next-scanner.config.js +++ b/packages/auth/i18next-scanner.config.js @@ -8,7 +8,6 @@ module.exports = { removeUnusedKeys: true, func: {list: ['i18n.t', '_i18n.t']}, lngs: ['en','de'], - defaultNs: 'dbp-auth', resource: { loadPath: 'src/i18n/{{lng}}/{{ns}}.json', savePath: 'src/i18n/{{lng}}/{{ns}}.json' diff --git a/packages/auth/src/auth-keycloak.js b/packages/auth/src/auth-keycloak.js index f5b5ab718c3dbfce64c932754b5c59ebc3bc5520..60c3b1612748f004d1fd3946942f2fa28c4da372 100644 --- a/packages/auth/src/auth-keycloak.js +++ b/packages/auth/src/auth-keycloak.js @@ -20,7 +20,6 @@ import {AdapterLitElement} from "@dbp-toolkit/provider/src/adapter-lit-element"; export class AuthKeycloak extends AdapterLitElement { constructor() { super(); - this.lang = 'de'; this.forceLogin = false; this.loadPerson = false; this.token = ""; @@ -33,6 +32,7 @@ export class AuthKeycloak extends AdapterLitElement { this._loginStatus = LoginStatus.UNKNOWN; this.requestedLoginStatus = LoginStatus.UNKNOWN; this._i18n = createInstance(); + this.lang = this._i18n.language; // Keycloak config this.keycloakUrl = null; diff --git a/packages/auth/src/dbp-auth-demo.js b/packages/auth/src/dbp-auth-demo.js index 3b9170f60a77d3f063294497aea8d778bfe6014f..93aa4627427de5d07025f81ec9ab0b8e1b7371b7 100644 --- a/packages/auth/src/dbp-auth-demo.js +++ b/packages/auth/src/dbp-auth-demo.js @@ -10,11 +10,11 @@ import DBPLitElement from "@dbp-toolkit/common/dbp-lit-element"; export class DbpAuthDemo extends ScopedElementsMixin(DBPLitElement) { constructor() { super(); - this.lang = 'de'; this.entryPointUrl = ''; this.auth = {}; this.noAuth = false; this._i18n = createInstance(); + this.lang = this._i18n.language; } static get scopedElements() { diff --git a/packages/auth/src/i18n.js b/packages/auth/src/i18n.js index a54f51bc97ca386d30adb3282547870b7501c2af..fbc1b032f3c662e149547117a8df129be5262e99 100644 --- a/packages/auth/src/i18n.js +++ b/packages/auth/src/i18n.js @@ -1,10 +1,10 @@ import {createInstance as _createInstance, setOverrides} from '@dbp-toolkit/common/i18next.js'; -import de from './i18n/de/dbp-auth.json'; -import en from './i18n/en/dbp-auth.json'; +import de from './i18n/de/translation.json'; +import en from './i18n/en/translation.json'; export function createInstance() { - return _createInstance({en: en, de: de}, 'de', 'en', 'dbp-auth'); + return _createInstance({en: en, de: de}, 'de', 'en'); } export {setOverrides}; \ No newline at end of file diff --git a/packages/auth/src/i18n/de/dbp-auth.json b/packages/auth/src/i18n/de/translation.json similarity index 100% rename from packages/auth/src/i18n/de/dbp-auth.json rename to packages/auth/src/i18n/de/translation.json diff --git a/packages/auth/src/i18n/en/dbp-auth.json b/packages/auth/src/i18n/en/translation.json similarity index 100% rename from packages/auth/src/i18n/en/dbp-auth.json rename to packages/auth/src/i18n/en/translation.json diff --git a/packages/auth/src/login-button.js b/packages/auth/src/login-button.js index 63e7353d567094b24cb376bc7a76da93557a97da..55423562cbfb9275273f06811b789d824121889e 100644 --- a/packages/auth/src/login-button.js +++ b/packages/auth/src/login-button.js @@ -55,8 +55,8 @@ export class LoginButton extends ScopedElementsMixin(AdapterLitElement) { constructor() { super(); - this.lang = 'de'; this._i18n = createInstance(); + this.lang = this._i18n.language; this.auth = {}; } diff --git a/packages/check-in-place-select/src/check-in-place-select.js b/packages/check-in-place-select/src/check-in-place-select.js index f2ed817d4a7a974001c94afcdf20e9424a4472e0..992b6148f629c71e398f23be0d4982f816a0f2ac 100644 --- a/packages/check-in-place-select/src/check-in-place-select.js +++ b/packages/check-in-place-select/src/check-in-place-select.js @@ -25,7 +25,6 @@ export class CheckInPlaceSelect extends ScopedElementsMixin(AdapterLitElement) { constructor() { super(); Object.assign(CheckInPlaceSelect.prototype, errorUtils.errorMixin); - this.lang = 'de'; this.entryPointUrl = ''; this.jsonld = null; this.$select = null; @@ -42,6 +41,7 @@ export class CheckInPlaceSelect extends ScopedElementsMixin(AdapterLitElement) { this.showCapacity = false; this.auth = {}; this._i18n = createInstance(); + this.lang = this._i18n.language; this._onDocumentClicked = this._onDocumentClicked.bind(this); } diff --git a/packages/check-in-place-select/src/dbp-check-in-place-select-demo.js b/packages/check-in-place-select/src/dbp-check-in-place-select-demo.js index d77e85619122d1d1a74b5cca5c94c7f281b3b615..b56c85ab68a97bf534d7bc6c916ce0bcb922a7d1 100644 --- a/packages/check-in-place-select/src/dbp-check-in-place-select-demo.js +++ b/packages/check-in-place-select/src/dbp-check-in-place-select-demo.js @@ -5,11 +5,14 @@ import {AuthKeycloak, LoginButton} from '@dbp-toolkit/auth'; import * as commonUtils from '@dbp-toolkit/common/utils'; import * as commonStyles from '@dbp-toolkit/common/styles'; import DBPLitElement from "@dbp-toolkit/common/dbp-lit-element"; +import {createInstance} from './i18n.js'; + export class CheckInPlaceSelectDemo extends ScopedElementsMixin(DBPLitElement) { constructor() { super(); - this.lang = 'de'; + this._i18n = createInstance(); + this.lang = this._i18n.language; this.entryPointUrl = ''; this.noAuth = false; } diff --git a/packages/common/dbp-common-demo.js b/packages/common/dbp-common-demo.js index 4e58093a0f163729582a7ac3a30c75b2b6f48d34..9a56ef03ec21d0d620844c2944453c36225b68e7 100644 --- a/packages/common/dbp-common-demo.js +++ b/packages/common/dbp-common-demo.js @@ -1,4 +1,4 @@ -import {i18n} from './i18n.js'; +import {createInstance} from './src/i18n.js'; import {css, html, LitElement} from 'lit-element'; import {ScopedElementsMixin} from '@open-wc/scoped-elements'; import * as commonUtils from './utils.js'; @@ -8,7 +8,8 @@ import {getIconCSS, Icon, MiniSpinner, Button, LoadingButton, Spinner, InlineNot export class DbpCommonDemo extends ScopedElementsMixin(LitElement) { constructor() { super(); - this.lang = 'de'; + this._i18n = createInstance(); + this.lang = this._i18n.language; this.noAuth = false; } @@ -39,7 +40,7 @@ export class DbpCommonDemo extends ScopedElementsMixin(LitElement) { connectedCallback() { super.connectedCallback(); - i18n.changeLanguage(this.lang); + this._i18n.changeLanguage(this.lang); this.updateComplete.then(()=>{ }); diff --git a/packages/common/error.js b/packages/common/error.js index aa61b9e25f7f3060b6ee5e09163f72844e739d33..f001f1747cc53f3fba0b001746260745e9379250 100644 --- a/packages/common/error.js +++ b/packages/common/error.js @@ -1,5 +1,5 @@ import {send as notify} from './notification'; -import {i18n} from "./i18n"; +import {createInstance} from "./src/i18n"; /** * Escapes html @@ -39,14 +39,17 @@ export const errorMixin = { * @param textStatus * @param errorThrown * @param icon + * @param lang */ - handleXhrError(jqXHR, textStatus, errorThrown, icon = "sad") { + handleXhrError(jqXHR, textStatus, errorThrown, icon = "sad", lang = "de") { // return if user aborted the request if (textStatus === "abort") { return; } let body; + const i18n = createInstance(); + i18n.changeLanguage(lang); if (jqXHR.responseJSON !== undefined && jqXHR.responseJSON["hydra:description"] !== undefined) { // response is a JSON-LD @@ -86,14 +89,17 @@ export const errorMixin = { * @param error * @param summary * @param icon + * @param lang */ - handleFetchError: async function (error, summary = "", icon = "sad") { + handleFetchError: async function (error, summary = "", icon = "sad", lang = "de") { // return if user aborted the request if (error.name === "AbortError") { return; } let body; + const i18n = createInstance(); + i18n.changeLanguage(lang); try { await error.json().then((json) => { diff --git a/packages/common/i18n.js b/packages/common/i18n.js deleted file mode 100644 index dc0125f75d796c81867d56e3c409936202ae00fe..0000000000000000000000000000000000000000 --- a/packages/common/i18n.js +++ /dev/null @@ -1,6 +0,0 @@ -import {createInstance} from './i18next.js'; - -import de from './i18n/de/translation.json'; -import en from './i18n/en/translation.json'; - -export const i18n = createInstance({en: en, de: de}, 'de', 'en'); \ No newline at end of file diff --git a/packages/common/i18next-scanner.config.js b/packages/common/i18next-scanner.config.js new file mode 100644 index 0000000000000000000000000000000000000000..773819264a14879dcd454bb9a5317ccdeec2e9d8 --- /dev/null +++ b/packages/common/i18next-scanner.config.js @@ -0,0 +1,17 @@ +module.exports = { + input: [ + 'src/*.js', + './*.js', + ], + output: './', + options: { + debug: false, + removeUnusedKeys: true, + func: {list: ['i18n.t', '_i18n.t']}, + lngs: ['en','de'], + resource: { + loadPath: 'src/i18n/{{lng}}/{{ns}}.json', + savePath: 'src/i18n/{{lng}}/{{ns}}.json' + }, + }, +} diff --git a/packages/common/jsonld.js b/packages/common/jsonld.js index 0a27bbfdaf6490239d2c73594960b85f63e0bc38..f74e38cf8b1b46881bde1376ce4472775f6d59d5 100644 --- a/packages/common/jsonld.js +++ b/packages/common/jsonld.js @@ -1,6 +1,6 @@ import {send as notify} from './notification'; import * as utils from "./utils"; -import {i18n} from "./i18n"; +import {createInstance} from "./src/i18n"; export default class JSONLD { constructor(baseApiUrl, entities) { @@ -43,9 +43,7 @@ export default class JSONLD { } static _initialize(apiUrl, successFnc, failureFnc, lang = 'de') { - if (lang !== 'de') { - i18n.changeLanguage(lang); - } + JSONLD._i18n.changeLanguage(lang); // if init api call was already successfully finished execute the success function if (JSONLD.instances[apiUrl] !== undefined) { @@ -72,6 +70,7 @@ export default class JSONLD { static _doInitialization(apiUrl) { const xhr = new XMLHttpRequest(); + const i18n = JSONLD._i18n; xhr.open("GET", apiUrl, true); xhr.onreadystatechange = function () { @@ -170,6 +169,7 @@ export default class JSONLD { * @param message */ static _executeFailureFunctions(apiUrl, message = "") { + const i18n = JSONLD._i18n; if (JSONLD.failureFunctions[apiUrl] !== undefined) { for (const fnc of JSONLD.failureFunctions[apiUrl]) { if (typeof fnc == 'function') { @@ -297,6 +297,7 @@ export default class JSONLD { } } +JSONLD._i18n = createInstance(); JSONLD.instances = {}; JSONLD.successFunctions = {}; JSONLD.failureFunctions = {}; diff --git a/packages/common/package.json b/packages/common/package.json index d4ed6c5f0b8c3cd447d1a833b4b725028a58f995..c14f62c5b9bb4c9826e3206b7139506ad61ffaac 100644 --- a/packages/common/package.json +++ b/packages/common/package.json @@ -25,9 +25,11 @@ "rollup": "^2.33.3", "rollup-plugin-copy": "^3.1.0", "rollup-plugin-delete": "^2.0.0", - "rollup-plugin-serve": "^1.0.1" + "rollup-plugin-serve": "^1.0.1", + "i18next-scanner": "^3.0.0" }, "scripts": { + "i18next": "i18next-scanner", "clean": "rm dist/*", "build": "rollup -c", "build-test": "rollup -c --environment BUILD:test", diff --git a/packages/common/src/i18n.js b/packages/common/src/i18n.js new file mode 100644 index 0000000000000000000000000000000000000000..ebd734720b5a52bbd4008d0e503ca96f9d3fa068 --- /dev/null +++ b/packages/common/src/i18n.js @@ -0,0 +1,8 @@ +import {createInstance as _createInstance} from '../i18next.js'; + +import de from './i18n/de/translation.json'; +import en from './i18n/en/translation.json'; + +export function createInstance() { + return _createInstance({en: en, de: de}, 'de', 'en'); +} \ No newline at end of file diff --git a/packages/common/i18n/de/translation.json b/packages/common/src/i18n/de/translation.json similarity index 100% rename from packages/common/i18n/de/translation.json rename to packages/common/src/i18n/de/translation.json diff --git a/packages/common/i18n/en/translation.json b/packages/common/src/i18n/en/translation.json similarity index 100% rename from packages/common/i18n/en/translation.json rename to packages/common/src/i18n/en/translation.json diff --git a/packages/data-table-view/i18next-scanner.config.js b/packages/data-table-view/i18next-scanner.config.js new file mode 100644 index 0000000000000000000000000000000000000000..aeb8fdb6532e6c951401ba91424e2a256353d391 --- /dev/null +++ b/packages/data-table-view/i18next-scanner.config.js @@ -0,0 +1,16 @@ +module.exports = { + input: [ + 'src/*.js', + ], + output: './', + options: { + debug: false, + removeUnusedKeys: true, + func: {list: ['i18n.t', '_i18n.t']}, + lngs: ['en','de'], + resource: { + loadPath: 'src/i18n/{{lng}}/{{ns}}.json', + savePath: 'src/i18n/{{lng}}/{{ns}}.json' + }, + }, +} diff --git a/packages/data-table-view/src/data-table-view.js b/packages/data-table-view/src/data-table-view.js index fb9690ba6da23b303106e15c712759a56c8e7b6f..609e642c9e5f28215595b4d8a446ee8c59688a9a 100644 --- a/packages/data-table-view/src/data-table-view.js +++ b/packages/data-table-view/src/data-table-view.js @@ -7,7 +7,7 @@ import bttn from 'datatables.net-buttons-dt'; import bttn2 from 'datatables.net-buttons'; import bttnHtml5 from 'datatables.net-buttons/js/buttons.html5.js'; import bttnPrint from 'datatables.net-buttons/js/buttons.print.js'; -import {i18n} from './i18n'; +import {createInstance} from './i18n'; import {css, html, unsafeCSS} from 'lit-element'; import de from '../assets/datatables/i18n/German'; import en from '../assets/datatables/i18n/English'; @@ -28,7 +28,8 @@ bttnPrint(window, $); export class DataTableView extends AdapterLitElement { constructor() { super(); - this.lang = 'de'; + this._i18n = createInstance(); + this.lang = this._i18n.language; // datatable properties this.table = null; this.responsive = null; @@ -100,6 +101,7 @@ export class DataTableView extends AdapterLitElement { set_datatable(data, languageChange = false) { const lang_obj = this.lang === 'de' ? de : en; + const i18n = this._i18n; if (typeof this.columns === 'undefined' || !this.columns.length) { if (data.length) @@ -229,7 +231,7 @@ export class DataTableView extends AdapterLitElement { changedProperties.forEach((oldValue, propName) => { if (propName === "lang") { - i18n.changeLanguage(this.lang).catch(e => { console.log(e);}); + this._i18n.changeLanguage(this.lang).catch(e => { console.log(e);}); languageChange = true; } }); diff --git a/packages/data-table-view/src/dbp-data-table-view-demo.js b/packages/data-table-view/src/dbp-data-table-view-demo.js index dc2bb24d0398aab00880490fd4b0b16b14bf0ef0..7544fdc067d938fc90e3b9faedf1e68f7266c354 100644 --- a/packages/data-table-view/src/dbp-data-table-view-demo.js +++ b/packages/data-table-view/src/dbp-data-table-view-demo.js @@ -1,6 +1,6 @@ import {AuthKeycloak, LoginButton} from '@dbp-toolkit/auth'; import {DataTableView} from './data-table-view.js'; -import {i18n} from './i18n'; +import {createInstance} from './i18n'; import {css, html} from 'lit-element'; import {ScopedElementsMixin} from '@open-wc/scoped-elements'; import * as commonUtils from '@dbp-toolkit/common/utils'; @@ -10,7 +10,8 @@ import DBPLitElement from "@dbp-toolkit/common/dbp-lit-element"; export class DataTableViewDemo extends ScopedElementsMixin(DBPLitElement) { constructor() { super(); - this.lang = 'de'; + this._i18n = createInstance(); + this.lang = this._i18n.language; this.entryPointUrl = ''; this.noAuth = false; } @@ -100,7 +101,7 @@ export class DataTableViewDemo extends ScopedElementsMixin(DBPLitElement) { update(changedProperties) { changedProperties.forEach((oldValue, propName) => { if (propName === "lang") { - i18n.changeLanguage(this.lang); + this._i18n.changeLanguage(this.lang); } }); diff --git a/packages/data-table-view/src/i18n.js b/packages/data-table-view/src/i18n.js index a2380632e7095df7cc09dddf372598f5d6b5898c..975c1993e2a567940c74f8d957a6b2a018125548 100644 --- a/packages/data-table-view/src/i18n.js +++ b/packages/data-table-view/src/i18n.js @@ -1,29 +1,8 @@ -import i18next from 'i18next'; +import {createInstance as _createInstance} from '@dbp-toolkit/common/i18next.js'; import de from './i18n/de/translation.json'; import en from './i18n/en/translation.json'; -const i18n = i18next.createInstance(); - -i18n.init({ - lng: 'de', - fallbackLng: ['de'], - debug: false, - initImmediate: false, // Don't init async - resources: { - en: {translation: en}, - de: {translation: de} - }, -}); - -console.assert(i18n.isInitialized); - -function dateTimeFormat(date, options) { - return new Intl.DateTimeFormat(i18n.languages, options).format(date); -} - -function numberFormat(number, options) { - return new Intl.NumberFormat(i18n.languages, options).format(number); -} - -export {i18n, dateTimeFormat, numberFormat}; +export function createInstance() { + return _createInstance({en: en, de: de}, 'de', 'en'); +} \ No newline at end of file diff --git a/packages/data-table-view/src/i18n/de/translation.json b/packages/data-table-view/src/i18n/de/translation.json index d1776ebc73f39cdfe749d64aa2357557c6399189..ed90a81bded1457b6812b1c1de10aa6e71d6b272 100644 --- a/packages/data-table-view/src/i18n/de/translation.json +++ b/packages/data-table-view/src/i18n/de/translation.json @@ -3,4 +3,4 @@ "export-excel": "Excel Export", "export-csv": "CSV Export", "column-search-placeholder": "Nach {{fieldName}} suchen" -} \ No newline at end of file +} diff --git a/packages/data-table-view/src/i18n/en/translation.json b/packages/data-table-view/src/i18n/en/translation.json index 33ea4a209861b14cd3c7e4c1a4902a6fab07bd89..0c0acdb39f4d0c3af06998f9cddfb426c23e2f21 100644 --- a/packages/data-table-view/src/i18n/en/translation.json +++ b/packages/data-table-view/src/i18n/en/translation.json @@ -3,4 +3,4 @@ "export-excel": "Excel Export", "export-csv": "CSV Export", "column-search-placeholder": "Search for {{fieldName}}" -} \ No newline at end of file +} diff --git a/packages/file-handling/i18next-scanner.config.js b/packages/file-handling/i18next-scanner.config.js index 8c277798414be902846c6eb4f0e95a19750cda39..aeb8fdb6532e6c951401ba91424e2a256353d391 100644 --- a/packages/file-handling/i18next-scanner.config.js +++ b/packages/file-handling/i18next-scanner.config.js @@ -6,6 +6,7 @@ module.exports = { options: { debug: false, removeUnusedKeys: true, + func: {list: ['i18n.t', '_i18n.t']}, lngs: ['en','de'], resource: { loadPath: 'src/i18n/{{lng}}/{{ns}}.json', diff --git a/packages/file-handling/src/clipboard.js b/packages/file-handling/src/clipboard.js index 0526c4164f54c3b9cd1eda92fac03400454e395c..d488a8dd2d977bd3768c6e0cd415af82efbe6fd1 100644 --- a/packages/file-handling/src/clipboard.js +++ b/packages/file-handling/src/clipboard.js @@ -1,4 +1,4 @@ -import {i18n} from './i18n'; +import {createInstance} from './i18n'; import {css, html} from 'lit-element'; import {ScopedElementsMixin} from '@open-wc/scoped-elements'; import * as commonUtils from '@dbp-toolkit/common/utils'; @@ -20,7 +20,8 @@ export class Clipboard extends ScopedElementsMixin(AdapterLitElement) { constructor() { super(); - this.lang = 'de'; + this._i18n = createInstance(); + this.lang = this._i18n.language; this.allowedMimeTypes = '*/*'; this.clipboardFiles = {files: ''}; this.clipboardSelectBtnDisabled = true; @@ -86,7 +87,7 @@ export class Clipboard extends ScopedElementsMixin(AdapterLitElement) { changedProperties.forEach((oldValue, propName) => { switch (propName) { case "lang": - i18n.changeLanguage(this.lang); + this._i18n.changeLanguage(this.lang); break; case "clipboardFiles": this.generateClipboardTable(); @@ -119,6 +120,7 @@ export class Clipboard extends ScopedElementsMixin(AdapterLitElement) { connectedCallback() { + const i18n = this._i18n; super.connectedCallback(); const that = this; this.updateComplete.then(() => { @@ -358,6 +360,7 @@ export class Clipboard extends ScopedElementsMixin(AdapterLitElement) { * @param files */ async sendClipboardFiles(files) { + const i18n = this._i18n; for (let i = 0; i < files.length; i ++) { await this.sendFileEvent(files[i].file); } @@ -384,6 +387,7 @@ export class Clipboard extends ScopedElementsMixin(AdapterLitElement) { * @param event */ onReceiveBeforeUnload(event) { + const i18n = this._i18n; // we don't need to stop if there are no signed files if (this.clipboardFiles.files.length === 0) { @@ -446,6 +450,8 @@ export class Clipboard extends ScopedElementsMixin(AdapterLitElement) { */ saveFilesToClipboard() { + const i18n = this._i18n; + //save it let data = {}; let files = []; @@ -476,6 +482,8 @@ export class Clipboard extends ScopedElementsMixin(AdapterLitElement) { * @param event */ finishedSaveFilesToClipboard(event) { + const i18n = this._i18n; + send({ "summary": i18n.t('clipboard.saved-files-title', {count: event.detail.count}), "body": i18n.t('clipboard.saved-files-body', {count: event.detail.count}), @@ -512,6 +520,8 @@ export class Clipboard extends ScopedElementsMixin(AdapterLitElement) { * */ clearClipboard() { + const i18n = this._i18n; + if (this.tabulatorTable && this.tabulatorTable.getSelectedData().length > 0) { let count = this.tabulatorTable.getSelectedData().length; this.tabulatorTable.deleteRow(this.tabulatorTable.getSelectedRows()); @@ -547,6 +557,7 @@ export class Clipboard extends ScopedElementsMixin(AdapterLitElement) { * @returns {html} */ getAdditionalButtons() { + const i18n = this._i18n; let buttonsAreDisabled = this.clipboardFiles.files.length === 0 ? true : this.clipboardSelectBtnDisabled; return html` <div class="flex-container additional-button-container"> @@ -611,6 +622,7 @@ export class Clipboard extends ScopedElementsMixin(AdapterLitElement) { * @returns {html} */ getClipboardSink() { + const i18n = this._i18n; const tabulatorCss = commonUtils.getAssetURL(pkgName, 'tabulator-tables/css/tabulator.min.css'); return html` <div class="wrapper"> @@ -645,6 +657,7 @@ export class Clipboard extends ScopedElementsMixin(AdapterLitElement) { */ getClipboardSource() { const tabulatorCss = commonUtils.getAssetURL(pkgName, 'tabulator-tables/css/tabulator.min.css'); + const i18n = this._i18n; return html` <div class="wrapper"> <div class="content"> diff --git a/packages/file-handling/src/demo.js b/packages/file-handling/src/demo.js index ede45f52aaf62783f43a612e66bf164678f0dcc0..e723a9a900f80ee620f469529223efbb5ef95dcd 100644 --- a/packages/file-handling/src/demo.js +++ b/packages/file-handling/src/demo.js @@ -1,4 +1,4 @@ -import {i18n} from './i18n'; +import {createInstance} from './i18n'; import {html, LitElement} from 'lit-element'; import {unsafeHTML} from 'lit-html/directives/unsafe-html.js'; import {ScopedElementsMixin} from '@open-wc/scoped-elements'; @@ -9,7 +9,8 @@ import * as commonUtils from '@dbp-toolkit/common/utils'; export class FileSourceDemo extends ScopedElementsMixin(LitElement) { constructor() { super(); - this.lang = 'de'; + this._i18n = createInstance(); + this.lang = this._i18n.language; this.url = ''; this.selectedFiles = []; this.selectedFilesCount = 0; @@ -46,7 +47,7 @@ export class FileSourceDemo extends ScopedElementsMixin(LitElement) { update(changedProperties) { changedProperties.forEach((oldValue, propName) => { if (propName === "lang") { - i18n.changeLanguage(this.lang); + this._i18n.changeLanguage(this.lang); } }); @@ -77,6 +78,8 @@ export class FileSourceDemo extends ScopedElementsMixin(LitElement) { } render() { + const i18n = this._i18n; + return html` <style> dbp-file-source.clean { diff --git a/packages/file-handling/src/file-sink.js b/packages/file-handling/src/file-sink.js index b71f6b2c711cc7ae7c02b025cad74ee3f3d13003..4a46ff3028c4eed0f7368f52ab6fea24f6155a2d 100644 --- a/packages/file-handling/src/file-sink.js +++ b/packages/file-handling/src/file-sink.js @@ -1,4 +1,4 @@ -import {i18n} from './i18n'; +import {createInstance} from './i18n'; import {css, html} from 'lit-element'; import {ScopedElementsMixin} from '@open-wc/scoped-elements'; import DBPLitElement from '@dbp-toolkit/common/dbp-lit-element'; @@ -22,7 +22,8 @@ export class FileSink extends ScopedElementsMixin(DbpFileHandlingLitElement) { constructor() { super(); this.context = ''; - this.lang = 'de'; + this._i18n = createInstance(); + this.lang = this._i18n.language; this.nextcloudAuthUrl = ''; this.nextcloudWebDavUrl = ''; this.nextcloudName ='Nextcloud'; @@ -127,7 +128,7 @@ export class FileSink extends ScopedElementsMixin(DbpFileHandlingLitElement) { changedProperties.forEach((oldValue, propName) => { switch (propName) { case "lang": - i18n.changeLanguage(this.lang); + this._i18n.changeLanguage(this.lang); break; case "enabledTargets": if (!this.hasEnabledDestination(this.activeTargets)) { @@ -168,6 +169,7 @@ export class FileSink extends ScopedElementsMixin(DbpFileHandlingLitElement) { } finishedFileUpload(event) { + const i18n = this._i18n; this.sendDestination(); MicroModal.close(this._('#modal-picker')); if (event.detail > 0) { @@ -273,6 +275,7 @@ export class FileSink extends ScopedElementsMixin(DbpFileHandlingLitElement) { } getNextcloudHtml() { + const i18n = this._i18n; if (this.enabledTargets.includes('nextcloud') && this.nextcloudWebDavUrl !== "" && this.nextcloudAuthUrl !== "") { return html` <dbp-nextcloud-file-picker id="nextcloud-file-picker" @@ -383,7 +386,7 @@ export class FileSink extends ScopedElementsMixin(DbpFileHandlingLitElement) { } render() { - + const i18n = this._i18n; return html` <vpu-notification lang="de" client-id="my-client-id"></vpu-notification> <div class="modal micromodal-slide" id="modal-picker" aria-hidden="true"> diff --git a/packages/file-handling/src/file-source.js b/packages/file-handling/src/file-source.js index 7992983c3a2ca3613b2dfe57634cf69f89446131..4b572d188f19ed9ccc7978d64120327e93bda1fe 100644 --- a/packages/file-handling/src/file-source.js +++ b/packages/file-handling/src/file-source.js @@ -1,4 +1,4 @@ -import {i18n} from './i18n'; +import {createInstance} from './i18n'; import {css, html} from 'lit-element'; import {ScopedElementsMixin} from '@open-wc/scoped-elements'; import DBPLitElement from '@dbp-toolkit/common/dbp-lit-element'; @@ -38,7 +38,8 @@ export class FileSource extends ScopedElementsMixin(DbpFileHandlingLitElement) { constructor() { super(); this.context = ''; - this.lang = 'de'; + this._i18n = createInstance(); + this.lang = this._i18n.language; this.nextcloudAuthUrl = ''; this.nextcloudName ='Nextcloud'; this.nextcloudWebDavUrl = ''; @@ -97,7 +98,7 @@ export class FileSource extends ScopedElementsMixin(DbpFileHandlingLitElement) { changedProperties.forEach((oldValue, propName) => { switch (propName) { case "lang": - i18n.changeLanguage(this.lang); + this._i18n.changeLanguage(this.lang); break; case "enabledTargets": if (!this.hasEnabledSource(this.activeTarget)) { @@ -328,6 +329,7 @@ export class FileSource extends ScopedElementsMixin(DbpFileHandlingLitElement) { // no suitable files found if (filesToHandle.length === 0) { + const i18n = this._i18n; console.error('ZIP file does not contain any files of ' + this.allowedMimeTypes); //throw new Error('ZIP file does not contain any files of ' + this.allowedMimeTypes); notify({ @@ -585,6 +587,7 @@ export class FileSource extends ScopedElementsMixin(DbpFileHandlingLitElement) { } render() { + const i18n = this._i18n; let allowedMimeTypes = this.allowedMimeTypes; if (this.decompressZip && this.allowedMimeTypes !== "*/*") { diff --git a/packages/file-handling/src/i18n.js b/packages/file-handling/src/i18n.js index 498d9f037b0a5ca481ec8de5df24640900285808..975c1993e2a567940c74f8d957a6b2a018125548 100644 --- a/packages/file-handling/src/i18n.js +++ b/packages/file-handling/src/i18n.js @@ -1,6 +1,8 @@ -import {createInstance} from '@dbp-toolkit/common/i18next.js'; +import {createInstance as _createInstance} from '@dbp-toolkit/common/i18next.js'; import de from './i18n/de/translation.json'; import en from './i18n/en/translation.json'; -export const i18n = createInstance({en: en, de: de}, 'de', 'en'); \ No newline at end of file +export function createInstance() { + return _createInstance({en: en, de: de}, 'de', 'en'); +} \ No newline at end of file diff --git a/packages/file-handling/src/nextcloud-file-picker.js b/packages/file-handling/src/nextcloud-file-picker.js index 46c3ecb4d30521a712fe0d9bdd280f33b272c82a..1ac5ea7b13064172c6b1cf768ba06e5a1a36605b 100644 --- a/packages/file-handling/src/nextcloud-file-picker.js +++ b/packages/file-handling/src/nextcloud-file-picker.js @@ -1,4 +1,4 @@ -import {i18n} from './i18n'; +import {createInstance} from './i18n'; import {css, html} from 'lit-element'; import {ScopedElementsMixin} from '@open-wc/scoped-elements'; import DBPLitElement from '@dbp-toolkit/common/dbp-lit-element'; @@ -19,7 +19,9 @@ import * as fileHandlingStyles from './styles'; export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) { constructor() { super(); - this.lang = 'de'; + this._i18n = createInstance(); + this.lang = this._i18n.language; + this.authUrl = ''; this.webDavUrl = ''; this.nextcloudName = 'Nextcloud'; @@ -37,7 +39,7 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) { this.loading = false; this._onReceiveWindowMessage = this.onReceiveWindowMessage.bind(this); - this.folderIsSelected = i18n.t('nextcloud-file-picker.load-in-folder'); + this.folderIsSelected = this._i18n.t('nextcloud-file-picker.load-in-folder'); this.generatedFilename = ''; this.replaceFilename = ''; this.customFilename = ''; @@ -97,7 +99,7 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) { changedProperties.forEach((oldValue, propName) => { switch (propName) { case "lang": - i18n.changeLanguage(this.lang); + this._i18n.changeLanguage(this.lang); break; case "directoriesOnly": if (this.directoriesOnly && this._("#select_all_wrapper")) { @@ -136,6 +138,7 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) { connectedCallback() { super.connectedCallback(); const that = this; + const i18n = this._i18n; this.updateComplete.then(() => { // see: https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage window.addEventListener('message', this._onReceiveWindowMessage); @@ -375,6 +378,7 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) { } openFilePicker() { + const i18n = this._i18n; if (this.webDavClient === null) { this.loading = true; this.statusText = i18n.t('nextcloud-file-picker.auth-progress'); @@ -423,6 +427,7 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) { * @param path */ loadDirectory(path) { + const i18n = this._i18n; if (typeof this.directoryPath === 'undefined' || this.directoryPath === undefined) { this.directoryPath = ''; } @@ -567,6 +572,7 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) { * @param fileData */ downloadFile(fileData) { + const i18n = this._i18n; this.loading = true; this.statusText = "Loading " + fileData.filename + "..."; @@ -597,6 +603,7 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) { * @param directory */ sendDirectory(directory) { + const i18n = this._i18n; this.tabulatorTable.deselectRow(); let path; @@ -621,6 +628,7 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) { * @param directory */ uploadFiles(files, directory) { + const i18n = this._i18n; this.loading = true; this.statusText = i18n.t('nextcloud-file-picker.upload-to', {path: directory}); this.fileList = files; @@ -641,6 +649,7 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) { * @param directory */ async uploadFile(directory) { + const i18n = this._i18n; if (this.abortUpload) { this.abortUpload = false; this.abortUploadButton = false; @@ -707,6 +716,7 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) { * */ async uploadFileAfterConflict() { + const i18n = this._i18n; if (this.abortUpload) { this.abortUpload = false; this.abortUploadButton = false; @@ -856,6 +866,7 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) { * @param directory */ replaceModalDialog(file, directory) { + const i18n = this._i18n; this.uploadFileObject = file; this.uploadFileDirectory = directory; let rights = this.checkRights(file); @@ -964,6 +975,7 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) { * @returns {string} correct cancel text */ getCancelText() { + const i18n = this._i18n; if (this.fileList.length > 1) { return i18n.t('nextcloud-file-picker.replace-cancel-all'); } @@ -991,6 +1003,7 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) { * */ openAddFolderDialogue() { + const i18n = this._i18n; if (this._('.addRowAnimation')) { this._('.addRowAnimation').classList.remove('addRowAnimation'); } @@ -1010,6 +1023,7 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) { * */ addFolder() { + const i18n = this._i18n; if (this._('#new-folder').value !== "") { let folderName = this._('#new-folder').value; if (typeof this.directoryPath === 'undefined') { @@ -1090,6 +1104,7 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) { * @returns {string} clickable breadcrumb path */ getBreadcrumb() { + const i18n = this._i18n; if (typeof this.directoryPath === 'undefined') { this.directoryPath = ''; } @@ -1596,6 +1611,7 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) { } render() { + const i18n = this._i18n; const tabulatorCss = commonUtils.getAssetURL(pkgName, 'tabulator-tables/css/tabulator.min.css'); return html` diff --git a/packages/knowledge-base-web-page-element-view/package.json b/packages/knowledge-base-web-page-element-view/package.json index df0e937daa5052335d27d2f3600907b26fee8422..e9be74960f48f871226e7c9896cf6bb4e76eb86f 100644 --- a/packages/knowledge-base-web-page-element-view/package.json +++ b/packages/knowledge-base-web-page-element-view/package.json @@ -30,7 +30,8 @@ "rollup-plugin-copy": "^3.1.0", "rollup-plugin-delete": "^2.0.0", "rollup-plugin-serve": "^1.0.1", - "rollup-plugin-terser": "^7.0.2" + "rollup-plugin-terser": "^7.0.2", + "i18next-scanner": "^3.0.0" }, "dependencies": { "@dbp-toolkit/auth": "^0.2.2", @@ -42,6 +43,7 @@ "material-design-icons-svg": "^3.0.0" }, "scripts": { + "i18next": "i18next-scanner", "clean": "rm dist/*", "build": "npm run build-local", "build-local": "rollup -c", diff --git a/packages/knowledge-base-web-page-element-view/src/dbp-knowledge-base-web-page-element-view-demo.js b/packages/knowledge-base-web-page-element-view/src/dbp-knowledge-base-web-page-element-view-demo.js index 717b3c1c4a495f4bb2ed6143bb1294aa0b81087a..4a739d9780f282b7fd1f62552d709619ce248829 100644 --- a/packages/knowledge-base-web-page-element-view/src/dbp-knowledge-base-web-page-element-view-demo.js +++ b/packages/knowledge-base-web-page-element-view/src/dbp-knowledge-base-web-page-element-view-demo.js @@ -1,4 +1,4 @@ -import {i18n} from './i18n'; +import {createInstance} from './i18n'; import {css, html} from 'lit-element'; import {ScopedElementsMixin} from '@open-wc/scoped-elements'; import {AuthKeycloak, LoginButton} from '@dbp-toolkit/auth'; @@ -10,7 +10,8 @@ import DBPLitElement from "@dbp-toolkit/common/dbp-lit-element"; export class KnowledgeBaseWebPageElementViewDemo extends ScopedElementsMixin(DBPLitElement) { constructor() { super(); - this.lang = 'de'; + this._i18n = createInstance(); + this.lang = this._i18n.language; this.entryPointUrl = ''; this.noAuth = false; } @@ -35,7 +36,7 @@ export class KnowledgeBaseWebPageElementViewDemo extends ScopedElementsMixin(DBP update(changedProperties) { changedProperties.forEach((oldValue, propName) => { if (propName === "lang") { - i18n.changeLanguage(this.lang); + this._i18n.changeLanguage(this.lang); } }); diff --git a/packages/knowledge-base-web-page-element-view/src/i18n.js b/packages/knowledge-base-web-page-element-view/src/i18n.js index 498d9f037b0a5ca481ec8de5df24640900285808..975c1993e2a567940c74f8d957a6b2a018125548 100644 --- a/packages/knowledge-base-web-page-element-view/src/i18n.js +++ b/packages/knowledge-base-web-page-element-view/src/i18n.js @@ -1,6 +1,8 @@ -import {createInstance} from '@dbp-toolkit/common/i18next.js'; +import {createInstance as _createInstance} from '@dbp-toolkit/common/i18next.js'; import de from './i18n/de/translation.json'; import en from './i18n/en/translation.json'; -export const i18n = createInstance({en: en, de: de}, 'de', 'en'); \ No newline at end of file +export function createInstance() { + return _createInstance({en: en, de: de}, 'de', 'en'); +} \ No newline at end of file diff --git a/packages/knowledge-base-web-page-element-view/src/knowledge-base-web-page-element-view.js b/packages/knowledge-base-web-page-element-view/src/knowledge-base-web-page-element-view.js index 9b34f065e3f921b2b545fc24db7d9753d728023f..57234041559bb04593f407fd1a153f1cb3faf271 100644 --- a/packages/knowledge-base-web-page-element-view/src/knowledge-base-web-page-element-view.js +++ b/packages/knowledge-base-web-page-element-view/src/knowledge-base-web-page-element-view.js @@ -1,4 +1,4 @@ -import {i18n} from './i18n'; +import {createInstance} from './i18n'; import {html} from 'lit-element'; import {ScopedElementsMixin} from '@open-wc/scoped-elements'; import {MiniSpinner} from '@dbp-toolkit/common'; @@ -12,7 +12,8 @@ import {AdapterLitElement} from "@dbp-toolkit/provider/src/adapter-lit-element"; export class KnowledgeBaseWebPageElementView extends ScopedElementsMixin(AdapterLitElement) { constructor() { super(); - this.lang = 'de'; + this._i18n = createInstance(); + this.lang = this._i18n.language; this.value = ''; this.html = ''; this.entryPointUrl = ''; @@ -56,6 +57,8 @@ export class KnowledgeBaseWebPageElementView extends ScopedElementsMixin(Adapter * Loads the data from the web page element */ loadWebPageElement() { + const i18n = this._i18n; + if (this.auth.token === undefined || this.auth.token === "") { return; } @@ -107,7 +110,7 @@ export class KnowledgeBaseWebPageElementView extends ScopedElementsMixin(Adapter update(changedProperties) { changedProperties.forEach((oldValue, propName) => { if (propName === "lang") { - i18n.changeLanguage(this.lang); + this._i18n.changeLanguage(this.lang); } switch(propName) { diff --git a/packages/matomo/i18next-scanner.config.js b/packages/matomo/i18next-scanner.config.js index 8c277798414be902846c6eb4f0e95a19750cda39..aeb8fdb6532e6c951401ba91424e2a256353d391 100644 --- a/packages/matomo/i18next-scanner.config.js +++ b/packages/matomo/i18next-scanner.config.js @@ -6,6 +6,7 @@ module.exports = { options: { debug: false, removeUnusedKeys: true, + func: {list: ['i18n.t', '_i18n.t']}, lngs: ['en','de'], resource: { loadPath: 'src/i18n/{{lng}}/{{ns}}.json', diff --git a/packages/matomo/src/dbp-matomo-demo.js b/packages/matomo/src/dbp-matomo-demo.js index bf07bd0fe1ffe33d694511ecad22db5da9979d1b..cad9ec437c6e8d54517150ee67f4cbae2f4524de 100644 --- a/packages/matomo/src/dbp-matomo-demo.js +++ b/packages/matomo/src/dbp-matomo-demo.js @@ -1,4 +1,4 @@ -import {i18n} from './i18n.js'; +import {createInstance} from './i18n.js'; import {css, html} from 'lit-element'; import {ScopedElementsMixin} from '@open-wc/scoped-elements'; import {AuthKeycloak, LoginButton} from '@dbp-toolkit/auth'; @@ -12,7 +12,8 @@ export class MatomoDemo extends ScopedElementsMixin(DBPLitElement) { constructor() { super(); - this.lang = 'de'; + this._i18n = createInstance(); + this.lang = this._i18n.language; this.entryPointUrl = ''; this.matomoUrl = ''; this.matomoSiteId = -1; @@ -38,9 +39,14 @@ export class MatomoDemo extends ScopedElementsMixin(DBPLitElement) { }; } - connectedCallback() { - super.connectedCallback(); - i18n.changeLanguage(this.lang); + update(changedProperties) { + changedProperties.forEach((oldValue, propName) => { + if (propName === "lang") { + this._i18n.changeLanguage(this.lang); + } + }); + + super.update(changedProperties); } track(action, message) { diff --git a/packages/matomo/src/i18n.js b/packages/matomo/src/i18n.js index 498d9f037b0a5ca481ec8de5df24640900285808..975c1993e2a567940c74f8d957a6b2a018125548 100644 --- a/packages/matomo/src/i18n.js +++ b/packages/matomo/src/i18n.js @@ -1,6 +1,8 @@ -import {createInstance} from '@dbp-toolkit/common/i18next.js'; +import {createInstance as _createInstance} from '@dbp-toolkit/common/i18next.js'; import de from './i18n/de/translation.json'; import en from './i18n/en/translation.json'; -export const i18n = createInstance({en: en, de: de}, 'de', 'en'); \ No newline at end of file +export function createInstance() { + return _createInstance({en: en, de: de}, 'de', 'en'); +} \ No newline at end of file diff --git a/packages/matomo/src/i18n/de/translation.json b/packages/matomo/src/i18n/de/translation.json index 87a8a87f09208414abfad579bfa3611cbcddc57b..0967ef424bce6791893e9a57bb952f80fd536e93 100644 --- a/packages/matomo/src/i18n/de/translation.json +++ b/packages/matomo/src/i18n/de/translation.json @@ -1,5 +1 @@ -{ - "matomo": { - - } -} \ No newline at end of file +{} diff --git a/packages/matomo/src/i18n/en/translation.json b/packages/matomo/src/i18n/en/translation.json index 87a8a87f09208414abfad579bfa3611cbcddc57b..0967ef424bce6791893e9a57bb952f80fd536e93 100644 --- a/packages/matomo/src/i18n/en/translation.json +++ b/packages/matomo/src/i18n/en/translation.json @@ -1,5 +1 @@ -{ - "matomo": { - - } -} \ No newline at end of file +{} diff --git a/packages/notification/i18next-scanner.config.js b/packages/notification/i18next-scanner.config.js index 8c277798414be902846c6eb4f0e95a19750cda39..aeb8fdb6532e6c951401ba91424e2a256353d391 100644 --- a/packages/notification/i18next-scanner.config.js +++ b/packages/notification/i18next-scanner.config.js @@ -6,6 +6,7 @@ module.exports = { options: { debug: false, removeUnusedKeys: true, + func: {list: ['i18n.t', '_i18n.t']}, lngs: ['en','de'], resource: { loadPath: 'src/i18n/{{lng}}/{{ns}}.json', diff --git a/packages/notification/src/dbp-notification-demo.js b/packages/notification/src/dbp-notification-demo.js index 64d507b3c165cf586ead1baf9fffd378585b7fd7..8919e31f560935ff169f9b8109324a7ba1193b04 100644 --- a/packages/notification/src/dbp-notification-demo.js +++ b/packages/notification/src/dbp-notification-demo.js @@ -1,4 +1,4 @@ -import {i18n} from './i18n'; +import {createInstance} from './i18n'; import {send as notify} from '@dbp-toolkit/common/notification'; import {css, html, LitElement} from 'lit-element'; import {ScopedElementsMixin} from '@open-wc/scoped-elements'; @@ -9,7 +9,8 @@ import * as commonStyles from "@dbp-toolkit/common/styles"; export class NotificationDemo extends ScopedElementsMixin(LitElement) { constructor() { super(); - this.lang = 'de'; + this._i18n = createInstance(); + this.lang = this._i18n.language; } static get scopedElements() { @@ -24,13 +25,15 @@ export class NotificationDemo extends ScopedElementsMixin(LitElement) { }; } - connectedCallback() { - super.connectedCallback(); - i18n.changeLanguage(this.lang); + update(changedProperties) { + changedProperties.forEach((oldValue, propName) => { + if (propName === "lang") { + this._i18n.changeLanguage(this.lang); + } + }); - this.updateComplete.then(()=>{ - }); - } + super.update(changedProperties); + } static get styles() { // language=css @@ -42,6 +45,8 @@ export class NotificationDemo extends ScopedElementsMixin(LitElement) { } render() { + const i18n = this._i18n; + return html` <section class="section"> <div class="container"> diff --git a/packages/notification/src/i18n.js b/packages/notification/src/i18n.js index 498d9f037b0a5ca481ec8de5df24640900285808..975c1993e2a567940c74f8d957a6b2a018125548 100644 --- a/packages/notification/src/i18n.js +++ b/packages/notification/src/i18n.js @@ -1,6 +1,8 @@ -import {createInstance} from '@dbp-toolkit/common/i18next.js'; +import {createInstance as _createInstance} from '@dbp-toolkit/common/i18next.js'; import de from './i18n/de/translation.json'; import en from './i18n/en/translation.json'; -export const i18n = createInstance({en: en, de: de}, 'de', 'en'); \ No newline at end of file +export function createInstance() { + return _createInstance({en: en, de: de}, 'de', 'en'); +} \ No newline at end of file diff --git a/packages/notification/src/notification.js b/packages/notification/src/notification.js index 9faf5efda5e758cb2b349717bde53098b99e9f27..76a9c7a7ccf63d1cab0b46fea9ca5ff4e83a13ca 100644 --- a/packages/notification/src/notification.js +++ b/packages/notification/src/notification.js @@ -1,4 +1,4 @@ -import {i18n} from './i18n'; +import {createInstance} from './i18n'; import {createUUID} from './utils'; import {css, html} from 'lit-element'; import DBPLitElement from '@dbp-toolkit/common/dbp-lit-element'; @@ -10,7 +10,8 @@ import * as commonStyles from '@dbp-toolkit/common/styles'; export class Notification extends DBPLitElement { constructor() { super(); - this.lang = 'de'; + this._i18n = createInstance(); + this.lang = this._i18n.language; } /** @@ -25,7 +26,6 @@ export class Notification extends DBPLitElement { connectedCallback() { super.connectedCallback(); - i18n.changeLanguage(this.lang); const that = this; window.addEventListener("dbp-notification-send", (e) => { @@ -63,9 +63,6 @@ export class Notification extends DBPLitElement { // mark the event as handled e.preventDefault(); }); - - this.updateComplete.then(()=>{ - }); } removeMessageId(messageElementId) { diff --git a/packages/organization-select/i18next-scanner.config.js b/packages/organization-select/i18next-scanner.config.js index 8c277798414be902846c6eb4f0e95a19750cda39..aeb8fdb6532e6c951401ba91424e2a256353d391 100644 --- a/packages/organization-select/i18next-scanner.config.js +++ b/packages/organization-select/i18next-scanner.config.js @@ -6,6 +6,7 @@ module.exports = { options: { debug: false, removeUnusedKeys: true, + func: {list: ['i18n.t', '_i18n.t']}, lngs: ['en','de'], resource: { loadPath: 'src/i18n/{{lng}}/{{ns}}.json', diff --git a/packages/organization-select/src/dbp-organization-select-demo.js b/packages/organization-select/src/dbp-organization-select-demo.js index 1ece3ccbca35f1592f7ddcf21b7b928a7623b483..6d4898bc53fe8eca0390f39f08a5b65a24fb727c 100644 --- a/packages/organization-select/src/dbp-organization-select-demo.js +++ b/packages/organization-select/src/dbp-organization-select-demo.js @@ -1,4 +1,4 @@ -import {i18n} from './i18n.js'; +import {createInstance} from './i18n.js'; import {css, html} from 'lit-element'; import {ScopedElementsMixin} from '@open-wc/scoped-elements'; import {OrganizationSelect} from './organization-select.js'; @@ -10,7 +10,8 @@ import DBPLitElement from "@dbp-toolkit/common/dbp-lit-element"; export class OrganizationSelectDemo extends ScopedElementsMixin(DBPLitElement) { constructor() { super(); - this.lang = 'de'; + this._i18n = createInstance(); + this.lang = this._i18n.language; this.entryPointUrl = ''; this.noAuth = false; } @@ -32,12 +33,11 @@ export class OrganizationSelectDemo extends ScopedElementsMixin(DBPLitElement) { }; } - connectedCallback() { - super.connectedCallback(); - i18n.changeLanguage(this.lang); - - this.updateComplete.then(()=>{ - }); + update(changedProperties) { + if (changedProperties.has("lang")) { + this._i18n.changeLanguage(this.lang); + } + super.update(changedProperties); } static get styles() { diff --git a/packages/organization-select/src/i18n.js b/packages/organization-select/src/i18n.js index 498d9f037b0a5ca481ec8de5df24640900285808..975c1993e2a567940c74f8d957a6b2a018125548 100644 --- a/packages/organization-select/src/i18n.js +++ b/packages/organization-select/src/i18n.js @@ -1,6 +1,8 @@ -import {createInstance} from '@dbp-toolkit/common/i18next.js'; +import {createInstance as _createInstance} from '@dbp-toolkit/common/i18next.js'; import de from './i18n/de/translation.json'; import en from './i18n/en/translation.json'; -export const i18n = createInstance({en: en, de: de}, 'de', 'en'); \ No newline at end of file +export function createInstance() { + return _createInstance({en: en, de: de}, 'de', 'en'); +} \ No newline at end of file diff --git a/packages/organization-select/src/i18n/de/translation.json b/packages/organization-select/src/i18n/de/translation.json index 9a8c760673e85d97460be4170d00c17f070a56fc..bcef063e83ed380940cbb466442734eb7aebb3e0 100644 --- a/packages/organization-select/src/i18n/de/translation.json +++ b/packages/organization-select/src/i18n/de/translation.json @@ -1,7 +1,6 @@ { "select-organization": { "placeholder": "Bitte wählen Sie ein Institut aus", - "loading": "Wird geladen...", - "load-error": "Fehler beim Laden der Organisation" + "loading": "Wird geladen..." } } diff --git a/packages/organization-select/src/i18n/en/translation.json b/packages/organization-select/src/i18n/en/translation.json index 75e626d77190b94982f148f69203b43e5f6788bb..ff54432a4ec79b0d3232c3c9a2ab45348cc544f0 100644 --- a/packages/organization-select/src/i18n/en/translation.json +++ b/packages/organization-select/src/i18n/en/translation.json @@ -1,7 +1,6 @@ { "select-organization": { "placeholder": "Please select an organization", - "loading": "Loading...", - "load-error": "Error loading the organization" + "loading": "Loading..." } } diff --git a/packages/organization-select/src/organization-select.js b/packages/organization-select/src/organization-select.js index 578fb010fe32216d2bb8d3da1d99a034bbe52c63..d96c793701f8dad95ce2f355485c9d20c341ce32 100644 --- a/packages/organization-select/src/organization-select.js +++ b/packages/organization-select/src/organization-select.js @@ -1,7 +1,7 @@ import $ from 'jquery'; import select2 from 'select2'; import select2CSSPath from 'select2/dist/css/select2.min.css'; -import {i18n} from './i18n.js'; +import {createInstance} from './i18n.js'; import {css, html} from 'lit-element'; import * as commonUtils from '@dbp-toolkit/common/utils'; import * as commonStyles from '@dbp-toolkit/common/styles'; @@ -16,7 +16,8 @@ export class OrganizationSelect extends AdapterLitElement { constructor() { super(); this.auth = {}; - this.lang = i18n.language; + this._i18n = createInstance(); + this.lang = this._i18n.language; this.entryPointUrl = ''; this.jsonld = null; this.organizations = []; @@ -93,6 +94,7 @@ export class OrganizationSelect extends AdapterLitElement { } async updateSelect2() { + const i18n = this._i18n; await this.updateComplete; const $select = this.$('#' + this.selectId); @@ -181,7 +183,7 @@ export class OrganizationSelect extends AdapterLitElement { changedProperties.forEach((oldValue, propName) => { switch (propName) { case "lang": - i18n.changeLanguage(this.lang); + this._i18n.changeLanguage(this.lang); this.updateSelect2(); break; case "value": { diff --git a/packages/person-profile/i18next-scanner.config.js b/packages/person-profile/i18next-scanner.config.js index 8c277798414be902846c6eb4f0e95a19750cda39..aeb8fdb6532e6c951401ba91424e2a256353d391 100644 --- a/packages/person-profile/i18next-scanner.config.js +++ b/packages/person-profile/i18next-scanner.config.js @@ -6,6 +6,7 @@ module.exports = { options: { debug: false, removeUnusedKeys: true, + func: {list: ['i18n.t', '_i18n.t']}, lngs: ['en','de'], resource: { loadPath: 'src/i18n/{{lng}}/{{ns}}.json', diff --git a/packages/person-profile/src/dbp-person-profile-demo.js b/packages/person-profile/src/dbp-person-profile-demo.js index 25269ea1ae3cc082971921c2fb77da253935a5b7..dbce0a584baf5118edc368e140138b18ba918741 100644 --- a/packages/person-profile/src/dbp-person-profile-demo.js +++ b/packages/person-profile/src/dbp-person-profile-demo.js @@ -1,5 +1,5 @@ import {AuthKeycloak, LoginButton} from '@dbp-toolkit/auth'; -import {i18n} from './i18n.js'; +import {createInstance} from './i18n.js'; import {css, html} from 'lit-element'; import {ScopedElementsMixin} from '@open-wc/scoped-elements'; import DBPLitElement from '@dbp-toolkit/common/dbp-lit-element'; @@ -12,7 +12,8 @@ import {PersonSelect} from '@dbp-toolkit/person-select'; export class PersonProfileDemo extends ScopedElementsMixin(DBPLitElement) { constructor() { super(); - this.lang = 'de'; + this._i18n = createInstance(); + this.lang = this._i18n.language; this.entryPointUrl = ''; this.person = ''; this.selectedPerson = ''; @@ -42,6 +43,10 @@ export class PersonProfileDemo extends ScopedElementsMixin(DBPLitElement) { } update(changedProperties) { + if (changedProperties.has("lang")) { + this._i18n.changeLanguage(this.lang); + } + changedProperties.forEach((oldValue, propName) => { switch (propName) { case 'auth': @@ -61,7 +66,6 @@ export class PersonProfileDemo extends ScopedElementsMixin(DBPLitElement) { connectedCallback() { super.connectedCallback(); - i18n.changeLanguage(this.lang); const that = this; this.updateComplete.then(()=>{ diff --git a/packages/person-profile/src/i18n.js b/packages/person-profile/src/i18n.js index 498d9f037b0a5ca481ec8de5df24640900285808..975c1993e2a567940c74f8d957a6b2a018125548 100644 --- a/packages/person-profile/src/i18n.js +++ b/packages/person-profile/src/i18n.js @@ -1,6 +1,8 @@ -import {createInstance} from '@dbp-toolkit/common/i18next.js'; +import {createInstance as _createInstance} from '@dbp-toolkit/common/i18next.js'; import de from './i18n/de/translation.json'; import en from './i18n/en/translation.json'; -export const i18n = createInstance({en: en, de: de}, 'de', 'en'); \ No newline at end of file +export function createInstance() { + return _createInstance({en: en, de: de}, 'de', 'en'); +} \ No newline at end of file diff --git a/packages/person-profile/src/person-profile.js b/packages/person-profile/src/person-profile.js index c8118ba5b4e7647664e2b81b7f8fc9c2ddc82356..4ac5576baa5649106d56ed507628894474261ea1 100644 --- a/packages/person-profile/src/person-profile.js +++ b/packages/person-profile/src/person-profile.js @@ -1,7 +1,7 @@ import JSONLD from '@dbp-toolkit/common/jsonld'; import {css, html} from 'lit-element'; -import {i18n} from './i18n.js'; +import {createInstance} from './i18n.js'; import DBPLitElement from '@dbp-toolkit/common/dbp-lit-element'; import * as commonStyles from '@dbp-toolkit/common/styles'; @@ -10,7 +10,8 @@ export class PersonProfile extends DBPLitElement { constructor() { super(); - this.lang = 'de'; + this._i18n = createInstance(); + this.lang = this._i18n.language; this.entryPointUrl = ''; this.jsonld = null; this.value = ''; @@ -29,18 +30,11 @@ export class PersonProfile extends DBPLitElement { }; } - connectedCallback() { - super.connectedCallback(); - - this.updateComplete.then(()=>{ - }); - } - update(changedProperties) { changedProperties.forEach((oldValue, propName) => { switch (propName) { case "lang": - i18n.changeLanguage(this.lang); + this._i18n.changeLanguage(this.lang); break; case "entryPointUrl": { const that = this; @@ -83,6 +77,7 @@ export class PersonProfile extends DBPLitElement { } render() { + const i18n = this._i18n; let role = i18n.t('person-profile.unknown'); if (this.person !== null && this.person.roles !== undefined) { // roles are only defined for self-disclosure diff --git a/packages/person-select/i18next-scanner.config.js b/packages/person-select/i18next-scanner.config.js index 8c277798414be902846c6eb4f0e95a19750cda39..aeb8fdb6532e6c951401ba91424e2a256353d391 100644 --- a/packages/person-select/i18next-scanner.config.js +++ b/packages/person-select/i18next-scanner.config.js @@ -6,6 +6,7 @@ module.exports = { options: { debug: false, removeUnusedKeys: true, + func: {list: ['i18n.t', '_i18n.t']}, lngs: ['en','de'], resource: { loadPath: 'src/i18n/{{lng}}/{{ns}}.json', diff --git a/packages/person-select/src/dbp-person-select-demo.js b/packages/person-select/src/dbp-person-select-demo.js index affc7c0a2317a49fda553cf524dca9ec9b500059..9bc90931d9cea7323bc50a5cad05f3c543e2cd1f 100644 --- a/packages/person-select/src/dbp-person-select-demo.js +++ b/packages/person-select/src/dbp-person-select-demo.js @@ -1,4 +1,4 @@ -import {i18n} from './i18n.js'; +import {createInstance} from './i18n.js'; import {css, html} from 'lit-element'; import {ScopedElementsMixin} from '@open-wc/scoped-elements'; import {PersonSelect} from './person-select.js'; @@ -10,7 +10,8 @@ import DBPLitElement from "@dbp-toolkit/common/dbp-lit-element"; export class PersonSelectDemo extends ScopedElementsMixin(DBPLitElement) { constructor() { super(); - this.lang = 'de'; + this._i18n = createInstance(); + this.lang = this._i18n.language; this.entryPointUrl = ''; this.noAuth = false; } @@ -32,14 +33,6 @@ export class PersonSelectDemo extends ScopedElementsMixin(DBPLitElement) { }; } - connectedCallback() { - super.connectedCallback(); - i18n.changeLanguage(this.lang); - - this.updateComplete.then(()=>{ - }); - } - static get styles() { // language=css return [ @@ -52,6 +45,13 @@ export class PersonSelectDemo extends ScopedElementsMixin(DBPLitElement) { ]; } + update(changedProperties) { + if (changedProperties.has("lang")) { + this._i18n.changeLanguage(this.lang); + } + super.update(changedProperties); + } + getAuthComponentHtml() { return this.noAuth ? html`<dbp-login-button subscribe="auth" lang="${this.lang}" show-image></dbp-login-button>` : html` <div class="container"> diff --git a/packages/person-select/src/i18n.js b/packages/person-select/src/i18n.js index 498d9f037b0a5ca481ec8de5df24640900285808..975c1993e2a567940c74f8d957a6b2a018125548 100644 --- a/packages/person-select/src/i18n.js +++ b/packages/person-select/src/i18n.js @@ -1,6 +1,8 @@ -import {createInstance} from '@dbp-toolkit/common/i18next.js'; +import {createInstance as _createInstance} from '@dbp-toolkit/common/i18next.js'; import de from './i18n/de/translation.json'; import en from './i18n/en/translation.json'; -export const i18n = createInstance({en: en, de: de}, 'de', 'en'); \ No newline at end of file +export function createInstance() { + return _createInstance({en: en, de: de}, 'de', 'en'); +} \ No newline at end of file diff --git a/packages/person-select/src/i18n/de/translation.json b/packages/person-select/src/i18n/de/translation.json index b5a39b9b0233a12199919e4ada0143951c842bad..4528f9010fd698f94f26739d01e2d1eb9a6d6b41 100644 --- a/packages/person-select/src/i18n/de/translation.json +++ b/packages/person-select/src/i18n/de/translation.json @@ -1,7 +1,6 @@ { "person-select": { "placeholder": "Bitte wählen Sie eine Person aus", - "error-summary": "Ein Fehler ist aufgetreten", "login-required": "Anmeldung erforderlich" } } diff --git a/packages/person-select/src/i18n/en/translation.json b/packages/person-select/src/i18n/en/translation.json index a89cdb1a16632a3b5255230cb5b33d93d2a28a4c..9bcb748c767c334de390e3c032250dd01f91c088 100644 --- a/packages/person-select/src/i18n/en/translation.json +++ b/packages/person-select/src/i18n/en/translation.json @@ -1,7 +1,6 @@ { "person-select": { "placeholder": "Please select a person", - "error-summary": "An error occurred", "login-required": "Login required" } } diff --git a/packages/person-select/src/person-select.js b/packages/person-select/src/person-select.js index 67c7466650d0c0ce0cda1ce440c9454de18d6a52..68d96a1e9c14d1078e6a746e3a6aab4a639c56f7 100644 --- a/packages/person-select/src/person-select.js +++ b/packages/person-select/src/person-select.js @@ -6,7 +6,7 @@ import select2LangEn from './i18n/en/select2'; import JSONLD from '@dbp-toolkit/common/jsonld'; import {css, html} from 'lit-element'; import {ScopedElementsMixin} from '@open-wc/scoped-elements'; -import {i18n} from './i18n.js'; +import {createInstance} from './i18n.js'; import {Icon} from '@dbp-toolkit/common'; import * as commonUtils from '@dbp-toolkit/common/utils'; import * as commonStyles from '@dbp-toolkit/common/styles'; @@ -29,7 +29,8 @@ export class PersonSelect extends ScopedElementsMixin(AdapterLitElement) { super(); Object.assign(PersonSelect.prototype, errorUtils.errorMixin); this.auth = {}; - this.lang = 'de'; + this._i18n = createInstance(); + this.lang = this._i18n.language; this.entryPointUrl = ''; this.jsonld = null; this.$select = null; @@ -129,6 +130,7 @@ export class PersonSelect extends ScopedElementsMixin(AdapterLitElement) { * @param ignorePreset */ initSelect2(ignorePreset = false) { + const i18n = this._i18n; const that = this; const $this = $(this); @@ -155,7 +157,7 @@ export class PersonSelect extends ScopedElementsMixin(AdapterLitElement) { width: '100%', language: this.lang === "de" ? select2LangDe() : select2LangEn(), minimumInputLength: 2, - placeholder: i18n.t(this.authenticated() ? 'person-select.placeholder' : 'person-select.login-required'), + placeholder: this.authenticated() ? i18n.t('person-select.placeholder') : i18n.t('person-select.login-required'), dropdownParent: this.$('#person-select-dropdown'), ajax: { delay: 500, @@ -277,7 +279,7 @@ export class PersonSelect extends ScopedElementsMixin(AdapterLitElement) { changedProperties.forEach((oldValue, propName) => { switch (propName) { case "lang": - i18n.changeLanguage(this.lang); + this._i18n.changeLanguage(this.lang); if (this.select2IsInitialized()) { // no other way to set an other language at runtime did work @@ -361,6 +363,7 @@ export class PersonSelect extends ScopedElementsMixin(AdapterLitElement) { } render() { + const i18n = this._i18n; const select2CSS = commonUtils.getAssetURL(select2CSSPath); return html` <link rel="stylesheet" href="${select2CSS}"> diff --git a/packages/provider/i18next-scanner.config.js b/packages/provider/i18next-scanner.config.js index 8c277798414be902846c6eb4f0e95a19750cda39..aeb8fdb6532e6c951401ba91424e2a256353d391 100644 --- a/packages/provider/i18next-scanner.config.js +++ b/packages/provider/i18next-scanner.config.js @@ -6,6 +6,7 @@ module.exports = { options: { debug: false, removeUnusedKeys: true, + func: {list: ['i18n.t', '_i18n.t']}, lngs: ['en','de'], resource: { loadPath: 'src/i18n/{{lng}}/{{ns}}.json', diff --git a/packages/provider/src/dbp-provider-demo.js b/packages/provider/src/dbp-provider-demo.js index c47ca1852cf503078b12f2bc454dd5ffcb8a53f8..634c11fc7e0e86bb2d883e28f04b6638128ce0bb 100644 --- a/packages/provider/src/dbp-provider-demo.js +++ b/packages/provider/src/dbp-provider-demo.js @@ -1,4 +1,4 @@ -import {i18n} from './i18n.js'; +import {createInstance} from './i18n.js'; import {css, html} from 'lit-element'; import {ScopedElementsMixin} from '@open-wc/scoped-elements'; import {AuthKeycloak, LoginButton} from '@dbp-toolkit/auth'; @@ -14,7 +14,8 @@ class ProviderDemo extends ScopedElementsMixin(DBPLitElement) { constructor() { super(); - this.lang = 'de'; + this._i18n = createInstance(); + this.lang = this._i18n.language; } static get scopedElements() { @@ -35,18 +36,12 @@ class ProviderDemo extends ScopedElementsMixin(DBPLitElement) { }; } - connectedCallback() { - super.connectedCallback(); - i18n.changeLanguage(this.lang); - - } - attributeChangedCallback(name, oldValue, newValue) { console.debug('ProviderDemo (' + this.id + ') attributeChangesCallback( ' + name + ', ' + oldValue + ', ' + newValue + ')'); switch(name) { case 'lang': this.lang = newValue; - i18n.changeLanguage(this.lang); + this._i18n.changeLanguage(this.lang); break; default: super.attributeChangedCallback(name, oldValue, newValue); @@ -71,6 +66,7 @@ class ProviderDemo extends ScopedElementsMixin(DBPLitElement) { } render() { + const i18n = this._i18n; return html` <section class="section"> <p>${i18n.t('demo.provider_description', {id: "root", description: "is the top most in hierarchy"})}</p> @@ -142,7 +138,8 @@ class DemoConsumer extends DBPLitElement { constructor() { super(); - this.lang = 'de'; + this._i18n = createInstance(); + this.lang = this._i18n.language; this.entryPointUrl = ''; // default values this.foo = 100; @@ -157,7 +154,6 @@ class DemoConsumer extends DBPLitElement { connectedCallback() { super.connectedCallback(); - i18n.changeLanguage(this.lang); console.debug('DemoConsumer(' + this.id + ') connectedCallback()'); this.render(); } @@ -184,7 +180,7 @@ class DemoConsumer extends DBPLitElement { switch(name) { case 'lang': this.lang = newValue; - i18n.changeLanguage(this.lang); + this._i18n.changeLanguage(this.lang); break; case 'foo': this.foo = parseInt(newValue); @@ -209,6 +205,7 @@ class DemoConsumer extends DBPLitElement { } render() { + const i18n = this._i18n; if (! this.connected) { return `not connected!`; } diff --git a/packages/provider/src/i18n.js b/packages/provider/src/i18n.js index 498d9f037b0a5ca481ec8de5df24640900285808..975c1993e2a567940c74f8d957a6b2a018125548 100644 --- a/packages/provider/src/i18n.js +++ b/packages/provider/src/i18n.js @@ -1,6 +1,8 @@ -import {createInstance} from '@dbp-toolkit/common/i18next.js'; +import {createInstance as _createInstance} from '@dbp-toolkit/common/i18next.js'; import de from './i18n/de/translation.json'; import en from './i18n/en/translation.json'; -export const i18n = createInstance({en: en, de: de}, 'de', 'en'); \ No newline at end of file +export function createInstance() { + return _createInstance({en: en, de: de}, 'de', 'en'); +} \ No newline at end of file diff --git a/packages/provider/src/i18n/de/translation.json b/packages/provider/src/i18n/de/translation.json index 981c4287b852d1888e6e42792423d9799ae9fc83..650f83a0c7b12b219550dcf82b663ba8ebb5954a 100644 --- a/packages/provider/src/i18n/de/translation.json +++ b/packages/provider/src/i18n/de/translation.json @@ -1,7 +1,4 @@ { - "de": "Deutsch", - "en": "Englisch", - "demo": { "provider": "Anbieter", "consumer": "Verbraucher", @@ -13,4 +10,4 @@ "price": "Preis", "sum": "Summe" } -} \ No newline at end of file +} diff --git a/packages/provider/src/i18n/en/translation.json b/packages/provider/src/i18n/en/translation.json index bc342774e83864c5cd6c4e4fda3c2f41c33847fa..e511b79f6a21db9fe5ea29cf912c4308604ba5ce 100644 --- a/packages/provider/src/i18n/en/translation.json +++ b/packages/provider/src/i18n/en/translation.json @@ -1,7 +1,4 @@ { - "de": "German", - "en": "English", - "demo": { "provider": "Provider", "consumer": "Consumer", @@ -13,4 +10,4 @@ "price": "Price", "sum": "sum" } -} \ No newline at end of file +} diff --git a/packages/qr-code-scanner/i18next-scanner.config.js b/packages/qr-code-scanner/i18next-scanner.config.js index 8c277798414be902846c6eb4f0e95a19750cda39..aeb8fdb6532e6c951401ba91424e2a256353d391 100644 --- a/packages/qr-code-scanner/i18next-scanner.config.js +++ b/packages/qr-code-scanner/i18next-scanner.config.js @@ -6,6 +6,7 @@ module.exports = { options: { debug: false, removeUnusedKeys: true, + func: {list: ['i18n.t', '_i18n.t']}, lngs: ['en','de'], resource: { loadPath: 'src/i18n/{{lng}}/{{ns}}.json', diff --git a/packages/qr-code-scanner/src/dbp-qr-code-scanner-demo.js b/packages/qr-code-scanner/src/dbp-qr-code-scanner-demo.js index 4b8bd63a9cd19c061033a41eda7c5e5246159706..2b78a7406b6baed80eb5ba6643882ad86abb6534 100644 --- a/packages/qr-code-scanner/src/dbp-qr-code-scanner-demo.js +++ b/packages/qr-code-scanner/src/dbp-qr-code-scanner-demo.js @@ -1,4 +1,4 @@ -import {i18n} from './i18n'; +import {createInstance} from './i18n'; import {css, html, LitElement} from 'lit-element'; import {ScopedElementsMixin} from '@open-wc/scoped-elements'; import * as commonUtils from '@dbp-toolkit/common/utils'; @@ -8,7 +8,8 @@ import {QrCodeScanner} from './qr-code-scanner.js'; export class QrCodeScannerDemo extends ScopedElementsMixin(LitElement) { constructor() { super(); - this.lang = 'de'; + this._i18n = createInstance(); + this.lang = this._i18n.language; } static get scopedElements() { @@ -23,12 +24,11 @@ export class QrCodeScannerDemo extends ScopedElementsMixin(LitElement) { }; } - connectedCallback() { - super.connectedCallback(); - i18n.changeLanguage(this.lang); - - this.updateComplete.then(()=>{ - }); + update(changedProperties) { + if (changedProperties.has("lang")) { + this._i18n.changeLanguage(this.lang); + } + super.update(changedProperties); } static get styles() { diff --git a/packages/qr-code-scanner/src/i18n.js b/packages/qr-code-scanner/src/i18n.js index 498d9f037b0a5ca481ec8de5df24640900285808..975c1993e2a567940c74f8d957a6b2a018125548 100644 --- a/packages/qr-code-scanner/src/i18n.js +++ b/packages/qr-code-scanner/src/i18n.js @@ -1,6 +1,8 @@ -import {createInstance} from '@dbp-toolkit/common/i18next.js'; +import {createInstance as _createInstance} from '@dbp-toolkit/common/i18next.js'; import de from './i18n/de/translation.json'; import en from './i18n/en/translation.json'; -export const i18n = createInstance({en: en, de: de}, 'de', 'en'); \ No newline at end of file +export function createInstance() { + return _createInstance({en: en, de: de}, 'de', 'en'); +} \ No newline at end of file diff --git a/packages/qr-code-scanner/src/i18n/de/translation.json b/packages/qr-code-scanner/src/i18n/de/translation.json index da2f50d51d479a5681cf064b3728131613f33301..652c7eec581270a762169ee1e7115c00b779e48e 100644 --- a/packages/qr-code-scanner/src/i18n/de/translation.json +++ b/packages/qr-code-scanner/src/i18n/de/translation.json @@ -1,7 +1,6 @@ { "no-camera-access": "Zugriff auf Kamera nicht möglich.", "check-access": "Bitte stellen Sie sicher, dass eine Webcam oder Kamera aktiviert ist und überprüfen Sie ob Ihr Browser die notwendigen Berechtigungen besitzt.", - "finished-scan": "Scannen abgeschlossen.", "loading-video": "Video laden ...", "no-qr-detected": "Kein QR-Code erkannt.", "no-support": "Ihr Browser unterstützt keine Videoaufnahmen.", diff --git a/packages/qr-code-scanner/src/i18n/en/translation.json b/packages/qr-code-scanner/src/i18n/en/translation.json index 59ef87c97203b8b1506cf3c56cdae413a319c3bb..cb653c89b4a8f597518943fa7142720cb52695a5 100644 --- a/packages/qr-code-scanner/src/i18n/en/translation.json +++ b/packages/qr-code-scanner/src/i18n/en/translation.json @@ -1,7 +1,6 @@ { "no-camera-access": "Unable to access video stream.", "check-access": "Please make sure that a webcam or camera is activated and check whether your browser has the necessary authorizations.", - "finished-scan": "Finished scanning.", "loading-video": "⌛ Loading video...", "no-qr-detected": "No QR code detected.", "no-support": "Your browser does not support video recording.", diff --git a/packages/qr-code-scanner/src/qr-code-scanner.js b/packages/qr-code-scanner/src/qr-code-scanner.js index 59bda21bbe7d608217691e8b404110f4eb36a8bd..4b07ef0123111d86b55c814547fcb31836bb59bc 100644 --- a/packages/qr-code-scanner/src/qr-code-scanner.js +++ b/packages/qr-code-scanner/src/qr-code-scanner.js @@ -1,4 +1,4 @@ -import {i18n} from './i18n'; +import {createInstance} from './i18n'; import {css, html, unsafeCSS} from 'lit-element'; import DBPLitElement from '@dbp-toolkit/common/dbp-lit-element'; import * as commonStyles from '@dbp-toolkit/common/styles'; @@ -33,9 +33,10 @@ function getPrimaryDevice(devices) { * * Moreimportant devices first. * + * @param i18n * @returns {Map<string,string>} the map of devices */ -async function getVideoDevices() { +async function getVideoDevices(i18n) { let devices_map = new Map(); if (navigator.mediaDevices && navigator.mediaDevices.enumerateDevices @@ -135,7 +136,8 @@ class QRScanner { export class QrCodeScanner extends ScopedElementsMixin(DBPLitElement) { constructor() { super(); - this.lang = 'de'; + this._i18n = createInstance(); + this.lang = this._i18n.language; this._askPermission = false; this._loading = false; @@ -181,9 +183,8 @@ export class QrCodeScanner extends ScopedElementsMixin(DBPLitElement) { async connectedCallback() { super.connectedCallback(); - i18n.changeLanguage(this.lang); - let devices = await getVideoDevices(); + let devices = await getVideoDevices(this._i18n); this._activeCamera = getPrimaryDevice(devices) || ''; this._devices = devices; @@ -209,7 +210,7 @@ export class QrCodeScanner extends ScopedElementsMixin(DBPLitElement) { changedProperties.forEach((oldValue, propName) => { switch (propName) { case "lang": - i18n.changeLanguage(this.lang); + this._i18n.changeLanguage(this.lang); break; } }); @@ -232,6 +233,7 @@ export class QrCodeScanner extends ScopedElementsMixin(DBPLitElement) { } async _startScanning() { + const i18n = this._i18n; console.assert(this._lock.isLocked()); await this.updateComplete; @@ -488,6 +490,7 @@ export class QrCodeScanner extends ScopedElementsMixin(DBPLitElement) { } render() { + const i18n = this._i18n; let hasDevices = this._devices.size > 0; let showCanvas = this._videoRunning && !this._askPermission && !this._loading; let noSupportString = checkIosMobileSupport(this._devices) ? i18n.t('no-ios-support') : i18n.t('no-support'); diff --git a/packages/typescript-example/src/i18n.ts b/packages/typescript-example/src/i18n.ts index 498d9f037b0a5ca481ec8de5df24640900285808..975c1993e2a567940c74f8d957a6b2a018125548 100644 --- a/packages/typescript-example/src/i18n.ts +++ b/packages/typescript-example/src/i18n.ts @@ -1,6 +1,8 @@ -import {createInstance} from '@dbp-toolkit/common/i18next.js'; +import {createInstance as _createInstance} from '@dbp-toolkit/common/i18next.js'; import de from './i18n/de/translation.json'; import en from './i18n/en/translation.json'; -export const i18n = createInstance({en: en, de: de}, 'de', 'en'); \ No newline at end of file +export function createInstance() { + return _createInstance({en: en, de: de}, 'de', 'en'); +} \ No newline at end of file diff --git a/packages/typescript-example/src/typescript-example.ts b/packages/typescript-example/src/typescript-example.ts index 60fe3c8c7fc3fed194fa1b63b65d11d1e4c48820..a7c6503ad91cc8541706dcd6470243f269517819 100644 --- a/packages/typescript-example/src/typescript-example.ts +++ b/packages/typescript-example/src/typescript-example.ts @@ -1,5 +1,5 @@ -import {html,LitElement,property} from 'lit-element'; -import {i18n} from './i18n'; +import {html,LitElement} from 'lit-element'; +import {createInstance} from './i18n'; export class TypeScriptExample extends LitElement { @@ -8,20 +8,20 @@ export class TypeScriptExample extends LitElement { constructor() { super(); - this._i18n = i18n.cloneInstance(); + this._i18n = createInstance(); + this.lang = this._i18n.language; } - @property({type: String}) - lang = ''; + static get properties() { + return { + lang: {type: String} + }; + } update(changedProperties) { - changedProperties.forEach((oldValue, propName) => { - switch (propName) { - case "lang": - this._i18n.changeLanguage(this.lang); - break; - } - }); + if (changedProperties.has("lang")) { + this._i18n.changeLanguage(this.lang); + } super.update(changedProperties); }