You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

358 lines
11 KiB

/**
* This file is part of the jps-like-websites lib
* URL: https://git.labos.goip.de/chris/jpc-like-websites
* @copyright by its creator Christian Martin
*/
/**
* Represents the most basic and simple form of a Component.
* It is mainly a collection of wrapper methods
* around the HTMLElement methods to make them chainable.
* It serves as base for further functionallity extensions.
* @property {Map<string, SStoreDefinition>} _style
*/
class Component extends StyleAndScriptStoringComponent {
/**
* @type {boolean}
*/
#isCompel;
/**
* @type {WebTrinity}
*/
_wenity;
/**
* @type {Array<any>}
*/
_toRegister;
/**
* @type {boolean}
*/
_isContextMenu;
/**
* Initializes the component
* @param {HTMLElement} element the base element
* @param {Map<string,string>} attr Specific already known attributes
*/
constructor(element, attr = {}) {
super(element, attr);
this.#isCompel = false;
this._isContextMenu = false;
this._modifier = new Modifier()
.margin(new Sides().all(0));
this._modifier._modifications['display'] = "flex";
this._toRegister = [];
}
/**
* Adds a class to classList via HTMLElement.classList.add() method.
* Further collects rules in a property until generate is called.
*
* @CAUGHTION implementation is not safe to use, ignoring extStore is recommended;
*
* @todo difference between stylings and classes, extStore logic in combination with the Page.register... logic
*
* @override
*
* @param {string} styleClass (without the '.' in the front)
* @param {string|Modifier|map<string,string>} styling
* @param {ExtStorage|ExtStoreType|ExtStorePosition|OverwriteBehaviour|EXPosConfer|ESOverwriteConfer} extStore
* if a unique definition is desired, all constants or configurator objects are allowed - they will be processed accordingly
* @returns {Component} this component object
*/
addStyleClass(styleClass, styling = null, extStore = null) {
if (!extStore) {
extStore = this._styleClassesExtStore;
} else if (extStore.isMissing()) {
extStore = extStore.fillBy(this._styleClassesExtStore);
}
if (styling) {
if (styling instanceof Modifier) {
styling = styling._modifications;
}
Page.registerStyling('.' + styleClass, styling);
}
this._element.classList.add(styleClass);
return this;
}
/**
*
* @returns {Component}
*/
isHigherComponent() {
this.#isCompel = true;
return this.setAttribute("data-compel-isHCompel", "true")
}
/**
* 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
*/
subscribeOnGenerate(listName) {
this._toRegister.push(listName);
return this;
}
/**
* Defines how a child Component is to be appended.
* @param {Component} component the child component to add it.
* @returns {HTMLElement}
*/
_appendChildComponent(component) {
let child = new WebTrinity();
if (component instanceof Component) {
child = component.generate();
}
if (component instanceof WebTrinity) {
child = component;
}
if (component instanceof HTMLElement) {
console.log("No wenity set - htmlEl was given");
child.html = component;
}
this._element.append(child.html);
return child;
}
_processStyles(extStore = null) {
if (!extStore) {
extStore = this._stylesExtStore.updateForGeneralStyling();
} else {
extStore.updateForGeneralStyling();
}
/**
* @todo very likely code dupplication - but kept for the time being
* for error tracking.
*/
if (extStore._type === ExtStoreType.INTERNALIZED_WITHIN) {
fillAttrsInContainerByCb(
this._modifier._modifications,
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 counter = 0;
for (let i = 0; i < this._styles.length; i++) {
const ssd = this._styles[i];
/* 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.updateForGeneralStyling()._type
: extStore._type
);
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 = document.createElement("style");
container.setAttribute("data-compel-individually-nr", counter++);
let styleRules = Object.keys(ssd._definition);
for (let j = 0; j < styleRules.length; j++) {
let rule = styleRules[j];
container.innerText += `${rule} {${ssd._definition[rule]} } `;
}
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;
}
_processFunctions(extStore = null) {
if (!extStore) {
extStore = this._functionsExtStore.updateForFunctions();
} else {
extStore.updateForFunctions();
}
const forCollection = new Map();
const collectForBefore = [];
let counter = 0;
for (let i = 0; i < this._functions.length; i++) {
const ssd = this._functions[i];
/* Make sure that the type is unified for later processing */
let refESType = (
ssd._extStore && ssd._extStore._type
? ssd._extStore.updateForFunctions()._type
: extStore._type
);
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:
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, []);
}
forCollection.get(refESType).push(ssd);
break;
}
}
return forCollection;
}
/**
* Ends chain.
* Applies all modifications on the element.
* Processes alls stored additions.
* Returns the constructed HTMLElement of this Component.
*
*
*
* @param {ExtStorage}
* @returns {WebTrinity} the constructed HTMLElement of this Component.
*/
generate(styleStore = null, functionStore = null) {
this._wenity = new WebTrinity();
/* DEAL WITH COMPONENT MODIFICATION FIRST */
this._modifier._modifications["justify-content"] = this._arrangement;
this._modifier._modifications["align-content"] = this._alignment;
this._modifier._modifications["align-items"] = this._alignment;
this._modifier._modifications["text-align"] = this._alignment;
let collectedWenities = [];
for (let i = 0; i < this._children.length; i++) {
/**
* @type {Component}
*/
let child = this._children[i];
if (child instanceof ChainableModifier) {
child = child.toComponent();
}
child._modifier._updateDimensionsBy(this._modifier._paddingValues);
child = child.generate();
let wenity = this._appendChildComponent(child);
if (!wenity.isSSEmpty()) {
collectedWenities.push(wenity);
}
}
let styleCollection = this._processStyles(styleStore);
/* dealing with being the "collecting" one or not
if (this.#isCompel) {
let collectedContainer = document.createElement("style");
collectedContainer.setAttribute("data-compel-collected", counter);
Page.addElementToPage(collectedContainer, extStore, this._element);
}else{
this._wenity.css = stylesForCollection;
}
*/
/**
* @type {Map<ExtStoreType, Array<SStoreDefinition>>}
*/
const funcCollections = this._processFunctions(functionStore);
if (this.#isCompel) {
funcCollections.get(ExtStoreType.COLLECTED_DOC_FOOTER)
funcCollections.get(ExtStoreType.COLLECTED_DOC_HEAD)
funcCollections.get(ExtStoreType.COLLECTED_SEGMENT_BEGIN)
} else {
this._wenity.js = funcCollections;
this._wenity.css = styleCollection;
}
this._wenity.html = this._element;
return this._wenity;
}
}