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