|
|
@ -1,551 +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(); |
|
|
|
/** |
|
|
|
* Enum to access common events |
|
|
|
*/ |
|
|
|
const CommonEvents = Object.freeze({ |
|
|
|
ONCLICK: "onClick", |
|
|
|
}) |
|
|
|
|
|
|
|
/** |
|
|
|
* A simple Color class for rgb set color values. |
|
|
|
*/ |
|
|
|
class Color { |
|
|
|
#red; |
|
|
|
#green; |
|
|
|
#blue; |
|
|
|
|
|
|
|
constructor(red, green, blue) { |
|
|
|
this.#red = red |
|
|
|
this.#green = green |
|
|
|
this.#blue = blue |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* |
|
|
|
* @returns {string} an rgb object string |
|
|
|
*/ |
|
|
|
cssRGBString() { |
|
|
|
return `rgb(${this.#red}, ${this.#green}, ${this.#blue})`; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 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, |
|
|
|
}) |
|
|
|
/** |
|
|
|
* 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%. |
|
|
|
* @returns this modifier object |
|
|
|
*/ |
|
|
|
fillMaxWidth() { |
|
|
|
this.modifications["width"] = "100%"; |
|
|
|
return this; |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* Sets the modification for height to 100%. |
|
|
|
* @returns this modifier object |
|
|
|
*/ |
|
|
|
fillMaxHeight() { |
|
|
|
this.modifications["height"] = "100%"; |
|
|
|
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; |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
/** |
|
|
|
* A chainable HTMLElement builder. |
|
|
|
*/ |
|
|
|
class Component { |
|
|
|
_element; |
|
|
|
_modifier |
|
|
|
_alignment; |
|
|
|
_arrangement; |
|
|
|
|
|
|
|
constructor(element, attr = {}) { |
|
|
|
this._modifier = new Modifier().margin(new Siding().all(0)); |
|
|
|
this._element = element; |
|
|
|
Object.keys(attr) |
|
|
|
.forEach(key => { |
|
|
|
this._element.setAttribute(key, attr[key]); |
|
|
|
}) |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 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|Array<Component>} innerComponent |
|
|
|
* @returns this component object |
|
|
|
*/ |
|
|
|
childContext(innerComponent) { |
|
|
|
if (innerComponent instanceof Array) { |
|
|
|
for (let i = 0; i < innerComponent.length; i++) { |
|
|
|
this._element.append(innerComponent[i].generate()); |
|
|
|
} |
|
|
|
} else { |
|
|
|
this._element.append(innerComponent.generate()); |
|
|
|
} |
|
|
|
return this; |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* |
|
|
|
* @param {CommonEvent} commonEvent |
|
|
|
* @param {string} functionName |
|
|
|
* @returns this component object |
|
|
|
*/ |
|
|
|
setEvent(commonEvent, functionName) { |
|
|
|
return this.setAttribute(commonEvent, `${functionName}(this)`) |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
/** |
|
|
|
* 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 |
|
|
|
*/ |
|
|
|
childContext(innerComponent) { |
|
|
|
if (innerComponent instanceof Array) { |
|
|
|
innerComponent.forEach(icomp => { |
|
|
|
icomp.modifier( |
|
|
|
new Modifier() |
|
|
|
.setStyleRule("flex", "none") |
|
|
|
) |
|
|
|
}) |
|
|
|
} else { |
|
|
|
innerComponent.modifier( |
|
|
|
new Modifier() |
|
|
|
.setStyleRule("flex", "none") |
|
|
|
) |
|
|
|
} |
|
|
|
return super.childContext(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() |
|
|
|
.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() |
|
|
|
.setStyleRule("flex-direction", "row") |
|
|
|
) |
|
|
|
} |
|
|
|
} |
|
|
|
const builder = { |
|
|
|
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); }, |
|
|
|
|
|
|
|
row: function (attr = {}) { return new Row(attr) }, |
|
|
|
column: function (attr = {}) { return new Column(attr) }, |
|
|
|
page: function(innerComponents){ |
|
|
|
Page.generate(); |
|
|
|
document.querySelector('#root').appendChild(innerComponents.generate()) |
|
|
|
} |
|
|
|
} |