From 646afba4d3be59fb24399e17fda9eb40165454a9 Mon Sep 17 00:00:00 2001 From: chris Date: Sun, 2 Mar 2025 15:03:32 +0100 Subject: [PATCH] FIX,REFA: extStore handling during generate and appendToPage the switch-case resolvement is mostly moved to the ExtStorage class changed some iteration approaches removed unnecessary tasks fixed some (missing) documentation --- src/component.js | 182 ++++++------------ src/componentAncestry/addStyleAndFunctions.js | 6 +- src/context.js | 74 +------ src/context/extStore.js | 96 +++++---- 4 files changed, 123 insertions(+), 235 deletions(-) diff --git a/src/component.js b/src/component.js index 481dc39..97275c8 100644 --- a/src/component.js +++ b/src/component.js @@ -154,7 +154,7 @@ class Component extends StyleAndScriptStoringComponent { registerAsContextMenu() { this.subscribeOnGenerate(CommonCompelGroups.IS_CONTEXT_MENU); this._isContextMenu = true; - + return this.addStyleClass('contextmenu') .hidden(); } @@ -304,161 +304,83 @@ class Component extends StyleAndScriptStoringComponent { } + /** + * + * @param {ExtStorage} extStore + * @returns {Array} + */ _processStyles(extStore = null) { - if (!extStore) { - extStore = this._stylesExtStore.setupForGeneralStyling(); - } else { - extStore.setupForGeneralStyling(); - } - - /** - * @todo very likely code dupplication - but kept for the time being - * for error tracking. - */ - if (extStore === ExtStoreType.INTERNALIZED_WITHIN) { - let sizings = Object.keys(this._modifier._modifications) - .filter(e => e.includes("width") || e.includes("height")) - .filter(e => this._modifier._modifications[e].includes("calc")) - .reduce((a, c) => a.add( - c, - this._modifier - ._modifications[c] - .split('(')[1] - .split(' - ')[0] - ), new ObjectAccessObject()); - - fillAttrsInContainerByCb( - this._modifier._modifications, - this._element, - (key, val, el) => { el.style[key] = val; } - ); - - let hasElSizing = sizings.keys.some(k => Object.keys(this._element.style).includes(k)); - if (sizings.keys.length > 0 && !hasElSizing) { - console.log("Fixing sizing - because not supported 'calc'", sizings); - - fillAttrsInContainerByCb( - sizings, - this._element, - (key, val, el) => { el.style[key] = val; } - ); - } - - } else { - /* ADDS ELEMENT MODIFIER TO this._styles list for styles processing */ - let modifierSSD = new SStoreDefinition(); - modifierSSD._identifier = "." + this._compName; - modifierSSD._definition = this._modifier._modifications; - modifierSSD._extStore = extStore; - this._styles.unshift(modifierSSD); - } + extStore = (extStore + ? extStore + : this._stylesExtStore + ) + .setupForGeneralStyling(); let forCollection = []; let counter = 0; - for (let i = 0; i < this._styles.length; i++) { - const ssd = this._styles[i]; + for (const ssd of this._styles) { /* Make sure that the type is unified for later processing */ if (ssd._definition instanceof Modifier) { ssd._definition = ssd._definition._modifications; } /* Check/Ensure proper ExtStorageType for following comparison */ - let refESType = ( - ssd._extStore && ssd._extStore._type - ? ssd._extStore.setupForGeneralStyling()._type - : extStore._type - ); + /** + * @type {ExtStorage} + */ + let curExtStore = extStore; - switch (refESType) { - - case ExtStoreType.INTERNALIZED_WITHIN: - fillAttrsInContainerByCb( - ssd._definition, - this._element, - (key, val, el) => { el.style[key] = val; } - ) - break; - - case ExtStoreType.INDIVIDUALLY_DOC_HEAD: - let container = generateAndFillStyleTag([ssd]); - container.setAttribute("data-compel-individually-nr", counter++); - Page.addElementToPage(container, refESType); - break; - - case ExtStoreType.COLLECTED_DOC_HEAD: - forCollection.push(ssd); - break; - - case ExtStoreType.CENTRALIZED_DOC_HEAD: - Page.registerStyling(ssd._identifier, ssd._definition); - break; + if (Object.hasOwn(ssd, "_extStore") && ssd._extStore) { + curExtStore = ssd._extStore.setupForGeneralStyling(); + } + + if (curExtStore.getStylingDistribution()(ssd, this._element, counter)) { + forCollection.push(ssd); } } return forCollection; } - + /** + * + * @param {ExtStorage} extStore + * @returns {Array} + */ _processFunctions(extStore = null) { - if (!extStore) { - extStore = this._functionsExtStore.setupForFunctions(); - } else { - extStore.setupForFunctions(); - } + extStore = (extStore + ? extStore + : this._functionsExtStore + ) + .setupForFunctions(); const forCollection = new Map(); const collectForBefore = []; let counter = 0; - for (let i = 0; i < this._functions.length; i++) { - const ssd = this._functions[i]; + for (const ssd of this._functions) { /* Make sure that the type is unified for later processing */ - let refESType = ( - ssd._extStore && ssd._extStore._type - ? ssd._extStore.setupForFunctions()._type - : extStore._type - ); + let curExtStore = extStore; + if (Object.hasOwn(ssd, "_extStore") && ssd._extStore) { + curExtStore = ssd._extStore.setupForFunctions(); + } - switch (refESType) { - case ExtStoreType.CENTRALIZED_DOC_HEAD: - case ExtStoreType.CENTRALIZED_SEGMENT_BEGIN: - case ExtStoreType.CENTRALIZED_DOC_FOOTER: - Page.registerPageFunction(ssd._identifier, ssd._definition); - break; - - case ExtStoreType.INDIVIDUALLY_WITHIN: - case ExtStoreType.INDIVIDUALLY_BEFORE: - case ExtStoreType.INDIVIDUALLY_SEGMENT_BEGIN: - case ExtStoreType.INDIVIDUALLY_DOC_FOOTER: - case ExtStoreType.INDIVIDUALLY_DOC_HEAD: - - let container = document.createElement("script"); - container.setAttribute("data-compel-individually-nr", counter++); - container.innerText += getScriptTagInjectionText( - clearFunctionDeclarationText(ssd._definition), - ssd._identifier - ); - Page.addElementToPage(container, refESType, this._element); - - break; - - case ExtStoreType.COLLECTED_BEFORE: + if (curExtStore.getFunctionDistribution()(ssd, counter)) { + if (curExtStore._position.BEFORE) { collectForBefore.push(ssd); - break; - - case ExtStoreType.COLLECTED_SEGMENT_BEGIN: - case ExtStoreType.COLLECTED_DOC_FOOTER: - case ExtStoreType.COLLECTED_DOC_HEAD: - if (!forCollection.has(refESType)) { - forCollection.set(refESType, []); + } else { + if (!forCollection.has(curExtStore)) { + forCollection.set(curExtStore, []); } - forCollection.get(refESType).push(ssd); - break; + forCollection.get(curExtStore).push(ssd); + } } } + + return forCollection; } @@ -476,8 +398,18 @@ class Component extends StyleAndScriptStoringComponent { generate(styleStore = null, functionStore = null) { this._wenity = new WebTrinity(); + if (!styleStore) { + styleStore = this._stylesExtStore; + } + /* DEAL WITH COMPONENT MODIFICATION FIRST */ - this._styles.push(new SStoreDefinition(this._compName, this._modifier, this._stylesExtStore)); + // @todo pay attention to the "overwrite" behaviour - the local modifier styles are the "closest" + // it might be appropriate to use this._styles.unshift(...) instead. + this._styles.push(new SStoreDefinition( + (styleStore._aggregation !== ESAggregation.INTERNALIZED ? "." : "") + this._compName, + this._modifier, + this._stylesExtStore + )); /* DEAL WITH CHILDREN */ let collectedWenities = []; diff --git a/src/componentAncestry/addStyleAndFunctions.js b/src/componentAncestry/addStyleAndFunctions.js index 60d1b6e..fed1e4d 100644 --- a/src/componentAncestry/addStyleAndFunctions.js +++ b/src/componentAncestry/addStyleAndFunctions.js @@ -11,11 +11,11 @@ */ class StyleAndScriptStoringComponent extends ModifiableComponent { /** - * @type {ExtStore} + * @type {ExtStorage} */ _styleClassesExtStore /** - * @type {ExtStore} + * @type {ExtStorage} */ _stylesExtStore; /** @@ -23,7 +23,7 @@ class StyleAndScriptStoringComponent extends ModifiableComponent { */ _styles; /** - * @type {ExtStore} + * @type {ExtStorage} */ _functionsExtStore; /** diff --git a/src/context.js b/src/context.js index d80c618..9a34ea8 100644 --- a/src/context.js +++ b/src/context.js @@ -75,78 +75,20 @@ class PageBuilder extends ScriptAndStyleContext { /** + * Inserts the given element according to the extStore into the page/document. + * The refElement is a reference element for the case + * that extStore._position defines "before" or "segment_begin", + * which will then look for the refElement as the corresponding insert reference. * * @param {HTMLElement|Component} element - * @param {extStoreType} extStoreType + * @param {ExtStorage} extStore * @param {HTMLElement|Component} refElement */ - addElementToPage(element, extStoreType = ExtStoreType.CENTRALIZED_DOC_HEAD, refElement = null) { + addElementToPage(element, extStore = ExtStoreType.CENTRALIZED_DOC_HEAD) { let { insertCallEl, relativePositioning } = {}; - if (!refElement) { - switch (extStoreType) { - case ExtStoreType.INDIVIDUALLY_DOC_HEAD: - case ExtStoreType.CENTRALIZED_DOC_HEAD: - case ExtStoreType.COLLECTED_DOC_HEAD: - insertCallEl = document.querySelector('head'); - break; - - case ExtStoreType.INDIVIDUALLY_DOC_FOOTER: - case ExtStoreType.COLLECTED_DOC_FOOTER: - case ExtStoreType.CENTRALIZED_DOC_FOOTER: - insertCallEl = document.querySelector('footer'); - break; - - case ExtStoreType.INTERNALIZED_WITHIN: - break; - - case ExtStoreType.INDIVIDUALLY_WITHIN: - case ExtStoreType.INDIVIDUALLY_BEFORE: - case ExtStoreType.INDIVIDUALLY_SEGMENT_BEGIN: - case ExtStoreType.COLLECTED_BEFORE: - case ExtStoreType.COLLECTED_SEGMENT_BEGIN: - case ExtStoreType.CENTRALIZED_SEGMENT_BEGIN: - console.log("ExtStorePosition defines a relative position, but no reference Element is given - doing nothing!") - return - } - } else if (refElement instanceof Component) { - refElement = refElement.generate() - } - - let refAttribute = "data-autocompel" - let refNode = document.querySelector(`[${refAttribute}='${refElement.getAttribute(refAttribute)}']`); - - switch (extStoreType) { - case ExtStoreType.INDIVIDUALLY_DOC_HEAD: - case ExtStoreType.CENTRALIZED_DOC_HEAD: - case ExtStoreType.COLLECTED_DOC_HEAD: - relativePositioning = "beforeend"; - break; - - case ExtStoreType.INDIVIDUALLY_DOC_FOOTER: - case ExtStoreType.COLLECTED_DOC_FOOTER: - case ExtStoreType.CENTRALIZED_DOC_FOOTER: - relativePositioning = "beforeend"; - break; - case ExtStoreType.INTERNALIZED_WITHIN: - - case ExtStoreType.INDIVIDUALLY_WITHIN: - relativePositioning = "afterbegin"; - break - - case ExtStoreType.INDIVIDUALLY_BEFORE: - case ExtStoreType.COLLECTED_BEFORE: - relativePositioning = "beforebegin"; - break; - - case ExtStoreType.INDIVIDUALLY_SEGMENT_BEGIN: - case ExtStoreType.COLLECTED_SEGMENT_BEGIN: - case ExtStoreType.CENTRALIZED_SEGMENT_BEGIN: - insertCallEl = refNode.closest('[data-compel-isHCompel="true"]'); - relativePositioning = "afterbegin"; - break; - - } + relativePositioning = extStore.getRelativePositioning(); + insertCallEl = extStore.getRefElement(element); insertCallEl.insertAdjacentElement( relativePositioning, diff --git a/src/context/extStore.js b/src/context/extStore.js index b3dec54..0c50ca4 100644 --- a/src/context/extStore.js +++ b/src/context/extStore.js @@ -8,10 +8,10 @@ * ESAggregation := Extensions Storage Aggregation (method) */ const ESAggregation = Object.freeze({ - INTERNALIZED: 0, - INDIVIDUALLY: 1, - COLLECTED: 2, - CENTRALIZED: 3 + INTERNALIZED: "intern", + INDIVIDUALLY: "individual", + COLLECTED: "collected", + CENTRALIZED: "centralized" }); /** @@ -136,7 +136,7 @@ class ExtStorage { */ this._aggregation = aggregation; /** - * @type {ESAggregation} + * @type {ExtStorePosition} */ this._position = position; /** @@ -191,6 +191,17 @@ class ExtStorage { return this._type === null || this._overwriteBehaviour === null; } + /** + * + * @returns {boolean} + */ + isNotInternalOrIndividual() { + return !( + this._aggregation === ESAggregation.INTERNALIZED + || this._aggregation === ESAggregation.INDIVIDUALLY + ); + } + /** * * @param {ExtStorage} otherExtStore @@ -209,6 +220,7 @@ class ExtStorage { } /** + * @todo check if still implemented correctly * Takes the singleValue and an ExtStore object to copy all values from. * Then the singleValue will be compared to the three enums for the type of value. * After the type is identified the corresponding (copied) value will be updated. @@ -263,37 +275,35 @@ class ExtStorage { * @returns {ExtStorage} */ setupForGeneralStyling() { - switch (this) { + if (this === ExtStoreType.INTERNALIZED_WITHIN) { + this._position = ExtStorePosition.WITHIN; + this._aggregation = ESAggregation.INTERNALIZED; + return this; + } - case ExtStoreType.INTERNALIZED_WITHIN: - break; + this._position = ExtStorePosition.DOC_HEAD; + switch (this) { case ExtStoreType.INDIVIDUALLY_WITHIN: case ExtStoreType.INDIVIDUALLY_BEFORE: case ExtStoreType.INDIVIDUALLY_SEGMENT_BEGIN: case ExtStoreType.INDIVIDUALLY_DOC_FOOTER: - this._position = ExtStorePosition.DOC_HEAD; - this._aggregation = ESAggregation.INDIVIDUALLY; - break; - case ExtStoreType.INDIVIDUALLY_DOC_HEAD: + this._aggregation = ESAggregation.INDIVIDUALLY; break; case ExtStoreType.COLLECTED_BEFORE: case ExtStoreType.COLLECTED_SEGMENT_BEGIN: case ExtStoreType.COLLECTED_DOC_FOOTER: - this._position = ExtStorePosition.DOC_HEAD; + case ExtStoreType.COLLECTED_DOC_HEAD: this._aggregation = ESAggregation.COLLECTED; - case ExtStoreType.COLLECTED_DOC_HEAD: + this._aggregation = ESAggregation.COLLECTED; break; case ExtStoreType.CENTRALIZED_DOC_HEAD: - break - - case ExtStoreType.CENTRALIZED_SEGMENT_BEGIN: + case ExtStoreType.CENTRALIED_SEGMENT_BEGIN: case ExtStoreType.CENTRALIZED_DOC_FOOTER: default: - this._position = ExtStorePosition.DOC_HEAD; this._aggregation = ESAggregation.CENTRALIZED; break } @@ -342,15 +352,19 @@ class ExtStorage { } /** - * + * Expects a reference element for the positions before and segment_begin. + * Otherwise will return head, footer or element accordingly. * @param {HTMLLIElement|Component} element * @returns {HTMLElement} */ getRefElement(element = null) { let ensuredElement = element; if (!element) { + console.log("ExtStorePosition defines a relative position, but no reference Element is given - using head!") return document.querySelector('head'); - } else if (element instanceof Component) { + } + + if (element instanceof Component) { ensuredElement = element.generate().html; } @@ -376,21 +390,27 @@ class ExtStorage { ) } + /** + * + * @returns {function(SStoreDefinition,HTMLElement,number): boolean} + */ getStylingDistribution() { - switch (ExtStorePosition) { + switch (this._aggregation) { case ESAggregation.INDIVIDUALLY: - return function (ssd, orgElement) { + return function (ssd, orgElement, counter) { let container = generateAndFillStyleTag([ssd]); container.setAttribute("data-compel-individually-nr", counter++); Page.addElementToPage(container, this); + return false; } case ESAggregation.COLLECTED: return function (ssd, orgElement) { - return ssd; + return true; } case ESAggregation.CENTRALIZED: return function (ssd, orgElement) { Page.registerStyling(ssd._identifier, ssd._definition); + return false; } case ESAggregation.INTERNALIZED: @@ -398,48 +418,42 @@ class ExtStorage { return function (ssd, orgElement) { fillAttrsInContainerByCb( ssd._definition, - this._element, + orgElement, (key, val, el) => { el.style[key] = val; } - ) + ); + return false; } } } /** * - * @returns {Function<>} + * @returns {function(SStoreDefinition, Map, number): boolean} */ getFunctionDistribution() { switch (this._aggregation) { + case ESAggregation.INTERNALIZED: case ESAggregation.INDIVIDUALLY: - return function (ssd, bubbelingCollectionMap) { + return function (ssd, counter) { let container = document.createElement("script"); container.setAttribute("data-compel-individually-nr", counter++); container.innerText += getScriptTagInjectionText( clearFunctionDeclarationText(ssd._definition), ssd._identifier ); - Page.addElementToPage(container, refESType, this._element); - + Page.addElementToPage(container, refESType); + return false; } case ESAggregation.COLLECTED: - return function (ssd, bubbelingCollectionMap) { - if (!bubbelingCollectionMap) { - - bubbelingCollectionMap = new Map(); - } else if (bubbelingCollectionMap.has(this)) { - bubbelingCollectionMap.set(this, []); - } - - bubbelingCollectionMap.get(this).push(ssd); - - return bubbelingCollectionMap; + return function () { + return true; } case ESAggregation.CENTRALIZED: default: - return function (ssd, bubbelingCollectionMap) { + return function (ssd) { Page.registerPageFunction(ssd._identifier, ssd._definition); + return false; } } }