Compare commits
12 Commits
03eb5fbc24
...
825ba24ad6
Author | SHA1 | Date |
---|---|---|
|
825ba24ad6 | 6 months ago |
|
012e2e8afa | 6 months ago |
|
dd4ac1d771 | 6 months ago |
|
b98c3be3be | 6 months ago |
|
a2765d9383 | 6 months ago |
|
2d3b2c0f46 | 6 months ago |
|
1f962b8695 | 6 months ago |
|
5bf4f2e856 | 6 months ago |
|
0a2d16ecea | 6 months ago |
|
d3dbd4ecd3 | 6 months ago |
|
060918fe51 | 6 months ago |
|
62b85b35b5 | 7 months ago |
24 changed files with 1751 additions and 732 deletions
@ -1,9 +1,28 @@ |
|||||
TARGET="jpc-like-websites.js" |
TARGET="jpc-like-websites.js" |
||||
SRC="src/js" |
SRC="src" |
||||
ORDERED_LIST="context.js componentAttribute.js color.js modifier.js component.js baseComponents.js builder.js" |
|
||||
|
SUB_LIST="siding.js shapes.js border.js dimensions.js" |
||||
|
MODIFIERS_LIST="alignment.js arrangement.js modifier.js" |
||||
|
HIGHER_LIST="commonEvents.js context.js component.js baseComponents.js builder.js" |
||||
|
|
||||
echo "" > $TARGET |
echo "" > $TARGET |
||||
|
echo "/* ## color.js ## */" >> $TARGET |
||||
|
cat $SRC/color.js >> $TARGET |
||||
|
|
||||
|
echo "/* # SUB_LIST # */" >> $TARGET |
||||
|
for i in $SUB_LIST; do |
||||
|
echo "/* ## $i ## */" >> $TARGET |
||||
|
cat $SRC/sizeSide/$i >> $TARGET |
||||
|
done |
||||
|
|
||||
|
echo "/* # MODIFIERS_LIST # */" >> $TARGET |
||||
|
for i in $MODIFIERS_LIST; do |
||||
|
echo "/* ## $i ## */" >> $TARGET |
||||
|
cat $SRC/$i >> $TARGET |
||||
|
done |
||||
|
|
||||
for i in $ORDERED_LIST; do |
echo "/* # HIGHER_LIST # */" >> $TARGET |
||||
|
for i in $HIGHER_LIST; do |
||||
|
echo "/* ## $i ## */" >> $TARGET |
||||
cat $SRC/$i >> $TARGET |
cat $SRC/$i >> $TARGET |
||||
done |
done |
||||
|
@ -0,0 +1,37 @@ |
|||||
|
/** |
||||
|
* Enum providing common alignment rules |
||||
|
*/ |
||||
|
const Alignment = Object.freeze({ |
||||
|
/* Normal alignment */ |
||||
|
NORMAL: "normal", |
||||
|
|
||||
|
/* Basic positional alignment */ |
||||
|
/* align-content does not take left and right values */ |
||||
|
START: "start", |
||||
|
CENTER: "center", |
||||
|
END: "end", |
||||
|
FLEX_START: "flex-start", |
||||
|
FLEX_END: "flex-end", |
||||
|
|
||||
|
/* Baseline alignment */ |
||||
|
BASELINE: "baseline", |
||||
|
FIRST_BASELINE: "first baseline", |
||||
|
LAST_BASELINE: "last baseline", |
||||
|
|
||||
|
/* Distributed alignment */ |
||||
|
SPACE_BETWEEN: "space-between", |
||||
|
SPACE_AROUND: "space-around", |
||||
|
SPACE_EVENLY: "space-evenly", |
||||
|
STRETCH: "stretch", |
||||
|
|
||||
|
/* Overflow alignment */ |
||||
|
SAFE_CENTER: "safe center", |
||||
|
UNSAFE_CENTER: "unsafe center", |
||||
|
|
||||
|
/* Global values */ |
||||
|
INHERIT: "inherit", |
||||
|
INITIAL: "initial", |
||||
|
REVERT: "revert", |
||||
|
REVERT_LAYER: "revert-layer", |
||||
|
UNSET: "unset" |
||||
|
}) |
@ -0,0 +1,12 @@ |
|||||
|
/** |
||||
|
* Enum providing common alignment rules |
||||
|
*/ |
||||
|
const Arrangement = Object.freeze({ |
||||
|
START: "start", |
||||
|
END: "end", |
||||
|
CENTER: "center", |
||||
|
SPACE_BETWEEN: "space-between", |
||||
|
SPACE_EVENLY: "space-evenly", |
||||
|
SPACE_AROUND: "space-around", |
||||
|
|
||||
|
}) |
@ -0,0 +1,99 @@ |
|||||
|
/** |
||||
|
* Represents container Components. |
||||
|
* Some predefined modifications are applied on the child components. |
||||
|
*/ |
||||
|
class FlexContainerComponent extends Component { |
||||
|
constructor(attr = {}) { |
||||
|
super(document.createElement("div"), attr) |
||||
|
.addStyleClass("flex-container-component") |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* |
||||
|
* @param {Component|Array<Component>} innerComponent |
||||
|
* @returns {FlexContainerComponent} this component object |
||||
|
*/ |
||||
|
childContext(innerComponent) { |
||||
|
if (innerComponent instanceof Array) { |
||||
|
innerComponent |
||||
|
.map(cl => { |
||||
|
if (cl instanceof Component) { |
||||
|
return cl |
||||
|
} else { |
||||
|
return cl.ensureModifier().toComponent() |
||||
|
} |
||||
|
}) |
||||
|
.forEach(icomp => { |
||||
|
icomp._modifier = new Modifier() |
||||
|
.setStyleRule("flex", "none") |
||||
|
.join(icomp._modifier) |
||||
|
|
||||
|
}) |
||||
|
} |
||||
|
return super.childContext(innerComponent); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* A FlexContainerComponent, which organizes the children in a column like manner. |
||||
|
*/ |
||||
|
class Column extends FlexContainerComponent { |
||||
|
constructor(attr = {}) { |
||||
|
super(attr) |
||||
|
.addStyleClass("column-component") |
||||
|
.modifier( |
||||
|
new Modifier() |
||||
|
.setStyleRule("flex-direction", "column") |
||||
|
); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* A FlexContainerComponent, which organizes the children in a row like manner. |
||||
|
*/ |
||||
|
class Row extends FlexContainerComponent { |
||||
|
constructor(attr = {}) { |
||||
|
super(attr) |
||||
|
.addStyleClass("row-component") |
||||
|
.modifier( |
||||
|
new Modifier() |
||||
|
.fillMaxWidth() |
||||
|
.setStyleRule("flex-direction", "row") |
||||
|
) |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* |
||||
|
* @param {*} innerComponent |
||||
|
* @returns {Row} |
||||
|
*/ |
||||
|
childContext(innerComponent) { |
||||
|
if (innerComponent instanceof Array) { |
||||
|
innerComponent |
||||
|
.map(cl => (cl instanceof Component ? cl : cl.ensureModifier().toComponent())) |
||||
|
.forEach((icomp, i) => { |
||||
|
/* sets the width for all elements, |
||||
|
to avoid overlapping or line break because of lacking width, |
||||
|
a percent is subtracted for every child element */ |
||||
|
/* To enable "override" a new Modifier is generated and joined |
||||
|
with the modifier of the component */ |
||||
|
icomp._modifier = new Modifier() |
||||
|
.setStyleRule("float", (i === 0 ? "left" : "right")) |
||||
|
.join(icomp._modifier) |
||||
|
}) |
||||
|
} |
||||
|
return super.childContext(innerComponent) |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* |
||||
|
* @returns {Row} |
||||
|
*/ |
||||
|
distibuteSpacingEvenly() { |
||||
|
this._element.children.forEach(child => { |
||||
|
child.style["width"] = (100 / innerComponent.length); |
||||
|
}) |
||||
|
return this; |
||||
|
} |
||||
|
} |
||||
|
|
@ -0,0 +1,220 @@ |
|||||
|
/** |
||||
|
* Method Collection with predefined HTMLElements |
||||
|
*/ |
||||
|
const builder = { |
||||
|
components: { |
||||
|
parent: {}, |
||||
|
current: {}, |
||||
|
previous: {}, |
||||
|
next: {}, |
||||
|
openedChain: {} |
||||
|
}, |
||||
|
|
||||
|
/** |
||||
|
* |
||||
|
* @param {string} tag |
||||
|
* @param {Map<string,string>} attr |
||||
|
* @returns {Component} |
||||
|
*/ |
||||
|
genTag: function (tag, attr = {}) { return new Component(document.createElement(tag), attr).addStyleClass(`el-${tag}`); }, |
||||
|
|
||||
|
/** |
||||
|
* |
||||
|
* @param {Map<string,string>} attr |
||||
|
* @returns {Component} |
||||
|
*/ |
||||
|
anchor: function (attr = {}) { return builder.genTag("a", attr); }, |
||||
|
/** |
||||
|
* |
||||
|
* @param {Map<string,string>} attr |
||||
|
* @returns {Component} |
||||
|
*/ |
||||
|
label: function (attr = {}) { return builder.genTag("label", attr); }, |
||||
|
/** |
||||
|
* |
||||
|
* @param {Map<string,string>} attr |
||||
|
* @returns {Component} |
||||
|
*/ |
||||
|
button: function (attr = {}) { return builder.genTag("button", attr); }, |
||||
|
/** |
||||
|
* |
||||
|
* @param {Map<string,string>} attr |
||||
|
* @returns {Component} |
||||
|
*/ |
||||
|
input: function (attr = {}) { return builder.genTag("input", attr); }, |
||||
|
/** |
||||
|
* |
||||
|
* @param {Map<string,string>} attr |
||||
|
* @returns {Component} |
||||
|
*/ |
||||
|
div: function (attr = {}) { return builder.genTag("div", attr); }, |
||||
|
/** |
||||
|
* |
||||
|
* @param {Map<string,string>} attr |
||||
|
* @returns {Component} |
||||
|
*/ |
||||
|
span: function (attr = {}) { return builder.genTag("span", attr); }, |
||||
|
/** |
||||
|
* |
||||
|
* @param {Map<string,string>} attr |
||||
|
* @returns {Component} |
||||
|
*/ |
||||
|
paragraph: function (attr = {}) { return builder.genTag("paragraph", attr); }, |
||||
|
/** |
||||
|
* |
||||
|
* @param {Map<string,string>} attr |
||||
|
* @returns {Component} |
||||
|
*/ |
||||
|
header: function (sizeGroup, attr = {}) { return builder.genTag(`h${sizeGroup}`, attr); }, |
||||
|
/** |
||||
|
* |
||||
|
* @param {Map<string,string>} attr |
||||
|
* @returns {Component} |
||||
|
*/ |
||||
|
checkbox: function (attr = {}) { return builder.input({ "type": "checkbox" }) }, |
||||
|
/** |
||||
|
* |
||||
|
* @param {Map<string,string>} attr |
||||
|
* @returns {Component} |
||||
|
*/ |
||||
|
select: function (attr = {}) { return builder.genTag("select", attr); }, |
||||
|
/** |
||||
|
* |
||||
|
* @param {Map<string,string>} attr |
||||
|
* @returns {Component} |
||||
|
*/ |
||||
|
option: function (attr = {}) { return builder.genTag("option", attr); }, |
||||
|
/** |
||||
|
* |
||||
|
* @param {Map<string,string>} attr |
||||
|
* @returns {Component} |
||||
|
*/ |
||||
|
select: function (attr = {}) { return builder.genTag("select", attr); }, |
||||
|
/** |
||||
|
* |
||||
|
* @param {Map<string,string>} attr |
||||
|
* @returns {Component} |
||||
|
*/ |
||||
|
radioBtn: function (attr = {}) { return builder.genTag("radioBtn", attr); }, |
||||
|
/** |
||||
|
* |
||||
|
* @param {Map<string,string>} attr |
||||
|
* @returns {Component} |
||||
|
*/ |
||||
|
icon: function (attr = {}) { return builder.genTag("icon", attr); }, |
||||
|
/** |
||||
|
* |
||||
|
* @param {Map<string,string>} attr |
||||
|
* @returns {Component} |
||||
|
*/ |
||||
|
img: function (attr = {}) { return builder.genTag("img", attr); }, |
||||
|
|
||||
|
/** |
||||
|
* |
||||
|
* @param {Map<string,string>} attr |
||||
|
* @returns {Component} |
||||
|
*/ |
||||
|
textarea: function (attr = {}) { return builder.genTag("textarea", attr); }, |
||||
|
|
||||
|
/** |
||||
|
* |
||||
|
* @param {Map<string,string>} attr |
||||
|
* @returns {Component} |
||||
|
*/ |
||||
|
table: function (attr = {}) { return builder.genTag("table", attr) }, |
||||
|
|
||||
|
/** |
||||
|
* |
||||
|
* @param {Map<string,string>} attr |
||||
|
* @returns {Component} |
||||
|
*/ |
||||
|
tableRow: function (attr = {}) { return builder.genTag("tr", attr) }, |
||||
|
|
||||
|
/** |
||||
|
* |
||||
|
* @param {Map<string,string>} attr |
||||
|
* @returns {Component} |
||||
|
*/ |
||||
|
tableCell: function (attr = {}) { return builder.genTag("td", attr) }, |
||||
|
|
||||
|
/** |
||||
|
* |
||||
|
* @param {Map<string,string>} attr |
||||
|
* @returns {Component} |
||||
|
*/ |
||||
|
tableCaption: function (attr = {}) { return builder.genTag("caption", attr) }, |
||||
|
|
||||
|
/** |
||||
|
* |
||||
|
* @param {Map<string,string>} attr |
||||
|
* @returns {Component} |
||||
|
*/ |
||||
|
tableHeadCell: function (attr = {}) { return builder.genTag("th", attr) }, |
||||
|
|
||||
|
/** |
||||
|
* |
||||
|
* @param {Map<string,string>} attr |
||||
|
* @returns {Component} |
||||
|
*/ |
||||
|
tableBody: function (attr = {}) { return builder.genTag("tbody", attr) }, |
||||
|
|
||||
|
/** |
||||
|
* |
||||
|
* @param {Map<string,string>} attr |
||||
|
* @returns {Component} |
||||
|
*/ |
||||
|
tableHead: function (attr = {}) { return builder.genTag("thead", attr) }, |
||||
|
/** |
||||
|
* |
||||
|
* @param {Map<string,string>} attr |
||||
|
* @returns {Component} |
||||
|
*/ |
||||
|
tableFooter: function (attr = {}) { return builder.genTag("tfoot", attr) }, |
||||
|
|
||||
|
/** |
||||
|
* |
||||
|
* @param {Map<string,string>} attr |
||||
|
* @returns {Component} |
||||
|
*/ |
||||
|
form: function (attr = {}) { |
||||
|
return builder.genTag("form", attr) |
||||
|
.addStyleClass("flex-container-component") |
||||
|
.chainModifier() |
||||
|
.setStyleRule("flex-direction", "column") |
||||
|
.ensureModifier() |
||||
|
.toComponent() |
||||
|
}, |
||||
|
|
||||
|
/** |
||||
|
* |
||||
|
* @param {*} attr |
||||
|
* @returns {Row} |
||||
|
*/ |
||||
|
row: function (attr = {}) { return new Row(attr) }, |
||||
|
|
||||
|
/** |
||||
|
* |
||||
|
* @param {*} attr |
||||
|
* @returns {Column} |
||||
|
*/ |
||||
|
column: function (attr = {}) { return new Column(attr) }, |
||||
|
|
||||
|
/** |
||||
|
* |
||||
|
* @param {*} innerComponents |
||||
|
*/ |
||||
|
page: function (innerComponents) { |
||||
|
let main = document.querySelector('main') |
||||
|
|
||||
|
main.parentElement.insertAdjacentElement( |
||||
|
"afterbegin", |
||||
|
builder.genTag("main") |
||||
|
.alignment(Alignment.CENTER) |
||||
|
.arrangement(Arrangement.CENTER) |
||||
|
.childContext(innerComponents) |
||||
|
.generate() |
||||
|
) |
||||
|
Page.generate(); |
||||
|
main.remove(); |
||||
|
} |
||||
|
} |
@ -0,0 +1,8 @@ |
|||||
|
/** |
||||
|
* Enum to access common events |
||||
|
*/ |
||||
|
const CommonEvents = Object.freeze({ |
||||
|
ONCLICK: "onclick", |
||||
|
ONCHANGE: "onchange" |
||||
|
}) |
||||
|
|
@ -0,0 +1,234 @@ |
|||||
|
/** |
||||
|
* A chainable HTMLElement builder. |
||||
|
*/ |
||||
|
class Component { |
||||
|
_element; |
||||
|
_modifier |
||||
|
_alignment; |
||||
|
_arrangement; |
||||
|
_toRegister; |
||||
|
|
||||
|
constructor(element, attr = {}) { |
||||
|
this._modifier = new Modifier().margin(new Sides().all(0)); |
||||
|
var akeys = Object.keys(attr); |
||||
|
for (let i = 0; i < akeys.length; i++) { |
||||
|
element.setAttribute(akeys[i], attr[akeys[i]]); |
||||
|
} |
||||
|
this._element = element; |
||||
|
this._toRegister = []; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Sets the alignment (modifications) for this element or more specific for its children. |
||||
|
* @param {Alignment} alignment |
||||
|
* @returns {Component} this component object |
||||
|
*/ |
||||
|
alignment(alignment) { |
||||
|
this._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._modifier._modifications["justify-content"] = alignment;
|
||||
|
|
||||
|
return this; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Sets the arrangement (modifications) for this element or more specific for its children. |
||||
|
* @param {Arrangement} arrangement |
||||
|
* @returns {Component} this component object |
||||
|
*/ |
||||
|
arrangement(arrangement) { |
||||
|
this._arrangement = arrangement; |
||||
|
switch (arrangement) { |
||||
|
case Arrangement.START: |
||||
|
this._modifier._modifications["justify-content"] = "start"; |
||||
|
break; |
||||
|
case Arrangement.END: |
||||
|
this._modifier._modifications["justify-content"] = "end"; |
||||
|
break; |
||||
|
case Arrangement.CENTER: |
||||
|
this._modifier._modifications["justify-content"] = "center"; |
||||
|
break; |
||||
|
case Arrangement.SPACE_AROUND: |
||||
|
this._modifier._modifications["justify-content"] = "space-around"; |
||||
|
break; |
||||
|
case Arrangement.SPACE_BETWEEN: |
||||
|
this._modifier._modifications["justify-content"] = "space-between"; |
||||
|
break; |
||||
|
case Arrangement.SPACE_EVENLY: |
||||
|
this._modifier._modifications["justify-content"] = "space-evenly"; |
||||
|
break; |
||||
|
} |
||||
|
return this; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* |
||||
|
* @param {Modifier} modifier |
||||
|
* @returns {Component} this component object |
||||
|
*/ |
||||
|
modifier(modifier) { |
||||
|
this._modifier = this._modifier.join(modifier.ensureModifier()) |
||||
|
return this; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Sets the innerText of the element |
||||
|
* @param {string} text |
||||
|
* @returns {Component} this component object |
||||
|
*/ |
||||
|
text(text) { |
||||
|
this._element.innerText = text; |
||||
|
return this; |
||||
|
} |
||||
|
|
||||
|
title(text) { |
||||
|
this._element.title = text; |
||||
|
return this; |
||||
|
} |
||||
|
/** |
||||
|
* |
||||
|
* @param {string} styleClass |
||||
|
* @returns {Component} this component object |
||||
|
*/ |
||||
|
addStyleClass(styleClass) { |
||||
|
this._element.classList.add(styleClass); |
||||
|
return this; |
||||
|
} |
||||
|
|
||||
|
registerStyleClass(styleClass, styleRuleMap){ |
||||
|
Page.registerStyling('.'+styleClass, styleRuleMap); |
||||
|
return this.addStyleClass(styleClass); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* |
||||
|
* @param {string} key |
||||
|
* @param {string} value |
||||
|
* @returns {Component} this component object |
||||
|
*/ |
||||
|
setAttribute(key, value) { |
||||
|
this._element.setAttribute(key, value); |
||||
|
return this; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* Ends chain. |
||||
|
* Applies all modifications on the element. |
||||
|
* @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; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* Opens a context to create element children. |
||||
|
* Either as one component or a list/array of components. |
||||
|
* @param {Component|Array<Component>} component |
||||
|
* @returns {Component} this component object |
||||
|
*/ |
||||
|
childContext(component) { |
||||
|
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 { |
||||
|
this._element.append( |
||||
|
(component instanceof Component |
||||
|
? component |
||||
|
: component.toComponent() |
||||
|
) |
||||
|
.generate() |
||||
|
); |
||||
|
} |
||||
|
return this; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* @deprecated |
||||
|
* @param {Array<Component>} innerComponent |
||||
|
* @returns {Component} this component object |
||||
|
*/ |
||||
|
componentChildren(innerComponent) { |
||||
|
for (let i = 0; i < innerComponent.length; i++) { |
||||
|
this.childContext(innerComponent[i]); |
||||
|
} |
||||
|
return this; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* |
||||
|
* @param {CommonEvent} commonEvent |
||||
|
* @param {string} functionName |
||||
|
* @returns {Component} this component object |
||||
|
*/ |
||||
|
setEvent(commonEvent, functionName) { |
||||
|
return this.setAttribute(commonEvent, `${functionName}(this)`); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* |
||||
|
* @returns {ChainableModifier} |
||||
|
*/ |
||||
|
chainModifier() { |
||||
|
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" |
||||
|
this.addStyleClass(cssClass) |
||||
|
this._modifier._modifications["box-shadow"] = "4px 6px #999"; |
||||
|
|
||||
|
let bckk = "background-color"; |
||||
|
if (this._modifier._modifications.hasOwnProperty(bckk)) { |
||||
|
let bckc = this._modifier._modifications[bckk]; |
||||
|
delete this._modifier._modifications[bckk]; |
||||
|
Page.registerStyling(`.${cssClass}`, { |
||||
|
[bckk]: bckc |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
Page.registerStyling(`.${cssClass}:hover`, { |
||||
|
"background-color": Colors.greenyellow.cssRGBString(), |
||||
|
}) |
||||
|
Page.registerStyling(`.${cssClass}:active`, { |
||||
|
"background-color": Colors.greenyellow.cssRGBString(), |
||||
|
"box-shadow": "1px 2px #666", |
||||
|
"transform": "translateY(4px)" |
||||
|
}) |
||||
|
|
||||
|
return this.setEvent(CommonEvents.ONCLICK, eventName); |
||||
|
} |
||||
|
*/ |
||||
|
} |
@ -0,0 +1,130 @@ |
|||||
|
/** |
||||
|
* The class provides overreaching options for building the website. |
||||
|
*/ |
||||
|
class PageBuilder { |
||||
|
#cssClasses; |
||||
|
#functions; |
||||
|
#delayedFunctions; |
||||
|
#repeatingFunctions; |
||||
|
#functionNames; |
||||
|
#cssElementIdentifiers; |
||||
|
|
||||
|
constructor() { |
||||
|
this.#cssClasses = document.createElement("style"); |
||||
|
this.#functions = document.createElement("script"); |
||||
|
this.#functionNames = []; |
||||
|
this.#cssElementIdentifiers = []; |
||||
|
this.#delayedFunctions = []; |
||||
|
this.#repeatingFunctions = {}; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Registers a function to be added later in a script tag in the head of the document. |
||||
|
* @param {string} name |
||||
|
* @param {func} fun |
||||
|
*/ |
||||
|
registerFunction(name, fun) { |
||||
|
if (!this.#functionNames.includes(name)) { |
||||
|
this.#functions.innerText += `const ${name} = ${fun};`; |
||||
|
this.#functionNames.push(name); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* @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. |
||||
|
* @param {string} elementDefinition The element identifier |
||||
|
* @param {Map<string, string>} styleRuleMap The Styling rules/values |
||||
|
*/ |
||||
|
registerStyling(elementDefinition, styleRuleMap) { |
||||
|
if (!this.#cssElementIdentifiers.includes(elementDefinition)) { |
||||
|
this.#cssClasses.innerText += `${elementDefinition |
||||
|
} {${Object.keys(styleRuleMap) |
||||
|
.map(e => e + ": " + styleRuleMap[e] + "; ") |
||||
|
.join(" ") |
||||
|
}} ` |
||||
|
this.#cssElementIdentifiers.push(elementDefinition) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 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<any>} 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 }); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* |
||||
|
* @param {number} relaunchSeconds timeinterval for page to reload (changes) |
||||
|
*/ |
||||
|
inDev(relaunchSeconds = 20) { |
||||
|
let head = document.querySelector("head"); |
||||
|
let meta = document.createElement("meta"); |
||||
|
meta.setAttribute("http-equiv", "refresh"); |
||||
|
meta.setAttribute("content", `${relaunchSeconds}`); |
||||
|
|
||||
|
head.insertAdjacentElement("beforeend", meta); |
||||
|
this.#functions.innerText = ` |
||||
|
let ts = new Date(); |
||||
|
console.log("Refreshed at: ", ts.getHours()+':'+ts.getMinutes()+':'+ts.getSeconds(), "Intervall ${relaunchSeconds}s"); |
||||
|
`;
|
||||
|
} |
||||
|
} |
||||
|
|
||||
|
const Page = new PageBuilder(); |
@ -1,89 +0,0 @@ |
|||||
/** |
|
||||
* Represents container Components. |
|
||||
* Some predefined modifications are applied on the child components. |
|
||||
*/ |
|
||||
class FlexContainerComponent extends Component { |
|
||||
constructor(attr = {}) { |
|
||||
super(document.createElement("div"), attr) |
|
||||
.addStyleClass("flex-container-component") |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* |
|
||||
* @param {Component|Array<Component>} innerComponent |
|
||||
* @returns this component object |
|
||||
*/ |
|
||||
childComponents(innerComponent) { |
|
||||
if (innerComponent instanceof Array) { |
|
||||
innerComponent.forEach(icomp => { |
|
||||
(icomp instanceof Component |
|
||||
? icomp |
|
||||
: icomp.backToComponent() |
|
||||
) |
|
||||
.chainModifier() |
|
||||
.setStyleRule("flex", "none") |
|
||||
|
|
||||
}) |
|
||||
} else if (!innerComponent instanceof Component) { |
|
||||
innerComponent |
|
||||
.backToComponent() |
|
||||
.chainModifier() |
|
||||
.setStyleRule("flex", "none") |
|
||||
} |
|
||||
return super.childComponents(innerComponent); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* A FlexContainerComponent, which organizes the children in a column like manner. |
|
||||
*/ |
|
||||
class Column extends FlexContainerComponent { |
|
||||
constructor(attr = {}) { |
|
||||
super(document.createElement("div"), attr) |
|
||||
.addStyleClass("column-component") |
|
||||
.modifier( |
|
||||
new Modifier() |
|
||||
.fillMaxHeight() |
|
||||
.setStyleRule("flex-direction", "column") |
|
||||
); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* A FlexContainerComponent, which organizes the children in a row like manner. |
|
||||
*/ |
|
||||
class Row extends FlexContainerComponent { |
|
||||
constructor(attr = {}) { |
|
||||
super(attr) |
|
||||
.addStyleClass("row-component") |
|
||||
.modifier( |
|
||||
new Modifier() |
|
||||
.fillMaxWidth() |
|
||||
.setStyleRule("flex-direction", "row") |
|
||||
) |
|
||||
} |
|
||||
|
|
||||
childComponents(innerComponent) { |
|
||||
if (innerComponent instanceof Array) { |
|
||||
innerComponent.forEach((icomp, i) => { |
|
||||
(icomp instanceof Component |
|
||||
? icomp |
|
||||
: icomp.backToComponent() |
|
||||
).modifier( |
|
||||
/* sets the width for all elements, |
|
||||
to avoid overlapping or line break because of lacking width, |
|
||||
a percent is subtracted for every child element */ |
|
||||
new Modifier() |
|
||||
.setStyleRule("float", (i === 0 ? "left" : "right")) |
|
||||
.fillMaxWidth((Math.floor((10000 - 100 * innerComponent.length) / innerComponent.length) / 10000)) |
|
||||
) |
|
||||
}) |
|
||||
} else { |
|
||||
innerComponent.modifier( |
|
||||
new Modifier() |
|
||||
.setStyleRule("flex", "none") |
|
||||
) |
|
||||
} |
|
||||
return super.childComponents(innerComponent) |
|
||||
} |
|
||||
} |
|
@ -1,44 +0,0 @@ |
|||||
const builder = { |
|
||||
components: { |
|
||||
parent: {}, |
|
||||
current: {}, |
|
||||
previous: {}, |
|
||||
next: {}, |
|
||||
openedChain: {} |
|
||||
}, |
|
||||
|
|
||||
genTag: function (tag, attr = {}) { return new Component(document.createElement(tag), attr); }, |
|
||||
|
|
||||
anchor: function (attr = {}) { return builder.genTag("a", attr); }, |
|
||||
label: function (attr = {}) { return builder.genTag("label", attr); }, |
|
||||
button: function (attr = {}) { return builder.genTag("button", attr); }, |
|
||||
input: function (attr = {}) { return builder.genTag("input", attr); }, |
|
||||
div: function (attr = {}) { return builder.genTag("div", attr); }, |
|
||||
paragraph: function (attr = {}) { return builder.genTag("paragraph", attr); }, |
|
||||
header: function (sizeGroup, attr = {}) { return builder.genTag(`h${sizeGroup}`, attr); }, |
|
||||
checkbox: function (attr = {}) { return builder.genTag("checkbox", attr); }, |
|
||||
selection: function (attr = {}) { return builder.genTag("selection", attr); }, |
|
||||
option: function (attr = {}) { return builder.genTag("option", attr); }, |
|
||||
section: function (attr = {}) { return builder.genTag("section", attr); }, |
|
||||
radioBtn: function (attr = {}) { return builder.genTag("radioBtn", attr); }, |
|
||||
icon: function (attr = {}) { return builder.genTag("icon", attr); }, |
|
||||
img: function (attr = {}) { return builder.genTag("img", attr); }, |
|
||||
textarea: function (attr = {}) { return builder.genTag("textarea", attr); }, |
|
||||
|
|
||||
table: function (attr = {}) { return builder.genTag("table", attr) }, |
|
||||
tableRow: function (attr = {}) { return builder.genTag("tr", attr) }, |
|
||||
tableCell: function (attr = {}) { return builder.genTag("td", attr) }, |
|
||||
tableCaption: function (attr = {}) { return builder.genTag("caption", attr) }, |
|
||||
tableHeadCell: function (attr = {}) { return builder.genTag("th", attr) }, |
|
||||
tableBody: function (attr = {}) { return builder.genTag("tbody", attr) }, |
|
||||
tableHead: function (attr = {}) { return builder.genTag("thead", attr) }, |
|
||||
tableFooter: function (attr = {}) { return builder.genTag("tfoot", attr) }, |
|
||||
|
|
||||
|
|
||||
row: function (attr = {}) { return new Row(attr) }, |
|
||||
column: function (attr = {}) { return new Column(attr) }, |
|
||||
page: function (innerComponents) { |
|
||||
Page.generate(); |
|
||||
document.querySelector('main').appendChild(innerComponents.generate()) |
|
||||
} |
|
||||
} |
|
@ -1,161 +0,0 @@ |
|||||
/** |
|
||||
* A chainable HTMLElement builder. |
|
||||
*/ |
|
||||
class Component { |
|
||||
_element; |
|
||||
_modifier |
|
||||
_alignment; |
|
||||
_arrangement; |
|
||||
|
|
||||
constructor(element, attr = {}) { |
|
||||
this._modifier = new Modifier().margin(new Siding().all(0)); |
|
||||
var akeys = Object.keys(attr); |
|
||||
for (let i = 0; i < akeys.length; i++) { |
|
||||
element.setAttribute(akeys[i], attr[akeys[i]]); |
|
||||
} |
|
||||
this._element = element; |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* Sets the alignment (modifications) for this element or more specific for its children. |
|
||||
* @param {Alignment} alignment |
|
||||
* @returns this component object |
|
||||
*/ |
|
||||
alignment(alignment) { |
|
||||
this._alignment = alignment; |
|
||||
return this; |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* Sets the arrangement (modifications) for this element or more specific for its children. |
|
||||
* @param {Arrangement} arrangement |
|
||||
* @returns this component object |
|
||||
*/ |
|
||||
arrangement(arrangement) { |
|
||||
this._arrangement = arrangement; |
|
||||
switch (arrangement) { |
|
||||
case Arrangement.START: |
|
||||
this._modifier.modifications["justify-content", "start"] |
|
||||
break; |
|
||||
case Arrangement.END: |
|
||||
this._modifier.modifications["justify-content", "end"] |
|
||||
break; |
|
||||
case Arrangement.CENTER: |
|
||||
this._modifier.modifications["justify-content", "center"] |
|
||||
break; |
|
||||
case Arrangement.SPACE_AROUND: |
|
||||
this._modifier.modifications["justify-content", "space-around"] |
|
||||
break; |
|
||||
case Arrangement.SPACE_BETWEEN: |
|
||||
this._modifier.modifications["justify-content", "space-between"] |
|
||||
break; |
|
||||
case Arrangement.SPACE_EVENLY: |
|
||||
this._modifier.modifications["justify-content", "space-evenly"] |
|
||||
break; |
|
||||
} |
|
||||
return this; |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* |
|
||||
* @param {Modifier} modifier |
|
||||
* @returns this component object |
|
||||
*/ |
|
||||
modifier(modifier) { |
|
||||
this._modifier = this._modifier.join(modifier) |
|
||||
return this; |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* Sets the innerText of the element |
|
||||
* @param {string} text |
|
||||
* @returns this component object |
|
||||
*/ |
|
||||
text(text) { |
|
||||
this._element.innerText = text; |
|
||||
return this; |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* |
|
||||
* @param {string} styleClass |
|
||||
* @returns this component object |
|
||||
*/ |
|
||||
addStyleClass(styleClass) { |
|
||||
this._element.classList.add(styleClass); |
|
||||
return this; |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* |
|
||||
* @param {string} key |
|
||||
* @param {string} value |
|
||||
* @returns this component object |
|
||||
*/ |
|
||||
setAttribute(key, value) { |
|
||||
this._element.setAttribute(key, value); |
|
||||
return this; |
|
||||
} |
|
||||
|
|
||||
|
|
||||
/** |
|
||||
* Ends chain. |
|
||||
* Applies all modifications on the element. |
|
||||
* @returns {HTMLElemment} the html element |
|
||||
*/ |
|
||||
generate() { |
|
||||
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]]; |
|
||||
} |
|
||||
return this._element; |
|
||||
} |
|
||||
|
|
||||
|
|
||||
/** |
|
||||
* |
|
||||
* @param {Component} component |
|
||||
* @returns this component object |
|
||||
*/ |
|
||||
child(component) { |
|
||||
this._element.append( |
|
||||
(component instanceof Component |
|
||||
?component |
|
||||
:component.backToComponent() |
|
||||
) |
|
||||
.generate() |
|
||||
); |
|
||||
return this; |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* |
|
||||
* @param {Array<Component>} innerComponent |
|
||||
* @returns this component object |
|
||||
*/ |
|
||||
childComponents(innerComponent) { |
|
||||
for (let i = 0; i < innerComponent.length; i++) { |
|
||||
this.child(innerComponent[i]); |
|
||||
} |
|
||||
return this; |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* |
|
||||
* @param {CommonEvent} commonEvent |
|
||||
* @param {string} functionName |
|
||||
* @returns this component object |
|
||||
*/ |
|
||||
setEvent(commonEvent, functionName) { |
|
||||
return this.setAttribute(commonEvent, `${functionName}(this)`); |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* |
|
||||
* @returns {ChainableModifier} |
|
||||
*/ |
|
||||
chainModifier() { |
|
||||
return new ChainableModifier(this); |
|
||||
} |
|
||||
|
|
||||
} |
|
@ -1,212 +0,0 @@ |
|||||
/** |
|
||||
* Enum to access common events |
|
||||
*/ |
|
||||
const CommonEvents = Object.freeze({ |
|
||||
ONCLICK: "onClick", |
|
||||
}) |
|
||||
|
|
||||
|
|
||||
/** |
|
||||
* Simple Dimensions container for the height and width in pixels. |
|
||||
*/ |
|
||||
class Dimensions { |
|
||||
#x; |
|
||||
#y; |
|
||||
|
|
||||
/** |
|
||||
* Sets width (x) value of pixels |
|
||||
* @param {number} pixels |
|
||||
* @returns this Dimensions Modifier |
|
||||
*/ |
|
||||
width(pixels) { |
|
||||
this.#x = pixels; |
|
||||
return this; |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* Sets height (y) value of pixels |
|
||||
* @param {number} pixels |
|
||||
* @returns this Dimensions Modifier |
|
||||
*/ |
|
||||
height(pixels) { |
|
||||
this.#y = pixels; |
|
||||
return this; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* The Class holds values from each side/direction of an element. |
|
||||
* Used for margin/padding. |
|
||||
*/ |
|
||||
class Siding { |
|
||||
pxLeft = 0; |
|
||||
pxRight = 0; |
|
||||
pxTop = 0; |
|
||||
pxBottom = 0; |
|
||||
|
|
||||
/** |
|
||||
* sets the pixels-value for all sides. |
|
||||
* @param {number} pixels siding from all sides |
|
||||
* @returns this Siding Object |
|
||||
*/ |
|
||||
all(pixels) { |
|
||||
this.pxLeft = pixels; |
|
||||
this.pxRight = pixels; |
|
||||
this.pxTop = pixels; |
|
||||
this.pxBottom = pixels; |
|
||||
return this; |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* sets the pixels-value for the horizontal sides (left and right). |
|
||||
* @param {number} pixels siding for left and right. |
|
||||
* @returns this Siding Object |
|
||||
*/ |
|
||||
horizontal(pixels) { |
|
||||
this.pxLeft = pixels; |
|
||||
this.pxRight = pixels; |
|
||||
return this; |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* sets the pixels-value for the vertical sides (left and right). |
|
||||
* @param {number} pixels siding for top and bottom. |
|
||||
* @returns this Siding Object |
|
||||
*/ |
|
||||
vertical(pixels) { |
|
||||
this.pxTop = pixels; |
|
||||
this.pxBottom = pixels; |
|
||||
return this; |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* sets the pixels-value for the left side. |
|
||||
* @param {number} pixels siding for left |
|
||||
* @returns this Siding Object |
|
||||
*/ |
|
||||
left(pixels) { |
|
||||
this.pxLeft = pixels; |
|
||||
return this; |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* sets the pixels-value for the right side. |
|
||||
* @param {number} pixels siding for right |
|
||||
* @returns this Siding Object |
|
||||
*/ |
|
||||
right(pixels) { |
|
||||
this.pxRight = pixels; |
|
||||
return this; |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* sets the pixels-value for the top side. |
|
||||
* @param {number} pixels siding for top |
|
||||
* @returns this Siding Object |
|
||||
*/ |
|
||||
top(pixels) { |
|
||||
this.pxTop = pixels; |
|
||||
return this; |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* sets the pixels-value for the bottom side. |
|
||||
* @param {number} pixels siding for bottom |
|
||||
* @returns this Siding Object |
|
||||
*/ |
|
||||
bottom(pixels) { |
|
||||
this.pxBottom = pixels; |
|
||||
return this; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* Enum providing common alignment rules |
|
||||
*/ |
|
||||
const Alignment = Object.freeze({ |
|
||||
BEGIN_BORDER: 0, |
|
||||
CENTER: 1, |
|
||||
END_BORDER: 2, |
|
||||
}) |
|
||||
|
|
||||
/** |
|
||||
* Enum providing common alignment rules |
|
||||
*/ |
|
||||
const Arrangement = Object.freeze({ |
|
||||
START: 0, |
|
||||
END: 1, |
|
||||
CENTER: 2, |
|
||||
SPACE_BETWEEN: 3, |
|
||||
SPACE_EVENLY: 4, |
|
||||
SPACE_AROUND: 5, |
|
||||
}) |
|
||||
|
|
||||
|
|
||||
class ChainableDimensions extends Dimensions { |
|
||||
#modifier; |
|
||||
constructor(modifier) { |
|
||||
super(); |
|
||||
this.#modifier = modifier; |
|
||||
} |
|
||||
|
|
||||
backToModifier() { |
|
||||
return this.#modifier; |
|
||||
} |
|
||||
|
|
||||
backToComponent() { |
|
||||
return this.#modifier.backToComponent(); |
|
||||
} |
|
||||
|
|
||||
componentChild(innerComponent) { |
|
||||
return this.#modifier.backToComponent() |
|
||||
.child(innerComponent); |
|
||||
} |
|
||||
|
|
||||
componentChildComponents(innerComponent) { |
|
||||
return this.#modifier.backToComponent() |
|
||||
.childComponents(innerComponent); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
class ChainableSiding extends Siding { |
|
||||
#modifier; |
|
||||
constructor(modifier) { |
|
||||
super(); |
|
||||
this.#modifier = modifier; |
|
||||
} |
|
||||
|
|
||||
backToModifier() { |
|
||||
return this.#modifier; |
|
||||
} |
|
||||
|
|
||||
backToComponent() { |
|
||||
return this.#modifier.backToComponent(); |
|
||||
} |
|
||||
|
|
||||
|
|
||||
|
|
||||
componentChild(innerComponent) { |
|
||||
return this.#modifier |
|
||||
.backToComponent() |
|
||||
.child(innerComponent); |
|
||||
} |
|
||||
|
|
||||
componentChildComponents(innerComponent) { |
|
||||
return this.#modifier |
|
||||
.backToComponent() |
|
||||
.childComponents(innerComponent); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
const LineStyles = Object.freeze({ |
|
||||
dotted: 0, |
|
||||
dashed: 1, |
|
||||
solid: 2, |
|
||||
double: 3, |
|
||||
groove: 4, |
|
||||
ridge: 5, |
|
||||
inset: 6, |
|
||||
outset: 7, |
|
||||
none: 8, |
|
||||
hidden: 9 |
|
||||
}) |
|
@ -1,32 +0,0 @@ |
|||||
/** |
|
||||
* The class provides overreaching options for building the website. |
|
||||
*/ |
|
||||
class PageBuilder { |
|
||||
#cssClasses; |
|
||||
#functions; |
|
||||
|
|
||||
constructor() { |
|
||||
this.#cssClasses = document.createElement("style"); |
|
||||
this.#functions = document.createElement("script"); |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* Registers a function to be added later in a script tag in the head of the document. |
|
||||
* @param {string} name |
|
||||
* @param {func} fun |
|
||||
*/ |
|
||||
registerFunction(name, fun) { |
|
||||
this.#functions.innerText += `const ${name} = ${fun}`; |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* Adds a script tag into the head of the document. |
|
||||
*/ |
|
||||
generate() { |
|
||||
document.querySelector("head") |
|
||||
.appendChild(this.#functions) |
|
||||
} |
|
||||
|
|
||||
} |
|
||||
|
|
||||
const Page = new PageBuilder(); |
|
@ -1,179 +0,0 @@ |
|||||
/** |
|
||||
* A chained class that sets most of the stylings of an element. |
|
||||
*/ |
|
||||
class Modifier { |
|
||||
modifications = {}; |
|
||||
|
|
||||
constructor() { |
|
||||
this.modifications = new Object(); |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* Sets the modifications for widht and height to 100%. |
|
||||
* @returns this modifier object |
|
||||
*/ |
|
||||
fillMaxSize() { |
|
||||
this.modifications["width"] = "100%"; |
|
||||
this.modifications["height"] = "100%"; |
|
||||
return this; |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* Sets the modification for width to 100%. |
|
||||
* @param {number} fraction |
|
||||
* @returns this modifier object |
|
||||
*/ |
|
||||
fillMaxWidth(fraction) { |
|
||||
this.modifications["width"] = (100 * fraction) + "%"; |
|
||||
return this; |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* Sets the modification for height to 100%. |
|
||||
* @param {number} fraction |
|
||||
* @returns this modifier object |
|
||||
*/ |
|
||||
fillMaxHeight(fraction) { |
|
||||
this.modifications["height"] = (100 * fraction) + "%"; |
|
||||
return this; |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* Sets modifications according to the dimensions object. |
|
||||
* @param {Dimensions} dimensions |
|
||||
* @returns this modifier object |
|
||||
*/ |
|
||||
size(dimensions) { |
|
||||
this.modifications["height"] = dimensions.height + "px"; |
|
||||
this.modifications["width"] = dimensions.width + "px"; |
|
||||
return this; |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* Sets the padding on all sides according to the given siding object. |
|
||||
* Currently the padding will always be set |
|
||||
* to the most recent padding/siding. |
|
||||
* @param {Siding} siding |
|
||||
* @returns this modifier object |
|
||||
*/ |
|
||||
padding(siding) { |
|
||||
this.modifications["padding-right"] = siding.pxRight + "px"; |
|
||||
this.modifications["padding-left"] = siding.pxLeft + "px"; |
|
||||
this.modifications["padding-top"] = siding.pxTop + "px"; |
|
||||
this.modifications["padding-bottom"] = siding.pxBottom + "px"; |
|
||||
return this; |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* Sets the margin on all sides according to the given siding object. |
|
||||
* Currently the margin will always be set |
|
||||
* to the most recent margin/siding. |
|
||||
* @param {Siding} siding |
|
||||
* @returns this modifier object |
|
||||
*/ |
|
||||
margin(siding) { |
|
||||
this.modifications["margin-right"] = siding.pxRight + "px"; |
|
||||
this.modifications["margin-left"] = siding.pxLeft + "px"; |
|
||||
this.modifications["margin-top"] = siding.pxTop + "px"; |
|
||||
this.modifications["margin-bottom"] = siding.pxBottom + "px"; |
|
||||
return this; |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* Sets the background-color as a rgb color. |
|
||||
* @param {Color} color |
|
||||
* @returns this modifier object |
|
||||
*/ |
|
||||
background(color) { |
|
||||
this.modifications["background-color"] = color.cssRGBString(); |
|
||||
return this; |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* Sets the color as a rgb color. |
|
||||
* @param {Color} color |
|
||||
* @returns this modifier object |
|
||||
*/ |
|
||||
color(color) { |
|
||||
this.modifications["color"] = color.cssRGBString(); |
|
||||
return this; |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* Adds the modifications of the given Modifier to current Modifier. |
|
||||
* This is especailly used in the cases of extending existing/pre defined |
|
||||
* Components. |
|
||||
* CAUTION matching existing modifications will be ignored. |
|
||||
* @param modifier The "new" Modifier |
|
||||
* @returns The "old/current" Modifier, |
|
||||
* extended with the modifications of the given Modifier. |
|
||||
*/ |
|
||||
join(modifier, modifications = {}) { |
|
||||
var keys = Object.keys(modifier.modifications); |
|
||||
for (let i = 0; i < keys.length; i++) { |
|
||||
if (!this.modifications.hasOwnProperty(keys[i])) |
|
||||
this.modifications[keys[i]] = modifier.modifications[keys[i]]; |
|
||||
} |
|
||||
return this; |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* |
|
||||
* @param {string} key a css style rule |
|
||||
* @param {string} value the corresponding value to the css style rule |
|
||||
* @returns this modifier object |
|
||||
*/ |
|
||||
setStyleRule(key, value) { |
|
||||
this.modifications[key] = value; |
|
||||
return this; |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* Sets a border line (with given linestyle) to all sides. |
|
||||
* If lineStyle is an array, the containing LineStyles, |
|
||||
* are applied in the order: [top, right, bottom, left]. |
|
||||
* @param {LineStyles|Array<LineStyles>} lineStyle the style of the border line |
|
||||
* @returns this modifier object |
|
||||
*/ |
|
||||
border(lineStyle, width = 1, color = Colors.black) { |
|
||||
var lstyle = (lineStyle instanceof Array |
|
||||
? lineStyle.join(" ") |
|
||||
: lineStyle); |
|
||||
this.modifications["border"] = `${width}px ${lstyle} ${color.cssRGBString}`; |
|
||||
return this; |
|
||||
} |
|
||||
|
|
||||
} |
|
||||
|
|
||||
class ChainableModifier extends Modifier { |
|
||||
_component; |
|
||||
|
|
||||
constructor(component) { |
|
||||
super(); |
|
||||
this._component = component; |
|
||||
} |
|
||||
|
|
||||
backToComponent() { |
|
||||
return this._component.modifier(this); |
|
||||
} |
|
||||
|
|
||||
chainSize() { |
|
||||
return new ChainableDimensions(this); |
|
||||
} |
|
||||
|
|
||||
chainPaddingSiding() { |
|
||||
return new ChainableSiding(this); |
|
||||
} |
|
||||
|
|
||||
componentChild(innerComponent) { |
|
||||
return this._component |
|
||||
.modifier(this) |
|
||||
.child(innerComponent); |
|
||||
} |
|
||||
|
|
||||
componentChildComponents(innerComponent) { |
|
||||
return this._component |
|
||||
.modifier(this) |
|
||||
.childComponents(innerComponent); |
|
||||
} |
|
||||
} |
|
@ -0,0 +1,246 @@ |
|||||
|
/** |
||||
|
* A chained class that sets most of the stylings of an element. |
||||
|
*/ |
||||
|
class Modifier { |
||||
|
_modifications; |
||||
|
|
||||
|
constructor() { |
||||
|
this._modifications = new Object(); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Sets the modifications for widht and height to 100%. |
||||
|
* @returns {Modifier} this modifier object |
||||
|
*/ |
||||
|
fillMaxSize(widthFraction = 1, heightFraction = 1) { |
||||
|
return this.fillMaxWidth(widthFraction) |
||||
|
.fillMaxHeight(heightFraction); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Sets the modification for width to 100%. |
||||
|
* @param {number} fraction |
||||
|
* @returns {Modifier} this modifier object |
||||
|
*/ |
||||
|
fillMaxWidth(fraction = 1) { |
||||
|
this._modifications["width"] = (100 * fraction) + "%"; |
||||
|
return this; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Sets the modification for height to 100%. |
||||
|
* @param {number} fraction |
||||
|
* @returns {Modifier} this modifier object |
||||
|
*/ |
||||
|
fillMaxHeight(fraction = 1) { |
||||
|
this._modifications["height"] = (100 * fraction) + "%"; |
||||
|
return this; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Sets modifications according to the dimensions object. |
||||
|
* @param {Dimensions} dimensions |
||||
|
* @returns {Modifier} this modifier object |
||||
|
*/ |
||||
|
dimensions(dimensions) { |
||||
|
dimensions.toModifications() |
||||
|
.forEach(kvpair => { |
||||
|
this._modifications[kvpair.key] = kvpair.value; |
||||
|
}) |
||||
|
return this; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Sets the padding on all sides according to the given padding object. |
||||
|
* Currently the padding will always be set |
||||
|
* to the most recent padding/padding. |
||||
|
* @param {Sides} siding |
||||
|
* @returns {Modifier} this modifier object |
||||
|
*/ |
||||
|
padding(siding) { |
||||
|
let keyToAdd = ""; |
||||
|
if (siding instanceof PaddingChain) { |
||||
|
|
||||
|
} else if (siding instanceof Sides) { |
||||
|
keyToAdd = "padding-" |
||||
|
} |
||||
|
siding.toModifications() |
||||
|
.forEach(kvpair => { |
||||
|
this._modifications[keyToAdd + kvpair.key] = kvpair.value; |
||||
|
}) |
||||
|
return this; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Sets the margin on all sides according to the given siding object. |
||||
|
* Currently the margin will always be set |
||||
|
* to the most recent margin/siding. |
||||
|
* @param {Sides} siding |
||||
|
* @returns {Modifier} this modifier object |
||||
|
*/ |
||||
|
margin(siding) { |
||||
|
this._modifications["margin"] = siding.getOrderedValues().join(' '); |
||||
|
return this; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Sets the background-color as a rgb color. |
||||
|
* @param {Color} color |
||||
|
* @returns {Modifier} this modifier object |
||||
|
*/ |
||||
|
background(color) { |
||||
|
this._modifications["background-color"] = color.cssRGBString(); |
||||
|
return this; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Sets the color as a rgb color. |
||||
|
* @param {Color} color |
||||
|
* @returns {Modifier} this modifier object |
||||
|
*/ |
||||
|
color(color) { |
||||
|
this._modifications["color"] = color.cssRGBString(); |
||||
|
return this; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Adds the modifications of the given Modifier to current Modifier. |
||||
|
* This is especailly used in the cases of extending existing/pre defined |
||||
|
* Components. |
||||
|
* CAUTION matching existing modifications will be overwritten. |
||||
|
* @param modifier The "new" Modifier |
||||
|
* @returns {Modifier} The "old/current" Modifier, |
||||
|
* extended with the modifications of the given Modifier. |
||||
|
*/ |
||||
|
join(modifier, modifications = {}) { |
||||
|
var keys = Object.keys(modifier.ensureModifier()._modifications); |
||||
|
for (let i = 0; i < keys.length; i++) { |
||||
|
/* if (!this._modifications.hasOwnProperty(keys[i])) */ |
||||
|
this._modifications[keys[i]] = modifier.ensureModifier()._modifications[keys[i]]; |
||||
|
} |
||||
|
return this; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* |
||||
|
* @param {string} key a css style rule |
||||
|
* @param {string} value the corresponding value to the css style rule |
||||
|
* @returns {Modifier} this modifier object |
||||
|
*/ |
||||
|
setStyleRule(key, value) { |
||||
|
this._modifications[key] = value; |
||||
|
return this; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Sets a border line (with given linestyle) to all sides. |
||||
|
* If lineStyle is an array, the containing LineStyles, |
||||
|
* are applied in the order: [top, right, bottom, left]. |
||||
|
* @param {Border} border the style of the border line |
||||
|
* @returns {Modifier} this modifier object |
||||
|
*/ |
||||
|
border(border) { |
||||
|
border.toModifications() |
||||
|
.forEach(e => this._modifications[e.key] = e.value); |
||||
|
return this.clip(border._shape) |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* |
||||
|
* @param {Shape} shape |
||||
|
* @returns {Modifier} |
||||
|
*/ |
||||
|
clip(shape) { |
||||
|
this._modifications["border-radius"] = shape.getOrderedValues().join(' '); |
||||
|
return this; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* |
||||
|
* @param {number} size of width and height in pixels |
||||
|
* @returns {DimensionsChain} |
||||
|
*/ |
||||
|
linkDimensions(size = -1) { |
||||
|
if (size === -1) { |
||||
|
return new DimensionsChain(this); |
||||
|
} else { |
||||
|
return new DimensionsChain(this).all(size).ensureModifier() |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* |
||||
|
* @param {number} amount the padding for all four sides |
||||
|
* @returns {PaddingChain} |
||||
|
*/ |
||||
|
linkPadding(amount = -1) { |
||||
|
if (amount === -1) { |
||||
|
return new PaddingChain(this); |
||||
|
} else { |
||||
|
return new PaddingChain(this).all(amount); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* |
||||
|
* @param {number} cornerRadius will create a rounded rectangle with the given cornerRadius |
||||
|
* @returns {ShapeChain} |
||||
|
*/ |
||||
|
linkClip(cornerRadius = -1) { |
||||
|
if (cornerRadius === -1) { |
||||
|
return new ShapeChain(this); |
||||
|
} else { |
||||
|
return new ShapeChain(this).all(cornerRadius); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* |
||||
|
* @param {number} borderWidth sets the width of all four border sides |
||||
|
* @returns {BorderChain} |
||||
|
*/ |
||||
|
linkBorder(borderWidth = -1) { |
||||
|
if (borderWidth === -1) { |
||||
|
return new BorderChain(this); |
||||
|
} else { |
||||
|
return new BorderChain(this).width(borderWidth); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* |
||||
|
* @returns {Modifier} |
||||
|
*/ |
||||
|
ensureModifier() { |
||||
|
return this; |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
class ChainableModifier extends Modifier { |
||||
|
_component; |
||||
|
|
||||
|
constructor(component) { |
||||
|
super(); |
||||
|
this._component = component; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* |
||||
|
* @returns {Component} |
||||
|
*/ |
||||
|
toComponent() { |
||||
|
return this._component.modifier(this); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* |
||||
|
* @param {Component|Array<Component>} innerComponent |
||||
|
* @returns {Component} the parent Component |
||||
|
*/ |
||||
|
childContext(innerComponent) { |
||||
|
return this._component |
||||
|
.modifier(this) |
||||
|
.childContext(innerComponent); |
||||
|
} |
||||
|
} |
@ -0,0 +1,210 @@ |
|||||
|
|
||||
|
const LineStyles = Object.freeze({ |
||||
|
dotted: "dotted", |
||||
|
dashed: "dashed", |
||||
|
solid: "solid", |
||||
|
double: "double", |
||||
|
groove: "groove", |
||||
|
ridge: "ridge", |
||||
|
inset: "inset", |
||||
|
outset: "outset", |
||||
|
none: "none", |
||||
|
hidden: "hidden" |
||||
|
}) |
||||
|
|
||||
|
class BorderDefinition { |
||||
|
constructor(width = 0, color = Colors.black, style = LineStyles.solid) { |
||||
|
this._width = width; |
||||
|
this._color = color; |
||||
|
this._style = style; |
||||
|
} |
||||
|
|
||||
|
width(width) { |
||||
|
this._width = width; |
||||
|
return this; |
||||
|
} |
||||
|
color(color) { |
||||
|
this._color = color; |
||||
|
return this; |
||||
|
} |
||||
|
style(style) { |
||||
|
this._style = style; |
||||
|
return this; |
||||
|
} |
||||
|
join(def) { |
||||
|
Object.keys(def) |
||||
|
.forEach(key => this[key] = def[key]); |
||||
|
return this; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
const Define = Object.freeze({ |
||||
|
width: new BorderDefinition().width, |
||||
|
style: new BorderDefinition().style, |
||||
|
color: new BorderDefinition().color |
||||
|
}) |
||||
|
|
||||
|
class Border extends Sides { |
||||
|
constructor(width = 0, color = Colors.black, style = LineStyles.solid, defaultUnit = SizeUnits.PIXEL, shape = Shapes.Rectangle) { |
||||
|
super(0, defaultUnit); |
||||
|
this._fFirst = new BorderDefinition(width, color, style); |
||||
|
this._fSecond = new BorderDefinition(width, color, style); |
||||
|
this._fThird = new BorderDefinition(width, color, style); |
||||
|
this._fForth = new BorderDefinition(width, color, style); |
||||
|
this._shape = shape; |
||||
|
} |
||||
|
|
||||
|
setByIndex(index, value) { |
||||
|
if (value instanceof BorderDefinition) { |
||||
|
this.getByIndex(index).join(value) |
||||
|
} else { |
||||
|
this.getByIndex(index)._width = value |
||||
|
} |
||||
|
return this; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* |
||||
|
* @param {string} key |
||||
|
* @param {*} value |
||||
|
*/ |
||||
|
setOnDirections(key, value) { |
||||
|
let orderedAttributes = this.getOrderedAttributes() |
||||
|
for (let i = 0; i < this.getOrderedAttributes.length; i++) { |
||||
|
orderedAttributes[i][key] = value; |
||||
|
} |
||||
|
return this; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* |
||||
|
* @param {number} width |
||||
|
* @returns {Border} |
||||
|
*/ |
||||
|
width(width) { |
||||
|
this._fFirst._width = width; |
||||
|
this._fSecond._width = width; |
||||
|
this._fThird._width = width; |
||||
|
this._fForth._width = width; |
||||
|
return this; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* |
||||
|
* @param {*} color |
||||
|
* @returns {Border} |
||||
|
*/ |
||||
|
color(color) { |
||||
|
this._fFirst._color = color; |
||||
|
this._fSecond._color = color; |
||||
|
this._fThird._color = color; |
||||
|
this._fForth._color = color; |
||||
|
return this; |
||||
|
} |
||||
|
|
||||
|
shape(shape) { |
||||
|
this._shape = shape; |
||||
|
return this; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Sets the border-style of all sides to the given. |
||||
|
* @param {LineStyles} lineStyle style of the border |
||||
|
* @returns {Border} |
||||
|
*/ |
||||
|
setStyleAll(lineStyle) { |
||||
|
this._fFirst._style = lineStyle; |
||||
|
this._fSecond._style = lineStyle; |
||||
|
this._fThird._style = lineStyle; |
||||
|
this._fForth._style = lineStyle; |
||||
|
return this; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* |
||||
|
* @param {LineStyles} lineStyle |
||||
|
* @param {*} sidingRefSide |
||||
|
* @returns {Border} |
||||
|
*/ |
||||
|
setLineStyle(lineStyle, sidingRefSide) { |
||||
|
this._sidingStyles.setBySidingRef(sidingRefSide, lineStyle) |
||||
|
return this; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* |
||||
|
* @param {Map<SidingRefSides, LineStyles} refSideStyleMap |
||||
|
* @returns {Border} |
||||
|
*/ |
||||
|
setLineStyles(refSideStyleMap) { |
||||
|
let rkeys = Object.keys(refSideStyleMap); |
||||
|
for (let i = 0; i < array.length; i++) { |
||||
|
this._sidingStyles.setBySidingRef(rkeys[i]) = refSideStyleMap[rkeys[i]]; |
||||
|
} |
||||
|
return this; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
toModifications() { |
||||
|
let names = ["left", "top", "right", "bottom"]; |
||||
|
return this.getOrderedAttributes() |
||||
|
.flatMap((bdef, i) => { |
||||
|
if (bdef.width == 0) |
||||
|
return [] |
||||
|
|
||||
|
return [ |
||||
|
{ key: `border-${names[i]}-width`, value: bdef._width + this._unit }, |
||||
|
{ key: `border-${names[i]}-color`, value: bdef._color }, |
||||
|
{ key: `border-${names[i]}-style`, value: bdef._style } |
||||
|
] |
||||
|
}) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
class BorderChain extends Border { |
||||
|
constructor(modifier){ |
||||
|
super(); |
||||
|
this._modifier = modifier; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* |
||||
|
* @returns {Modifier|ChainableModifier} |
||||
|
*/ |
||||
|
toModifier() { |
||||
|
return this._modifier |
||||
|
.border(this); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* |
||||
|
* @returns {Modifier|ChainableModifier} |
||||
|
*/ |
||||
|
ensureModifier() { |
||||
|
return this.toModifier() |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Applies the border modification on the modifier |
||||
|
* and returns (through the modifier) to the corresponding component. |
||||
|
* @returns {Component} |
||||
|
*/ |
||||
|
toComponent() { |
||||
|
return this._modifier |
||||
|
.dimensions(this) |
||||
|
.toComponent(); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* |
||||
|
* @param {Component} innerComponent will be set to the corresponding component |
||||
|
* @returns {Component} the corr. Component after the childContext was applied. |
||||
|
*/ |
||||
|
childContext(innerComponent) { |
||||
|
return this._modifier |
||||
|
.dimensions(this) |
||||
|
.toComponent() |
||||
|
.childContext(innerComponent); |
||||
|
} |
||||
|
} |
@ -0,0 +1,105 @@ |
|||||
|
/** |
||||
|
* Simple Dimensions container for the height and width in pixels. |
||||
|
*/ |
||||
|
class Dimensions extends DirectionUnitDependentAttribute { |
||||
|
constructor(defaultValue = 0, defaultUnit = SizeUnits.PIXEL) { |
||||
|
super(); |
||||
|
this._unit = defaultUnit; |
||||
|
this._fFirst = defaultValue; |
||||
|
this._fSecond = defaultValue; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Sets width (x) value of amount |
||||
|
* @param {number} amount |
||||
|
* @returns {Dimensions} this Dimensions Modifier |
||||
|
*/ |
||||
|
width(amount) { |
||||
|
this._fFirst = amount; |
||||
|
return this; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Sets height (y) value of amount |
||||
|
* @param {number} amount |
||||
|
* @returns {Dimensions} this Dimensions Modifier |
||||
|
*/ |
||||
|
height(amount) { |
||||
|
this._fSecond = amount; |
||||
|
return this; |
||||
|
} |
||||
|
|
||||
|
all(size) { |
||||
|
return this.width(size).height(size); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
getOrderedValues() { |
||||
|
return this.getOrderedValues().slice(2) |
||||
|
} |
||||
|
|
||||
|
toModifications() { |
||||
|
let w = { key: "width", value: this._fFirst + this._unit } |
||||
|
let h = { key: "height", value: this._fSecond + this._unit } |
||||
|
let is_w = this._fFirst > 0; |
||||
|
let is_h = this._fSecond > 0; |
||||
|
if (is_h && is_w) { |
||||
|
return [w, h] |
||||
|
} else if (is_w) { |
||||
|
return [w] |
||||
|
} else if (is_h) { |
||||
|
return [h] |
||||
|
} else { |
||||
|
return [] |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
class DimensionsChain extends Dimensions { |
||||
|
_modifier; |
||||
|
constructor(modifier) { |
||||
|
super(); |
||||
|
this._modifier = modifier; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* |
||||
|
* @returns {Modifier|ChainableModifier} |
||||
|
*/ |
||||
|
toModifier() { |
||||
|
return this._modifier |
||||
|
.dimensions(this); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* |
||||
|
* @returns {Modifier|ChainableModifier} |
||||
|
*/ |
||||
|
ensureModifier() { |
||||
|
return this.toModifier() |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* |
||||
|
* @returns {Component} the Component that was (supposed to be) modified by this obj. |
||||
|
*/ |
||||
|
toComponent() { |
||||
|
return this._modifier |
||||
|
.dimensions(this) |
||||
|
.toComponent(); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* |
||||
|
* @param {Component|Array<Component>} innerComponent children of the Component under modification. |
||||
|
* @returns {Component} |
||||
|
*/ |
||||
|
childContext(innerComponent) { |
||||
|
return this._modifier |
||||
|
.dimensions(this) |
||||
|
.toComponent() |
||||
|
.childContext(innerComponent); |
||||
|
} |
||||
|
} |
||||
|
|
@ -0,0 +1,131 @@ |
|||||
|
class Shape extends DirectionUnitDependentAttribute { |
||||
|
constructor(defaultValue = 0, defaultUnit = SizeUnits.PIXEL) { |
||||
|
super(defaultValue, defaultUnit); |
||||
|
} |
||||
|
/** |
||||
|
* |
||||
|
* @param {*} amount |
||||
|
* @returns {Shape} |
||||
|
*/ |
||||
|
topLeft(amount) { |
||||
|
this._fFirst = amount; |
||||
|
return this; |
||||
|
} |
||||
|
/** |
||||
|
* |
||||
|
* @param {*} amount |
||||
|
* @returns {Shape} |
||||
|
*/ |
||||
|
topRight(amount) { |
||||
|
this._fSecond = amount; |
||||
|
return this; |
||||
|
} |
||||
|
/** |
||||
|
* |
||||
|
* @param {*} amount |
||||
|
* @returns {Shape} |
||||
|
*/ |
||||
|
bottomLeft(amount) { |
||||
|
this._fThird = amount; |
||||
|
return this; |
||||
|
} |
||||
|
/** |
||||
|
* |
||||
|
* @param {*} amount |
||||
|
* @returns {Shape} |
||||
|
*/ |
||||
|
bottomRight(amount) { |
||||
|
this._fForth = amount; |
||||
|
return this; |
||||
|
} |
||||
|
/** |
||||
|
* |
||||
|
* @param {*} amount |
||||
|
* @returns {Shape} |
||||
|
*/ |
||||
|
diagonalPositive(amount) { |
||||
|
return this.bottomLeft(amount).topRight(amount); |
||||
|
} |
||||
|
/** |
||||
|
* |
||||
|
* @param {*} amount |
||||
|
* @returns {Shape} |
||||
|
*/ |
||||
|
diagonalNegative(amount) { |
||||
|
return this.topLeft(amount).bottomRight(amount); |
||||
|
} |
||||
|
|
||||
|
left(amount) { |
||||
|
return this.topLeft(amount).bottomLeft(amount); |
||||
|
} |
||||
|
|
||||
|
right(amount) { |
||||
|
return this.topRight(amount).bottomRight(amount); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* |
||||
|
* @param {*} amount |
||||
|
*/ |
||||
|
getSidingRefValueMap() { |
||||
|
return { |
||||
|
[SidingRefCorners.TOPLEFT]: this.getBySidingRef(SidingRefCorners.TOPLEFT), |
||||
|
[SidingRefCorners.TOPRIGHT]: this.getBySidingRef(SidingRefCorners.TOPRIGHT), |
||||
|
[SidingRefCorners.BOTTOMLEFT]: this.getBySidingRef(SidingRefCorners.BOTTOMLEFT), |
||||
|
[SidingRefCorners.BOTTOMRIGHT]: this.getBySidingRef(SidingRefCorners.BOTTOMRIGHT), |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
class ShapeChain extends Shape { |
||||
|
_modifier; |
||||
|
constructor(modifier) { |
||||
|
super(); |
||||
|
this._modifier = modifier; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* |
||||
|
* @returns {Modifier|ChainableModifier} |
||||
|
*/ |
||||
|
toModifier() { |
||||
|
return this._modifier |
||||
|
.clip(this); |
||||
|
} |
||||
|
/** |
||||
|
* |
||||
|
* @returns {Modifier|ChainableModifier} |
||||
|
*/ |
||||
|
ensureModifier() { |
||||
|
return this.toModifier() |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* |
||||
|
* @returns {Component} the Component that was (supposed to be) modified by this obj. |
||||
|
*/ |
||||
|
toComponent() { |
||||
|
return this._modifier |
||||
|
.clip(this) |
||||
|
.toComponent(); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* |
||||
|
* @param {Component|Array<Component>} innerComponent children of the Component under modification. |
||||
|
* @returns {Component} |
||||
|
*/ |
||||
|
childContext(innerComponent) { |
||||
|
return this._modifier |
||||
|
.clip(this) |
||||
|
.toComponent() |
||||
|
.childContext(innerComponent); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
const Shapes = Object.freeze({ |
||||
|
Rectangle: new Shape(), |
||||
|
RoundedCorner: new Shape(), |
||||
|
Circle: new Shape(49, SizeUnits.PERCENT) |
||||
|
}) |
@ -0,0 +1,260 @@ |
|||||
|
const SizeUnits = Object.freeze({ |
||||
|
PIXEL: "px", |
||||
|
PERCENT: "%" |
||||
|
}) |
||||
|
|
||||
|
|
||||
|
class DirectionUnitDependentAttribute { |
||||
|
_unit; |
||||
|
_fFirst; |
||||
|
_fSecond; |
||||
|
_fThird; |
||||
|
_fForth; |
||||
|
|
||||
|
constructor(defaultValue = 0, defaultUnit = SizeUnits.PIXEL) { |
||||
|
this._unit = defaultUnit; |
||||
|
this._fFirst = defaultValue; |
||||
|
this._fSecond = defaultValue; |
||||
|
this._fThird = defaultValue; |
||||
|
this._fForth = defaultValue; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* |
||||
|
* @param {Units} unit The unit of the amount or style |
||||
|
* @returns {DirectionUnitDependentAttribute} this - Object |
||||
|
*/ |
||||
|
setUnit(unit) { |
||||
|
this._unit = unit; |
||||
|
return this; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* |
||||
|
* @returns {array<*>} list of attributes |
||||
|
*/ |
||||
|
getOrderedAttributes() { |
||||
|
return [this._fFirst, this._fSecond, this._fThird, this._fForth]; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* @returns {Array<string>} |
||||
|
*/ |
||||
|
getOrderedValues() { |
||||
|
return this.getOrderedAttributes().map(a => a + this._unit); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Since the basic values are from "first" to "fourth", |
||||
|
* they can be also accessed in the ordered way. |
||||
|
* |
||||
|
* Mainly used by the setup of directions of subclasses. |
||||
|
* @param {number} index [1,4] |
||||
|
* @param {number} value |
||||
|
* @returns {DirectionUnitDependentAttribute} this |
||||
|
*/ |
||||
|
setByIndex(index, value) { |
||||
|
switch (index) { |
||||
|
case 1: |
||||
|
this._fFirst = value; |
||||
|
break; |
||||
|
case 2: |
||||
|
this._fSecond = value; |
||||
|
break; |
||||
|
case 3: |
||||
|
this._fThird = value; |
||||
|
break; |
||||
|
case 4: |
||||
|
this._fForth = value; |
||||
|
break; |
||||
|
|
||||
|
default: |
||||
|
this._fFirst = value; |
||||
|
break; |
||||
|
} |
||||
|
return this; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Since the basic values are from "first" to "fourth", |
||||
|
* they can be also accessed in the ordered way. |
||||
|
* |
||||
|
* Mainly used by the setup of directions of subclasses. |
||||
|
* @param {number} index [1,4] |
||||
|
* @returns {*} this value of index |
||||
|
*/ |
||||
|
getByIndex(index) { |
||||
|
switch (index) { |
||||
|
case 1: |
||||
|
return this._fFirst; |
||||
|
case 2: |
||||
|
return this._fSecond; |
||||
|
case 3: |
||||
|
return this._fThird; |
||||
|
case 4: |
||||
|
return this._fForth; |
||||
|
|
||||
|
default: |
||||
|
return this._fFirst; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Placeholder for overrides |
||||
|
* @returns {Object} |
||||
|
*/ |
||||
|
toModifications() { |
||||
|
return this.getOrderedValues() |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* sets the amount-value for all directions. |
||||
|
* @param {number} amount value to set for all directions |
||||
|
* @returns {DirectionUnitDependentAttribute} this |
||||
|
*/ |
||||
|
all(amount) { |
||||
|
this._fFirst = amount; |
||||
|
this._fSecond = amount; |
||||
|
this._fThird = amount; |
||||
|
this._fForth = amount; |
||||
|
return this; |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
|
||||
|
class Sides extends DirectionUnitDependentAttribute { |
||||
|
/** |
||||
|
* |
||||
|
* @param {number|string} defaultValue |
||||
|
* @param {SizeUnits} defaultUnit |
||||
|
*/ |
||||
|
constructor(defaultValue = 0, defaultUnit = SizeUnits.PIXEL) { |
||||
|
super(defaultValue, defaultUnit); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* sets the amount-value for the left side. |
||||
|
* @param {number} amount siding for left |
||||
|
* @returns {Siding} this Siding Object |
||||
|
*/ |
||||
|
left(amount) { |
||||
|
return this.setByIndex(1, amount); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* sets the amount-value for the right side. |
||||
|
* @param {number} amount siding for right |
||||
|
* @returns {Siding} this Siding Object |
||||
|
*/ |
||||
|
right(amount) { |
||||
|
return this.setByIndex(3, amount); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* sets the amount-value for the top side. |
||||
|
* @param {number} amount siding for top |
||||
|
* @returns {Siding} this Siding Object |
||||
|
*/ |
||||
|
top(amount) { |
||||
|
return this.setByIndex(2, amount); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* sets the amount-value for the bottom side. |
||||
|
* @param {number} amount siding for bottom |
||||
|
* @returns {Siding} this Siding Object |
||||
|
*/ |
||||
|
bottom(amount) { |
||||
|
return this.setByIndex(4, amount); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* sets the amount-value for the horizontal sides (left and right). |
||||
|
* @param {number} amount siding for left and right. |
||||
|
* @returns {Sides} this Siding Object |
||||
|
*/ |
||||
|
horizontal(amount) { |
||||
|
return this.left(amount).right(amount); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* sets the amount-value for the vertical sides (left and right). |
||||
|
* @param {number} amount siding for top and bottom. |
||||
|
* @returns {Sides} this Siding Object |
||||
|
*/ |
||||
|
vertical(amount) { |
||||
|
return this.top(amount).bottom(amount); |
||||
|
} |
||||
|
|
||||
|
toModifications() { |
||||
|
return [ |
||||
|
{ key: "left", value: this._fFirst + this._unit }, |
||||
|
{ key: "top", value: this._fSecond + this._unit }, |
||||
|
{ key: "right", value: this._fThird + this._unit }, |
||||
|
{ key: "bottom", value: this._fForth + this._unit } |
||||
|
] |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
class PaddingChain extends Sides { |
||||
|
_modifier; |
||||
|
constructor(modifier) { |
||||
|
super(); |
||||
|
this._modifier = modifier; |
||||
|
} |
||||
|
|
||||
|
toModifier() { |
||||
|
return this._modifier |
||||
|
.padding(this); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Returns the corresponding Modifier. |
||||
|
* Basically climbs up the chain level. |
||||
|
* @returns {Modifier} |
||||
|
*/ |
||||
|
ensureModifier() { |
||||
|
return this.toModifier() |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Returns the style-modifications of the class. |
||||
|
* @returns {Map<string,string>} |
||||
|
*/ |
||||
|
toModifications() { |
||||
|
return [ |
||||
|
{ key: "padding-left", value: this._fFirst + this._unit }, |
||||
|
{ key: "padding-top", value: this._fSecond + this._unit }, |
||||
|
{ key: "padding-right", value: this._fThird + this._unit }, |
||||
|
{ key: "padding-bottom", value: this._fForth + this._unit } |
||||
|
] |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* |
||||
|
* @returns {Component} the Component that was (supposed to be) modified by this obj. |
||||
|
*/ |
||||
|
toComponent() { |
||||
|
return this._modifier |
||||
|
.padding(this) |
||||
|
.toComponent(); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* |
||||
|
* @param {Component|Array<Component>} innerComponent children of the Component under modification. |
||||
|
* @returns {Component} |
||||
|
*/ |
||||
|
childContext(innerComponent) { |
||||
|
return this._modifier |
||||
|
.padding(this) |
||||
|
.toComponent() |
||||
|
.childContext(innerComponent); |
||||
|
} |
||||
|
} |
||||
|
|
Loading…
Reference in new issue