diff --git a/application/example/i18n/providers/embed.mjs b/application/example/i18n/providers/embed.mjs index 52912ff1a24444d0a8678586f078fcc0d0a0d899..652669adef0d678a4abab9faf72f0889a5069c80 100644 --- a/application/example/i18n/providers/embed.mjs +++ b/application/example/i18n/providers/embed.mjs @@ -1,5 +1,5 @@ import {Embed} from '@schukai/monster/source/i18n/providers/embed.mjs'; -// read from scritp tag with id i18n +// read from script tag with id i18n const translation = new Embed('i18n'); diff --git a/application/source/dom/customelement.mjs b/application/source/dom/customelement.mjs index 0cccfb1b2ffb8159d0f27e1a2590c483f7b4ac9a..3b991a412732c12d627db5afbe8fd418c23ac0ea 100644 --- a/application/source/dom/customelement.mjs +++ b/application/source/dom/customelement.mjs @@ -295,25 +295,45 @@ class CustomElement extends HTMLElement { * Before you can use this method, you must have loaded the translations. * * @returns {Monster.DOM.CustomElement} + * @throws {Error} Cannot find element with translations. Add a translations object to the document. */ updateI18n() { - const translations = getDocumentTranslations(); if (!translations) { return this; } - const labels = this.getOption("labels"); - if (!isIterable(labels)) { + let labels = this.getOption("labels"); + if (!(isObject(labels) || isIterable(labels))) { return this; } for (const key in labels) { - const text = translations.getText(key, labels[key]); - if (text !== labels[key]) { - this.setOption("labels." + key, text); + const def = labels[key]; + + if (isString(def)) { + const text = translations.getText(key, def); + if (text !== def) { + this.setOption("labels." + key, text); + } + continue; + } else if (isObject(def)) { + for (const k in def) { + const d = def[k]; + + const text = translations.getPluralRuleText(key, k, d); + if (!isString(text)) { + throw new Error("Invalid labels definition"); + } + if (text !== d) { + this.setOption("labels." + key + "." + k, text); + } + } + continue; } + throw new Error("Invalid labels definition"); + } return this; } @@ -973,10 +993,10 @@ function registerCustomElement(element) { if (customElements === undefined) { throw new Error("customElements is not supported."); } - + if (customElements.get(element.getTag()) !== undefined) { return; } - + customElements.define(element.getTag(), element); } diff --git a/application/source/i18n/translations.mjs b/application/source/i18n/translations.mjs index 8d6836938266c993ab706ee0802f54787955bfa8..a575d87dadc6984ad0d108367222f85a4c33fed8 100644 --- a/application/source/i18n/translations.mjs +++ b/application/source/i18n/translations.mjs @@ -104,7 +104,7 @@ class Translations extends Base { } else { count = validateInteger(count); if (count === 0) { - // special handlig for zero count + // special handling for zero count if (r.hasOwnProperty("zero")) { return validateString(r["zero"]); } diff --git a/development/playground/i18n-control/index.html b/development/playground/i18n-control/index.html new file mode 100644 index 0000000000000000000000000000000000000000..5113abe71aa55e92771ec8c7f8407fb15d811f9e --- /dev/null +++ b/development/playground/i18n-control/index.html @@ -0,0 +1,24 @@ +<!DOCTYPE html> +<html lang="en"> +<head> + <script type="module" src="main.mjs"></script> +</head> +<body> +<h1>Updater</h1> + +<script type="application/json" data-monster-role="translations"> + { + "theListContainsNoEntries": "translation1", + "key2": { + "other": "translation2" + }, + "multi": { + "two": "translation3" + } + } +</script> + +<monster-1>Monster1</monster-1> + +</body> +</html> diff --git a/development/playground/i18n-control/main.mjs b/development/playground/i18n-control/main.mjs new file mode 100644 index 0000000000000000000000000000000000000000..7bfa80beb59562ea05af688c961ce184a06c472e --- /dev/null +++ b/development/playground/i18n-control/main.mjs @@ -0,0 +1,76 @@ +import {Fetch} from '../../../application/source/i18n/providers/fetch.mjs'; +import {Updater} from '../../../application/source/dom/updater.mjs'; +import {CustomElement, registerCustomElement} from '../../../application/source/dom/customelement.mjs'; +import {domReady} from '../../../application/source/dom/ready.mjs'; +import {Embed} from '../../../application/source/i18n/providers/embed.mjs'; + + +class Monster1 extends CustomElement { + + + get defaults() { + return Object.assign( + {}, + super.defaults, + { + labels: { + theListContainsNoEntries: "The list contains no entries", + multi: { + zero: "Zero", + one: "One", + two: "Two", + few: "Few", + many: "Many", + other: "Other" + + } + } + }); + }; + + /** + * + * @return {string} + */ + static getTag() { + return "monster-1"; + } + +} + + +domReady.then(() => { + + Embed.assignTranslationsToElement().then(() => { + m1.updateI18n(); + console.log(m1.getOption('labels')); + console.log(m1.getOption('labels.multi.two')); + }); + + const translation = new Embed('i18n'); + const m1 = document.querySelector("monster-1"); + + +// read from scritp tag with id i18n + + +}); + +registerCustomElement(Monster1); + +// +// const provider = new Fetch('translation.json', { +// method: 'GET', +// headers: { +// 'Content-Type': 'application/json', +// }, +// }); +// +// provider +// .assignToElement() +// .then(() => { +// new Updater(document.body, {}).run(); +// }) +// .catch((e) => { +// console.error(e); +// }); diff --git a/development/playground/i18n-control/translation.json b/development/playground/i18n-control/translation.json new file mode 100644 index 0000000000000000000000000000000000000000..88b3d7123ad3385ca8ae033933b77a3bb4efbe42 --- /dev/null +++ b/development/playground/i18n-control/translation.json @@ -0,0 +1,4 @@ +{ + "key1": "value1", + "key2": "value2" +} \ No newline at end of file