/** * The class provides overreaching options for building the website. */ class PageBuilder { #cssClasses; #functions; #delayedFunctions; #repeatingFunctions; #functionNames; #cssElementIdentifiers; constructor() { this.#cssClasses = document.createElement("style"); this.#functions = document.createElement("script"); this.#functionNames = []; this.#cssElementIdentifiers = []; this.#delayedFunctions = []; this.#repeatingFunctions = {}; } /** * Registers a function to be added later in a script tag in the head of the document. * @param {string} name * @param {func} fun */ registerFunction(name, fun) { if (!this.#functionNames.includes(name)) { this.#functions.innerText += `const ${name} = ${fun};`; this.#functionNames.push(name); } } /** * @experimental Attention is adviced, registration mechanism doesn't work yet * @param {string} name The name the interval will be tied to * @param {Function} fun the function that is supposed to be executed repeatedly * @param {number} interval the time in ms between executions */ registerRepeatingFunction(name, fun, interval) { if (!Object.keys(this.#repeatingFunctions).includes(name)) { this.#repeatingFunctions[name] = { name: name, fun: fun, interval: interval }; } } /** * Adds the styling rules to the element identifiers into the style tag. * An elementDefinition can only be used once, repeated use will be ignored. * @param {string} elementDefinition The element identifier * @param {Map} styleRuleMap The Styling rules/values */ registerStyling(elementDefinition, styleRuleMap) { if (!this.#cssElementIdentifiers.includes(elementDefinition)) { this.#cssClasses.innerText += `${elementDefinition } {${Object.keys(styleRuleMap) .map(e => e + ": " + styleRuleMap[e] + "; ") .join(" ") }} ` this.#cssElementIdentifiers.push(elementDefinition) } } /** * Adds into the (head) document. * - script tag * - function tag * - sets and registers repeatedly executed functions * - sets (timeout and) functions that are supposed to be executed after load */ generate() { let head = document.querySelector("head"); head.appendChild(this.#functions) head.appendChild(this.#cssClasses) /* set repeating functions */ let repeatedFun = Object.values(this.#repeatingFunctions) .reduce((a, c, i, arr) => Object.assign(a, { [c.name]: setInterval(c.fun, c.interval) }), {}); /* set timeouts for funcitons executed after load */ for (let i = 0; i < this.#delayedFunctions.length; i++) { let func = this.#delayedFunctions[i]; if (func.repeat) { setTimeout(setInterval(func.func, func.interval), func.dl, func.args); } else { setTimeout(func.func, func.dl, func.args); } } console.log(this.#functionNames); } /** * Registeres a function to be executed after page-load * @param {Function} func the function that will be executed * @param {number} delay the time in ms the execution is delayed after load * @param {string} name if provided the function will be registered as well * @param {Array} args arguments for the function * @param {boolean} repeat defines if the function is supposed to be repeated as well * @param {number} interval if the function is supposed to repeat, this defines the interval of repetition */ executeAfterLoad(func, delay = 1000, name = '', args = [], repeat = false, interval = 5000) { if (name !== '') { this.registerFunction(name, func); } this.#delayedFunctions.push({ dl: delay, func: func, args: args, repeat: repeat, interval: interval }); } /** * * @param {number} relaunchSeconds timeinterval for page to reload (changes) */ inDev(relaunchSeconds = 20) { let head = document.querySelector("head"); let meta = document.createElement("meta"); meta.setAttribute("http-equiv", "refresh"); meta.setAttribute("content", `${relaunchSeconds}`); head.insertAdjacentElement("beforeend", meta); this.#functions.innerText = ` let ts = new Date(); console.log("Refreshed at: ", ts.getHours()+':'+ts.getMinutes()+':'+ts.getSeconds(), "Intervall ${relaunchSeconds}s"); `; } } const Page = new PageBuilder();