ks-fwork 3.0.1 → 3.0.2
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/dist/ks-fwork.js +61 -32
- package/package.json +1 -1
package/dist/ks-fwork.js
CHANGED
|
@@ -315,6 +315,12 @@ function removeAttribute(el, name) {
|
|
|
315
315
|
el.removeAttribute(name);
|
|
316
316
|
}
|
|
317
317
|
|
|
318
|
+
function extractPropsAndEvents(vNode) {
|
|
319
|
+
const { on: events = {}, ...props } = vNode.props;
|
|
320
|
+
delete props.key;
|
|
321
|
+
return { props, events }
|
|
322
|
+
}
|
|
323
|
+
|
|
318
324
|
function mountDOM(vNode, parentEl, index, hostComponent = null) {
|
|
319
325
|
switch (vNode.type) {
|
|
320
326
|
case DOM_TYPES.TEXT: {
|
|
@@ -330,7 +336,7 @@ function mountDOM(vNode, parentEl, index, hostComponent = null) {
|
|
|
330
336
|
break;
|
|
331
337
|
}
|
|
332
338
|
case DOM_TYPES.COMPONENT: {
|
|
333
|
-
createComponentNode(vNode, parentEl, index);
|
|
339
|
+
createComponentNode(vNode, parentEl, index, hostComponent);
|
|
334
340
|
}
|
|
335
341
|
default: {
|
|
336
342
|
throw new Error(`Can't mount virtual node of type: ${vNode.type}`);
|
|
@@ -344,9 +350,9 @@ function createTextNode(vNode, parentEl, index) {
|
|
|
344
350
|
insert(textNode, parentEl, index);
|
|
345
351
|
}
|
|
346
352
|
function createElementNode(vNode, parentEl, index, hostComponent) {
|
|
347
|
-
const { tag,
|
|
353
|
+
const { tag, children } = vNode;
|
|
348
354
|
const el = document.createElement(tag);
|
|
349
|
-
addProps(el,
|
|
355
|
+
addProps(el, vNode, hostComponent);
|
|
350
356
|
vNode.el = el;
|
|
351
357
|
children.forEach((child) => mountDOM(child, el, null, hostComponent));
|
|
352
358
|
insert(el, parentEl, index);
|
|
@@ -360,14 +366,14 @@ function createFragmentNode(vNode, parentEl, index, hostComponent) {
|
|
|
360
366
|
}
|
|
361
367
|
function createComponentNode(vNode, parentEl, index, hostComponent) {
|
|
362
368
|
const Component = vNode.tag;
|
|
363
|
-
const props = vNode
|
|
364
|
-
const component = new Component(props);
|
|
369
|
+
const { props, events } = extractPropsAndEvents(vNode);
|
|
370
|
+
const component = new Component(props, events, hostComponent);
|
|
365
371
|
component.mount(parentEl, index);
|
|
366
372
|
vNode.component = component;
|
|
367
373
|
vNode.el = component.firstElement;
|
|
368
374
|
}
|
|
369
|
-
function addProps(el,
|
|
370
|
-
const {
|
|
375
|
+
function addProps(el, vNode, hostComponent) {
|
|
376
|
+
const { props: attrs, events} = extractPropsAndEvents(vNode);
|
|
371
377
|
vNode.listeners = addEventListeners(events, el, hostComponent);
|
|
372
378
|
setAttributes(el, attrs);
|
|
373
379
|
}
|
|
@@ -390,7 +396,14 @@ function insert(el, parentEl, index) {
|
|
|
390
396
|
function areNodesEqual(nodeOne, nodeTwo) {
|
|
391
397
|
if (nodeOne.type !== nodeTwo.type) return false;
|
|
392
398
|
if (nodeOne.type === DOM_TYPES.ELEMENT) {
|
|
393
|
-
|
|
399
|
+
const { tag: tagOne, props: { key: keyOne } } = nodeOne;
|
|
400
|
+
const { tag: tagTwo, props: { key: keyTwo } } = nodeTwo;
|
|
401
|
+
return tagOne === tagTwo && keyOne === keyTwo;
|
|
402
|
+
}
|
|
403
|
+
if (nodeOne.type === DOM_TYPES.COMPONENT) {
|
|
404
|
+
const { tag: componentOne, props: { key: keyOne } } = nodeOne;
|
|
405
|
+
const { tag: componentTwo, props: { key: keyTwo } } = nodeTwo;
|
|
406
|
+
return componentOne === componentTwo && keyOne === keyTwo;
|
|
394
407
|
}
|
|
395
408
|
return true;
|
|
396
409
|
}
|
|
@@ -477,7 +490,7 @@ function patchElement(oldVNode, newVNode, hostComponent) {
|
|
|
477
490
|
}
|
|
478
491
|
function patchComponent(oldVNode, newVNode) {
|
|
479
492
|
const { component } = oldVNode;
|
|
480
|
-
const { props } = newVNode;
|
|
493
|
+
const { props } = extractPropsAndEvents(newVNode);
|
|
481
494
|
component.updateProps(props);
|
|
482
495
|
newVNode.component = component;
|
|
483
496
|
newVNode.el = component.firstElement;
|
|
@@ -559,40 +572,29 @@ function patchChildren(oldVNode, newVNode, hostComponent) {
|
|
|
559
572
|
}
|
|
560
573
|
}
|
|
561
574
|
|
|
562
|
-
function createApp(
|
|
575
|
+
function createApp(RootComponent, props = {}) {
|
|
563
576
|
let parentEl = null;
|
|
564
577
|
let rootNode = null;
|
|
565
578
|
let isMounted = false;
|
|
566
579
|
const dispatcher = new Dispatcher();
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
});
|
|
573
|
-
unsubscribers.push(unsubscribe);
|
|
574
|
-
}
|
|
575
|
-
function emit(actionName, payload) {
|
|
576
|
-
dispatcher.dispatch(actionName, payload);
|
|
577
|
-
}
|
|
578
|
-
function renderApp() {
|
|
579
|
-
const newRootNode = view(state, emit);
|
|
580
|
-
rootNode = patchDOM(rootNode, newRootNode, parentEl);
|
|
580
|
+
[dispatcher.afterEveryCommand(renderApp)];
|
|
581
|
+
function reset() {
|
|
582
|
+
parentEl = null;
|
|
583
|
+
rootNode = null;
|
|
584
|
+
isMounted = false;
|
|
581
585
|
}
|
|
582
586
|
return {
|
|
583
587
|
mount(_parentEl) {
|
|
584
588
|
if (isMounted) throw new Error('The application is already mounted');
|
|
585
589
|
parentEl = _parentEl;
|
|
586
|
-
rootNode =
|
|
590
|
+
rootNode = h(RootComponent, props);
|
|
587
591
|
mountDOM(rootNode, parentEl);
|
|
592
|
+
isMounted = true;
|
|
588
593
|
},
|
|
589
594
|
unmount() {
|
|
590
|
-
if (
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
rootNode = null;
|
|
594
|
-
unsubscribers.forEach((unsubscribe) => unsubscribe());
|
|
595
|
-
isMounted = false;
|
|
595
|
+
if (!isMounted) throw new Error('The application is not mounted');
|
|
596
|
+
destroyDOM(rootNode);
|
|
597
|
+
reset();
|
|
596
598
|
},
|
|
597
599
|
}
|
|
598
600
|
}
|
|
@@ -645,9 +647,15 @@ function defineComponent({ render, state, ...methods }) {
|
|
|
645
647
|
#isMounted = false;
|
|
646
648
|
#vNode = null;
|
|
647
649
|
#hostEl = null;
|
|
648
|
-
|
|
650
|
+
#eventHandlers = null;
|
|
651
|
+
#parentComponent = null;
|
|
652
|
+
#dispatcher = new Dispatcher();
|
|
653
|
+
#subscriptions = [];
|
|
654
|
+
constructor(props = {}, eventHandlers = {}, parentComponent = null) {
|
|
649
655
|
this.props = props;
|
|
650
656
|
this.state = state ? state(props) : {};
|
|
657
|
+
this.#eventHandlers = eventHandlers;
|
|
658
|
+
this.#parentComponent = parentComponent;
|
|
651
659
|
}
|
|
652
660
|
get elements() {
|
|
653
661
|
if (this.#vNode == null) {
|
|
@@ -687,12 +695,16 @@ function defineComponent({ render, state, ...methods }) {
|
|
|
687
695
|
render() {
|
|
688
696
|
return render.call(this);
|
|
689
697
|
}
|
|
698
|
+
emit(eventName, payload) {
|
|
699
|
+
this.#dispatcher.dispatch(eventName, payload);
|
|
700
|
+
}
|
|
690
701
|
mount(hostEl, index = null) {
|
|
691
702
|
if (this.#isMounted) {
|
|
692
703
|
throw new Error('Component is already mounted');
|
|
693
704
|
}
|
|
694
705
|
this.#vNode = this.render();
|
|
695
706
|
mountDOM(this.#vNode, hostEl, index, this);
|
|
707
|
+
this.#wireEventHandlers();
|
|
696
708
|
this.#hostEl = hostEl;
|
|
697
709
|
this.#isMounted = true;
|
|
698
710
|
}
|
|
@@ -701,9 +713,11 @@ function defineComponent({ render, state, ...methods }) {
|
|
|
701
713
|
throw new Error('Component is not mounted');
|
|
702
714
|
}
|
|
703
715
|
destroyDOM(this.#vNode);
|
|
716
|
+
this.#subscriptions.forEach((unsubscribe) => unsubscribe());
|
|
704
717
|
this.#vNode = null;
|
|
705
718
|
this.#hostEl = null;
|
|
706
719
|
this.#isMounted = false;
|
|
720
|
+
this.#subscriptions = [];
|
|
707
721
|
}
|
|
708
722
|
#patch() {
|
|
709
723
|
if (!this.#isMounted) {
|
|
@@ -712,6 +726,21 @@ function defineComponent({ render, state, ...methods }) {
|
|
|
712
726
|
const vNode = this.render();
|
|
713
727
|
this.#vNode = patchDOM(this.#vNode, vNode, this.#hostEl, this);
|
|
714
728
|
}
|
|
729
|
+
#wireEventHandlers() {
|
|
730
|
+
this.#subscriptions = Object.entries(this.#eventHandlers).map(
|
|
731
|
+
([eventName, handler]) =>
|
|
732
|
+
this.#wireEventHandler(eventName, handler)
|
|
733
|
+
);
|
|
734
|
+
}
|
|
735
|
+
#wireEventHandler(eventName, handler) {
|
|
736
|
+
return this.#dispatcher.subscribe(eventName, (payload) => {
|
|
737
|
+
if (this.#parentComponent) {
|
|
738
|
+
handler.call(this.#parentComponent, payload);
|
|
739
|
+
} else {
|
|
740
|
+
handler(payload);
|
|
741
|
+
}
|
|
742
|
+
})
|
|
743
|
+
}
|
|
715
744
|
}
|
|
716
745
|
for (const methodName in methods) {
|
|
717
746
|
if (hasOwnProperty(Component, methodName)) {
|