vaderjs 1.4.2 → 1.4.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/{README.md → README.MD} +9 -19
- package/config/index.ts +12 -66
- package/document/index.ts +49 -0
- package/index.ts +283 -322
- package/main.js +314 -0
- package/package.json +8 -24
- package/.editorconfig +0 -11
- package/.vscode/c_cpp_properties.json +0 -21
- package/.vscode/settings.json +0 -12
- package/binaries/Kalix/index.js +0 -665
- package/binaries/compiler/main.js +0 -461
- package/binaries/vader.js +0 -74
- package/binaries/watcher/hmr.js +0 -36
- package/client/index.d.ts +0 -226
- package/client/runtime/index.js +0 -417
- package/client/runtime/router.js +0 -235
- package/plugins/cloudflare/functions/index.js +0 -98
- package/plugins/cloudflare/toCopy/@server/Kalix/index.js +0 -625
- package/plugins/cloudflare/toCopy/@server/cloudflare_ssr/index.js +0 -85
- package/plugins/cloudflare/toCopy/node_modules/vaderjs/server/index.js +0 -99
- package/plugins/cloudflare/toCopy/src/client.js +0 -432
- package/plugins/cloudflare/toCopy/src/router.js +0 -235
- package/plugins/ssg/index.js +0 -124
- package/plugins/vercel/functions/index.ts +0 -8
- package/router/index.ts +0 -181
- package/server/index.js +0 -129
- package/vader.js +0 -177
package/index.ts
CHANGED
|
@@ -1,344 +1,305 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
let isClassComponent = function(element) {
|
|
2
|
+
return element.toString().startsWith("class");
|
|
3
|
+
};
|
|
4
|
+
|
|
5
|
+
declare global {
|
|
6
|
+
interface Window {
|
|
7
|
+
onbeforeunload: any;
|
|
8
|
+
localStorage: any;
|
|
9
|
+
sessionStorage: any;
|
|
10
|
+
}
|
|
11
|
+
const genKey: any;
|
|
12
|
+
let isServer: boolean;
|
|
6
13
|
}
|
|
14
|
+
//@ts-ignore
|
|
15
|
+
globalThis.isServer = typeof window === "undefined";
|
|
7
16
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* @description useFetch allows you to make POST - GET - PUT - DELETE requests then returns the data, loading state and error
|
|
20
|
+
* @param url
|
|
21
|
+
* @param options
|
|
22
|
+
* @returns [data, loading, error]
|
|
23
|
+
*/
|
|
24
|
+
export const useFetch = (url: string, options: any) => {
|
|
25
|
+
return [null, true, null];
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* @description A custom hook that allows you to use state in a functional component
|
|
30
|
+
* @param key
|
|
31
|
+
* @param promise
|
|
32
|
+
* @returns
|
|
33
|
+
*/
|
|
34
|
+
export const useAsyncState = (key: string, promise: Promise<any>) => {
|
|
35
|
+
return [null, () => {}];
|
|
36
|
+
}
|
|
37
|
+
export const useEffect = (callback:any, dependencies: any[]) => {
|
|
38
|
+
dependencies = dependencies.map((dep) => dep.toString());
|
|
39
|
+
if (dependencies.length === 0) {
|
|
40
|
+
callback();
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* @description - Create a new element
|
|
46
|
+
* @param element
|
|
47
|
+
* @param props
|
|
48
|
+
* @param children
|
|
49
|
+
* @returns
|
|
50
|
+
*/
|
|
51
|
+
export const e = (element: any, props: any, ...children: any[]) => {
|
|
52
|
+
if(typeof element === "function"){
|
|
53
|
+
let instance = new Component();
|
|
54
|
+
instance.render = element;
|
|
55
|
+
return instance.render()
|
|
56
|
+
}
|
|
57
|
+
return { type: element, props: props || {}, children: children || [] };
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* @description - Create a new element
|
|
62
|
+
* @param key
|
|
63
|
+
* @param initialState
|
|
64
|
+
* @returns {state, (newState: any, Element: string) => void, key}
|
|
65
|
+
*/
|
|
66
|
+
export const useState = (key, initialState) => {
|
|
67
|
+
const instance = new Component;
|
|
68
|
+
return [instance.state[key],
|
|
69
|
+
/**
|
|
70
|
+
* @description - Set the state of the component
|
|
71
|
+
* @param newState
|
|
72
|
+
* @param Element
|
|
73
|
+
*/
|
|
74
|
+
(newState: any, Element: string) => {
|
|
75
|
+
instance.setState({ [key]: newState }, Element);
|
|
76
|
+
}, key];
|
|
77
|
+
}
|
|
78
|
+
//@ts-ignore
|
|
79
|
+
let state = {};
|
|
80
|
+
export class Component {
|
|
81
|
+
props: any;
|
|
82
|
+
state: any;
|
|
83
|
+
element: any;
|
|
84
|
+
Mounted: boolean;
|
|
85
|
+
effect: any[];
|
|
86
|
+
key: string;
|
|
87
|
+
prevState: any;
|
|
88
|
+
constructor() {
|
|
89
|
+
this.key = Math.random().toString(36).substring(7);
|
|
90
|
+
this.props = {};
|
|
91
|
+
//@ts-ignore
|
|
92
|
+
state[this.key] = {};
|
|
93
|
+
this.state = state[this.key];
|
|
94
|
+
this.effect = [];
|
|
95
|
+
this.Mounted = false;
|
|
96
|
+
this.element = null;
|
|
97
|
+
}
|
|
98
|
+
setState(newState: any, Element: string) {
|
|
99
|
+
state[this.key] = { ...this.state, ...newState };
|
|
100
|
+
console.log(state[this.key]);
|
|
101
|
+
this.forceUpdate(Element);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
useEffect(callback: any, dependencies: any[]) {
|
|
105
|
+
if (dependencies.length === 0 && this.Mounted && this.effect.length === 0) {
|
|
106
|
+
callback();
|
|
107
|
+
this.effect.push(callback);
|
|
108
|
+
}else{
|
|
109
|
+
for (let i = 0; i < dependencies.length; i++) {
|
|
110
|
+
if (this.effect[i] !== dependencies[i]) {
|
|
111
|
+
this.effect = dependencies;
|
|
112
|
+
callback();
|
|
113
|
+
}
|
|
114
|
+
}
|
|
32
115
|
}
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
forward: () => void,
|
|
116
|
+
}
|
|
117
|
+
useState(key: string, initialState: any) {
|
|
118
|
+
if (!this.state[key]) {
|
|
119
|
+
console.log(`State ${key} does not exist`)
|
|
120
|
+
this.state[key] = initialState;
|
|
39
121
|
}
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
removeItem: (key: string) => void,
|
|
44
|
-
clear: () => void,
|
|
122
|
+
|
|
123
|
+
window.onbeforeunload = () => {
|
|
124
|
+
sessionStorage.setItem("state", JSON.stringify({}));
|
|
45
125
|
}
|
|
46
126
|
/**
|
|
47
|
-
*
|
|
48
|
-
* @
|
|
49
|
-
* @
|
|
50
|
-
* @property {string} location.search - The query string of the current page
|
|
51
|
-
* @property {string} location.hash - The hash of the current page
|
|
52
|
-
* @property {string} location.host - The host of the current page
|
|
53
|
-
* @property {string} location.hostname - The hostname of the current page
|
|
54
|
-
* @property {string} location.port - The port of the current page
|
|
55
|
-
* @property {string} location.protocol - The protocol of the current page
|
|
56
|
-
* @property {string} location.origin - The origin of the current page
|
|
57
|
-
* @property {Function} location.reload - Reloads the current page
|
|
58
|
-
* @property {Object} history - The history object
|
|
59
|
-
* @property {Function} history.pushState - Pushes a new state to the history object
|
|
127
|
+
*
|
|
128
|
+
* @param {*} newState
|
|
129
|
+
* @param {*} Element - The element affected by the state change
|
|
60
130
|
*/
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
host: string,
|
|
71
|
-
hostname: string,
|
|
72
|
-
port: string,
|
|
73
|
-
protocol: string,
|
|
74
|
-
origin: string,
|
|
75
|
-
reload: () => void,
|
|
76
|
-
},
|
|
77
|
-
history: {
|
|
78
|
-
pushState: (state: any, title: string, url: string) => void,
|
|
79
|
-
replaceState: (state: any, title: string, url: string) => void,
|
|
80
|
-
go: (delta: number) => void,
|
|
81
|
-
back: () => void,
|
|
82
|
-
forward: () => void,
|
|
83
|
-
},
|
|
84
|
-
localStorage: {
|
|
85
|
-
getItem: (key: string) => string,
|
|
86
|
-
setItem: (key: string, value: string) => void,
|
|
87
|
-
removeItem: (key: string) => void,
|
|
88
|
-
clear: () => void,
|
|
89
|
-
},
|
|
131
|
+
const setState = (newState, Element) => {
|
|
132
|
+
this.prevState = { ...this.state };
|
|
133
|
+
this.state[key] = newState;
|
|
134
|
+
state[this.key] = { ...this.state };
|
|
135
|
+
this.forceUpdate(Element);
|
|
136
|
+
};
|
|
137
|
+
const returnKey = key;
|
|
138
|
+
return [this.state[key], setState, returnKey];
|
|
139
|
+
}
|
|
90
140
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
/**
|
|
94
|
-
* @type {Object}
|
|
95
|
-
* @description The file object
|
|
96
|
-
* @property {string} name - The name of the file
|
|
97
|
-
* @property {string} filetype - The type of the file
|
|
98
|
-
* @property {string} dataUrl - The data url of the file
|
|
99
|
-
* @property {string} text - The text content of the file
|
|
100
|
-
* @property {string} fileUrl - The file url
|
|
101
|
-
* @property {number} filesize - The file size
|
|
102
|
-
* @property {Blob} blob - The file blob
|
|
103
|
-
* @property {number} lastModified - The last modified date
|
|
104
|
-
* @property {string} mimetype - The file mimetype
|
|
105
|
-
*/
|
|
106
|
-
|
|
107
|
-
const requirePath: (path: string) => any;
|
|
141
|
+
useFetch(url, options) {
|
|
142
|
+
const { key } = options;
|
|
108
143
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
lastModified:{
|
|
113
|
-
date: string,
|
|
114
|
-
time: string,
|
|
115
|
-
parsed: string,
|
|
116
|
-
},
|
|
117
|
-
size: number,
|
|
118
|
-
fileContent: string,
|
|
144
|
+
console.log(key);
|
|
145
|
+
if (!key) {
|
|
146
|
+
throw new Error(`You must supply a key for the affected element in the options object`);
|
|
119
147
|
}
|
|
120
|
-
/**
|
|
121
|
-
* @description HTMLTextNode is a global interface that represents a text node
|
|
122
|
-
*/
|
|
123
148
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
toString: () => string,
|
|
128
|
-
}
|
|
129
|
-
/**
|
|
130
|
-
* @description HTMLElement is a global interface that represents an HTML element
|
|
131
|
-
*/
|
|
132
|
-
interface HTMLElement{
|
|
133
|
-
tagName: string,
|
|
134
|
-
id: string,
|
|
135
|
-
nodeType: number,
|
|
136
|
-
classList:{
|
|
137
|
-
add: (className: string) => void,
|
|
138
|
-
remove: (className: string) => void,
|
|
139
|
-
toggle: (className: string) => void,
|
|
140
|
-
contains: (className: string) => boolean,
|
|
141
|
-
}
|
|
142
|
-
props: {
|
|
143
|
-
[key: string]: string,
|
|
144
|
-
}
|
|
145
|
-
children: HTMLElement[],
|
|
146
|
-
outerHTML: string,
|
|
147
|
-
innerHTML: string,
|
|
148
|
-
textContent: string,
|
|
149
|
-
firstChild: HTMLElement | HTMLTextNode | null,
|
|
150
|
-
style?: {
|
|
151
|
-
|
|
152
|
-
display: string,
|
|
153
|
-
position: string,
|
|
154
|
-
top: string,
|
|
155
|
-
left: string,
|
|
156
|
-
right: string,
|
|
157
|
-
bottom: string,
|
|
158
|
-
width: string,
|
|
159
|
-
height: string,
|
|
160
|
-
maxWidth: string,
|
|
161
|
-
maxHeight: string,
|
|
162
|
-
minWidth: string,
|
|
163
|
-
minHeight: string,
|
|
164
|
-
margin: string,
|
|
165
|
-
marginTop: string,
|
|
166
|
-
marginRight: string,
|
|
167
|
-
marginBottom: string,
|
|
168
|
-
marginLeft: string,
|
|
169
|
-
padding: string,
|
|
170
|
-
paddingTop: string,
|
|
171
|
-
paddingRight: string,
|
|
172
|
-
paddingBottom: string,
|
|
173
|
-
paddingLeft: string,
|
|
174
|
-
overflow: string,
|
|
175
|
-
zIndex: string,
|
|
176
|
-
cursor: string,
|
|
177
|
-
textAlign: string,
|
|
178
|
-
fontSize: string,
|
|
179
|
-
fontWeight: string,
|
|
180
|
-
fontStyle: string,
|
|
181
|
-
textDecoration: string,
|
|
182
|
-
lineHeight: string,
|
|
183
|
-
letterSpacing: string,
|
|
184
|
-
textTransform: string,
|
|
185
|
-
backgroundColor: string,
|
|
186
|
-
backgroundImage: string,
|
|
187
|
-
backgroundSize: string,
|
|
188
|
-
backgroundPosition: string,
|
|
189
|
-
backgroundRepeat: string,
|
|
190
|
-
backgroundAttachment: string,
|
|
191
|
-
backgroundClip: string,
|
|
192
|
-
backgroundOrigin: string,
|
|
193
|
-
backgroundBlendMode: string,
|
|
194
|
-
boxShadow: string,
|
|
195
|
-
transition: string,
|
|
196
|
-
transform: string,
|
|
197
|
-
transformOrigin: string,
|
|
198
|
-
transformStyle: string,
|
|
199
|
-
perspective: string,
|
|
200
|
-
perspectiveOrigin: string,
|
|
201
|
-
backfaceVisibility: string,
|
|
202
|
-
filter: string,
|
|
203
|
-
backdropFilter: string,
|
|
204
|
-
mixBlendMode: string,
|
|
205
|
-
border: string,
|
|
206
|
-
borderTop: string,
|
|
207
|
-
borderRight: string,
|
|
208
|
-
borderBottom: string,
|
|
209
|
-
borderLeft: string,
|
|
210
|
-
borderStyle: string,
|
|
211
|
-
borderTopStyle: string,
|
|
212
|
-
borderRightStyle: string,
|
|
213
|
-
borderBottomStyle: string,
|
|
214
|
-
borderLeftStyle: string,
|
|
215
|
-
borderColor: string,
|
|
216
|
-
borderTopColor: string,
|
|
217
|
-
borderRightColor: string,
|
|
218
|
-
borderBottomColor: string,
|
|
219
|
-
borderLeftColor: string,
|
|
220
|
-
borderRadius: string,
|
|
221
|
-
borderTopLeftRadius: string,
|
|
222
|
-
borderTopRightRadius: string,
|
|
223
|
-
borderBottomRightRadius: string,
|
|
224
|
-
borderBottomLeftRadius: string,
|
|
225
|
-
borderWidth: string,
|
|
226
|
-
borderTopWidth: string,
|
|
227
|
-
borderRightWidth: string,
|
|
228
|
-
borderBottomWidth: string,
|
|
229
|
-
borderLeftWidth: string,
|
|
230
|
-
|
|
231
|
-
[key: string]: string,
|
|
232
|
-
}
|
|
233
|
-
attributes: {
|
|
234
|
-
[key: string]: string,
|
|
235
|
-
},
|
|
236
|
-
events: [],
|
|
237
|
-
toString: () => string,
|
|
238
|
-
getAttribute: (attr: string) => string | null,
|
|
239
|
-
setAttribute: (attr: string, value: string) => void,
|
|
240
|
-
appendChild: (child: HTMLElement) => void,
|
|
241
|
-
prepend: (child: HTMLElement) => void,
|
|
242
|
-
append: (...child: HTMLElement[]) => void,
|
|
243
|
-
insertBefore: (node1: HTMLElement, node2: HTMLElement) => void,
|
|
244
|
-
removeChild: (child: HTMLElement) => void,
|
|
245
|
-
querySelector: (selector: string) => HTMLElement | null,
|
|
246
|
-
querySelectorAll: (selector: string) => HTMLElement[],
|
|
247
|
-
}
|
|
248
|
-
}
|
|
249
|
-
let states = []
|
|
149
|
+
const loadingKey = "loading_" + url;
|
|
150
|
+
const errorKey = "error" + url;
|
|
151
|
+
const dataKey = "_data" + url;
|
|
250
152
|
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
}
|
|
256
|
-
states.push({state, setState})
|
|
257
|
-
return [state, setState]
|
|
258
|
-
}
|
|
153
|
+
// Initialize loading to false if loadingKey doesn't exist in state
|
|
154
|
+
const loading = state[this.key][loadingKey] !== undefined ? state[this.key][loadingKey] : true;
|
|
155
|
+
const error = state[this.key][errorKey] || null;
|
|
156
|
+
const data = state[this.key][dataKey] || null;
|
|
259
157
|
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
let dispatch = (action: any) => {
|
|
263
|
-
state = reducer(state, action)
|
|
264
|
-
}
|
|
265
|
-
states.push({state, dispatch})
|
|
266
|
-
return [state, dispatch]
|
|
267
|
-
}
|
|
268
|
-
let refs = []
|
|
269
|
-
|
|
158
|
+
if (loading && !error && !data) {
|
|
159
|
+
state[this.key][loadingKey] = true;
|
|
270
160
|
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
161
|
+
fetch(url, options)
|
|
162
|
+
.then((res) => res.json())
|
|
163
|
+
.then((data) => {
|
|
164
|
+
state[this.key][dataKey] = data;
|
|
165
|
+
state[this.key][loadingKey] = false;
|
|
166
|
+
this.forceUpdate(key);
|
|
167
|
+
})
|
|
168
|
+
.catch((err) => {
|
|
169
|
+
state[this.key][errorKey] = err;
|
|
170
|
+
state[this.key][loadingKey] = false;
|
|
171
|
+
this.forceUpdate(key);
|
|
172
|
+
});
|
|
275
173
|
}
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
refs.push(ref)
|
|
279
|
-
return ref
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
/**
|
|
283
|
-
* @description The mounted function is called when the component is mounted based on pregenerated keys
|
|
284
|
-
* @param callback {Function}
|
|
285
|
-
* @param parent {Function}
|
|
286
|
-
*/
|
|
287
|
-
export const Mounted = (callback: Function, parent: Function) => {
|
|
288
|
-
callback()
|
|
174
|
+
|
|
175
|
+
return [data, loading, error];
|
|
289
176
|
}
|
|
290
|
-
|
|
291
|
-
let effects = []
|
|
292
|
-
/**
|
|
293
|
-
* Use this to perform DOM mutations. This is the primary method you use to update the user interface in response to event handlers and server responses.
|
|
294
|
-
* Prefer the standard `useEffect` when possible to avoid blocking visual updates.
|
|
295
|
-
*/
|
|
296
177
|
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
178
|
+
|
|
179
|
+
forceUpdate(key) {
|
|
180
|
+
//@ts-ignore
|
|
181
|
+
let el = Array.from(document.querySelectorAll("*")).filter((el2: any) =>{ return el2.key === key})[0];
|
|
182
|
+
let newl = this.parseToElement(this.render());
|
|
183
|
+
if(newl.key !== key){
|
|
184
|
+
//@ts-ignore
|
|
185
|
+
newl = Array.from(newl.children).filter((el2) => el2.key === key)[0];
|
|
186
|
+
}
|
|
187
|
+
if (this.Reconciler.shouldUpdate(el, newl)) {
|
|
188
|
+
el.replaceWith(newl);
|
|
300
189
|
}
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
190
|
+
}
|
|
191
|
+
Reconciler = {
|
|
192
|
+
shouldUpdate(oldElement, newElement) {
|
|
193
|
+
if(oldElement.outerHTML === newElement.outerHTML){
|
|
194
|
+
return false;
|
|
195
|
+
}
|
|
196
|
+
let attributes = oldElement.attributes;
|
|
197
|
+
let newAttributes = newElement.attributes;
|
|
198
|
+
for (let i = 0; i < attributes.length; i++) {
|
|
199
|
+
let attribute = attributes[i];
|
|
200
|
+
if (attribute.name === "key") {
|
|
201
|
+
continue;
|
|
202
|
+
}
|
|
203
|
+
if (attribute.name === "class") {
|
|
204
|
+
if (attribute.value !== newElement.className) {
|
|
205
|
+
return true;
|
|
206
|
+
}
|
|
207
|
+
continue;
|
|
208
|
+
}
|
|
209
|
+
if (attribute.value !== newAttributes[attribute.name]) {
|
|
210
|
+
return true;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
return true;
|
|
310
214
|
}
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
215
|
+
};
|
|
216
|
+
|
|
217
|
+
parseToElement = (element: any) => {
|
|
218
|
+
if(!element) return document.createElement("div");
|
|
219
|
+
let el = document.createElement(element.type);
|
|
220
|
+
let isText = typeof element === "string" || typeof element === "number" || typeof element === "boolean";
|
|
221
|
+
if (isText) {
|
|
222
|
+
el.textContent = element;
|
|
223
|
+
} else {
|
|
224
|
+
let attributes = element.props;
|
|
225
|
+
let children = element.children;
|
|
226
|
+
for (let key in attributes) {
|
|
227
|
+
if(key === "key"){
|
|
228
|
+
el.key = attributes[key];
|
|
229
|
+
continue;
|
|
230
|
+
}
|
|
231
|
+
if (key === "className") {
|
|
232
|
+
el.className = attributes[key];
|
|
233
|
+
continue;
|
|
234
|
+
}
|
|
235
|
+
if (key === "style") {
|
|
236
|
+
for (let styleKey in attributes[key]) {
|
|
237
|
+
el.style[styleKey] = attributes[key][styleKey];
|
|
238
|
+
}
|
|
239
|
+
continue;
|
|
240
|
+
}
|
|
241
|
+
//@ts-ignore
|
|
242
|
+
if (key.startsWith("on")) {
|
|
243
|
+
console.log(key.substring(2).toLowerCase());
|
|
244
|
+
el.addEventListener(key.substring(2).toLowerCase(), attributes[key]);
|
|
245
|
+
continue;
|
|
246
|
+
}
|
|
247
|
+
el.setAttribute(key, attributes[key]);
|
|
248
|
+
}
|
|
249
|
+
for (let i = 0;i < children.length; i++) {
|
|
250
|
+
let child = children[i];
|
|
251
|
+
if (Array.isArray(child)) {
|
|
252
|
+
child.forEach((c) => {
|
|
253
|
+
el.appendChild(this.parseToElement(c));
|
|
254
|
+
});
|
|
255
|
+
}
|
|
256
|
+
if(typeof child === "function"){
|
|
257
|
+
el.appendChild(this.parseToElement(child()));
|
|
258
|
+
}else
|
|
259
|
+
if (typeof child === "object") {
|
|
260
|
+
el.appendChild(this.parseToElement(child));
|
|
261
|
+
}else{
|
|
262
|
+
let span = document.createElement("span");
|
|
263
|
+
span.innerHTML = child;
|
|
264
|
+
el.appendChild(span);
|
|
265
|
+
}
|
|
266
|
+
}
|
|
338
267
|
}
|
|
268
|
+
return el;
|
|
269
|
+
};
|
|
270
|
+
e(element: string | Function, props: any, ...children: any[]) {
|
|
271
|
+
if(typeof element === "function"){
|
|
272
|
+
return element();
|
|
273
|
+
}
|
|
274
|
+
return { type: element, props: props || {}, children: children || [] };
|
|
275
|
+
}
|
|
276
|
+
toElement() {
|
|
277
|
+
let children = this.render();
|
|
278
|
+
let el = this.parseToElement(children);
|
|
279
|
+
return el;
|
|
280
|
+
}
|
|
281
|
+
render() {
|
|
282
|
+
return "";
|
|
283
|
+
}
|
|
339
284
|
}
|
|
340
|
-
|
|
341
|
-
export
|
|
342
|
-
|
|
285
|
+
|
|
286
|
+
export function render(element: any, container) {
|
|
287
|
+
if (isClassComponent(element)) {
|
|
288
|
+
const instance = new element();
|
|
289
|
+
instance.Mounted = true;
|
|
290
|
+
let el = instance.toElement();
|
|
291
|
+
instance.element = el;
|
|
292
|
+
container.innerHTML = "";
|
|
293
|
+
container.replaceWith(el);
|
|
294
|
+
} else {
|
|
295
|
+
const newInstance = new Component;
|
|
296
|
+
element = element.bind(newInstance);
|
|
297
|
+
newInstance.render = element;
|
|
298
|
+
newInstance.Mounted = true;
|
|
299
|
+
let el = newInstance.toElement();
|
|
300
|
+
newInstance.element = el;
|
|
301
|
+
container.innerHTML = "";
|
|
302
|
+
container.replaceWith(el);
|
|
303
|
+
}
|
|
343
304
|
}
|
|
344
|
-
|
|
305
|
+
|