Something went wrong on our end
Select Git revision
resourcemanager.mjs
-
Volker Schukai authoredVolker Schukai authored
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;
}