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.
238 lines
6.7 KiB
238 lines
6.7 KiB
/**
|
|
* 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.
|
|
* @abstract
|
|
*/
|
|
class ElementWrapper {
|
|
/**
|
|
* The basic HTMLElement the Component is wrapped around.
|
|
* It will be modified in several ways and in the end returned.
|
|
* @type {HTMLElement}
|
|
*/
|
|
_element;
|
|
/**
|
|
* The auto-generated name of the component.
|
|
* @type {string}
|
|
*/
|
|
_compName;
|
|
/**
|
|
* The auto-generated name of the component.
|
|
* @type {string}
|
|
*/
|
|
_givenName;
|
|
/**
|
|
* @type {Component}
|
|
*/
|
|
_parentComponent;
|
|
|
|
/**
|
|
* Initializes the component
|
|
* @param {HTMLElement} element the base element
|
|
* @param {map<string,string>} attr Specific already known attributes
|
|
*/
|
|
constructor(element, attr = {}) {
|
|
helperFun.fillAttrsInContainerByCb(
|
|
attr,
|
|
element,
|
|
function (k, v, con) {
|
|
con.setAttribute(k, v);
|
|
}
|
|
);
|
|
|
|
this._compName = Page.autoRegisterComponent();
|
|
element.setAttribute('data-autocompel', this._compName);
|
|
this._element = element;
|
|
this.addStyleClass(this._compName);
|
|
}
|
|
|
|
setComponentName(name) {
|
|
this._givenName = name;
|
|
this.setAttribute('data-compel', name);
|
|
Page.registerComponent(name);
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* (Wrapper) Sets the innerText of the element
|
|
* @todo add Alignment of text functionality
|
|
* @param {string} text
|
|
* @returns {Component} this component object
|
|
*/
|
|
text(text) {
|
|
if (this._element instanceof HTMLInputElement && this._element.type === "text") {
|
|
this._element.value = text;
|
|
} else {
|
|
this._element.innerText = text;
|
|
}
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Wrapper to set the HTMLElement.title attribute
|
|
* @param {string} text
|
|
* @returns {Component}
|
|
*/
|
|
title(text) {
|
|
this._element.title = text;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Wrapper for HTMLElement.classList.add()
|
|
* @param {string} styleClass
|
|
* @returns {Component} this component object
|
|
*/
|
|
addStyleClass(styleClass) {
|
|
this._element.classList.add(styleClass);
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Wrapper for the HTMLElement.setAttribute() method.
|
|
* @param {string} key
|
|
* @param {string} value
|
|
* @returns {Component} this component object
|
|
*/
|
|
setAttribute(key, value) {
|
|
this._element.setAttribute(key, value);
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Wrapper for the HTMLElement.addEventListener()
|
|
* @param {keyof WindowEventMap|CommonEvents} theEvent
|
|
* @param {Function} theListener
|
|
* @param {boolean|AddEventListenerOptions} options
|
|
* @returns {Component} this component object
|
|
*/
|
|
addEventListener(theEvent, theListener, options = null) {
|
|
this._element.addEventListener(theEvent, theListener, options)
|
|
return this;
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* @inheritdoc
|
|
* @extends ElementWrapper
|
|
* @abstract
|
|
*/
|
|
class ChildbearerComponent extends ElementWrapper {
|
|
/**
|
|
* @type {Array<Component>} children
|
|
*/
|
|
_children;
|
|
/**
|
|
* @type {Alignment} alignment
|
|
*/
|
|
_alignment;
|
|
|
|
/**
|
|
* @type {Arrangement} arrangement
|
|
*/
|
|
_arrangement;
|
|
|
|
constructor(element, attr = {}) {
|
|
super(element, attr);
|
|
this._children = [];
|
|
}
|
|
|
|
/**
|
|
* @todo: Unify logic extract modifications into responsible construct
|
|
* @todo: Make it work as expected, fix docu
|
|
* @todo: Differentiate between directions (horizontal, vertiacl)
|
|
*
|
|
* Sets the alignment (modifications) for this element or more specific for its children.
|
|
* @param {Alignment} alignment
|
|
* @returns {Component} this component object
|
|
*/
|
|
alignment(alignment) {
|
|
/*
|
|
this._modifier._modifications["display"] = "flex";
|
|
this._modifier._modifications["align-content"] = alignment;
|
|
this._modifier._modifications["align-items"] = alignment;
|
|
this._modifier._modifications["text-align"] = alignment;
|
|
*/
|
|
this._alignment = alignment;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* @todo: Unify logic extract modifications into responsible construct
|
|
* @todo: Differentiate between directions (horizontal, vertical)
|
|
* @todo: Make it work as expected, fix docu
|
|
*
|
|
* Sets the arrangement (modifications) for this element or more specific for its children.
|
|
* @param {Arrangement} arrangement
|
|
* @returns {Component} this component object
|
|
*/
|
|
arrangement(arrangement) {
|
|
/*
|
|
this._modifier._modifications["justify-content"] = arrangement;
|
|
*/
|
|
this._arrangement = arrangement;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Opens a context to create children elements.
|
|
* Either as one component or a list/array of components.
|
|
* @param {Component|Array<Component>} component
|
|
* @returns {Component} this component object
|
|
*/
|
|
childContext(component) {
|
|
if (!component) return this;
|
|
|
|
if (arguments.length > 1) {
|
|
for (let i = 0; i < arguments.length; i++) {
|
|
this.childContext(arguments[i]);
|
|
}
|
|
} else if (component instanceof Array) {
|
|
for (let i = 0; i < component.length; i++) {
|
|
this.childContext(component[i]);
|
|
}
|
|
} else {
|
|
if (!(component instanceof Component)) {
|
|
this.childContext(component.toComponent())
|
|
} else {
|
|
this._children.push(component.end());
|
|
}
|
|
}
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Ends chain for the current component.
|
|
* Returns the builder object.
|
|
* The Component that is selected there will be set as child to this one.
|
|
*
|
|
* This funciton is a convenience function.
|
|
* Mainly to offer the possibility to reduce the depth of method chains.
|
|
* Especially in the case of components with only one child.
|
|
*
|
|
* @returns {builder} the given
|
|
*/
|
|
chainChild() {
|
|
return builder._nextComponent(this);
|
|
}
|
|
|
|
/**
|
|
* Ends a chainChild - chain.
|
|
* If components are setup as chainChild
|
|
* they would be wrongfully taken through childContext().
|
|
* Therefore thoose chains are recursively resolved through this method.
|
|
* @returns {Component}
|
|
*/
|
|
end() {
|
|
let parent = this._parentComponent;
|
|
if (parent) {
|
|
this._parentComponent = null;
|
|
return parent
|
|
.childContext(this)
|
|
.end();
|
|
}
|
|
return this;
|
|
}
|
|
}
|
|
|