@viewfly/core 0.0.1-alpha.6 → 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 +2 -2
- package/bundles/index.esm.js +260 -284
- package/bundles/index.js +260 -284
- package/bundles/model/component.d.ts +6 -3
- package/bundles/model/jsx-element.d.ts +21 -10
- package/package.json +2 -2
package/bundles/index.esm.js
CHANGED
|
@@ -47,25 +47,29 @@ const jsxErrorFn = makeError('JSX');
|
|
|
47
47
|
const Fragment = function Fragment() {
|
|
48
48
|
throw jsxErrorFn('Fragment does not support calling.');
|
|
49
49
|
};
|
|
50
|
-
function jsx(setup, config) {
|
|
50
|
+
function jsx(setup, config, key) {
|
|
51
51
|
if (typeof setup === 'string') {
|
|
52
|
-
return new JSXElement(setup, config);
|
|
52
|
+
return new JSXElement(setup, config, key);
|
|
53
53
|
}
|
|
54
54
|
return new JSXComponent(function (context) {
|
|
55
|
-
return new Component(context, setup, config);
|
|
55
|
+
return new Component(context, setup, config, key);
|
|
56
56
|
});
|
|
57
57
|
}
|
|
58
|
-
function jsxs(setup, config) {
|
|
58
|
+
function jsxs(setup, config, key) {
|
|
59
59
|
if (typeof setup === 'string') {
|
|
60
|
-
return new JSXElement(setup, config);
|
|
60
|
+
return new JSXElement(setup, config, key);
|
|
61
61
|
}
|
|
62
62
|
return new JSXComponent(function (context) {
|
|
63
|
-
return new Component(context, setup, config);
|
|
63
|
+
return new Component(context, setup, config, key);
|
|
64
64
|
});
|
|
65
65
|
}
|
|
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) {
|
|
@@ -171,11 +200,16 @@ class Props {
|
|
|
171
200
|
}
|
|
172
201
|
}
|
|
173
202
|
class JSXElement {
|
|
174
|
-
constructor(name, config) {
|
|
203
|
+
constructor(name, config, key) {
|
|
175
204
|
this.name = name;
|
|
176
205
|
this.config = config;
|
|
206
|
+
this.key = key;
|
|
207
|
+
this.$$typeOf = this.name;
|
|
177
208
|
this.props = new Props(config);
|
|
178
209
|
}
|
|
210
|
+
is(target) {
|
|
211
|
+
return target.$$typeOf === this.$$typeOf;
|
|
212
|
+
}
|
|
179
213
|
}
|
|
180
214
|
|
|
181
215
|
const componentSetupStack = [];
|
|
@@ -212,10 +246,12 @@ class Component extends ReflectiveInjector {
|
|
|
212
246
|
get changed() {
|
|
213
247
|
return this._changed;
|
|
214
248
|
}
|
|
215
|
-
constructor(context, setup, config) {
|
|
249
|
+
constructor(context, setup, config, key) {
|
|
216
250
|
super(context, []);
|
|
217
251
|
this.setup = setup;
|
|
218
252
|
this.config = config;
|
|
253
|
+
this.key = key;
|
|
254
|
+
this.$$typeOf = this.setup;
|
|
219
255
|
this.destroyCallbacks = [];
|
|
220
256
|
this.mountCallbacks = [];
|
|
221
257
|
this.propsChangedCallbacks = [];
|
|
@@ -228,6 +264,9 @@ class Component extends ReflectiveInjector {
|
|
|
228
264
|
this.props = new Props(config);
|
|
229
265
|
this.parentComponent = this.parentInjector;
|
|
230
266
|
}
|
|
267
|
+
is(target) {
|
|
268
|
+
return target.$$typeOf === this.$$typeOf;
|
|
269
|
+
}
|
|
231
270
|
addProvide(providers) {
|
|
232
271
|
providers = Array.isArray(providers) ? providers : [providers];
|
|
233
272
|
providers.forEach(p => {
|
|
@@ -633,21 +672,6 @@ function getObjectChanges(target, source) {
|
|
|
633
672
|
remove: [],
|
|
634
673
|
add: []
|
|
635
674
|
};
|
|
636
|
-
// if (!target) {
|
|
637
|
-
// if (source) {
|
|
638
|
-
// Object.keys(source).forEach(key => {
|
|
639
|
-
// changes.remove.push([key, source[key]])
|
|
640
|
-
// })
|
|
641
|
-
// }
|
|
642
|
-
// return changes
|
|
643
|
-
// }
|
|
644
|
-
//
|
|
645
|
-
// if (!source) {
|
|
646
|
-
// Object.keys(target).forEach(key => {
|
|
647
|
-
// changes.add.push([key, target[key]])
|
|
648
|
-
// })
|
|
649
|
-
// return changes
|
|
650
|
-
// }
|
|
651
675
|
Object.keys(target).forEach(key => {
|
|
652
676
|
const leftValue = target[key];
|
|
653
677
|
if (!Reflect.has(source, key)) {
|
|
@@ -673,20 +697,6 @@ function getMapChanges(target, source) {
|
|
|
673
697
|
remove: [],
|
|
674
698
|
set: []
|
|
675
699
|
};
|
|
676
|
-
// if (!target) {
|
|
677
|
-
// if (source) {
|
|
678
|
-
// source.forEach((value, key) => {
|
|
679
|
-
// changes.remove.push([key, value])
|
|
680
|
-
// })
|
|
681
|
-
// }
|
|
682
|
-
// return changes
|
|
683
|
-
// }
|
|
684
|
-
// if (!source) {
|
|
685
|
-
// target.forEach((value, key) => {
|
|
686
|
-
// changes.set.push([key, value])
|
|
687
|
-
// })
|
|
688
|
-
// return changes
|
|
689
|
-
// }
|
|
690
700
|
target.forEach((value, key) => {
|
|
691
701
|
const rightValue = source.get(key);
|
|
692
702
|
if (value === rightValue) {
|
|
@@ -708,58 +718,22 @@ function getMapChanges(target, source) {
|
|
|
708
718
|
});
|
|
709
719
|
return changes;
|
|
710
720
|
}
|
|
711
|
-
|
|
712
|
-
const changes = {
|
|
713
|
-
add: [],
|
|
714
|
-
remove: []
|
|
715
|
-
};
|
|
716
|
-
// if (!target) {
|
|
717
|
-
// if (source) {
|
|
718
|
-
// source.forEach(i => {
|
|
719
|
-
// changes.remove.push(i)
|
|
720
|
-
// })
|
|
721
|
-
// }
|
|
722
|
-
// return changes
|
|
723
|
-
// }
|
|
724
|
-
//
|
|
725
|
-
// if (!source) {
|
|
726
|
-
// target.forEach(i => {
|
|
727
|
-
// changes.add.push(i)
|
|
728
|
-
// })
|
|
729
|
-
// return changes
|
|
730
|
-
// }
|
|
731
|
-
target.forEach(i => {
|
|
732
|
-
if (!source.has(i)) {
|
|
733
|
-
changes.add.push(i);
|
|
734
|
-
}
|
|
735
|
-
});
|
|
736
|
-
source.forEach(i => {
|
|
737
|
-
if (!target.has(i)) {
|
|
738
|
-
changes.remove.push(i);
|
|
739
|
-
}
|
|
740
|
-
});
|
|
741
|
-
return changes;
|
|
742
|
-
}
|
|
743
|
-
const compareText = '0'.repeat(8);
|
|
721
|
+
const compareText = '0'.repeat(6);
|
|
744
722
|
function getNodeChanges(newVNode, oldVNode) {
|
|
745
723
|
const newProps = newVNode.props;
|
|
746
724
|
const oldProps = oldVNode.props;
|
|
747
725
|
const styleChanges = getMapChanges(newProps.styles, oldProps.styles);
|
|
748
726
|
const attrChanges = getMapChanges(newProps.attrs, oldProps.attrs);
|
|
749
|
-
const classesChanges = getSetChanges(newProps.classes, oldProps.classes);
|
|
750
727
|
const listenerChanges = getObjectChanges(newProps.listeners, oldProps.listeners);
|
|
751
728
|
return {
|
|
752
729
|
styleChanges,
|
|
753
730
|
attrChanges,
|
|
754
|
-
classesChanges,
|
|
755
731
|
listenerChanges,
|
|
756
732
|
isChanged: [
|
|
757
733
|
attrChanges.set.length,
|
|
758
734
|
attrChanges.remove.length,
|
|
759
735
|
styleChanges.set.length,
|
|
760
736
|
styleChanges.remove.length,
|
|
761
|
-
classesChanges.add.length,
|
|
762
|
-
classesChanges.remove.length,
|
|
763
737
|
listenerChanges.add.length,
|
|
764
738
|
listenerChanges.remove.length
|
|
765
739
|
].join('') !== compareText
|
|
@@ -785,10 +759,10 @@ let Renderer = class Renderer {
|
|
|
785
759
|
}
|
|
786
760
|
render() {
|
|
787
761
|
const { component, host } = this.rootComponentRef;
|
|
788
|
-
const
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
762
|
+
const atom = new Atom(component, null);
|
|
763
|
+
this.buildView(atom, {
|
|
764
|
+
isParent: true,
|
|
765
|
+
host
|
|
792
766
|
});
|
|
793
767
|
}
|
|
794
768
|
refresh() {
|
|
@@ -866,81 +840,149 @@ let Renderer = class Renderer {
|
|
|
866
840
|
else {
|
|
867
841
|
atom.child = null;
|
|
868
842
|
}
|
|
869
|
-
this.diff(atom.child, diffAtom, context);
|
|
843
|
+
this.diff(atom.child, diffAtom, context, 0, 0);
|
|
870
844
|
component.rendered();
|
|
871
845
|
}
|
|
872
|
-
diff(
|
|
846
|
+
diff(newAtom, oldAtom, context, expectIndex, index) {
|
|
873
847
|
const oldChildren = [];
|
|
874
|
-
while (
|
|
875
|
-
oldChildren.push(
|
|
876
|
-
|
|
848
|
+
while (oldAtom) {
|
|
849
|
+
oldChildren.push({
|
|
850
|
+
index,
|
|
851
|
+
atom: oldAtom
|
|
852
|
+
});
|
|
853
|
+
oldAtom = oldAtom.sibling;
|
|
854
|
+
index++;
|
|
877
855
|
}
|
|
878
856
|
const commits = [];
|
|
879
|
-
const
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
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);
|
|
886
863
|
}
|
|
887
|
-
|
|
888
|
-
|
|
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);
|
|
889
871
|
}
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
this.cleanView(atom, false);
|
|
904
|
-
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
|
+
}
|
|
905
885
|
}
|
|
906
|
-
}
|
|
907
|
-
if (isComponent) {
|
|
908
886
|
start.jsxNode.rendered();
|
|
909
|
-
}
|
|
910
|
-
}
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
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
|
+
}
|
|
918
900
|
}
|
|
919
|
-
|
|
920
|
-
|
|
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);
|
|
921
909
|
}
|
|
922
|
-
|
|
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;
|
|
923
930
|
context.isParent = false;
|
|
924
931
|
});
|
|
925
|
-
}
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
addReuseCommit(start, reusedAtom);
|
|
931
|
-
}
|
|
932
|
-
else {
|
|
933
|
-
addCreateCommit(start);
|
|
932
|
+
},
|
|
933
|
+
create: (start) => {
|
|
934
|
+
commits.push(() => {
|
|
935
|
+
this.buildView(start, context);
|
|
936
|
+
});
|
|
934
937
|
}
|
|
935
|
-
|
|
938
|
+
};
|
|
939
|
+
while (newAtom && !newAtom.nativeNode) {
|
|
940
|
+
this.createChanges(newAtom, expectIndex, oldChildren, changeCommits);
|
|
941
|
+
newAtom = newAtom.sibling;
|
|
942
|
+
expectIndex++;
|
|
936
943
|
}
|
|
937
|
-
for (const
|
|
938
|
-
this.cleanView(atom, false);
|
|
944
|
+
for (const item of oldChildren) {
|
|
945
|
+
this.cleanView(item.atom, false);
|
|
939
946
|
}
|
|
940
|
-
for (
|
|
947
|
+
for (let i = 0; i < commits.length; i++) {
|
|
948
|
+
const commit = commits[i];
|
|
941
949
|
commit();
|
|
942
950
|
}
|
|
943
951
|
}
|
|
952
|
+
createChanges(newAtom, lastIndex, oldChildren, changeCommits) {
|
|
953
|
+
let isReuse = false;
|
|
954
|
+
for (let i = 0; i < oldChildren.length; i++) {
|
|
955
|
+
const { atom: diffAtom, index: diffIndex } = oldChildren[i];
|
|
956
|
+
const key = newAtom.jsxNode.key;
|
|
957
|
+
const diffKey = diffAtom.jsxNode.key;
|
|
958
|
+
if (key !== undefined && diffKey !== undefined) {
|
|
959
|
+
if (diffKey !== key) {
|
|
960
|
+
continue;
|
|
961
|
+
}
|
|
962
|
+
isReuse = lastIndex > diffIndex;
|
|
963
|
+
}
|
|
964
|
+
if (newAtom.jsxNode.is(diffAtom.jsxNode)) {
|
|
965
|
+
if (newAtom.jsxNode instanceof JSXElement) {
|
|
966
|
+
if (isReuse) {
|
|
967
|
+
this.nativeRenderer.remove(diffAtom.nativeNode);
|
|
968
|
+
}
|
|
969
|
+
changeCommits.reuseElement(newAtom, diffAtom, lastIndex, diffIndex);
|
|
970
|
+
}
|
|
971
|
+
else if (newAtom.jsxNode instanceof JSXText) {
|
|
972
|
+
changeCommits.reuseText(newAtom, diffAtom);
|
|
973
|
+
}
|
|
974
|
+
else {
|
|
975
|
+
if (isReuse) {
|
|
976
|
+
this.temporarilyRemove(diffAtom);
|
|
977
|
+
}
|
|
978
|
+
changeCommits.reuseComponent(newAtom, diffAtom, lastIndex, diffIndex);
|
|
979
|
+
}
|
|
980
|
+
oldChildren.splice(i, 1);
|
|
981
|
+
return;
|
|
982
|
+
}
|
|
983
|
+
}
|
|
984
|
+
changeCommits.create(newAtom);
|
|
985
|
+
}
|
|
944
986
|
cleanView(atom, isClean) {
|
|
945
987
|
if (atom.nativeNode) {
|
|
946
988
|
if (!isClean) {
|
|
@@ -961,148 +1003,74 @@ let Renderer = class Renderer {
|
|
|
961
1003
|
atom.jsxNode.destroy();
|
|
962
1004
|
}
|
|
963
1005
|
}
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
if (
|
|
968
|
-
|
|
969
|
-
const nativeNode = diffAtom.nativeNode;
|
|
970
|
-
start.nativeNode = nativeNode;
|
|
971
|
-
this.updateNativeNodeProperties(start.jsxNode, diffAtom.jsxNode, nativeNode);
|
|
972
|
-
oldChildren.splice(i, 1);
|
|
973
|
-
return diffAtom;
|
|
974
|
-
}
|
|
1006
|
+
temporarilyRemove(atom) {
|
|
1007
|
+
let next = atom.child;
|
|
1008
|
+
while (next) {
|
|
1009
|
+
if (next.jsxNode instanceof Component) {
|
|
1010
|
+
this.temporarilyRemove(next);
|
|
975
1011
|
}
|
|
976
|
-
else
|
|
977
|
-
|
|
978
|
-
const nativeNode = diffAtom.nativeNode;
|
|
979
|
-
if (start.jsxNode.text !== diffAtom.jsxNode.text) {
|
|
980
|
-
this.nativeRenderer.syncTextContent(nativeNode, start.jsxNode.text);
|
|
981
|
-
}
|
|
982
|
-
start.nativeNode = nativeNode;
|
|
983
|
-
oldChildren.splice(i, 1);
|
|
984
|
-
return diffAtom;
|
|
985
|
-
}
|
|
986
|
-
}
|
|
987
|
-
else if (diffAtom.jsxNode instanceof Component) {
|
|
988
|
-
if (start.jsxNode.setup === diffAtom.jsxNode.setup) {
|
|
989
|
-
const { isChanged } = getNodeChanges(start.jsxNode, diffAtom.jsxNode);
|
|
990
|
-
if (isChanged) {
|
|
991
|
-
diffAtom.jsxNode.invokePropsChangedHooks(start.jsxNode.config);
|
|
992
|
-
}
|
|
993
|
-
const newProps = start.jsxNode.props;
|
|
994
|
-
start.jsxNode = diffAtom.jsxNode;
|
|
995
|
-
start.jsxNode.props = newProps;
|
|
996
|
-
const { render } = this.componentAtomCaches.get(start.jsxNode);
|
|
997
|
-
const template = render();
|
|
998
|
-
if (template) {
|
|
999
|
-
this.linkTemplate(template, start.jsxNode, start);
|
|
1000
|
-
}
|
|
1001
|
-
this.componentAtomCaches.set(start.jsxNode, {
|
|
1002
|
-
render,
|
|
1003
|
-
atom: start
|
|
1004
|
-
});
|
|
1005
|
-
oldChildren.splice(i, 1);
|
|
1006
|
-
return diffAtom;
|
|
1007
|
-
}
|
|
1012
|
+
else {
|
|
1013
|
+
this.nativeRenderer.remove(next.nativeNode);
|
|
1008
1014
|
}
|
|
1015
|
+
next = next.sibling;
|
|
1009
1016
|
}
|
|
1010
|
-
return null;
|
|
1011
1017
|
}
|
|
1012
|
-
|
|
1013
|
-
if (atom.jsxNode instanceof
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
this.nativeRenderer.appendChild(nativeNode, child);
|
|
1020
|
-
}
|
|
1018
|
+
buildView(atom, context) {
|
|
1019
|
+
if (atom.jsxNode instanceof Component) {
|
|
1020
|
+
this.componentRender(atom.jsxNode, atom);
|
|
1021
|
+
let child = atom.child;
|
|
1022
|
+
while (child) {
|
|
1023
|
+
this.buildView(child, context);
|
|
1024
|
+
child = child.sibling;
|
|
1021
1025
|
}
|
|
1022
|
-
|
|
1026
|
+
atom.jsxNode.rendered();
|
|
1023
1027
|
}
|
|
1024
|
-
else
|
|
1025
|
-
|
|
1028
|
+
else {
|
|
1029
|
+
let nativeNode;
|
|
1030
|
+
let applyRefs = null;
|
|
1031
|
+
if (atom.jsxNode instanceof JSXElement) {
|
|
1032
|
+
const { nativeNode: n, applyRefs: a } = this.createElement(atom.jsxNode);
|
|
1033
|
+
nativeNode = n;
|
|
1034
|
+
applyRefs = a;
|
|
1035
|
+
}
|
|
1036
|
+
else {
|
|
1037
|
+
nativeNode = this.createTextNode(atom.jsxNode);
|
|
1038
|
+
}
|
|
1026
1039
|
atom.nativeNode = nativeNode;
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
const { template, render } = atom.jsxNode.init();
|
|
1030
|
-
this.componentAtomCaches.set(atom.jsxNode, {
|
|
1031
|
-
atom,
|
|
1032
|
-
render
|
|
1033
|
-
});
|
|
1034
|
-
if (template) {
|
|
1035
|
-
this.linkTemplate(template, atom.jsxNode, atom);
|
|
1036
|
-
}
|
|
1037
|
-
if (atom.child) {
|
|
1038
|
-
return this.buildView(atom.child);
|
|
1039
|
-
}
|
|
1040
|
-
return [];
|
|
1041
|
-
}
|
|
1042
|
-
buildView(chain) {
|
|
1043
|
-
const context = [];
|
|
1044
|
-
const children = [];
|
|
1045
|
-
function getContext() {
|
|
1046
|
-
return context[context.length - 1];
|
|
1047
|
-
}
|
|
1048
|
-
let atom = chain;
|
|
1049
|
-
const stopAtom = chain.parent;
|
|
1050
|
-
wrap: while (atom) {
|
|
1051
|
-
if (atom.jsxNode instanceof Component) {
|
|
1052
|
-
this.componentRender(atom.jsxNode, atom);
|
|
1053
|
-
if (atom.child) {
|
|
1054
|
-
atom = atom.child;
|
|
1055
|
-
continue;
|
|
1056
|
-
}
|
|
1057
|
-
atom.jsxNode.rendered();
|
|
1040
|
+
if (context.isParent) {
|
|
1041
|
+
this.nativeRenderer.prependChild(context.host, nativeNode);
|
|
1058
1042
|
}
|
|
1059
1043
|
else {
|
|
1060
|
-
|
|
1061
|
-
const nativeNode = atom.jsxNode instanceof JSXElement ? this.createElement(atom.jsxNode) : this.createTextNode(atom.jsxNode);
|
|
1062
|
-
atom.nativeNode = nativeNode;
|
|
1063
|
-
if (host) {
|
|
1064
|
-
this.nativeRenderer.appendChild(host, nativeNode);
|
|
1065
|
-
}
|
|
1066
|
-
else {
|
|
1067
|
-
children.push(nativeNode);
|
|
1068
|
-
}
|
|
1069
|
-
if (atom.child) {
|
|
1070
|
-
context.push(nativeNode);
|
|
1071
|
-
atom = atom.child;
|
|
1072
|
-
continue;
|
|
1073
|
-
}
|
|
1044
|
+
this.nativeRenderer.insertAfter(nativeNode, context.host);
|
|
1074
1045
|
}
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
}
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
}
|
|
1085
|
-
if (atom === stopAtom) {
|
|
1086
|
-
break wrap;
|
|
1087
|
-
}
|
|
1088
|
-
if (isComponent) {
|
|
1089
|
-
continue;
|
|
1046
|
+
if (atom.jsxNode instanceof JSXElement) {
|
|
1047
|
+
const childContext = {
|
|
1048
|
+
isParent: true,
|
|
1049
|
+
host: nativeNode
|
|
1050
|
+
};
|
|
1051
|
+
let child = atom.child;
|
|
1052
|
+
while (child) {
|
|
1053
|
+
this.buildView(child, childContext);
|
|
1054
|
+
child = child.sibling;
|
|
1090
1055
|
}
|
|
1091
|
-
|
|
1056
|
+
}
|
|
1057
|
+
context.host = nativeNode;
|
|
1058
|
+
context.isParent = false;
|
|
1059
|
+
if (applyRefs) {
|
|
1060
|
+
applyRefs();
|
|
1092
1061
|
}
|
|
1093
1062
|
}
|
|
1094
|
-
return children;
|
|
1095
1063
|
}
|
|
1096
|
-
componentRender(component,
|
|
1064
|
+
componentRender(component, from) {
|
|
1097
1065
|
const { template, render } = component.init();
|
|
1098
1066
|
if (template) {
|
|
1099
|
-
this.linkTemplate(template, component,
|
|
1067
|
+
this.linkTemplate(template, component, from);
|
|
1100
1068
|
}
|
|
1101
1069
|
this.componentAtomCaches.set(component, {
|
|
1102
1070
|
render,
|
|
1103
|
-
atom:
|
|
1071
|
+
atom: from
|
|
1104
1072
|
});
|
|
1105
|
-
return
|
|
1073
|
+
return from;
|
|
1106
1074
|
}
|
|
1107
1075
|
createChainByComponentFactory(context, factory, parent) {
|
|
1108
1076
|
const component = factory.createInstance(context);
|
|
@@ -1158,34 +1126,39 @@ let Renderer = class Renderer {
|
|
|
1158
1126
|
createElement(vNode) {
|
|
1159
1127
|
const nativeNode = this.nativeRenderer.createElement(vNode.name);
|
|
1160
1128
|
const props = vNode.props;
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
Object.keys(props.listeners).forEach(type => {
|
|
1175
|
-
this.nativeRenderer.listen(nativeNode, type, props.listeners[type]);
|
|
1176
|
-
});
|
|
1177
|
-
this.applyRefs(bindingRefs, nativeNode, true);
|
|
1129
|
+
let bindingRefs;
|
|
1130
|
+
props.attrs.forEach((value, key) => {
|
|
1131
|
+
if (key === refKey) {
|
|
1132
|
+
bindingRefs = value;
|
|
1133
|
+
return;
|
|
1134
|
+
}
|
|
1135
|
+
this.nativeRenderer.setProperty(nativeNode, key, value);
|
|
1136
|
+
});
|
|
1137
|
+
props.styles.forEach((value, key) => {
|
|
1138
|
+
this.nativeRenderer.setStyle(nativeNode, key, value);
|
|
1139
|
+
});
|
|
1140
|
+
if (props.classes) {
|
|
1141
|
+
this.nativeRenderer.setClass(nativeNode, props.classes);
|
|
1178
1142
|
}
|
|
1179
|
-
|
|
1143
|
+
Object.keys(props.listeners).forEach(type => {
|
|
1144
|
+
this.nativeRenderer.listen(nativeNode, type, props.listeners[type]);
|
|
1145
|
+
});
|
|
1146
|
+
return {
|
|
1147
|
+
nativeNode,
|
|
1148
|
+
applyRefs: () => {
|
|
1149
|
+
this.applyRefs(bindingRefs, nativeNode, true);
|
|
1150
|
+
}
|
|
1151
|
+
};
|
|
1180
1152
|
}
|
|
1181
1153
|
createTextNode(child) {
|
|
1182
1154
|
return this.nativeRenderer.createTextNode(child.text);
|
|
1183
1155
|
}
|
|
1184
1156
|
updateNativeNodeProperties(newVNode, oldVNode, nativeNode) {
|
|
1185
|
-
const
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
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);
|
|
1189
1162
|
styleChanges.remove.forEach(i => this.nativeRenderer.removeStyle(nativeNode, i[0]));
|
|
1190
1163
|
styleChanges.set.forEach(i => this.nativeRenderer.setStyle(nativeNode, i[0], i[1]));
|
|
1191
1164
|
let unBindRefs;
|
|
@@ -1204,16 +1177,19 @@ let Renderer = class Renderer {
|
|
|
1204
1177
|
}
|
|
1205
1178
|
this.nativeRenderer.setProperty(nativeNode, key, value);
|
|
1206
1179
|
});
|
|
1207
|
-
|
|
1208
|
-
|
|
1180
|
+
if (newProps.classes !== oldProps.classes) {
|
|
1181
|
+
this.nativeRenderer.setClass(nativeNode, newProps.classes);
|
|
1182
|
+
}
|
|
1209
1183
|
listenerChanges.remove.forEach(i => {
|
|
1210
1184
|
this.nativeRenderer.unListen(nativeNode, i[0], i[1]);
|
|
1211
1185
|
});
|
|
1212
1186
|
listenerChanges.add.forEach(i => {
|
|
1213
1187
|
this.nativeRenderer.listen(nativeNode, i[0], i[1]);
|
|
1214
1188
|
});
|
|
1215
|
-
|
|
1216
|
-
|
|
1189
|
+
return () => {
|
|
1190
|
+
this.applyRefs(unBindRefs, nativeNode, false);
|
|
1191
|
+
this.applyRefs(bindRefs, nativeNode, true);
|
|
1192
|
+
};
|
|
1217
1193
|
}
|
|
1218
1194
|
applyRefs(refs, nativeNode, binding) {
|
|
1219
1195
|
refs = Array.isArray(refs) ? refs : [refs];
|