-
Notifications
You must be signed in to change notification settings - Fork 0
/
element-builder.ts
115 lines (85 loc) · 3.05 KB
/
element-builder.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
import { StringMap } from "../types";
// TODO: need to be checked if app is running in browser
let localContext: Document = document;
export class ElementBuilder {
private result?: HTMLElement;
private styles: StringMap = {};
private attributes: StringMap = {};
private readonly contentBuffer: (string | HTMLElement)[] = [];
private constructor(private readonly elementName: string, private readonly parent?: ElementBuilder) {
}
public static setContext(context: Document): void {
localContext = context;
}
public static start(elementName: string): ElementBuilder {
return new ElementBuilder(elementName);
}
public child(elementName: string): ElementBuilder {
return new ElementBuilder(elementName, this);
}
public reset(): ElementBuilder {
this.styles = {};
this.attributes = {};
delete this.result;
return this.clearContent();
}
public style(key: CSSStyleDeclaration, value: string): ElementBuilder {
this.styles.key = value;
return this;
}
public attribute(key: string, value: string): ElementBuilder {
this.attributes.key = value;
return this;
}
public content(newContent: string | HTMLElement): ElementBuilder {
return this.clearContent().addContent(newContent);
}
public addContent(newContent: string | HTMLElement): ElementBuilder {
this.contentBuffer.push(newContent);
return this;
}
public clearContent(): ElementBuilder {
this.contentBuffer.splice(0, this.contentBuffer.length);
return this;
}
public finish(): ElementBuilder {
if (!this.parent) {
throw new Error("Parent must be set");
}
return this.parent.addContent(this.build());
}
public build(): HTMLElement {
this.result = localContext.createElement(this.elementName);
this.contentBuffer.forEach((content) => {
if (typeof content === "string") {
(this.result as HTMLElement).innerHTML += content;
} else {
(this.result as HTMLElement).appendChild(content);
}
});
return this.result;
}
public id(id: string): ElementBuilder {
return this.attribute("id", id);
}
public clazz(clazz: string): ElementBuilder {
return this.attribute("class", clazz);
}
public buildAndAppendTo(parent: HTMLElement): ElementBuilder {
parent.appendChild(this.build());
return this;
}
public get(): HTMLElement | undefined {
return this.result;
}
}
ElementBuilder.start("div").attribute("class", "main-class").attribute("id", "main-id").build();
ElementBuilder.start("div").clazz("main-class").id("main-id").build();
ElementBuilder.start("table")
.id("main-table")
.child("tr").clazz("table-row")
.child("td").clazz("table-column")
.content("hello world")
.finish()
.finish()
.buildAndAppendTo(document.body);