Something went wrong on our end
Select Git revision
-
Volker Schukai authoredVolker Schukai authored
embed.mjs 4.33 KiB
/**
* Copyright schukai GmbH and contributors 2022. All Rights Reserved.
* Node module: @schukai/monster
* This file is licensed under the AGPLv3 License.
* License text available at https://www.gnu.org/licenses/agpl-3.0.en.html
*/
import {internalSymbol} from "../../constants.mjs";
import {extend} from "../../data/extend.mjs";
import {getDocument} from "../../dom/util.mjs";
import {isString} from "../../types/is.mjs";
import {validateObject, validateString} from "../../types/validate.mjs";
import {parseLocale} from "../locale.mjs";
import {Provider} from "../provider.mjs";
import {Translations} from "../translations.mjs";
export {Embed};
/**
* The Embed provider retrieves a JSON file from the given Script Tag.
*
* @externalExample ../../../example/i18n/providers/embed.mjs
* @license AGPLv3
* @since 1.13.0
* @copyright schukai GmbH
* @memberOf Monster.I18n.Providers
* @see {@link https://datatracker.ietf.org/doc/html/rfc3066}
* @tutorial i18n-locale-and-formatter
*/
class Embed extends Provider {
/**
* ```html
* <script id="translations" type="application/json">
* {
* "hello": "Hallo"
* }
* </script>
* ```
*
*
* ```javascript
* new Embed('translations')
* ```
*
* @param {HTMLElement|string} elementOrId
* @param {Object} options
*/
constructor(elementOrId, options) {
super(options);
if (options === undefined) {
options = {};
}
if (elementOrId instanceof HTMLElement) {
/**
* @property {HTMLElement|string}
*/
this.translateElement = elementOrId;
} else {
/**
* @property {HTMLElement|string}
*/
this.translateElement = getDocument().getElementById(validateString(elementOrId));
}
/**
* @private
* @property {Object} options
*/
this[internalSymbol] = extend({}, super.defaults, this.defaults, validateObject(options));
}
/**
* Defaults
*
* @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API}
*/
get defaults() {
return extend({}, super.defaults);
}
/**
*
* @param {Locale|string} locale
* @return {Promise}
*/
getTranslations(locale) {
if (isString(locale)) {
locale = parseLocale(locale);
}
return new Promise((resolve, reject) => {
if (this.translateElement === null) {
reject(new Error("Text not found"));
return;
}
if (!(this.translateElement instanceof HTMLScriptElement)) {
reject(new Error("Element is not a script tag"));
return;
}
if (this.translateElement.type !== "application/json") {
reject(new Error("Element is not a script tag with type application/json"));
return;
}
let translations = null;
try {
translations = JSON.parse(this.translateElement.innerHTML);
} catch (e) {
reject(e);
return;
}
if (translations === null) {
reject(new Error("Translations not found or invalid"));
return;
}
const t = new Translations(locale);
t.assignTranslations(translations);
resolve(t);
});
}
/**
* Initializes the translations for the current document.
*
* `script[data-monster-role=translations]` is searched for and the translations are assigned to the element.
*
* @param element
* @returns {Promise<unknown[]>}
*/
static assignTranslationsToElement(element) {
const d = getDocument()
if (!(element instanceof HTMLElement)) {
element = d.querySelector("body");
}
const list = d.querySelectorAll("script[data-monster-role=translations]");
if (list === null) {
return;
}
const promises = [];
let result
list.forEach((translationElement) => {
const p = new Embed(translationElement);
promises.push(p.assignToElement(undefined, element));
});
return Promise.all(promises);
}
}