-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathJavascriptUI.ts
More file actions
208 lines (187 loc) · 7.82 KB
/
JavascriptUI.ts
File metadata and controls
208 lines (187 loc) · 7.82 KB
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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
import { JSDOM } from "jsdom"
export enum Font { title, text }
export type Content = () => void
type CurrentContent = Array<_Element>
let currentContent:CurrentContent = []
class _Element {
public modifyElement(document: Document, element: HTMLElement, parent?: HTMLDivElement): HTMLElement {
element.style.paddingTop = `${this._padding[0]}px`
element.style.paddingBottom = `${this._padding[1]}px`
element.style.paddingLeft = `${this._padding[2]}px`
element.style.paddingRight = `${this._padding[3]}px`
element.style.marginTop = `${this._margin[0]}px`
element.style.marginBottom = `${this._margin[1]}px`
element.style.marginLeft = `${this._margin[2]}px`
element.style.marginRight = `${this._margin[3]}px`
element.style.flex = "0 1 auto"
return element
}
public toElement(document: Document, parent?: HTMLDivElement): HTMLElement {
return document.createElement("a")
}
private _margin: Array<number> = [0, 0, 0, 0]
public margin(all: number, top?: number, bottom?: number, left?: number, right?: number): typeof this {
this._margin = [
(typeof top === "undefined" ? all : top),
(typeof bottom === "undefined" ? all : bottom),
(typeof left === "undefined" ? all : left),
(typeof right === "undefined" ? all : right)
]
return this
}
private _padding: Array<number> = [0, 0, 0, 0]
public padding(all: number, top?: number, bottom?: number, left?: number, right?: number): typeof this {
this._padding = [
(typeof top === "undefined" ? all : top),
(typeof bottom === "undefined" ? all : bottom),
(typeof left === "undefined" ? all : left),
(typeof right === "undefined" ? all : right)
]
return this
}
constructor() { currentContent.push(this) }
}
class _Content extends _Element {
content: CurrentContent = []
public modifyElement(document: Document, element: HTMLDivElement): HTMLDivElement {
element = super.modifyElement(document, element) as HTMLDivElement
this.content.forEach(_element => element.appendChild(_element.toElement(document, element)))
return element
}
public toElement(document: Document): HTMLDivElement {
return this.modifyElement(document, document.createElement("div"))
}
constructor(content: Content) {
super()
const originalContent = currentContent
currentContent = []
content()
this.content = currentContent
currentContent = originalContent
}
}
export function Group(content: Content): _Content { return new _Content(content) }
class _Body extends _Content {
public toDocument(document: Document) {
document.body.style.margin = "unset"
document.body.style.display = "flex"
document.body.style.flexFlow = "column"
document.body.style.height, document.body.style.width = "100%"
document.body.appendChild(this.toElement(document))
}
public modifyElement(document: Document, element: HTMLDivElement): HTMLDivElement {
element.style.margin = "unset"
element.style.display = "flex"
element.style.flexFlow = "column"
element.style.height, element.style.width = "100%"
element = super.modifyElement(document, element) as HTMLDivElement
return element
}
}
export function Body(content: Content): _Body {
const originalContent = currentContent
currentContent = []
const body = new _Body(content)
// code below are for testing (printing the generated html)
const dom = new JSDOM()
body.toDocument(dom.window.document)
console.log(dom.serialize())
currentContent = originalContent
return body
}
class _Events { }
export function Events(content: Content): _Events { return new _Events() }
export interface View {
events?: _Events
body?: _Content
}
class _HStack extends _Content {
constructor(content: Content) { super(content) }
public modifyElement(document: Document, element: HTMLDivElement): HTMLDivElement {
element.style.flexFlow = "row"
element.style.display = "flex"
return super.modifyElement(document, element) as HTMLDivElement
}
public toElement(document: Document): HTMLDivElement {
return this.modifyElement(document, document.createElement("div"))
}
}
export function HStack(content: Content): _HStack { return new _HStack(content) }
class _VStack extends _Content {
constructor(content: Content) { super(content) }
public modifyElement(document: Document, element: HTMLDivElement): HTMLDivElement {
element.style.flexFlow = "column"
element.style.display = "flex"
return super.modifyElement(document, element) as HTMLDivElement
}
public toElement(document: Document): HTMLDivElement {
return this.modifyElement(document, document.createElement("div"))
}
}
export function VStack(content: Content): _VStack { return new _VStack(content) }
class _Divider extends _Element {
constructor() { super() }
public modifyElement(document: Document, element: HTMLSpanElement, parent?: HTMLDivElement): HTMLSpanElement {
element = super.modifyElement(document, element, parent) as HTMLSpanElement
element.style.backgroundColor = "#000000"
const size = parent.style.flexFlow === "column" ? ["auto", "5px"] : ["5px", "auto"]
console.log("" + parent.style.flexFlow)
element.style.width = size[0]
element.style.height = size[1]
return element
}
public toElement(document: Document, parent?: HTMLDivElement): HTMLSpanElement {
return this.modifyElement(document, document.createElement("span"), parent)
}
}
export function Divider(): _Divider { return new _Divider() }
class _Spacer extends _Element {
public modifyElement(document, element: HTMLDivElement, parent?: HTMLDivElement): HTMLDivElement {
element = super.modifyElement(document, element) as HTMLDivElement
element.style.flex = "1 1 auto"
return element
}
public toElement(document: Document, parent?: HTMLDivElement): HTMLDivElement {
return this.modifyElement(document, document.createElement("div"), parent)
}
}
export function Spacer(): _Spacer { return new _Spacer() }
class _Text extends _Element {
public text: string
constructor(text: string) {
super()
this.text = text
}
public modifyElement(document: Document, element: HTMLHeadingElement | HTMLParagraphElement, parent?: HTMLDivElement): HTMLHeadingElement | HTMLParagraphElement {
element = super.modifyElement(document, element) as HTMLHeadingElement | HTMLParagraphElement
element.textContent = this.text
element.style.fontWeight = this._bold ? "bold" : "normal"
element.style.fontStyle = this._italic ? "italic" : "normal"
element.style.textDecoration = this._underline ? "underline" : "none"
return element
}
public toElement(document: Document, parent?: HTMLDivElement): HTMLHeadingElement | HTMLParagraphElement {
return this.modifyElement(document, document.createElement(this._font === Font.text ? "p" : "h1"), parent)
}
private _font: Font = Font.text
public font(font: Font): typeof this {
this._font = font
return this
}
private _bold: boolean = false
public bold(bold: boolean = true): typeof this {
this._bold = bold
return this
}
private _italic: boolean = false
public italic(italic: boolean = true): typeof this {
this._italic = italic
return this
}
private _underline: boolean = false
public underline(underline: boolean = true): typeof this {
this._underline = underline
return this
}
}
export function Text(text: string): _Text { return new _Text(text) }