@schukai/monster
Version:
Monster is a simple library for creating fast, robust and lightweight websites.
168 lines (150 loc) • 4.3 kB
JavaScript
/**
* Copyright © schukai GmbH and all contributing authors, {{copyRightYear}}. All rights reserved.
* Node module: @schukai/monster
*
* This source code is licensed under the GNU Affero General Public License version 3 (AGPLv3).
* The full text of the license can be found at: https://www.gnu.org/licenses/agpl-3.0.en.html
*
* For those who do not wish to adhere to the AGPLv3, a commercial license is available.
* Acquiring a commercial license allows you to use this software without complying with the AGPLv3 terms.
* For more information about purchasing a commercial license, please contact schukai GmbH.
*
* SPDX-License-Identifier: AGPL-3.0
*/
import { internalStateSymbol } from "../../constants.mjs";
import { extend } from "../../data/extend.mjs";
import { getGlobalFunction } from "../../types/global.mjs";
import { addAttributeToken } from "../attributes.mjs";
import {
ATTRIBUTE_CLASS,
ATTRIBUTE_ERRORMESSAGE,
ATTRIBUTE_ID,
ATTRIBUTE_SRC,
ATTRIBUTE_TITLE,
ATTRIBUTE_TYPE,
TAG_SCRIPT,
} from "../constants.mjs";
import {
KEY_DOCUMENT,
KEY_QUERY,
referenceSymbol,
Resource,
} from "../resource.mjs";
import { instanceSymbol } from "../../constants.mjs";
export { Data };
/**
* This class is used by the resource manager to embed data.
*
* @license AGPLv3
* @since 1.25.0
* @copyright schukai GmbH
* @summary A Data Resource class
*/
class Data extends Resource {
/**
* @property {string} mode=cors https://developer.mozilla.org/en-US/docs/Web/API/fetch
* @property {string} credentials=same-origin https://developer.mozilla.org/en-US/docs/Web/API/fetch
* @property {string} type=application/json {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script#attr-type}
*/
get defaults() {
return extend({}, super.defaults, {
mode: "cors",
credentials: "same-origin",
type: "application/json",
});
}
/**
*
* @return {Monster.DOM.Resource.Data}
*/
create() {
createElement.call(this);
return this;
}
/**
* This method appends the HTMLElement to the specified document
*
* throws {Error} target not found
* @return {Monster.DOM.Resource}
*/
connect() {
const self = this;
if (!(this[referenceSymbol] instanceof HTMLElement)) {
this.create();
}
appendToDocument.call(this);
return this;
}
/**
* This method is called by the `instanceof` operator.
* @return {symbol}
* @since 2.1.0
*/
static get [instanceSymbol]() {
return Symbol.for("@schukai/monster/dom/resource/data");
}
/**
* @return {string}
*/
static getURLAttribute() {
return ATTRIBUTE_SRC;
}
}
/**
* @private
* @return {Monster.DOM.Resource.Data}
*/
function createElement() {
const document = this.getOption(KEY_DOCUMENT);
this[referenceSymbol] = document.createElement(TAG_SCRIPT);
for (const key of [
ATTRIBUTE_TYPE,
ATTRIBUTE_ID,
ATTRIBUTE_CLASS,
ATTRIBUTE_TITLE,
]) {
if (this.getOption(key) !== undefined) {
this[referenceSymbol][key] = this.getOption(key);
}
}
return this;
}
/**
* @private
* @return {Promise}
* throws {Error} target not found
*/
function appendToDocument() {
const targetNode = document.querySelector(this.getOption(KEY_QUERY, "head"));
if (!(targetNode instanceof HTMLElement)) {
throw new Error("target not found");
}
targetNode.appendChild(this[referenceSymbol]);
getGlobalFunction("fetch")(this.getOption(ATTRIBUTE_SRC), {
method: "GET", // *GET, POST, PUT, DELETE, etc.
mode: this.getOption("mode", "cors"), // no-cors, *cors, same-origin
cache: "no-cache", // *default, no-cache, reload, force-cache, only-if-cached
credentials: this.getOption("credentials", "same-origin"), // include, *same-origin, omit
headers: {
Accept: this.getOption("type", "application/json"),
},
redirect: "follow", // manual, *follow, error
referrerPolicy: "no-referrer", // no-referrer,
})
.then((response) => {
return response.text();
})
.then((text) => {
const textNode = document.createTextNode(text);
this[referenceSymbol].appendChild(textNode);
this[internalStateSymbol].getSubject()["loaded"] = true;
})
.catch((e) => {
this[internalStateSymbol].setSubject({
loaded: true,
error: e.toString(),
});
targetNode.setAttribute(ATTRIBUTE_ERRORMESSAGE, e.toString());
});
return this;
}