vaderjs 1.4.1-ui7iuy47 → 1.4.2-kml56

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.
@@ -0,0 +1,625 @@
1
+ /**
2
+ * @module DOMParser
3
+ * @description The DOMParser interface provides the ability to parse HTML source code from a string into a DOM Document.
4
+ */
5
+ export class DOMParser {
6
+ /**
7
+ * @decription - parse html to a document
8
+ * @param {string} html
9
+ * @returns {Document}
10
+ */
11
+ parseFromString(html) {
12
+ let doc = new Document();
13
+ return {
14
+ error: "Not implemented",
15
+ }
16
+
17
+ }
18
+ /**
19
+ * @description - Returns a string containing the HTML serialization of the element's descendants.
20
+ * @returns {string}
21
+ */
22
+ toString() {
23
+ return this.tree.toString();
24
+ }
25
+
26
+ }
27
+ export class HTMLTextNode {
28
+ constructor(text) {
29
+ this.nodeValue = text;
30
+ this.nodeType = 3;
31
+ this.tagName = "TEXT_ELEMENT";
32
+ this.props = { nodeValue: text };
33
+ }
34
+
35
+ toString() {
36
+ return this.nodeValue;
37
+ }
38
+
39
+ insertBefore(node) {
40
+ this.nodeValue = `${node.toString()}${this.nodeValue}`;
41
+ return this;
42
+ }
43
+ }
44
+ export class HTMLElement {
45
+ constructor(tagName, props, children) {
46
+ this.tagName = tagName;
47
+ this.props = props;
48
+ this.children = children;
49
+ this.outerHTML = this.toString("outerHTML");
50
+ this.innerHTML = this.toString("innerHTML");
51
+ this.textContent = this.toString("innerText");
52
+ /**
53
+ * @type {HTMLElement | HTMLTextNode}
54
+ */
55
+ this.firstChild = this.children[0];
56
+ this.style = props?.style || {};
57
+
58
+ this.attributes = props;
59
+ this.events = [];
60
+ /**
61
+ * @type {string | null}
62
+ */
63
+ this.id = props?.id || null;
64
+ this.nodeType = 1;
65
+ this.accessKey = null;
66
+ }
67
+
68
+ /**
69
+ * @description - Returns a string containing the HTML serialization of the element's descendants.
70
+ * @param {string} type - outerHTML, innerHTML, innerText
71
+ * @returns {string}
72
+ */
73
+ toString(type = "outerHTML") {
74
+ switch (type) {
75
+ case "outerHTML":
76
+ if (this.tagName === "TEXT_ELEMENT") {
77
+ return this.props.nodeValue;
78
+ }
79
+ let props = "";
80
+ for (let key in this.props) {
81
+ if (key !== 'style' && key !== 'ref' && !key.startsWith('on')) {
82
+ props += `${key}="${this.props[key]}" `
83
+ }
84
+ }
85
+ let children = this.children
86
+ .map((child) => {
87
+ return child.toString();
88
+ }).join("");
89
+ if (this.attributes?.style) {
90
+ for (let key in this.attributes.style) {
91
+ this.style[key] = this.attributes.style[key]
92
+ }
93
+ }
94
+
95
+
96
+ if (this.attributes && Object.keys(this.attributes).length > 0) {
97
+ props += ` ${Object.keys(this.attributes).map((key) =>{
98
+ if(key !== 'style' && !props.includes(key) && key !== 'ref' && !key.startsWith('on')){
99
+ return `${key}="${this.attributes[key]}"`
100
+ }
101
+ }).join(' ')}`
102
+ }
103
+ if (this.style && Object.keys(this.style).length > 0) {
104
+ props += ` style="${handleStyles(this.style, this)}"`
105
+ }
106
+ if (this.props?.id) {
107
+ this.id = this.props.id
108
+ }
109
+ return `<${this.tagName} ${props}>${children}</${this.tagName}>`;
110
+ case "innerHTML":
111
+ return this.children.map((child) => {
112
+ child.toString("outerHTML");
113
+ child.toString("innerHTML");
114
+ child.toString("innerText");
115
+ return child.toString("outerHTML");
116
+ }).join("");
117
+ case "innerText":
118
+ let string = ''
119
+ this.children
120
+ .map((child) => {
121
+ if(child instanceof HTMLTextNode){
122
+ string += child.nodeValue
123
+ }
124
+ })
125
+ .join("");
126
+ return string;
127
+ default:
128
+ break;
129
+ }
130
+ }
131
+ /**
132
+ * @description - Appends a node as the last child of a node.
133
+ * @param {HTMLElement|HTMLTextNode} child
134
+ * @returns
135
+ */
136
+ appendChild(child) {
137
+ this.outerHTML = this.toString("outerHTML");
138
+ this.innerHTML = this.toString("innerHTML");
139
+ this.textContent = this.toString("innerText");
140
+ if (!this.children.includes(child)) {
141
+ this.children.push(child);
142
+ this.outerHTML = this.toString("outerHTML");
143
+ this.innerHTML = this.toString("innerHTML");
144
+ }
145
+ return this;
146
+ }
147
+ /**
148
+ * @description - set the content of the element
149
+ * @param {string} content
150
+ * @returns {HTMLElement}
151
+ */
152
+ setContent(content) {
153
+ let textNode = new HTMLTextNode(content);
154
+ this.children = [textNode];
155
+ this.outerHTML = this.toString("outerHTML");
156
+ this.innerHTML = this.toString("innerHTML");
157
+ return this;
158
+ }
159
+
160
+ /**
161
+ * @description - Appends a set of Node objects or DOMString objects after the last child of the ParentNode.
162
+ * @param {...any} children
163
+ * @returns {HTMLElement}
164
+ */
165
+ append(...children) {
166
+ this.outerHTML = this.toString("outerHTML");
167
+ this.innerHTML = this.toString("innerHTML");
168
+ this.textContent = this.toString("innerText");
169
+ this.children = [...this.children, ...children];
170
+ return this;
171
+ }
172
+ /**
173
+ * @description - Inserts a set of Node objects or DOMString objects after the last child of the ParentNode.
174
+ * @param {HTMLElement | HTMLTextNode} node1
175
+ * @param {HTMLElement | HTMLTextNode} node2
176
+ * @returns {HTMLElement}
177
+ */
178
+ insertBefore(node1, node2) {
179
+ this.outerHTML = this.toString("outerHTML");
180
+ this.innerHTML = this.toString("innerHTML");
181
+ this.textContent = this.toString("innerText");
182
+ this.children = this.children.map((child) => {
183
+ if (child === node2) {
184
+ return node1;
185
+ }
186
+ return child;
187
+ });
188
+ return this;
189
+ }
190
+ /**
191
+ * @description - Inserts a set of Node objects or DOMString objects after the last child of the ParentNode.
192
+ * @param {HTMLElement|HTMLTextNode} child
193
+ * @returns {HTMLElement}
194
+ */
195
+ prepend(child) {
196
+ this.outerHTML = this.toString("outerHTML");
197
+ this.innerHTML = this.toString("innerHTML");
198
+ this.textContent = this.toString("innerText");
199
+ this.children = [child, ...this.children];
200
+ return this;
201
+ }
202
+
203
+ /**
204
+ *
205
+ */
206
+ remove() {
207
+ this.outerHTML = "";
208
+ this.innerHTML = "";
209
+ this.textContent = "";
210
+ this.children = [];
211
+ return this;
212
+ }
213
+ /**
214
+ * @description - Removes a child node from the DOM
215
+ * @param {Object} child
216
+ * @returns {HTMLElement}
217
+ */
218
+ removeChild(child) {
219
+ this.children = this.children.filter((c) => c !== child);
220
+ this.innerHTML = this.toString("innerHTML");
221
+ this.outerHTML = this.toString("outerHTML");
222
+ this.textContent = this.toString("innerText");
223
+ return this;
224
+ }
225
+
226
+ /**
227
+ * @description - Search for a specific attribute and returns the value of the attribute.
228
+ * @param {string} name
229
+ * @returns {string | null}
230
+ */
231
+ getAttribute(name) {
232
+ switch (true){
233
+ case Object.keys(this.props).includes(name):
234
+ return this.props[name]
235
+ case Object.keys(this.attributes).includes(name):
236
+ return this.attributes[name]
237
+ }
238
+ return null;
239
+ }
240
+ /**
241
+ * @description - Sets the value of an attribute on the specified element. If the attribute already exists, the value is updated; otherwise a new attribute is added with the specified name and value.
242
+ * @param {string} name
243
+ * @param {string} value
244
+ * @returns {HTMLElement}
245
+ */
246
+
247
+ setAttribute(name, value) {
248
+ this.props[name] = value;
249
+ this.attributes[name] = value;
250
+ this.outerHTML = this.toString("outerHTML");
251
+ this.innerHTML = this.toString("innerHTML");
252
+ this.textContent = this.toString("innerText");
253
+ return this;
254
+ }
255
+
256
+ /**
257
+ * @method classList
258
+ * @description - add, remove, toggle, or check the presence of a class in the class attribute of an element
259
+ * @returns {(add: (className: string) => HTMLElement | HTMLTextNode | null, remove: (className: string) => HTMLElement | HTMLTextNode | null, toggle: (className: string) => HTMLElement | HTMLTextNode | null, contains: (className: string) => boolean) => HTMLElement | HTMLTextNode | null}
260
+ */
261
+ classList = {
262
+ add: (className) => {
263
+ this.props.className = `${this.props.className} ${className}`;
264
+ return this;
265
+ },
266
+ remove: (className) => {
267
+ this.props.className = this.props.className.replace(className, "");
268
+ return this;
269
+ },
270
+ toggle: (className) => {
271
+ if (this.props.className.includes(className)) {
272
+ this.props.className = this.props.className.replace(className, "");
273
+ } else {
274
+ this.props.className = `${this.props.className} ${className}`;
275
+ }
276
+ return this;
277
+ },
278
+ contains: (className) => {
279
+ return this.attributes["class" || "className"].includes(className);
280
+ },
281
+ };
282
+
283
+ /**
284
+ *
285
+ * @param {string} selector
286
+ * @returns {HTMLElement}
287
+ */
288
+ querySelector(selector) {
289
+ switch (true) {
290
+ case selector.startsWith("."):
291
+ this.innerHTML = this.toString("innerHTML");
292
+ this.outerHTML = this.toString("outerHTML");
293
+ this.textContent = this.toString("innerText");
294
+ return this.children.find((child) => {
295
+ child.outerHTML = child.toString();
296
+ return child.props.className.includes(selector.substring(1));
297
+ });
298
+ case selector.startsWith("#"):
299
+ this.innerHTML = this.toString("innerHTML");
300
+ this.outerHTML = this.toString("outerHTML");
301
+ this.textContent = this.toString("innerText");
302
+ return this.children.find((child) => {
303
+ child.outerHTML = child.toString();
304
+ return child.props.id === selector.substring(1);
305
+ });
306
+ default:
307
+ this.innerHTML = this.toString("innerHTML");
308
+ this.outerHTML = this.toString("outerHTML");
309
+ this.textContent = this.toString("innerText");
310
+ let child = this.children.find((child) => {
311
+ child.outerHTML = child.toString();
312
+ return child.tagName === selector;
313
+ }
314
+ );
315
+ if (!child) {
316
+ // check if children of children have the selector
317
+ this.innerHTML = this.toString("innerHTML");
318
+ this.outerHTML = this.toString("outerHTML");
319
+ this.textContent = this.toString("innerText");
320
+ this.children.forEach((c) => {
321
+ if (c.children) {
322
+ child = c.children.find((child) => {
323
+ child.outerHTML = child.toString("outerHTML");
324
+ child.innerHTML = child.toString("innerHTML");
325
+ return child.tagName === selector;
326
+ }
327
+ );
328
+ }
329
+ })
330
+ }
331
+
332
+ return child;
333
+ }
334
+ }
335
+ /**
336
+ * @description - Returns a list of elements with the given tag name. The subtree underneath the specified element is searched, excluding the element itself.
337
+ * @param {string} selector
338
+ * @returns {Array<HTMLElement | HTMLTextNode>}
339
+ */
340
+ querySelectorAll(selector) {
341
+ switch (true) {
342
+ case selector.startsWith("."):
343
+ return this.children.filter((child) => {
344
+ return child.props.className.includes(selector.substring(1));
345
+ });
346
+ case selector === '*':
347
+ return this.children;
348
+ case selector.startsWith("#"):
349
+ return this.children.filter((child) => {
350
+ return child.props.id === selector.substring(1);
351
+ });
352
+ default:
353
+ return this.children.filter((child) => {
354
+ return child.tagName === selector;
355
+ });
356
+ }
357
+ }
358
+ parseHTML(html) {
359
+ const parser = new DOMParser();
360
+ const parsed = parser.parseFromString(html);
361
+ return parsed;
362
+ }
363
+ }
364
+ /**
365
+ * @module Document
366
+ * @description - The Document interface represents any web page loaded in the browser and serves as an entry point into the web page's content, which is the DOM tree.
367
+ */
368
+ export class Document {
369
+ constructor() {
370
+ this.tree = [];
371
+ /**
372
+ * @description - Returns the <body> or <frameset> node of the current document.
373
+ * @type {HTMLElement}
374
+ */
375
+ this.body = new HTMLElement("body", {}, []);
376
+ /**
377
+ * @description - Document.documentElement returns the Element that is the root element of the document
378
+ * @type {HTMLElement}
379
+ * @returns {{outerHTML: string, innerHTML: string}}
380
+ */
381
+ this.documentElement = new HTMLElement("html", {}, [this.body]);
382
+
383
+
384
+ /**
385
+ * @description - Document.head returns the <head> element of the current document.
386
+ * @type {HTMLElement}
387
+ */
388
+ this.head = new HTMLElement("head", {}, []);
389
+
390
+ /**
391
+ * @description - Returns the first child of a node, or the first child that is an element, and null if there are no child elements.
392
+ * **/
393
+ this.firstElementChild = null;
394
+ }
395
+
396
+ /**
397
+ * @description - Creates a new Text node. This method can be used to escape HTML characters.
398
+ * @param {sring} text
399
+ * @returns {HTMLTextNode}
400
+ */
401
+ createTextNode(text) {
402
+ return new HTMLTextNode(text);
403
+ }
404
+ /**
405
+ * @description - Creates a new element with the provided tag name or node object.
406
+ * @param {Object | string} nodeData
407
+ * @returns {HTMLElement}
408
+ */
409
+ createElement(nodeData) {
410
+ if (typeof nodeData === 'string') {
411
+ return new HTMLElement(nodeData, {}, [])
412
+ }
413
+ let { tagName, props, children } = nodeData;
414
+ let node = new HTMLElement(tagName, props, children);
415
+ children = children.filter((child) => child !== null || child !== undefined)
416
+ node.children = children.map((child) => {
417
+ if (child.tagName === "TEXT_ELEMENT") {
418
+ return new HTMLTextNode(child);
419
+ }
420
+ if (child instanceof HTMLElement) {
421
+ return child;
422
+ }
423
+ return this.createElement(child);
424
+ });
425
+ return node;
426
+ }
427
+
428
+
429
+
430
+ /**
431
+ * @description - Returns the first element that is a descendant of the element on which it is invoked that matches the specified group of selectors.
432
+ * @param {string} selector
433
+ * @returns {HTMLElement | HTMLTextNode | null}
434
+ */
435
+ querySelector(selector) {
436
+ switch (true) {
437
+ case selector.startsWith("."):
438
+ return this.tree.find((child) => {
439
+ child.outerHTML = child.toString();
440
+ return child.props.className.includes(selector.substring(1));
441
+ });
442
+ case selector.startsWith("#"):
443
+ return this.tree.find((child) => {
444
+ return child.props.id === selector.substring(1);
445
+ });
446
+ default:
447
+ let child = this.tree.find((child) => {
448
+ child.outerHTML = child.toString();
449
+ return child.tagName === selector;
450
+ })
451
+ if (!child) {
452
+ // check if children of children have the selector
453
+ this.tree.forEach((c) => {
454
+ if (c.children) {
455
+ child = c.children.find((child) => {
456
+ child.outerHTML = child.toString();
457
+ return child.tagName === selector;
458
+ }
459
+ );
460
+ }
461
+ })
462
+ }
463
+ return child;
464
+ }
465
+ }
466
+
467
+ /**
468
+ * @description - Returns a list of elements with the given tag name. The subtree underneath the specified element is searched, excluding the element itself.
469
+ * @param {string} selector
470
+ * @returns {Array<HTMLElement | HTMLTextNode>}
471
+ */
472
+ querySelectorAll(selector) {
473
+ switch (true) {
474
+ case selector.startsWith("."):
475
+ return this.tree.filter((child) => {
476
+ return child.props.className.includes(selector.substring(1));
477
+ });
478
+ case selector.startsWith("#"):
479
+ return this.tree.filter((child) => {
480
+ return child.props.id === selector.substring(1);
481
+ });
482
+ default:
483
+ return this.tree.filter((child) => {
484
+ return child.tagName === selector;
485
+ });
486
+ }
487
+ }
488
+
489
+
490
+ /**
491
+ * @description - Returns a string containing the HTML serialization of the element's descendants.
492
+ * @returns {string}
493
+ */
494
+
495
+ toString() {
496
+ this.tree.push(this.documentElement)
497
+ this.tree.push(this.head)
498
+ this.tree.push(this.body)
499
+ return this.tree.map((child) => {
500
+ return child.toString();
501
+ }).join("");
502
+
503
+ }
504
+
505
+ }
506
+
507
+ function handleStyles(styles, nodeEl) {
508
+ let style = "";
509
+ for (let key in styles) {
510
+ let lower = key.replace(/([A-Z])/g, (g) => `-${g[0].toLowerCase()}`);
511
+ if (typeof styles[key] === "object") {
512
+ style += handleStyles(styles[key], nodeEl);
513
+ }
514
+ style += `${lower}:${styles[key]};`;
515
+ }
516
+ return style;
517
+ }
518
+
519
+ /**
520
+ * @method Element
521
+ * @description - Create a virtual jsx DOM element
522
+ * @param {string} tag
523
+ * @param {Object} props
524
+ * @param {...any} children
525
+ * @returns
526
+ */
527
+ export function Element(tag, props = {}, ...children) {
528
+ if(typeof tag === 'function'){
529
+ let el = tag(props, children)
530
+ return el
531
+ }
532
+ if(props === null){
533
+ props = {}
534
+ }
535
+ let node = {
536
+ tagName: tag,
537
+ props: props || {},
538
+ children: children,
539
+ _key: null,
540
+ innerHTML: "",
541
+ outerHTML: "",
542
+ textContent: "",
543
+ events: [],
544
+ parentNode: null,
545
+ appendChild: (child) => {
546
+ children.push(child);
547
+ return node;
548
+ },
549
+ querySelector: (selector) => {
550
+ switch (true) {
551
+ case selector.startsWith("."):
552
+ return children.find((child) => {
553
+ child.outerHTML = child.toString();
554
+ return child.props.className.includes(selector.substring(1));
555
+ });
556
+ case selector.startsWith("#"):
557
+ return children.find((child) => {
558
+ return child.props.id === selector.substring(1);
559
+ });
560
+ default:
561
+ let child = children.find((child) => {
562
+ return child.tagName === selector;
563
+ })
564
+ if (!child) {
565
+ // check if children of children have the selector
566
+ children.forEach((c) => {
567
+ if (c.children) {
568
+ child = c.children.find((child) => {
569
+ child.outerHTML = child.toString();
570
+ return child.tagName === selector;
571
+ }
572
+ );
573
+ }
574
+ })
575
+ }
576
+ return child;
577
+ }
578
+ },
579
+ };
580
+
581
+ if (props?.children) {
582
+ switch (true) {
583
+ case typeof props.children === 'string':
584
+ children = [props.children]
585
+ break;
586
+ case Array.isArray(props.children):
587
+ children = props.children
588
+ break;
589
+ default:
590
+ children = [props.children]
591
+ }
592
+
593
+ node.children = children
594
+ delete props.children
595
+ }
596
+
597
+ for (var i = 0; i < children.length; i++) {
598
+ if (typeof children[i] === "string" || typeof children[i] === "number") {
599
+ children[i] = {
600
+ tagName: "TEXT_ELEMENT",
601
+ props: { nodeValue: children[i] },
602
+ _key: null,
603
+ parentNode: { tagName: tag, props: props, children: children, _key: null},
604
+ children: [],
605
+ };
606
+ children[i] = new HTMLTextNode(children[i].props.nodeValue);
607
+ } else {
608
+ if (children[i]) {
609
+ children[i].parentNode = { tagName: tag, props: props, children: children };
610
+ }
611
+
612
+ children[i] = new HTMLElement(children[i].tagName, children[i].props, children[i].children)
613
+ }
614
+ }
615
+
616
+ return new HTMLElement(tag, props, children);
617
+ }
618
+
619
+ export default {
620
+ Document,
621
+ Element,
622
+ DOMParser,
623
+ HTMLTextNode,
624
+ HTMLElement
625
+ };
@@ -0,0 +1,85 @@
1
+ import { Document , Element} from "../Kalix/index.js"
2
+ class Component {
3
+ constructor(props){
4
+ this.props = props
5
+ this._key = Math.random().toString(36).substring(7)
6
+ this.state = {}
7
+ this.htmlNode = null
8
+ this.firstChild = null
9
+ this.Element = Element
10
+ }
11
+
12
+
13
+ setState(newState){
14
+ this.state = newState
15
+ }
16
+
17
+
18
+ useState(name, initialValue){
19
+ if(!this.state[name]){
20
+ this.state[name] = initialValue
21
+ }
22
+
23
+ let getState = () => this.state[name]
24
+ let setState = (newValue) => {
25
+
26
+
27
+ }
28
+ return [getState, setState]
29
+
30
+ }
31
+ useReducer(name, reducer, initialState){
32
+ let [state, setState] = this.useState(name, initialState)
33
+ let dispatch = (action) => {
34
+ let newState = reducer(state(), action)
35
+ setState(newState)
36
+ }
37
+
38
+ return [state, dispatch]
39
+ }
40
+
41
+ useEffect(effect, deps){
42
+
43
+ }
44
+
45
+ render(){
46
+ return null
47
+ }
48
+
49
+ }
50
+ export async function generatePage(element, options = {entry:"", props: any}, args = []) {
51
+ globalThis.isServer = true
52
+ let serverSideProps = await options.props(...args)
53
+ let name = element.name
54
+
55
+ let comp = new Component()
56
+ element = element.bind(comp)
57
+ comp.render = (props)=> {
58
+ return element(props)
59
+ }
60
+ let data = new Document().createElement(comp.render(serverSideProps))
61
+ let document = new Document()
62
+ document.documentElement.setContent(data.querySelector('html') ? data.querySelector('html').innerHTML : '')
63
+ document.head.setContent(data.querySelector('head') ? data.querySelector('head').innerHTML : '')
64
+ data.removeChild(data.querySelector('head'))
65
+ let div = new Document().createElement('div')
66
+ div.setAttribute('id', 'app')
67
+ div.setContent(data.innerHTML)
68
+ document.body.appendChild(div)
69
+ let script = new Document().createElement('script')
70
+ script.setAttribute('type', 'module')
71
+ script.setContent(script.innerHTML + '\n' + `
72
+
73
+ import ${name} from "${options?.entry}"
74
+ import {render} from '/src/client.js'
75
+ import Kuai from '/src/router.js'
76
+ let kuai = new Kuai({container: document.getElementById('app')})
77
+ kuai.get('/', (c) => {
78
+ c.html(render(${name}, document.getElementById('app'), {...c, props: ${JSON.stringify(serverSideProps.props)}}))
79
+ })
80
+ kuai.use('/', () => console.log('Middleware'))
81
+ kuai.listen()
82
+ `)
83
+ document.body.appendChild(script)
84
+ return `<!DOCTYPE html>${document.head.toString()}${document.body.innerHTML}`
85
+ }