Skip to content
Snippets Groups Projects
Select Git revision
  • a1fa21a41031cc07966cf851c85c9ae0e4c45ffa
  • master default protected
  • 1.31
  • 4.34.1
  • 4.34.0
  • 4.33.1
  • 4.33.0
  • 4.32.2
  • 4.32.1
  • 4.32.0
  • 4.31.0
  • 4.30.1
  • 4.30.0
  • 4.29.1
  • 4.29.0
  • 4.28.0
  • 4.27.0
  • 4.26.0
  • 4.25.5
  • 4.25.4
  • 4.25.3
  • 4.25.2
  • 4.25.1
23 results

Monster.Data.Transformer.html

Blame
  • 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);
        }
        
    }