Skip to content
Snippets Groups Projects
Select Git revision
  • 5c9878ccecf56ed2ef6254d8331cd7ef93a025b4
  • 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

resourcemanager.mjs

Blame
  • resourcemanager.mjs 5.25 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 { extend } from "../data/extend.mjs";
    import { Base } from "../types/base.mjs";
    import { getGlobalObject } from "../types/global.mjs";
    import {equipWithInternal} from "../types/internal.mjs";
    import { isArray } from "../types/is.mjs";
    import { ATTRIBUTE_HREF, ATTRIBUTE_SRC } from "./constants.mjs";
    import { Resource } from "./resource.mjs";
    import { Data } from "./resource/data.mjs";
    import { Stylesheet } from "./resource/link/stylesheet.mjs";
    import { Script } from "./resource/script.mjs";
    
    export { ResourceManager };
    
    /**
     * The ResourceManager is a singleton that manages all resources.
     *
     * @license AGPLv3
     * @since 1.25.0
     * @copyright schukai GmbH
     * @memberOf Monster.DOM
     * @summary A Resource class
     */
    class ResourceManager extends Base {
        /**
         *
         * @param {Object} options
         * throw {Error} unsupported document type
         */
        constructor(options) {
            super(options);
            equipWithInternal.call(this);
    
            if (!(this.getOption("document") instanceof Document)) {
                throw new Error("unsupported document type");
            }
        }
    
        /**
         * @deprecated since 3.15.0 use getInternal instead
         * @property {string} baseurl
         */
        getOption(key) {
            return this.getInternal(key);
        }
    
        /**
         * @property {string} baseurl
         */
        getBaseURL() {
            this.getOption("document")?.baseURL;
        }
    
        /**
         * @property {string} baseurl
         * @deprecated since 3.15.0 use internalDefaults instead
         */
        get defaults() {
            return this.internalDefaults;
        }
    
        /**
         *
         * @property {HTMLDocument} document=document Document
         * @property {Object} resources
         * @property {Array} resources.scripts=[] array with {@link Monster.DOM.Resource.Script} objects
         * @property {Array} resources.stylesheets=[] array with {@link Monster.DOM.Resource.Link.Stylesheet} objects
         * @property {Array} resources.data=[] array with {@link Monster.DOM.Resource.Data} objects
         */
        get internalDefaults() {
            return Object.assign({},  {
                document: getGlobalObject("document"),
                resources: {
                    scripts: [],
                    stylesheets: [],
                    data: [],
                },
            });
        }
    
        /**
         * Append Tags to DOM
         *
         * @return {Monster.DOM.ResourceManager}
         * @throws {Error} unsupported resource definition
         */
        connect() {
            runResourceMethod.call(this, "connect");
            return this;
        }
    
        /**
         * Check if available
         *
         * @return {Promise}
         * @throws {Error} unsupported resource definition
         */
        available() {
            return Promise.all(runResourceMethod.call(this, "available"));
        }
    
        /**
         * Add a script
         *
         * @param {string|URL} url
         * @param [Object|undefined} options
         * @return {Monster.DOM.ResourceManager}
         * @see Monster.DOM.Resource.Script
         */
        addScript(url, options) {
            return addResource.call(this, "scripts", url, options);
        }
    
        /**
         * Add Stylesheet
         *
         * @param {string|URL} url
         * @param [Object|undefined} options
         * @return {Monster.DOM.ResourceManager}
         * @see Monster.DOM.Resource.Link.Stylesheet
         */
        addStylesheet(url, options) {
            return addResource.call(this, "stylesheets", url, options);
        }
    
        /**
         * Add Data Tag
         *
         * @param {string|URL} url
         * @param [Object|undefined} options
         * @return {Monster.DOM.ResourceManager}
         * @see Monster.DOM.Resource.Data
         */
        addData(url, options) {
            return addResource.call(this, "data", url, options);
        }
    }
    
    /**
     * @private
     * @param {string} method
     * @return {Array}
     */
    function runResourceMethod(method) {
        const self = this;
    
        const result = [];
    
        for (const type of ["scripts", "stylesheets", "data"]) {
            const resources = self.getOption(`resources.${type}`);
            if (!isArray(resources)) {
                continue;
            }
    
            for (const resource of resources) {
                if (!(resource instanceof Resource)) {
                    throw new Error("unsupported resource definition");
                }
    
                result.push(resource[method]());
            }
        }
    
        return result;
    }
    
    /**
     *
     * @param {string} type
     * @param {string|URL} url
     * @param [Object|undefined} options
     * @return {Monster.DOM.ResourceManager}
     * @private
     */
    function addResource(type, url, options) {
        const self = this;
    
        if (url instanceof URL) {
            url = url.toString();
        }
    
        options = options || {};
    
        let resource;
        switch (type) {
            case "scripts":
                resource = new Script(extend({}, options, { [ATTRIBUTE_SRC]: url }));
                break;
            case "stylesheets":
                resource = new Stylesheet(extend({}, options, { [ATTRIBUTE_HREF]: url }));
                break;
            case "data":
                resource = new Data(extend({}, options, { [ATTRIBUTE_SRC]: url }));
                break;
            default:
                throw new Error(`unsupported type ${type}`);
        }
    
        self.getOption("resources")?.[type].push(resource);
        return self;
    }