From 825ba24ad61b479806a90016d6d31821bdba9160 Mon Sep 17 00:00:00 2001 From: chris Date: Fri, 11 Oct 2024 16:27:59 +0200 Subject: [PATCH] FEAT: Component subscription and functions after load - Components are now capable of subscribing to a list on generate - function execution after page load with delay (repeated if wanted) - repeating function --- src/builder.js | 12 +++++----- src/component.js | 27 ++++++++++++++++++++-- src/context.js | 58 +++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 88 insertions(+), 9 deletions(-) diff --git a/src/builder.js b/src/builder.js index a4f83fc..d201007 100644 --- a/src/builder.js +++ b/src/builder.js @@ -204,17 +204,17 @@ const builder = { * @param {*} innerComponents */ page: function (innerComponents) { - Page.generate(); let main = document.querySelector('main') - + main.parentElement.insertAdjacentElement( "afterbegin", builder.genTag("main") - .alignment(Alignment.CENTER) - .arrangement(Arrangement.CENTER) - .childContext(innerComponents) - .generate() + .alignment(Alignment.CENTER) + .arrangement(Arrangement.CENTER) + .childContext(innerComponents) + .generate() ) + Page.generate(); main.remove(); } } diff --git a/src/component.js b/src/component.js index f78c82e..2b63263 100644 --- a/src/component.js +++ b/src/component.js @@ -6,6 +6,7 @@ class Component { _modifier _alignment; _arrangement; + _toRegister; constructor(element, attr = {}) { this._modifier = new Modifier().margin(new Sides().all(0)); @@ -14,6 +15,7 @@ class Component { element.setAttribute(akeys[i], attr[akeys[i]]); } this._element = element; + this._toRegister = []; } /** @@ -97,6 +99,11 @@ class Component { return this; } + registerStyleClass(styleClass, styleRuleMap){ + Page.registerStyling('.'+styleClass, styleRuleMap); + return this.addStyleClass(styleClass); + } + /** * * @param {string} key @@ -115,11 +122,15 @@ class Component { * @returns {HTMLElemment} the html element */ generate() { + /* apply styling to element */ var mkeys = Object.keys(this._modifier._modifications); for (let i = 0; i < mkeys.length; i++) { this._element.style[mkeys[i]] = this._modifier._modifications[mkeys[i]]; } - + /* subscribe/register to lists */ + for (let i = 0; i < this._toRegister.length; i++) { + this._toRegister[i].push(this._element); + } return this._element; } @@ -152,7 +163,7 @@ class Component { } /** - * + * @deprecated * @param {Array} innerComponent * @returns {Component} this component object */ @@ -181,6 +192,18 @@ class Component { return new ChainableModifier(this); } + /** + * Collects the given List in the _toRegister attribute. + * When generate() is called, + * the created Element will be registered (added) in every list + * within the list. + * @param {Array} listName + */ + registerOnGenerate(listName){ + this._toRegister.push(listName); + return this; + } + /* clickable(eventName) { let cssClass = "button-like" diff --git a/src/context.js b/src/context.js index 2ec6d50..cff6868 100644 --- a/src/context.js +++ b/src/context.js @@ -4,6 +4,8 @@ class PageBuilder { #cssClasses; #functions; + #delayedFunctions; + #repeatingFunctions; #functionNames; #cssElementIdentifiers; @@ -12,6 +14,8 @@ class PageBuilder { this.#functions = document.createElement("script"); this.#functionNames = []; this.#cssElementIdentifiers = []; + this.#delayedFunctions = []; + this.#repeatingFunctions = {}; } /** @@ -26,6 +30,22 @@ class PageBuilder { } } + /** + * @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. @@ -44,13 +64,49 @@ class PageBuilder { } /** - * Adds a script tag into the head of the document. + * 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 }); } /**