Browse Source

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
master
chris 1 month ago
parent
commit
646afba4d3
  1. 182
      src/component.js
  2. 6
      src/componentAncestry/addStyleAndFunctions.js
  3. 74
      src/context.js
  4. 96
      src/context/extStore.js

182
src/component.js

@ -154,7 +154,7 @@ class Component extends StyleAndScriptStoringComponent {
registerAsContextMenu() { registerAsContextMenu() {
this.subscribeOnGenerate(CommonCompelGroups.IS_CONTEXT_MENU); this.subscribeOnGenerate(CommonCompelGroups.IS_CONTEXT_MENU);
this._isContextMenu = true; this._isContextMenu = true;
return this.addStyleClass('contextmenu') return this.addStyleClass('contextmenu')
.hidden(); .hidden();
} }
@ -304,161 +304,83 @@ class Component extends StyleAndScriptStoringComponent {
} }
/**
*
* @param {ExtStorage} extStore
* @returns {Array<SStoreDefinition>}
*/
_processStyles(extStore = null) { _processStyles(extStore = null) {
if (!extStore) { extStore = (extStore
extStore = this._stylesExtStore.setupForGeneralStyling(); ? extStore
} else { : this._stylesExtStore
extStore.setupForGeneralStyling(); )
} .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);
}
let forCollection = []; let forCollection = [];
let counter = 0; let counter = 0;
for (let i = 0; i < this._styles.length; i++) { for (const ssd of this._styles) {
const ssd = this._styles[i];
/* Make sure that the type is unified for later processing */ /* Make sure that the type is unified for later processing */
if (ssd._definition instanceof Modifier) { if (ssd._definition instanceof Modifier) {
ssd._definition = ssd._definition._modifications; ssd._definition = ssd._definition._modifications;
} }
/* Check/Ensure proper ExtStorageType for following comparison */ /* Check/Ensure proper ExtStorageType for following comparison */
let refESType = ( /**
ssd._extStore && ssd._extStore._type * @type {ExtStorage}
? ssd._extStore.setupForGeneralStyling()._type */
: extStore._type let curExtStore = extStore;
);
switch (refESType) { if (Object.hasOwn(ssd, "_extStore") && ssd._extStore) {
curExtStore = ssd._extStore.setupForGeneralStyling();
case ExtStoreType.INTERNALIZED_WITHIN: }
fillAttrsInContainerByCb(
ssd._definition, if (curExtStore.getStylingDistribution()(ssd, this._element, counter)) {
this._element, forCollection.push(ssd);
(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;
} }
} }
return forCollection; return forCollection;
} }
/**
*
* @param {ExtStorage} extStore
* @returns {Array<SStoreDefinition>}
*/
_processFunctions(extStore = null) { _processFunctions(extStore = null) {
if (!extStore) { extStore = (extStore
extStore = this._functionsExtStore.setupForFunctions(); ? extStore
} else { : this._functionsExtStore
extStore.setupForFunctions(); )
} .setupForFunctions();
const forCollection = new Map(); const forCollection = new Map();
const collectForBefore = []; const collectForBefore = [];
let counter = 0; let counter = 0;
for (let i = 0; i < this._functions.length; i++) { for (const ssd of this._functions) {
const ssd = this._functions[i];
/* Make sure that the type is unified for later processing */ /* Make sure that the type is unified for later processing */
let refESType = ( let curExtStore = extStore;
ssd._extStore && ssd._extStore._type if (Object.hasOwn(ssd, "_extStore") && ssd._extStore) {
? ssd._extStore.setupForFunctions()._type curExtStore = ssd._extStore.setupForFunctions();
: extStore._type }
);
switch (refESType) { if (curExtStore.getFunctionDistribution()(ssd, counter)) {
case ExtStoreType.CENTRALIZED_DOC_HEAD: if (curExtStore._position.BEFORE) {
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:
collectForBefore.push(ssd); collectForBefore.push(ssd);
break; } else {
if (!forCollection.has(curExtStore)) {
case ExtStoreType.COLLECTED_SEGMENT_BEGIN: forCollection.set(curExtStore, []);
case ExtStoreType.COLLECTED_DOC_FOOTER:
case ExtStoreType.COLLECTED_DOC_HEAD:
if (!forCollection.has(refESType)) {
forCollection.set(refESType, []);
} }
forCollection.get(refESType).push(ssd); forCollection.get(curExtStore).push(ssd);
break; }
} }
} }
return forCollection; return forCollection;
} }
@ -476,8 +398,18 @@ class Component extends StyleAndScriptStoringComponent {
generate(styleStore = null, functionStore = null) { generate(styleStore = null, functionStore = null) {
this._wenity = new WebTrinity(); this._wenity = new WebTrinity();
if (!styleStore) {
styleStore = this._stylesExtStore;
}
/* DEAL WITH COMPONENT MODIFICATION FIRST */ /* 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 */ /* DEAL WITH CHILDREN */
let collectedWenities = []; let collectedWenities = [];

6
src/componentAncestry/addStyleAndFunctions.js

@ -11,11 +11,11 @@
*/ */
class StyleAndScriptStoringComponent extends ModifiableComponent { class StyleAndScriptStoringComponent extends ModifiableComponent {
/** /**
* @type {ExtStore} * @type {ExtStorage}
*/ */
_styleClassesExtStore _styleClassesExtStore
/** /**
* @type {ExtStore} * @type {ExtStorage}
*/ */
_stylesExtStore; _stylesExtStore;
/** /**
@ -23,7 +23,7 @@ class StyleAndScriptStoringComponent extends ModifiableComponent {
*/ */
_styles; _styles;
/** /**
* @type {ExtStore} * @type {ExtStorage}
*/ */
_functionsExtStore; _functionsExtStore;
/** /**

74
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 {HTMLElement|Component} element
* @param {extStoreType} extStoreType * @param {ExtStorage} extStore
* @param {HTMLElement|Component} refElement * @param {HTMLElement|Component} refElement
*/ */
addElementToPage(element, extStoreType = ExtStoreType.CENTRALIZED_DOC_HEAD, refElement = null) { addElementToPage(element, extStore = ExtStoreType.CENTRALIZED_DOC_HEAD) {
let { insertCallEl, relativePositioning } = {}; 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: relativePositioning = extStore.getRelativePositioning();
insertCallEl = extStore.getRefElement(element);
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;
}
insertCallEl.insertAdjacentElement( insertCallEl.insertAdjacentElement(
relativePositioning, relativePositioning,

96
src/context/extStore.js

@ -8,10 +8,10 @@
* ESAggregation := Extensions Storage Aggregation (method) * ESAggregation := Extensions Storage Aggregation (method)
*/ */
const ESAggregation = Object.freeze({ const ESAggregation = Object.freeze({
INTERNALIZED: 0, INTERNALIZED: "intern",
INDIVIDUALLY: 1, INDIVIDUALLY: "individual",
COLLECTED: 2, COLLECTED: "collected",
CENTRALIZED: 3 CENTRALIZED: "centralized"
}); });
/** /**
@ -136,7 +136,7 @@ class ExtStorage {
*/ */
this._aggregation = aggregation; this._aggregation = aggregation;
/** /**
* @type {ESAggregation} * @type {ExtStorePosition}
*/ */
this._position = position; this._position = position;
/** /**
@ -191,6 +191,17 @@ class ExtStorage {
return this._type === null || this._overwriteBehaviour === null; return this._type === null || this._overwriteBehaviour === null;
} }
/**
*
* @returns {boolean}
*/
isNotInternalOrIndividual() {
return !(
this._aggregation === ESAggregation.INTERNALIZED
|| this._aggregation === ESAggregation.INDIVIDUALLY
);
}
/** /**
* *
* @param {ExtStorage} otherExtStore * @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. * 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. * 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. * After the type is identified the corresponding (copied) value will be updated.
@ -263,37 +275,35 @@ class ExtStorage {
* @returns {ExtStorage} * @returns {ExtStorage}
*/ */
setupForGeneralStyling() { setupForGeneralStyling() {
switch (this) { if (this === ExtStoreType.INTERNALIZED_WITHIN) {
this._position = ExtStorePosition.WITHIN;
this._aggregation = ESAggregation.INTERNALIZED;
return this;
}
case ExtStoreType.INTERNALIZED_WITHIN: this._position = ExtStorePosition.DOC_HEAD;
break;
switch (this) {
case ExtStoreType.INDIVIDUALLY_WITHIN: case ExtStoreType.INDIVIDUALLY_WITHIN:
case ExtStoreType.INDIVIDUALLY_BEFORE: case ExtStoreType.INDIVIDUALLY_BEFORE:
case ExtStoreType.INDIVIDUALLY_SEGMENT_BEGIN: case ExtStoreType.INDIVIDUALLY_SEGMENT_BEGIN:
case ExtStoreType.INDIVIDUALLY_DOC_FOOTER: case ExtStoreType.INDIVIDUALLY_DOC_FOOTER:
this._position = ExtStorePosition.DOC_HEAD;
this._aggregation = ESAggregation.INDIVIDUALLY;
break;
case ExtStoreType.INDIVIDUALLY_DOC_HEAD: case ExtStoreType.INDIVIDUALLY_DOC_HEAD:
this._aggregation = ESAggregation.INDIVIDUALLY;
break; break;
case ExtStoreType.COLLECTED_BEFORE: case ExtStoreType.COLLECTED_BEFORE:
case ExtStoreType.COLLECTED_SEGMENT_BEGIN: case ExtStoreType.COLLECTED_SEGMENT_BEGIN:
case ExtStoreType.COLLECTED_DOC_FOOTER: case ExtStoreType.COLLECTED_DOC_FOOTER:
this._position = ExtStorePosition.DOC_HEAD; case ExtStoreType.COLLECTED_DOC_HEAD:
this._aggregation = ESAggregation.COLLECTED; this._aggregation = ESAggregation.COLLECTED;
case ExtStoreType.COLLECTED_DOC_HEAD: this._aggregation = ESAggregation.COLLECTED;
break; break;
case ExtStoreType.CENTRALIZED_DOC_HEAD: case ExtStoreType.CENTRALIZED_DOC_HEAD:
break case ExtStoreType.CENTRALIED_SEGMENT_BEGIN:
case ExtStoreType.CENTRALIZED_SEGMENT_BEGIN:
case ExtStoreType.CENTRALIZED_DOC_FOOTER: case ExtStoreType.CENTRALIZED_DOC_FOOTER:
default: default:
this._position = ExtStorePosition.DOC_HEAD;
this._aggregation = ESAggregation.CENTRALIZED; this._aggregation = ESAggregation.CENTRALIZED;
break 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 * @param {HTMLLIElement|Component} element
* @returns {HTMLElement} * @returns {HTMLElement}
*/ */
getRefElement(element = null) { getRefElement(element = null) {
let ensuredElement = element; let ensuredElement = element;
if (!element) { if (!element) {
console.log("ExtStorePosition defines a relative position, but no reference Element is given - using head!")
return document.querySelector('head'); return document.querySelector('head');
} else if (element instanceof Component) { }
if (element instanceof Component) {
ensuredElement = element.generate().html; ensuredElement = element.generate().html;
} }
@ -376,21 +390,27 @@ class ExtStorage {
) )
} }
/**
*
* @returns {function(SStoreDefinition,HTMLElement,number): boolean}
*/
getStylingDistribution() { getStylingDistribution() {
switch (ExtStorePosition) { switch (this._aggregation) {
case ESAggregation.INDIVIDUALLY: case ESAggregation.INDIVIDUALLY:
return function (ssd, orgElement) { return function (ssd, orgElement, counter) {
let container = generateAndFillStyleTag([ssd]); let container = generateAndFillStyleTag([ssd]);
container.setAttribute("data-compel-individually-nr", counter++); container.setAttribute("data-compel-individually-nr", counter++);
Page.addElementToPage(container, this); Page.addElementToPage(container, this);
return false;
} }
case ESAggregation.COLLECTED: case ESAggregation.COLLECTED:
return function (ssd, orgElement) { return function (ssd, orgElement) {
return ssd; return true;
} }
case ESAggregation.CENTRALIZED: case ESAggregation.CENTRALIZED:
return function (ssd, orgElement) { return function (ssd, orgElement) {
Page.registerStyling(ssd._identifier, ssd._definition); Page.registerStyling(ssd._identifier, ssd._definition);
return false;
} }
case ESAggregation.INTERNALIZED: case ESAggregation.INTERNALIZED:
@ -398,48 +418,42 @@ class ExtStorage {
return function (ssd, orgElement) { return function (ssd, orgElement) {
fillAttrsInContainerByCb( fillAttrsInContainerByCb(
ssd._definition, ssd._definition,
this._element, orgElement,
(key, val, el) => { el.style[key] = val; } (key, val, el) => { el.style[key] = val; }
) );
return false;
} }
} }
} }
/** /**
* *
* @returns {Function<<SStoreDefinition, Map<*, Array<>>} * @returns {function(SStoreDefinition, Map<ExtStorage, Array<SStoreDefinition>, number): boolean}
*/ */
getFunctionDistribution() { getFunctionDistribution() {
switch (this._aggregation) { switch (this._aggregation) {
case ESAggregation.INTERNALIZED:
case ESAggregation.INDIVIDUALLY: case ESAggregation.INDIVIDUALLY:
return function (ssd, bubbelingCollectionMap) { return function (ssd, counter) {
let container = document.createElement("script"); let container = document.createElement("script");
container.setAttribute("data-compel-individually-nr", counter++); container.setAttribute("data-compel-individually-nr", counter++);
container.innerText += getScriptTagInjectionText( container.innerText += getScriptTagInjectionText(
clearFunctionDeclarationText(ssd._definition), clearFunctionDeclarationText(ssd._definition),
ssd._identifier ssd._identifier
); );
Page.addElementToPage(container, refESType, this._element); Page.addElementToPage(container, refESType);
return false;
} }
case ESAggregation.COLLECTED: case ESAggregation.COLLECTED:
return function (ssd, bubbelingCollectionMap) { return function () {
if (!bubbelingCollectionMap) { return true;
bubbelingCollectionMap = new Map();
} else if (bubbelingCollectionMap.has(this)) {
bubbelingCollectionMap.set(this, []);
}
bubbelingCollectionMap.get(this).push(ssd);
return bubbelingCollectionMap;
} }
case ESAggregation.CENTRALIZED: case ESAggregation.CENTRALIZED:
default: default:
return function (ssd, bubbelingCollectionMap) { return function (ssd) {
Page.registerPageFunction(ssd._identifier, ssd._definition); Page.registerPageFunction(ssd._identifier, ssd._definition);
return false;
} }
} }
} }

Loading…
Cancel
Save