@viewfly/core 0.0.1-alpha.7 → 0.0.1-alpha.8
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/bundles/foundation/_utils.d.ts +0 -6
- package/bundles/foundation/injection-tokens.d.ts +1 -2
- package/bundles/foundation/renderer.d.ts +1 -1
- package/bundles/index.esm.js +172 -194
- package/bundles/index.js +172 -194
- package/bundles/model/component.d.ts +4 -2
- package/bundles/model/jsx-element.d.ts +14 -5
- package/package.json +2 -2
|
@@ -3,10 +3,6 @@ export interface MapChanges {
|
|
|
3
3
|
remove: [string, any][];
|
|
4
4
|
set: [string, any][];
|
|
5
5
|
}
|
|
6
|
-
export interface ArrayChanges {
|
|
7
|
-
remove: string[];
|
|
8
|
-
add: string[];
|
|
9
|
-
}
|
|
10
6
|
export interface ObjectChanges {
|
|
11
7
|
remove: [string, any][];
|
|
12
8
|
add: [string, any][];
|
|
@@ -14,11 +10,9 @@ export interface ObjectChanges {
|
|
|
14
10
|
export declare const refKey = "ref";
|
|
15
11
|
export declare function getObjectChanges(target: Record<string, any>, source: Record<string, any>): ObjectChanges;
|
|
16
12
|
export declare function getMapChanges(target: Map<string, any>, source: Map<string, any>): MapChanges;
|
|
17
|
-
export declare function getSetChanges(target: Set<string>, source: Set<string>): ArrayChanges;
|
|
18
13
|
export declare function getNodeChanges(newVNode: JSXElement | Component, oldVNode: JSXElement | Component): {
|
|
19
14
|
styleChanges: MapChanges;
|
|
20
15
|
attrChanges: MapChanges;
|
|
21
|
-
classesChanges: ArrayChanges;
|
|
22
16
|
listenerChanges: ObjectChanges;
|
|
23
17
|
isChanged: boolean;
|
|
24
18
|
};
|
|
@@ -8,8 +8,7 @@ export declare abstract class NativeRenderer<ElementNode = NativeNode, TextNode
|
|
|
8
8
|
abstract removeProperty(node: ElementNode, key: string): void;
|
|
9
9
|
abstract setStyle(target: ElementNode, key: string, value: any): void;
|
|
10
10
|
abstract removeStyle(target: ElementNode, key: string): void;
|
|
11
|
-
abstract
|
|
12
|
-
abstract removeClass(target: ElementNode, name: string): void;
|
|
11
|
+
abstract setClass(target: ElementNode, value: string): void;
|
|
13
12
|
abstract listen<T = any>(node: ElementNode, type: string, callback: (ev: T) => any): void;
|
|
14
13
|
abstract unListen(node: ElementNode, type: string, callback: (ev: any) => any): void;
|
|
15
14
|
abstract remove(node: ElementNode | TextNode): void;
|
|
@@ -16,8 +16,8 @@ export declare class Renderer {
|
|
|
16
16
|
private reconcileElement;
|
|
17
17
|
private applyChanges;
|
|
18
18
|
private diff;
|
|
19
|
+
private createChanges;
|
|
19
20
|
private cleanView;
|
|
20
|
-
private reuseAndUpdate;
|
|
21
21
|
private temporarilyRemove;
|
|
22
22
|
private buildView;
|
|
23
23
|
private componentRender;
|
package/bundles/index.esm.js
CHANGED
|
@@ -66,6 +66,10 @@ function jsxs(setup, config, key) {
|
|
|
66
66
|
class JSXText {
|
|
67
67
|
constructor(text) {
|
|
68
68
|
this.text = text;
|
|
69
|
+
this.$$typeOf = '#text';
|
|
70
|
+
}
|
|
71
|
+
is(target) {
|
|
72
|
+
return target.$$typeOf === this.$$typeOf;
|
|
69
73
|
}
|
|
70
74
|
}
|
|
71
75
|
function flatChildren(jsxNodes) {
|
|
@@ -90,7 +94,7 @@ class Props {
|
|
|
90
94
|
constructor(props) {
|
|
91
95
|
this.attrs = new Map();
|
|
92
96
|
this.styles = new Map();
|
|
93
|
-
this.classes =
|
|
97
|
+
this.classes = '';
|
|
94
98
|
this.listeners = {};
|
|
95
99
|
this.children = [];
|
|
96
100
|
if (!props) {
|
|
@@ -109,7 +113,7 @@ class Props {
|
|
|
109
113
|
return;
|
|
110
114
|
}
|
|
111
115
|
if (key === 'class') {
|
|
112
|
-
this.classes =
|
|
116
|
+
this.classes = Props.classToString(props[key]);
|
|
113
117
|
return;
|
|
114
118
|
}
|
|
115
119
|
if (key === 'style') {
|
|
@@ -142,6 +146,31 @@ class Props {
|
|
|
142
146
|
this.attrs.set(key, props[key]);
|
|
143
147
|
});
|
|
144
148
|
}
|
|
149
|
+
static classToString(config) {
|
|
150
|
+
if (!config) {
|
|
151
|
+
return '';
|
|
152
|
+
}
|
|
153
|
+
if (typeof config === 'string') {
|
|
154
|
+
return config;
|
|
155
|
+
}
|
|
156
|
+
else if (Array.isArray(config)) {
|
|
157
|
+
return config.map(i => {
|
|
158
|
+
return Props.classToString(i);
|
|
159
|
+
}).join(' ');
|
|
160
|
+
}
|
|
161
|
+
else if (typeof config === 'object') {
|
|
162
|
+
if (config.toString !== Object.prototype.toString && !config.toString.toString().includes('[native code]')) {
|
|
163
|
+
return config.toString();
|
|
164
|
+
}
|
|
165
|
+
const classes = [];
|
|
166
|
+
for (const key in config) {
|
|
167
|
+
if ({}.hasOwnProperty.call(config, key) && config[key]) {
|
|
168
|
+
classes.push(key);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
return classes.join(' ');
|
|
172
|
+
}
|
|
173
|
+
}
|
|
145
174
|
static classToArray(config) {
|
|
146
175
|
const classes = [];
|
|
147
176
|
if (!config) {
|
|
@@ -175,8 +204,12 @@ class JSXElement {
|
|
|
175
204
|
this.name = name;
|
|
176
205
|
this.config = config;
|
|
177
206
|
this.key = key;
|
|
207
|
+
this.$$typeOf = this.name;
|
|
178
208
|
this.props = new Props(config);
|
|
179
209
|
}
|
|
210
|
+
is(target) {
|
|
211
|
+
return target.$$typeOf === this.$$typeOf;
|
|
212
|
+
}
|
|
180
213
|
}
|
|
181
214
|
|
|
182
215
|
const componentSetupStack = [];
|
|
@@ -218,6 +251,7 @@ class Component extends ReflectiveInjector {
|
|
|
218
251
|
this.setup = setup;
|
|
219
252
|
this.config = config;
|
|
220
253
|
this.key = key;
|
|
254
|
+
this.$$typeOf = this.setup;
|
|
221
255
|
this.destroyCallbacks = [];
|
|
222
256
|
this.mountCallbacks = [];
|
|
223
257
|
this.propsChangedCallbacks = [];
|
|
@@ -230,6 +264,9 @@ class Component extends ReflectiveInjector {
|
|
|
230
264
|
this.props = new Props(config);
|
|
231
265
|
this.parentComponent = this.parentInjector;
|
|
232
266
|
}
|
|
267
|
+
is(target) {
|
|
268
|
+
return target.$$typeOf === this.$$typeOf;
|
|
269
|
+
}
|
|
233
270
|
addProvide(providers) {
|
|
234
271
|
providers = Array.isArray(providers) ? providers : [providers];
|
|
235
272
|
providers.forEach(p => {
|
|
@@ -635,21 +672,6 @@ function getObjectChanges(target, source) {
|
|
|
635
672
|
remove: [],
|
|
636
673
|
add: []
|
|
637
674
|
};
|
|
638
|
-
// if (!target) {
|
|
639
|
-
// if (source) {
|
|
640
|
-
// Object.keys(source).forEach(key => {
|
|
641
|
-
// changes.remove.push([key, source[key]])
|
|
642
|
-
// })
|
|
643
|
-
// }
|
|
644
|
-
// return changes
|
|
645
|
-
// }
|
|
646
|
-
//
|
|
647
|
-
// if (!source) {
|
|
648
|
-
// Object.keys(target).forEach(key => {
|
|
649
|
-
// changes.add.push([key, target[key]])
|
|
650
|
-
// })
|
|
651
|
-
// return changes
|
|
652
|
-
// }
|
|
653
675
|
Object.keys(target).forEach(key => {
|
|
654
676
|
const leftValue = target[key];
|
|
655
677
|
if (!Reflect.has(source, key)) {
|
|
@@ -675,20 +697,6 @@ function getMapChanges(target, source) {
|
|
|
675
697
|
remove: [],
|
|
676
698
|
set: []
|
|
677
699
|
};
|
|
678
|
-
// if (!target) {
|
|
679
|
-
// if (source) {
|
|
680
|
-
// source.forEach((value, key) => {
|
|
681
|
-
// changes.remove.push([key, value])
|
|
682
|
-
// })
|
|
683
|
-
// }
|
|
684
|
-
// return changes
|
|
685
|
-
// }
|
|
686
|
-
// if (!source) {
|
|
687
|
-
// target.forEach((value, key) => {
|
|
688
|
-
// changes.set.push([key, value])
|
|
689
|
-
// })
|
|
690
|
-
// return changes
|
|
691
|
-
// }
|
|
692
700
|
target.forEach((value, key) => {
|
|
693
701
|
const rightValue = source.get(key);
|
|
694
702
|
if (value === rightValue) {
|
|
@@ -710,58 +718,22 @@ function getMapChanges(target, source) {
|
|
|
710
718
|
});
|
|
711
719
|
return changes;
|
|
712
720
|
}
|
|
713
|
-
|
|
714
|
-
const changes = {
|
|
715
|
-
add: [],
|
|
716
|
-
remove: []
|
|
717
|
-
};
|
|
718
|
-
// if (!target) {
|
|
719
|
-
// if (source) {
|
|
720
|
-
// source.forEach(i => {
|
|
721
|
-
// changes.remove.push(i)
|
|
722
|
-
// })
|
|
723
|
-
// }
|
|
724
|
-
// return changes
|
|
725
|
-
// }
|
|
726
|
-
//
|
|
727
|
-
// if (!source) {
|
|
728
|
-
// target.forEach(i => {
|
|
729
|
-
// changes.add.push(i)
|
|
730
|
-
// })
|
|
731
|
-
// return changes
|
|
732
|
-
// }
|
|
733
|
-
target.forEach(i => {
|
|
734
|
-
if (!source.has(i)) {
|
|
735
|
-
changes.add.push(i);
|
|
736
|
-
}
|
|
737
|
-
});
|
|
738
|
-
source.forEach(i => {
|
|
739
|
-
if (!target.has(i)) {
|
|
740
|
-
changes.remove.push(i);
|
|
741
|
-
}
|
|
742
|
-
});
|
|
743
|
-
return changes;
|
|
744
|
-
}
|
|
745
|
-
const compareText = '0'.repeat(8);
|
|
721
|
+
const compareText = '0'.repeat(6);
|
|
746
722
|
function getNodeChanges(newVNode, oldVNode) {
|
|
747
723
|
const newProps = newVNode.props;
|
|
748
724
|
const oldProps = oldVNode.props;
|
|
749
725
|
const styleChanges = getMapChanges(newProps.styles, oldProps.styles);
|
|
750
726
|
const attrChanges = getMapChanges(newProps.attrs, oldProps.attrs);
|
|
751
|
-
const classesChanges = getSetChanges(newProps.classes, oldProps.classes);
|
|
752
727
|
const listenerChanges = getObjectChanges(newProps.listeners, oldProps.listeners);
|
|
753
728
|
return {
|
|
754
729
|
styleChanges,
|
|
755
730
|
attrChanges,
|
|
756
|
-
classesChanges,
|
|
757
731
|
listenerChanges,
|
|
758
732
|
isChanged: [
|
|
759
733
|
attrChanges.set.length,
|
|
760
734
|
attrChanges.remove.length,
|
|
761
735
|
styleChanges.set.length,
|
|
762
736
|
styleChanges.remove.length,
|
|
763
|
-
classesChanges.add.length,
|
|
764
|
-
classesChanges.remove.length,
|
|
765
737
|
listenerChanges.add.length,
|
|
766
738
|
listenerChanges.remove.length
|
|
767
739
|
].join('') !== compareText
|
|
@@ -868,110 +840,120 @@ let Renderer = class Renderer {
|
|
|
868
840
|
else {
|
|
869
841
|
atom.child = null;
|
|
870
842
|
}
|
|
871
|
-
this.diff(atom.child, diffAtom, context);
|
|
843
|
+
this.diff(atom.child, diffAtom, context, 0, 0);
|
|
872
844
|
component.rendered();
|
|
873
845
|
}
|
|
874
|
-
diff(
|
|
846
|
+
diff(newAtom, oldAtom, context, expectIndex, index) {
|
|
875
847
|
const oldChildren = [];
|
|
876
|
-
|
|
877
|
-
while (diffAtom) {
|
|
848
|
+
while (oldAtom) {
|
|
878
849
|
oldChildren.push({
|
|
879
850
|
index,
|
|
880
|
-
atom:
|
|
851
|
+
atom: oldAtom
|
|
881
852
|
});
|
|
882
|
-
|
|
853
|
+
oldAtom = oldAtom.sibling;
|
|
883
854
|
index++;
|
|
884
855
|
}
|
|
885
856
|
const commits = [];
|
|
886
|
-
const
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
this.nativeRenderer.prependChild(host, start.nativeNode);
|
|
857
|
+
const changeCommits = {
|
|
858
|
+
reuseComponent: (start, reusedAtom, expectIndex, diffIndex) => {
|
|
859
|
+
commits.push(() => {
|
|
860
|
+
const { isChanged } = getNodeChanges(start.jsxNode, reusedAtom.jsxNode);
|
|
861
|
+
if (isChanged) {
|
|
862
|
+
reusedAtom.jsxNode.invokePropsChangedHooks(start.jsxNode.config);
|
|
893
863
|
}
|
|
894
|
-
|
|
895
|
-
|
|
864
|
+
const newProps = start.jsxNode.props;
|
|
865
|
+
start.jsxNode = reusedAtom.jsxNode;
|
|
866
|
+
start.jsxNode.props = newProps;
|
|
867
|
+
const { render } = this.componentAtomCaches.get(start.jsxNode);
|
|
868
|
+
const template = render();
|
|
869
|
+
if (template) {
|
|
870
|
+
this.linkTemplate(template, start.jsxNode, start);
|
|
896
871
|
}
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
}
|
|
911
|
-
else if (reusedAtom.child) {
|
|
912
|
-
let atom = reusedAtom.child;
|
|
913
|
-
while (atom) {
|
|
914
|
-
this.cleanView(atom, false);
|
|
915
|
-
atom = atom.sibling;
|
|
872
|
+
this.componentAtomCaches.set(start.jsxNode, {
|
|
873
|
+
render,
|
|
874
|
+
atom: start
|
|
875
|
+
});
|
|
876
|
+
if (start.child) {
|
|
877
|
+
this.diff(start.child, reusedAtom.child, context, expectIndex, diffIndex);
|
|
878
|
+
}
|
|
879
|
+
else if (reusedAtom.child) {
|
|
880
|
+
let atom = reusedAtom.child;
|
|
881
|
+
while (atom) {
|
|
882
|
+
this.cleanView(atom, false);
|
|
883
|
+
atom = atom.sibling;
|
|
884
|
+
}
|
|
916
885
|
}
|
|
917
|
-
}
|
|
918
|
-
if (applyRefs) {
|
|
919
|
-
applyRefs();
|
|
920
|
-
}
|
|
921
|
-
if (isComponent) {
|
|
922
886
|
start.jsxNode.rendered();
|
|
923
|
-
}
|
|
924
|
-
}
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
887
|
+
});
|
|
888
|
+
},
|
|
889
|
+
reuseElement: (newAtom, oldAtom, expectIndex, oldIndex) => {
|
|
890
|
+
commits.push(() => {
|
|
891
|
+
newAtom.nativeNode = oldAtom.nativeNode;
|
|
892
|
+
const host = context.host;
|
|
893
|
+
if (expectIndex !== oldIndex) {
|
|
894
|
+
if (context.isParent) {
|
|
895
|
+
this.nativeRenderer.prependChild(host, newAtom.nativeNode);
|
|
896
|
+
}
|
|
897
|
+
else {
|
|
898
|
+
this.nativeRenderer.insertAfter(newAtom.nativeNode, host);
|
|
899
|
+
}
|
|
900
|
+
}
|
|
901
|
+
context.host = newAtom.nativeNode;
|
|
902
|
+
context.isParent = false;
|
|
903
|
+
const applyRefs = this.updateNativeNodeProperties(newAtom.jsxNode, oldAtom.jsxNode, newAtom.nativeNode);
|
|
904
|
+
if (newAtom.child) {
|
|
905
|
+
this.diff(newAtom.child, oldAtom.child, {
|
|
906
|
+
host: newAtom.nativeNode,
|
|
907
|
+
isParent: true
|
|
908
|
+
}, 0, 0);
|
|
909
|
+
}
|
|
910
|
+
else if (oldAtom.child) {
|
|
911
|
+
let atom = oldAtom.child;
|
|
912
|
+
while (atom) {
|
|
913
|
+
this.cleanView(atom, false);
|
|
914
|
+
atom = atom.sibling;
|
|
915
|
+
}
|
|
916
|
+
}
|
|
917
|
+
if (applyRefs) {
|
|
918
|
+
applyRefs();
|
|
919
|
+
}
|
|
920
|
+
});
|
|
921
|
+
},
|
|
922
|
+
reuseText: (newAtom, oldAtom) => {
|
|
923
|
+
commits.push(() => {
|
|
924
|
+
const nativeNode = oldAtom.nativeNode;
|
|
925
|
+
if (newAtom.jsxNode.text !== oldAtom.jsxNode.text) {
|
|
926
|
+
this.nativeRenderer.syncTextContent(nativeNode, newAtom.jsxNode.text);
|
|
927
|
+
}
|
|
928
|
+
newAtom.nativeNode = nativeNode;
|
|
929
|
+
context.host = nativeNode;
|
|
930
|
+
context.isParent = false;
|
|
931
|
+
});
|
|
932
|
+
},
|
|
933
|
+
create: (start) => {
|
|
934
|
+
commits.push(() => {
|
|
935
|
+
this.buildView(start, context);
|
|
936
|
+
});
|
|
939
937
|
}
|
|
940
|
-
|
|
941
|
-
|
|
938
|
+
};
|
|
939
|
+
while (newAtom && !newAtom.nativeNode) {
|
|
940
|
+
this.createChanges(newAtom, expectIndex, oldChildren, changeCommits);
|
|
941
|
+
newAtom = newAtom.sibling;
|
|
942
|
+
expectIndex++;
|
|
942
943
|
}
|
|
943
944
|
for (const item of oldChildren) {
|
|
944
945
|
this.cleanView(item.atom, false);
|
|
945
946
|
}
|
|
946
|
-
for (
|
|
947
|
+
for (let i = 0; i < commits.length; i++) {
|
|
948
|
+
const commit = commits[i];
|
|
947
949
|
commit();
|
|
948
950
|
}
|
|
949
951
|
}
|
|
950
|
-
|
|
951
|
-
if (atom.nativeNode) {
|
|
952
|
-
if (!isClean) {
|
|
953
|
-
this.nativeRenderer.remove(atom.nativeNode);
|
|
954
|
-
isClean = true;
|
|
955
|
-
}
|
|
956
|
-
if (atom.jsxNode instanceof JSXElement) {
|
|
957
|
-
const ref = atom.jsxNode.props.attrs.get(refKey);
|
|
958
|
-
this.applyRefs(ref, atom.nativeNode, false);
|
|
959
|
-
}
|
|
960
|
-
}
|
|
961
|
-
let child = atom.child;
|
|
962
|
-
while (child) {
|
|
963
|
-
this.cleanView(child, isClean);
|
|
964
|
-
child = child.sibling;
|
|
965
|
-
}
|
|
966
|
-
if (atom.jsxNode instanceof Component) {
|
|
967
|
-
atom.jsxNode.destroy();
|
|
968
|
-
}
|
|
969
|
-
}
|
|
970
|
-
reuseAndUpdate(start, lastIndex, oldChildren) {
|
|
952
|
+
createChanges(newAtom, lastIndex, oldChildren, changeCommits) {
|
|
971
953
|
let isReuse = false;
|
|
972
954
|
for (let i = 0; i < oldChildren.length; i++) {
|
|
973
955
|
const { atom: diffAtom, index: diffIndex } = oldChildren[i];
|
|
974
|
-
const key =
|
|
956
|
+
const key = newAtom.jsxNode.key;
|
|
975
957
|
const diffKey = diffAtom.jsxNode.key;
|
|
976
958
|
if (key !== undefined && diffKey !== undefined) {
|
|
977
959
|
if (diffKey !== key) {
|
|
@@ -979,55 +961,47 @@ let Renderer = class Renderer {
|
|
|
979
961
|
}
|
|
980
962
|
isReuse = lastIndex > diffIndex;
|
|
981
963
|
}
|
|
982
|
-
if (
|
|
983
|
-
if (
|
|
984
|
-
const nativeNode = diffAtom.nativeNode;
|
|
964
|
+
if (newAtom.jsxNode.is(diffAtom.jsxNode)) {
|
|
965
|
+
if (newAtom.jsxNode instanceof JSXElement) {
|
|
985
966
|
if (isReuse) {
|
|
986
|
-
this.nativeRenderer.remove(nativeNode);
|
|
967
|
+
this.nativeRenderer.remove(diffAtom.nativeNode);
|
|
987
968
|
}
|
|
988
|
-
|
|
989
|
-
oldChildren.splice(i, 1);
|
|
990
|
-
return diffAtom;
|
|
969
|
+
changeCommits.reuseElement(newAtom, diffAtom, lastIndex, diffIndex);
|
|
991
970
|
}
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
if (diffAtom.jsxNode instanceof JSXText) {
|
|
995
|
-
const nativeNode = diffAtom.nativeNode;
|
|
996
|
-
if (start.jsxNode.text !== diffAtom.jsxNode.text) {
|
|
997
|
-
this.nativeRenderer.syncTextContent(nativeNode, start.jsxNode.text);
|
|
998
|
-
}
|
|
999
|
-
start.nativeNode = nativeNode;
|
|
1000
|
-
oldChildren.splice(i, 1);
|
|
1001
|
-
return diffAtom;
|
|
971
|
+
else if (newAtom.jsxNode instanceof JSXText) {
|
|
972
|
+
changeCommits.reuseText(newAtom, diffAtom);
|
|
1002
973
|
}
|
|
1003
|
-
|
|
1004
|
-
else if (diffAtom.jsxNode instanceof Component) {
|
|
1005
|
-
if (start.jsxNode.setup === diffAtom.jsxNode.setup) {
|
|
974
|
+
else {
|
|
1006
975
|
if (isReuse) {
|
|
1007
976
|
this.temporarilyRemove(diffAtom);
|
|
1008
977
|
}
|
|
1009
|
-
|
|
1010
|
-
if (isChanged) {
|
|
1011
|
-
diffAtom.jsxNode.invokePropsChangedHooks(start.jsxNode.config);
|
|
1012
|
-
}
|
|
1013
|
-
const newProps = start.jsxNode.props;
|
|
1014
|
-
start.jsxNode = diffAtom.jsxNode;
|
|
1015
|
-
start.jsxNode.props = newProps;
|
|
1016
|
-
const { render } = this.componentAtomCaches.get(start.jsxNode);
|
|
1017
|
-
const template = render();
|
|
1018
|
-
if (template) {
|
|
1019
|
-
this.linkTemplate(template, start.jsxNode, start);
|
|
1020
|
-
}
|
|
1021
|
-
this.componentAtomCaches.set(start.jsxNode, {
|
|
1022
|
-
render,
|
|
1023
|
-
atom: start
|
|
1024
|
-
});
|
|
1025
|
-
oldChildren.splice(i, 1);
|
|
1026
|
-
return diffAtom;
|
|
978
|
+
changeCommits.reuseComponent(newAtom, diffAtom, lastIndex, diffIndex);
|
|
1027
979
|
}
|
|
980
|
+
oldChildren.splice(i, 1);
|
|
981
|
+
return;
|
|
1028
982
|
}
|
|
1029
983
|
}
|
|
1030
|
-
|
|
984
|
+
changeCommits.create(newAtom);
|
|
985
|
+
}
|
|
986
|
+
cleanView(atom, isClean) {
|
|
987
|
+
if (atom.nativeNode) {
|
|
988
|
+
if (!isClean) {
|
|
989
|
+
this.nativeRenderer.remove(atom.nativeNode);
|
|
990
|
+
isClean = true;
|
|
991
|
+
}
|
|
992
|
+
if (atom.jsxNode instanceof JSXElement) {
|
|
993
|
+
const ref = atom.jsxNode.props.attrs.get(refKey);
|
|
994
|
+
this.applyRefs(ref, atom.nativeNode, false);
|
|
995
|
+
}
|
|
996
|
+
}
|
|
997
|
+
let child = atom.child;
|
|
998
|
+
while (child) {
|
|
999
|
+
this.cleanView(child, isClean);
|
|
1000
|
+
child = child.sibling;
|
|
1001
|
+
}
|
|
1002
|
+
if (atom.jsxNode instanceof Component) {
|
|
1003
|
+
atom.jsxNode.destroy();
|
|
1004
|
+
}
|
|
1031
1005
|
}
|
|
1032
1006
|
temporarilyRemove(atom) {
|
|
1033
1007
|
let next = atom.child;
|
|
@@ -1163,7 +1137,9 @@ let Renderer = class Renderer {
|
|
|
1163
1137
|
props.styles.forEach((value, key) => {
|
|
1164
1138
|
this.nativeRenderer.setStyle(nativeNode, key, value);
|
|
1165
1139
|
});
|
|
1166
|
-
props.classes
|
|
1140
|
+
if (props.classes) {
|
|
1141
|
+
this.nativeRenderer.setClass(nativeNode, props.classes);
|
|
1142
|
+
}
|
|
1167
1143
|
Object.keys(props.listeners).forEach(type => {
|
|
1168
1144
|
this.nativeRenderer.listen(nativeNode, type, props.listeners[type]);
|
|
1169
1145
|
});
|
|
@@ -1178,10 +1154,11 @@ let Renderer = class Renderer {
|
|
|
1178
1154
|
return this.nativeRenderer.createTextNode(child.text);
|
|
1179
1155
|
}
|
|
1180
1156
|
updateNativeNodeProperties(newVNode, oldVNode, nativeNode) {
|
|
1181
|
-
const
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1157
|
+
const newProps = newVNode.props;
|
|
1158
|
+
const oldProps = oldVNode.props;
|
|
1159
|
+
const styleChanges = getMapChanges(newProps.styles, oldProps.styles);
|
|
1160
|
+
const attrChanges = getMapChanges(newProps.attrs, oldProps.attrs);
|
|
1161
|
+
const listenerChanges = getObjectChanges(newProps.listeners, oldProps.listeners);
|
|
1185
1162
|
styleChanges.remove.forEach(i => this.nativeRenderer.removeStyle(nativeNode, i[0]));
|
|
1186
1163
|
styleChanges.set.forEach(i => this.nativeRenderer.setStyle(nativeNode, i[0], i[1]));
|
|
1187
1164
|
let unBindRefs;
|
|
@@ -1200,8 +1177,9 @@ let Renderer = class Renderer {
|
|
|
1200
1177
|
}
|
|
1201
1178
|
this.nativeRenderer.setProperty(nativeNode, key, value);
|
|
1202
1179
|
});
|
|
1203
|
-
|
|
1204
|
-
|
|
1180
|
+
if (newProps.classes !== oldProps.classes) {
|
|
1181
|
+
this.nativeRenderer.setClass(nativeNode, newProps.classes);
|
|
1182
|
+
}
|
|
1205
1183
|
listenerChanges.remove.forEach(i => {
|
|
1206
1184
|
this.nativeRenderer.unListen(nativeNode, i[0], i[1]);
|
|
1207
1185
|
});
|
package/bundles/index.js
CHANGED
|
@@ -67,6 +67,10 @@ function jsxs(setup, config, key) {
|
|
|
67
67
|
class JSXText {
|
|
68
68
|
constructor(text) {
|
|
69
69
|
this.text = text;
|
|
70
|
+
this.$$typeOf = '#text';
|
|
71
|
+
}
|
|
72
|
+
is(target) {
|
|
73
|
+
return target.$$typeOf === this.$$typeOf;
|
|
70
74
|
}
|
|
71
75
|
}
|
|
72
76
|
function flatChildren(jsxNodes) {
|
|
@@ -91,7 +95,7 @@ class Props {
|
|
|
91
95
|
constructor(props) {
|
|
92
96
|
this.attrs = new Map();
|
|
93
97
|
this.styles = new Map();
|
|
94
|
-
this.classes =
|
|
98
|
+
this.classes = '';
|
|
95
99
|
this.listeners = {};
|
|
96
100
|
this.children = [];
|
|
97
101
|
if (!props) {
|
|
@@ -110,7 +114,7 @@ class Props {
|
|
|
110
114
|
return;
|
|
111
115
|
}
|
|
112
116
|
if (key === 'class') {
|
|
113
|
-
this.classes =
|
|
117
|
+
this.classes = Props.classToString(props[key]);
|
|
114
118
|
return;
|
|
115
119
|
}
|
|
116
120
|
if (key === 'style') {
|
|
@@ -143,6 +147,31 @@ class Props {
|
|
|
143
147
|
this.attrs.set(key, props[key]);
|
|
144
148
|
});
|
|
145
149
|
}
|
|
150
|
+
static classToString(config) {
|
|
151
|
+
if (!config) {
|
|
152
|
+
return '';
|
|
153
|
+
}
|
|
154
|
+
if (typeof config === 'string') {
|
|
155
|
+
return config;
|
|
156
|
+
}
|
|
157
|
+
else if (Array.isArray(config)) {
|
|
158
|
+
return config.map(i => {
|
|
159
|
+
return Props.classToString(i);
|
|
160
|
+
}).join(' ');
|
|
161
|
+
}
|
|
162
|
+
else if (typeof config === 'object') {
|
|
163
|
+
if (config.toString !== Object.prototype.toString && !config.toString.toString().includes('[native code]')) {
|
|
164
|
+
return config.toString();
|
|
165
|
+
}
|
|
166
|
+
const classes = [];
|
|
167
|
+
for (const key in config) {
|
|
168
|
+
if ({}.hasOwnProperty.call(config, key) && config[key]) {
|
|
169
|
+
classes.push(key);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
return classes.join(' ');
|
|
173
|
+
}
|
|
174
|
+
}
|
|
146
175
|
static classToArray(config) {
|
|
147
176
|
const classes = [];
|
|
148
177
|
if (!config) {
|
|
@@ -176,8 +205,12 @@ class JSXElement {
|
|
|
176
205
|
this.name = name;
|
|
177
206
|
this.config = config;
|
|
178
207
|
this.key = key;
|
|
208
|
+
this.$$typeOf = this.name;
|
|
179
209
|
this.props = new Props(config);
|
|
180
210
|
}
|
|
211
|
+
is(target) {
|
|
212
|
+
return target.$$typeOf === this.$$typeOf;
|
|
213
|
+
}
|
|
181
214
|
}
|
|
182
215
|
|
|
183
216
|
const componentSetupStack = [];
|
|
@@ -219,6 +252,7 @@ class Component extends di.ReflectiveInjector {
|
|
|
219
252
|
this.setup = setup;
|
|
220
253
|
this.config = config;
|
|
221
254
|
this.key = key;
|
|
255
|
+
this.$$typeOf = this.setup;
|
|
222
256
|
this.destroyCallbacks = [];
|
|
223
257
|
this.mountCallbacks = [];
|
|
224
258
|
this.propsChangedCallbacks = [];
|
|
@@ -231,6 +265,9 @@ class Component extends di.ReflectiveInjector {
|
|
|
231
265
|
this.props = new Props(config);
|
|
232
266
|
this.parentComponent = this.parentInjector;
|
|
233
267
|
}
|
|
268
|
+
is(target) {
|
|
269
|
+
return target.$$typeOf === this.$$typeOf;
|
|
270
|
+
}
|
|
234
271
|
addProvide(providers) {
|
|
235
272
|
providers = Array.isArray(providers) ? providers : [providers];
|
|
236
273
|
providers.forEach(p => {
|
|
@@ -636,21 +673,6 @@ function getObjectChanges(target, source) {
|
|
|
636
673
|
remove: [],
|
|
637
674
|
add: []
|
|
638
675
|
};
|
|
639
|
-
// if (!target) {
|
|
640
|
-
// if (source) {
|
|
641
|
-
// Object.keys(source).forEach(key => {
|
|
642
|
-
// changes.remove.push([key, source[key]])
|
|
643
|
-
// })
|
|
644
|
-
// }
|
|
645
|
-
// return changes
|
|
646
|
-
// }
|
|
647
|
-
//
|
|
648
|
-
// if (!source) {
|
|
649
|
-
// Object.keys(target).forEach(key => {
|
|
650
|
-
// changes.add.push([key, target[key]])
|
|
651
|
-
// })
|
|
652
|
-
// return changes
|
|
653
|
-
// }
|
|
654
676
|
Object.keys(target).forEach(key => {
|
|
655
677
|
const leftValue = target[key];
|
|
656
678
|
if (!Reflect.has(source, key)) {
|
|
@@ -676,20 +698,6 @@ function getMapChanges(target, source) {
|
|
|
676
698
|
remove: [],
|
|
677
699
|
set: []
|
|
678
700
|
};
|
|
679
|
-
// if (!target) {
|
|
680
|
-
// if (source) {
|
|
681
|
-
// source.forEach((value, key) => {
|
|
682
|
-
// changes.remove.push([key, value])
|
|
683
|
-
// })
|
|
684
|
-
// }
|
|
685
|
-
// return changes
|
|
686
|
-
// }
|
|
687
|
-
// if (!source) {
|
|
688
|
-
// target.forEach((value, key) => {
|
|
689
|
-
// changes.set.push([key, value])
|
|
690
|
-
// })
|
|
691
|
-
// return changes
|
|
692
|
-
// }
|
|
693
701
|
target.forEach((value, key) => {
|
|
694
702
|
const rightValue = source.get(key);
|
|
695
703
|
if (value === rightValue) {
|
|
@@ -711,58 +719,22 @@ function getMapChanges(target, source) {
|
|
|
711
719
|
});
|
|
712
720
|
return changes;
|
|
713
721
|
}
|
|
714
|
-
|
|
715
|
-
const changes = {
|
|
716
|
-
add: [],
|
|
717
|
-
remove: []
|
|
718
|
-
};
|
|
719
|
-
// if (!target) {
|
|
720
|
-
// if (source) {
|
|
721
|
-
// source.forEach(i => {
|
|
722
|
-
// changes.remove.push(i)
|
|
723
|
-
// })
|
|
724
|
-
// }
|
|
725
|
-
// return changes
|
|
726
|
-
// }
|
|
727
|
-
//
|
|
728
|
-
// if (!source) {
|
|
729
|
-
// target.forEach(i => {
|
|
730
|
-
// changes.add.push(i)
|
|
731
|
-
// })
|
|
732
|
-
// return changes
|
|
733
|
-
// }
|
|
734
|
-
target.forEach(i => {
|
|
735
|
-
if (!source.has(i)) {
|
|
736
|
-
changes.add.push(i);
|
|
737
|
-
}
|
|
738
|
-
});
|
|
739
|
-
source.forEach(i => {
|
|
740
|
-
if (!target.has(i)) {
|
|
741
|
-
changes.remove.push(i);
|
|
742
|
-
}
|
|
743
|
-
});
|
|
744
|
-
return changes;
|
|
745
|
-
}
|
|
746
|
-
const compareText = '0'.repeat(8);
|
|
722
|
+
const compareText = '0'.repeat(6);
|
|
747
723
|
function getNodeChanges(newVNode, oldVNode) {
|
|
748
724
|
const newProps = newVNode.props;
|
|
749
725
|
const oldProps = oldVNode.props;
|
|
750
726
|
const styleChanges = getMapChanges(newProps.styles, oldProps.styles);
|
|
751
727
|
const attrChanges = getMapChanges(newProps.attrs, oldProps.attrs);
|
|
752
|
-
const classesChanges = getSetChanges(newProps.classes, oldProps.classes);
|
|
753
728
|
const listenerChanges = getObjectChanges(newProps.listeners, oldProps.listeners);
|
|
754
729
|
return {
|
|
755
730
|
styleChanges,
|
|
756
731
|
attrChanges,
|
|
757
|
-
classesChanges,
|
|
758
732
|
listenerChanges,
|
|
759
733
|
isChanged: [
|
|
760
734
|
attrChanges.set.length,
|
|
761
735
|
attrChanges.remove.length,
|
|
762
736
|
styleChanges.set.length,
|
|
763
737
|
styleChanges.remove.length,
|
|
764
|
-
classesChanges.add.length,
|
|
765
|
-
classesChanges.remove.length,
|
|
766
738
|
listenerChanges.add.length,
|
|
767
739
|
listenerChanges.remove.length
|
|
768
740
|
].join('') !== compareText
|
|
@@ -869,110 +841,120 @@ exports.Renderer = class Renderer {
|
|
|
869
841
|
else {
|
|
870
842
|
atom.child = null;
|
|
871
843
|
}
|
|
872
|
-
this.diff(atom.child, diffAtom, context);
|
|
844
|
+
this.diff(atom.child, diffAtom, context, 0, 0);
|
|
873
845
|
component.rendered();
|
|
874
846
|
}
|
|
875
|
-
diff(
|
|
847
|
+
diff(newAtom, oldAtom, context, expectIndex, index) {
|
|
876
848
|
const oldChildren = [];
|
|
877
|
-
|
|
878
|
-
while (diffAtom) {
|
|
849
|
+
while (oldAtom) {
|
|
879
850
|
oldChildren.push({
|
|
880
851
|
index,
|
|
881
|
-
atom:
|
|
852
|
+
atom: oldAtom
|
|
882
853
|
});
|
|
883
|
-
|
|
854
|
+
oldAtom = oldAtom.sibling;
|
|
884
855
|
index++;
|
|
885
856
|
}
|
|
886
857
|
const commits = [];
|
|
887
|
-
const
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
this.nativeRenderer.prependChild(host, start.nativeNode);
|
|
858
|
+
const changeCommits = {
|
|
859
|
+
reuseComponent: (start, reusedAtom, expectIndex, diffIndex) => {
|
|
860
|
+
commits.push(() => {
|
|
861
|
+
const { isChanged } = getNodeChanges(start.jsxNode, reusedAtom.jsxNode);
|
|
862
|
+
if (isChanged) {
|
|
863
|
+
reusedAtom.jsxNode.invokePropsChangedHooks(start.jsxNode.config);
|
|
894
864
|
}
|
|
895
|
-
|
|
896
|
-
|
|
865
|
+
const newProps = start.jsxNode.props;
|
|
866
|
+
start.jsxNode = reusedAtom.jsxNode;
|
|
867
|
+
start.jsxNode.props = newProps;
|
|
868
|
+
const { render } = this.componentAtomCaches.get(start.jsxNode);
|
|
869
|
+
const template = render();
|
|
870
|
+
if (template) {
|
|
871
|
+
this.linkTemplate(template, start.jsxNode, start);
|
|
897
872
|
}
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
}
|
|
912
|
-
else if (reusedAtom.child) {
|
|
913
|
-
let atom = reusedAtom.child;
|
|
914
|
-
while (atom) {
|
|
915
|
-
this.cleanView(atom, false);
|
|
916
|
-
atom = atom.sibling;
|
|
873
|
+
this.componentAtomCaches.set(start.jsxNode, {
|
|
874
|
+
render,
|
|
875
|
+
atom: start
|
|
876
|
+
});
|
|
877
|
+
if (start.child) {
|
|
878
|
+
this.diff(start.child, reusedAtom.child, context, expectIndex, diffIndex);
|
|
879
|
+
}
|
|
880
|
+
else if (reusedAtom.child) {
|
|
881
|
+
let atom = reusedAtom.child;
|
|
882
|
+
while (atom) {
|
|
883
|
+
this.cleanView(atom, false);
|
|
884
|
+
atom = atom.sibling;
|
|
885
|
+
}
|
|
917
886
|
}
|
|
918
|
-
}
|
|
919
|
-
if (applyRefs) {
|
|
920
|
-
applyRefs();
|
|
921
|
-
}
|
|
922
|
-
if (isComponent) {
|
|
923
887
|
start.jsxNode.rendered();
|
|
924
|
-
}
|
|
925
|
-
}
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
888
|
+
});
|
|
889
|
+
},
|
|
890
|
+
reuseElement: (newAtom, oldAtom, expectIndex, oldIndex) => {
|
|
891
|
+
commits.push(() => {
|
|
892
|
+
newAtom.nativeNode = oldAtom.nativeNode;
|
|
893
|
+
const host = context.host;
|
|
894
|
+
if (expectIndex !== oldIndex) {
|
|
895
|
+
if (context.isParent) {
|
|
896
|
+
this.nativeRenderer.prependChild(host, newAtom.nativeNode);
|
|
897
|
+
}
|
|
898
|
+
else {
|
|
899
|
+
this.nativeRenderer.insertAfter(newAtom.nativeNode, host);
|
|
900
|
+
}
|
|
901
|
+
}
|
|
902
|
+
context.host = newAtom.nativeNode;
|
|
903
|
+
context.isParent = false;
|
|
904
|
+
const applyRefs = this.updateNativeNodeProperties(newAtom.jsxNode, oldAtom.jsxNode, newAtom.nativeNode);
|
|
905
|
+
if (newAtom.child) {
|
|
906
|
+
this.diff(newAtom.child, oldAtom.child, {
|
|
907
|
+
host: newAtom.nativeNode,
|
|
908
|
+
isParent: true
|
|
909
|
+
}, 0, 0);
|
|
910
|
+
}
|
|
911
|
+
else if (oldAtom.child) {
|
|
912
|
+
let atom = oldAtom.child;
|
|
913
|
+
while (atom) {
|
|
914
|
+
this.cleanView(atom, false);
|
|
915
|
+
atom = atom.sibling;
|
|
916
|
+
}
|
|
917
|
+
}
|
|
918
|
+
if (applyRefs) {
|
|
919
|
+
applyRefs();
|
|
920
|
+
}
|
|
921
|
+
});
|
|
922
|
+
},
|
|
923
|
+
reuseText: (newAtom, oldAtom) => {
|
|
924
|
+
commits.push(() => {
|
|
925
|
+
const nativeNode = oldAtom.nativeNode;
|
|
926
|
+
if (newAtom.jsxNode.text !== oldAtom.jsxNode.text) {
|
|
927
|
+
this.nativeRenderer.syncTextContent(nativeNode, newAtom.jsxNode.text);
|
|
928
|
+
}
|
|
929
|
+
newAtom.nativeNode = nativeNode;
|
|
930
|
+
context.host = nativeNode;
|
|
931
|
+
context.isParent = false;
|
|
932
|
+
});
|
|
933
|
+
},
|
|
934
|
+
create: (start) => {
|
|
935
|
+
commits.push(() => {
|
|
936
|
+
this.buildView(start, context);
|
|
937
|
+
});
|
|
940
938
|
}
|
|
941
|
-
|
|
942
|
-
|
|
939
|
+
};
|
|
940
|
+
while (newAtom && !newAtom.nativeNode) {
|
|
941
|
+
this.createChanges(newAtom, expectIndex, oldChildren, changeCommits);
|
|
942
|
+
newAtom = newAtom.sibling;
|
|
943
|
+
expectIndex++;
|
|
943
944
|
}
|
|
944
945
|
for (const item of oldChildren) {
|
|
945
946
|
this.cleanView(item.atom, false);
|
|
946
947
|
}
|
|
947
|
-
for (
|
|
948
|
+
for (let i = 0; i < commits.length; i++) {
|
|
949
|
+
const commit = commits[i];
|
|
948
950
|
commit();
|
|
949
951
|
}
|
|
950
952
|
}
|
|
951
|
-
|
|
952
|
-
if (atom.nativeNode) {
|
|
953
|
-
if (!isClean) {
|
|
954
|
-
this.nativeRenderer.remove(atom.nativeNode);
|
|
955
|
-
isClean = true;
|
|
956
|
-
}
|
|
957
|
-
if (atom.jsxNode instanceof JSXElement) {
|
|
958
|
-
const ref = atom.jsxNode.props.attrs.get(refKey);
|
|
959
|
-
this.applyRefs(ref, atom.nativeNode, false);
|
|
960
|
-
}
|
|
961
|
-
}
|
|
962
|
-
let child = atom.child;
|
|
963
|
-
while (child) {
|
|
964
|
-
this.cleanView(child, isClean);
|
|
965
|
-
child = child.sibling;
|
|
966
|
-
}
|
|
967
|
-
if (atom.jsxNode instanceof Component) {
|
|
968
|
-
atom.jsxNode.destroy();
|
|
969
|
-
}
|
|
970
|
-
}
|
|
971
|
-
reuseAndUpdate(start, lastIndex, oldChildren) {
|
|
953
|
+
createChanges(newAtom, lastIndex, oldChildren, changeCommits) {
|
|
972
954
|
let isReuse = false;
|
|
973
955
|
for (let i = 0; i < oldChildren.length; i++) {
|
|
974
956
|
const { atom: diffAtom, index: diffIndex } = oldChildren[i];
|
|
975
|
-
const key =
|
|
957
|
+
const key = newAtom.jsxNode.key;
|
|
976
958
|
const diffKey = diffAtom.jsxNode.key;
|
|
977
959
|
if (key !== undefined && diffKey !== undefined) {
|
|
978
960
|
if (diffKey !== key) {
|
|
@@ -980,55 +962,47 @@ exports.Renderer = class Renderer {
|
|
|
980
962
|
}
|
|
981
963
|
isReuse = lastIndex > diffIndex;
|
|
982
964
|
}
|
|
983
|
-
if (
|
|
984
|
-
if (
|
|
985
|
-
const nativeNode = diffAtom.nativeNode;
|
|
965
|
+
if (newAtom.jsxNode.is(diffAtom.jsxNode)) {
|
|
966
|
+
if (newAtom.jsxNode instanceof JSXElement) {
|
|
986
967
|
if (isReuse) {
|
|
987
|
-
this.nativeRenderer.remove(nativeNode);
|
|
968
|
+
this.nativeRenderer.remove(diffAtom.nativeNode);
|
|
988
969
|
}
|
|
989
|
-
|
|
990
|
-
oldChildren.splice(i, 1);
|
|
991
|
-
return diffAtom;
|
|
970
|
+
changeCommits.reuseElement(newAtom, diffAtom, lastIndex, diffIndex);
|
|
992
971
|
}
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
if (diffAtom.jsxNode instanceof JSXText) {
|
|
996
|
-
const nativeNode = diffAtom.nativeNode;
|
|
997
|
-
if (start.jsxNode.text !== diffAtom.jsxNode.text) {
|
|
998
|
-
this.nativeRenderer.syncTextContent(nativeNode, start.jsxNode.text);
|
|
999
|
-
}
|
|
1000
|
-
start.nativeNode = nativeNode;
|
|
1001
|
-
oldChildren.splice(i, 1);
|
|
1002
|
-
return diffAtom;
|
|
972
|
+
else if (newAtom.jsxNode instanceof JSXText) {
|
|
973
|
+
changeCommits.reuseText(newAtom, diffAtom);
|
|
1003
974
|
}
|
|
1004
|
-
|
|
1005
|
-
else if (diffAtom.jsxNode instanceof Component) {
|
|
1006
|
-
if (start.jsxNode.setup === diffAtom.jsxNode.setup) {
|
|
975
|
+
else {
|
|
1007
976
|
if (isReuse) {
|
|
1008
977
|
this.temporarilyRemove(diffAtom);
|
|
1009
978
|
}
|
|
1010
|
-
|
|
1011
|
-
if (isChanged) {
|
|
1012
|
-
diffAtom.jsxNode.invokePropsChangedHooks(start.jsxNode.config);
|
|
1013
|
-
}
|
|
1014
|
-
const newProps = start.jsxNode.props;
|
|
1015
|
-
start.jsxNode = diffAtom.jsxNode;
|
|
1016
|
-
start.jsxNode.props = newProps;
|
|
1017
|
-
const { render } = this.componentAtomCaches.get(start.jsxNode);
|
|
1018
|
-
const template = render();
|
|
1019
|
-
if (template) {
|
|
1020
|
-
this.linkTemplate(template, start.jsxNode, start);
|
|
1021
|
-
}
|
|
1022
|
-
this.componentAtomCaches.set(start.jsxNode, {
|
|
1023
|
-
render,
|
|
1024
|
-
atom: start
|
|
1025
|
-
});
|
|
1026
|
-
oldChildren.splice(i, 1);
|
|
1027
|
-
return diffAtom;
|
|
979
|
+
changeCommits.reuseComponent(newAtom, diffAtom, lastIndex, diffIndex);
|
|
1028
980
|
}
|
|
981
|
+
oldChildren.splice(i, 1);
|
|
982
|
+
return;
|
|
1029
983
|
}
|
|
1030
984
|
}
|
|
1031
|
-
|
|
985
|
+
changeCommits.create(newAtom);
|
|
986
|
+
}
|
|
987
|
+
cleanView(atom, isClean) {
|
|
988
|
+
if (atom.nativeNode) {
|
|
989
|
+
if (!isClean) {
|
|
990
|
+
this.nativeRenderer.remove(atom.nativeNode);
|
|
991
|
+
isClean = true;
|
|
992
|
+
}
|
|
993
|
+
if (atom.jsxNode instanceof JSXElement) {
|
|
994
|
+
const ref = atom.jsxNode.props.attrs.get(refKey);
|
|
995
|
+
this.applyRefs(ref, atom.nativeNode, false);
|
|
996
|
+
}
|
|
997
|
+
}
|
|
998
|
+
let child = atom.child;
|
|
999
|
+
while (child) {
|
|
1000
|
+
this.cleanView(child, isClean);
|
|
1001
|
+
child = child.sibling;
|
|
1002
|
+
}
|
|
1003
|
+
if (atom.jsxNode instanceof Component) {
|
|
1004
|
+
atom.jsxNode.destroy();
|
|
1005
|
+
}
|
|
1032
1006
|
}
|
|
1033
1007
|
temporarilyRemove(atom) {
|
|
1034
1008
|
let next = atom.child;
|
|
@@ -1164,7 +1138,9 @@ exports.Renderer = class Renderer {
|
|
|
1164
1138
|
props.styles.forEach((value, key) => {
|
|
1165
1139
|
this.nativeRenderer.setStyle(nativeNode, key, value);
|
|
1166
1140
|
});
|
|
1167
|
-
props.classes
|
|
1141
|
+
if (props.classes) {
|
|
1142
|
+
this.nativeRenderer.setClass(nativeNode, props.classes);
|
|
1143
|
+
}
|
|
1168
1144
|
Object.keys(props.listeners).forEach(type => {
|
|
1169
1145
|
this.nativeRenderer.listen(nativeNode, type, props.listeners[type]);
|
|
1170
1146
|
});
|
|
@@ -1179,10 +1155,11 @@ exports.Renderer = class Renderer {
|
|
|
1179
1155
|
return this.nativeRenderer.createTextNode(child.text);
|
|
1180
1156
|
}
|
|
1181
1157
|
updateNativeNodeProperties(newVNode, oldVNode, nativeNode) {
|
|
1182
|
-
const
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1158
|
+
const newProps = newVNode.props;
|
|
1159
|
+
const oldProps = oldVNode.props;
|
|
1160
|
+
const styleChanges = getMapChanges(newProps.styles, oldProps.styles);
|
|
1161
|
+
const attrChanges = getMapChanges(newProps.attrs, oldProps.attrs);
|
|
1162
|
+
const listenerChanges = getObjectChanges(newProps.listeners, oldProps.listeners);
|
|
1186
1163
|
styleChanges.remove.forEach(i => this.nativeRenderer.removeStyle(nativeNode, i[0]));
|
|
1187
1164
|
styleChanges.set.forEach(i => this.nativeRenderer.setStyle(nativeNode, i[0], i[1]));
|
|
1188
1165
|
let unBindRefs;
|
|
@@ -1201,8 +1178,9 @@ exports.Renderer = class Renderer {
|
|
|
1201
1178
|
}
|
|
1202
1179
|
this.nativeRenderer.setProperty(nativeNode, key, value);
|
|
1203
1180
|
});
|
|
1204
|
-
|
|
1205
|
-
|
|
1181
|
+
if (newProps.classes !== oldProps.classes) {
|
|
1182
|
+
this.nativeRenderer.setClass(nativeNode, newProps.classes);
|
|
1183
|
+
}
|
|
1206
1184
|
listenerChanges.remove.forEach(i => {
|
|
1207
1185
|
this.nativeRenderer.unListen(nativeNode, i[0], i[1]);
|
|
1208
1186
|
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Provider, ReflectiveInjector, AbstractType, Type, InjectionToken, InjectFlags, Injector } from '@tanbo/di';
|
|
2
|
-
import { JSXProps, JSXElement, Props, Key } from './jsx-element';
|
|
2
|
+
import { JSXProps, JSXElement, Props, Key, JSXTypeof } from './jsx-element';
|
|
3
3
|
export declare class JSXComponent {
|
|
4
4
|
createInstance: (injector: Component) => Component;
|
|
5
5
|
constructor(createInstance: (injector: Component) => Component);
|
|
@@ -11,10 +11,11 @@ export interface ComponentSetup<T extends JSXProps<any> = JSXProps<any>> {
|
|
|
11
11
|
/**
|
|
12
12
|
* Viewfly 组件管理类,用于管理组件的生命周期,上下文等
|
|
13
13
|
*/
|
|
14
|
-
export declare class Component extends ReflectiveInjector {
|
|
14
|
+
export declare class Component extends ReflectiveInjector implements JSXTypeof {
|
|
15
15
|
setup: ComponentSetup;
|
|
16
16
|
config?: JSXProps<any> | null | undefined;
|
|
17
17
|
key?: Key | undefined;
|
|
18
|
+
$$typeOf: ComponentSetup<JSXProps<any>>;
|
|
18
19
|
destroyCallbacks: LifeCycleCallback[];
|
|
19
20
|
mountCallbacks: LifeCycleCallback[];
|
|
20
21
|
propsChangedCallbacks: PropsChangedCallback<any>[];
|
|
@@ -29,6 +30,7 @@ export declare class Component extends ReflectiveInjector {
|
|
|
29
30
|
private propsChangedDestroyCallbacks;
|
|
30
31
|
private isFirstRending;
|
|
31
32
|
constructor(context: Injector, setup: ComponentSetup, config?: JSXProps<any> | null | undefined, key?: Key | undefined);
|
|
33
|
+
is(target: JSXTypeof): boolean;
|
|
32
34
|
addProvide<T>(providers: Provider<T> | Provider<T>[]): void;
|
|
33
35
|
init(): {
|
|
34
36
|
template: JSXTemplate;
|
|
@@ -11,27 +11,36 @@ export declare function jsx<T extends JSXChildNode>(name: string, config?: JSXPr
|
|
|
11
11
|
export declare function jsx<T extends JSXChildNode>(setup: ComponentSetup, config?: JSXProps<T> | null, key?: Key): JSXComponent;
|
|
12
12
|
export declare function jsxs<T extends JSXChildNode[]>(name: string, config?: JSXProps<T> | null, key?: Key): JSXElement;
|
|
13
13
|
export declare function jsxs<T extends JSXChildNode[]>(setup: ComponentSetup, config?: JSXProps<T> | null, key?: Key): JSXComponent;
|
|
14
|
+
export interface JSXTypeof {
|
|
15
|
+
$$typeOf: string | ComponentSetup;
|
|
16
|
+
is(target: JSXTypeof): boolean;
|
|
17
|
+
}
|
|
14
18
|
export interface VElementListeners {
|
|
15
19
|
[listenKey: string]: <T extends Event>(ev: T) => any;
|
|
16
20
|
}
|
|
17
|
-
export declare class JSXText {
|
|
21
|
+
export declare class JSXText implements JSXTypeof {
|
|
18
22
|
text: string;
|
|
23
|
+
$$typeOf: string;
|
|
19
24
|
constructor(text: string);
|
|
25
|
+
is(target: JSXTypeof): boolean;
|
|
20
26
|
}
|
|
21
|
-
export type
|
|
27
|
+
export type JSXNode = JSXElement | JSXComponent | JSXText;
|
|
22
28
|
export declare class Props {
|
|
23
29
|
attrs: Map<string, any>;
|
|
24
30
|
styles: Map<string, string | number>;
|
|
25
|
-
classes:
|
|
31
|
+
classes: string;
|
|
26
32
|
listeners: VElementListeners;
|
|
27
|
-
children:
|
|
33
|
+
children: JSXNode[];
|
|
28
34
|
constructor(props?: JSXProps<JSXChildNode> | JSXProps<JSXChildNode[]> | null);
|
|
35
|
+
static classToString(config: unknown): any;
|
|
29
36
|
static classToArray(config: unknown): string[];
|
|
30
37
|
}
|
|
31
|
-
export declare class JSXElement {
|
|
38
|
+
export declare class JSXElement implements JSXTypeof {
|
|
32
39
|
name: string;
|
|
33
40
|
config?: JSXProps<any> | null | undefined;
|
|
34
41
|
key?: Key | undefined;
|
|
42
|
+
$$typeOf: string;
|
|
35
43
|
props: Props;
|
|
36
44
|
constructor(name: string, config?: JSXProps<any> | null | undefined, key?: Key | undefined);
|
|
45
|
+
is(target: JSXTypeof): boolean;
|
|
37
46
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@viewfly/core",
|
|
3
|
-
"version": "0.0.1-alpha.
|
|
3
|
+
"version": "0.0.1-alpha.8",
|
|
4
4
|
"description": "Viewfly is a simple and easy-to-use JavaScript framework with an intuitive development experience.",
|
|
5
5
|
"main": "./bundles/index.js",
|
|
6
6
|
"module": "./bundles/index.esm.js",
|
|
@@ -37,5 +37,5 @@
|
|
|
37
37
|
"bugs": {
|
|
38
38
|
"url": "https://github.com/viewfly/viewfly.git/issues"
|
|
39
39
|
},
|
|
40
|
-
"gitHead": "
|
|
40
|
+
"gitHead": "462b51e8623348002ba7c6ba2caf7df131534506"
|
|
41
41
|
}
|