@viewfly/core 0.0.29 → 0.0.31
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 +7 -1
- package/bundles/foundation/component.d.ts +15 -4
- package/bundles/foundation/jsx-element.d.ts +14 -28
- package/bundles/foundation/renderer.d.ts +1 -2
- package/bundles/foundation/root.component.d.ts +5 -4
- package/bundles/index.esm.js +224 -169
- package/bundles/index.js +224 -169
- package/bundles/viewfly.d.ts +2 -1
- package/package.json +2 -2
package/bundles/index.js
CHANGED
|
@@ -569,6 +569,23 @@ function getObjectChanges(newProps, oldProps) {
|
|
|
569
569
|
});
|
|
570
570
|
return changes;
|
|
571
571
|
}
|
|
572
|
+
function getArrayChanges(left, right) {
|
|
573
|
+
const changes = {
|
|
574
|
+
add: [],
|
|
575
|
+
remove: []
|
|
576
|
+
};
|
|
577
|
+
for (const i of left) {
|
|
578
|
+
if (!right.includes(i)) {
|
|
579
|
+
changes.remove.push(i);
|
|
580
|
+
}
|
|
581
|
+
}
|
|
582
|
+
for (const i of right) {
|
|
583
|
+
if (!left.includes(i)) {
|
|
584
|
+
changes.add.push(i);
|
|
585
|
+
}
|
|
586
|
+
}
|
|
587
|
+
return changes;
|
|
588
|
+
}
|
|
572
589
|
function classToString(config) {
|
|
573
590
|
if (!config) {
|
|
574
591
|
return '';
|
|
@@ -632,23 +649,52 @@ function getSignalDepsContext() {
|
|
|
632
649
|
* Viewfly 组件管理类,用于管理组件的生命周期,上下文等
|
|
633
650
|
*/
|
|
634
651
|
class Component extends ReflectiveInjector {
|
|
635
|
-
|
|
636
|
-
|
|
652
|
+
get dirty() {
|
|
653
|
+
return this._dirty;
|
|
654
|
+
}
|
|
655
|
+
get changed() {
|
|
656
|
+
return this._changed;
|
|
657
|
+
}
|
|
658
|
+
constructor(parentComponent, type, props, key) {
|
|
659
|
+
super(parentComponent, [{
|
|
637
660
|
provide: Injector,
|
|
638
661
|
useFactory: () => this
|
|
639
662
|
}]);
|
|
640
|
-
this.
|
|
663
|
+
this.parentComponent = parentComponent;
|
|
664
|
+
this.type = type;
|
|
641
665
|
this.props = props;
|
|
642
666
|
this.key = key;
|
|
667
|
+
this.$$typeOf = this.type;
|
|
643
668
|
this.destroyCallbacks = [];
|
|
644
669
|
this.mountCallbacks = [];
|
|
645
670
|
this.propsChangedCallbacks = [];
|
|
646
671
|
this.updatedCallbacks = [];
|
|
672
|
+
this.changedSubComponents = new Set();
|
|
673
|
+
this._dirty = true;
|
|
674
|
+
this._changed = true;
|
|
647
675
|
this.updatedDestroyCallbacks = [];
|
|
648
676
|
this.propsChangedDestroyCallbacks = [];
|
|
649
677
|
this.isFirstRending = true;
|
|
678
|
+
}
|
|
679
|
+
markAsDirtied() {
|
|
680
|
+
this._dirty = true;
|
|
681
|
+
this.markAsChanged();
|
|
682
|
+
}
|
|
683
|
+
markAsChanged(changedComponent) {
|
|
684
|
+
if (changedComponent) {
|
|
685
|
+
this.changedSubComponents.add(changedComponent);
|
|
686
|
+
}
|
|
687
|
+
if (this._changed) {
|
|
688
|
+
return;
|
|
689
|
+
}
|
|
690
|
+
this._changed = true;
|
|
691
|
+
if (this.parentComponent instanceof Component) {
|
|
692
|
+
this.parentComponent.markAsChanged(this);
|
|
693
|
+
}
|
|
694
|
+
}
|
|
695
|
+
render() {
|
|
650
696
|
const self = this;
|
|
651
|
-
const proxiesProps = new Proxy(props, {
|
|
697
|
+
const proxiesProps = new Proxy(this.props, {
|
|
652
698
|
get(_, key) {
|
|
653
699
|
// 必须用 self,因为 props 会随着页面更新变更,使用 self 才能更新引用
|
|
654
700
|
return self.props[key];
|
|
@@ -663,10 +709,10 @@ class Component extends ReflectiveInjector {
|
|
|
663
709
|
});
|
|
664
710
|
componentSetupStack.push(this);
|
|
665
711
|
let isSetup = true;
|
|
666
|
-
const render = this.
|
|
712
|
+
const render = this.type(proxiesProps);
|
|
667
713
|
const isRenderFn = typeof render === 'function';
|
|
668
714
|
this.instance = isRenderFn ? { $render: render } : render;
|
|
669
|
-
this.refs = toRefs(props.ref);
|
|
715
|
+
this.refs = toRefs(this.props.ref);
|
|
670
716
|
this.mountCallbacks.push(() => {
|
|
671
717
|
for (const ref of this.refs) {
|
|
672
718
|
ref.bind(this.instance);
|
|
@@ -679,13 +725,11 @@ class Component extends ReflectiveInjector {
|
|
|
679
725
|
});
|
|
680
726
|
isSetup = false;
|
|
681
727
|
componentSetupStack.pop();
|
|
682
|
-
}
|
|
683
|
-
render() {
|
|
684
728
|
signalDepsStack.push([]);
|
|
685
729
|
let template = this.instance.$render();
|
|
686
730
|
const deps = signalDepsStack.pop();
|
|
687
|
-
this.unWatch = useEffect(deps, () => {
|
|
688
|
-
this.
|
|
731
|
+
this.unWatch = useEffect(Array.from(new Set(deps)), () => {
|
|
732
|
+
this.markAsDirtied();
|
|
689
733
|
});
|
|
690
734
|
this.template = template;
|
|
691
735
|
return template;
|
|
@@ -717,8 +761,8 @@ class Component extends ReflectiveInjector {
|
|
|
717
761
|
signalDepsStack.push([]);
|
|
718
762
|
this.template = this.instance.$render();
|
|
719
763
|
const deps = signalDepsStack.pop();
|
|
720
|
-
this.unWatch = useEffect(deps, () => {
|
|
721
|
-
this.
|
|
764
|
+
this.unWatch = useEffect(Array.from(new Set(deps)), () => {
|
|
765
|
+
this.markAsDirtied();
|
|
722
766
|
});
|
|
723
767
|
return this.template;
|
|
724
768
|
}
|
|
@@ -727,8 +771,10 @@ class Component extends ReflectiveInjector {
|
|
|
727
771
|
this.normalizedProviders.unshift(...providers.map(i => normalizeProvider(i)));
|
|
728
772
|
}
|
|
729
773
|
rendered() {
|
|
774
|
+
this.changedSubComponents.clear();
|
|
730
775
|
const is = this.isFirstRending;
|
|
731
776
|
this.isFirstRending = false;
|
|
777
|
+
this._dirty = this._changed = false;
|
|
732
778
|
if (is) {
|
|
733
779
|
this.invokeUpdatedHooks();
|
|
734
780
|
this.invokeMountHooks();
|
|
@@ -976,10 +1022,48 @@ function invokeDepFn(fn) {
|
|
|
976
1022
|
const data = fn();
|
|
977
1023
|
signalDepsStack.pop();
|
|
978
1024
|
return {
|
|
979
|
-
deps,
|
|
1025
|
+
deps: Array.from(new Set(deps)),
|
|
980
1026
|
data
|
|
981
1027
|
};
|
|
982
1028
|
}
|
|
1029
|
+
function listen(model, deps, callback, isContinue) {
|
|
1030
|
+
let isStop = false;
|
|
1031
|
+
const nextListen = () => {
|
|
1032
|
+
if (isStop) {
|
|
1033
|
+
return;
|
|
1034
|
+
}
|
|
1035
|
+
isStop = true;
|
|
1036
|
+
const { data: nextData, deps: nextDeps } = invokeDepFn(callback);
|
|
1037
|
+
model.set(nextData);
|
|
1038
|
+
if (typeof isContinue === 'function' && isContinue(nextData) === false) {
|
|
1039
|
+
unListen();
|
|
1040
|
+
return;
|
|
1041
|
+
}
|
|
1042
|
+
const changes = getArrayChanges(deps, nextDeps);
|
|
1043
|
+
deps = deps.filter(i => {
|
|
1044
|
+
const has = changes.remove.includes(i);
|
|
1045
|
+
if (has) {
|
|
1046
|
+
i[depsKey].delete(nextListen);
|
|
1047
|
+
return false;
|
|
1048
|
+
}
|
|
1049
|
+
return true;
|
|
1050
|
+
});
|
|
1051
|
+
for (const s of changes.add) {
|
|
1052
|
+
s[depsKey].add(nextListen);
|
|
1053
|
+
}
|
|
1054
|
+
deps.push(...changes.add);
|
|
1055
|
+
isStop = false;
|
|
1056
|
+
};
|
|
1057
|
+
const unListen = () => {
|
|
1058
|
+
for (const s of deps) {
|
|
1059
|
+
s[depsKey].delete(nextListen);
|
|
1060
|
+
}
|
|
1061
|
+
};
|
|
1062
|
+
for (const s of deps) {
|
|
1063
|
+
s[depsKey].add(nextListen);
|
|
1064
|
+
}
|
|
1065
|
+
return unListen;
|
|
1066
|
+
}
|
|
983
1067
|
/**
|
|
984
1068
|
* 使用派生值,Viewfly 会收集回调函数内同步执行时访问的 Signal,
|
|
985
1069
|
* 并在你获取 useDerived 函数返回的 Signal 的值时,自动计算最新的值。
|
|
@@ -991,29 +1075,10 @@ function useDerived(callback, isContinue) {
|
|
|
991
1075
|
let { data, deps } = invokeDepFn(callback);
|
|
992
1076
|
const signal = useSignal(data);
|
|
993
1077
|
const component = getSetupContext(false);
|
|
994
|
-
const
|
|
995
|
-
function listen(model, deps, callback, unListenRef, isContinue) {
|
|
996
|
-
const nextListen = () => {
|
|
997
|
-
unListenRef.unListen();
|
|
998
|
-
const { data: nextData, deps: nextDeps } = invokeDepFn(callback);
|
|
999
|
-
model.set(nextData);
|
|
1000
|
-
if (typeof isContinue !== 'function' || isContinue(nextData) !== false) {
|
|
1001
|
-
listen(model, nextDeps, callback, unListenRef, isContinue);
|
|
1002
|
-
}
|
|
1003
|
-
};
|
|
1004
|
-
unListenRef.unListen = () => {
|
|
1005
|
-
for (const s of deps) {
|
|
1006
|
-
s[depsKey].delete(nextListen);
|
|
1007
|
-
}
|
|
1008
|
-
};
|
|
1009
|
-
for (const s of deps) {
|
|
1010
|
-
s[depsKey].add(nextListen);
|
|
1011
|
-
}
|
|
1012
|
-
}
|
|
1013
|
-
listen(signal, deps, callback, unListenRef, isContinue);
|
|
1078
|
+
const unListen = listen(signal, deps, callback, isContinue);
|
|
1014
1079
|
if (component) {
|
|
1015
1080
|
component.destroyCallbacks.push(() => {
|
|
1016
|
-
|
|
1081
|
+
unListen();
|
|
1017
1082
|
});
|
|
1018
1083
|
}
|
|
1019
1084
|
return signal;
|
|
@@ -1086,25 +1151,23 @@ function Fragment(props) {
|
|
|
1086
1151
|
}
|
|
1087
1152
|
function jsx(setup, props, key) {
|
|
1088
1153
|
if (typeof setup === 'string') {
|
|
1089
|
-
return JSXElement.
|
|
1154
|
+
return JSXElement.createInstance(setup, props, key);
|
|
1090
1155
|
}
|
|
1091
|
-
return
|
|
1092
|
-
return new Component(context,
|
|
1156
|
+
return JSXComponent.createInstance(setup, props, function (context) {
|
|
1157
|
+
return new Component(context, setup, props, key);
|
|
1093
1158
|
}, key);
|
|
1094
1159
|
}
|
|
1095
1160
|
const jsxs = jsx;
|
|
1161
|
+
const JSXTextTypeOf = Symbol('JSXText');
|
|
1096
1162
|
class JSXText {
|
|
1097
1163
|
constructor(text) {
|
|
1098
1164
|
this.text = text;
|
|
1099
|
-
this.$$typeOf =
|
|
1100
|
-
}
|
|
1101
|
-
is(target) {
|
|
1102
|
-
return target.$$typeOf === this.$$typeOf;
|
|
1165
|
+
this.$$typeOf = JSXTextTypeOf;
|
|
1103
1166
|
}
|
|
1104
1167
|
}
|
|
1105
1168
|
class JSXElement {
|
|
1106
|
-
static
|
|
1107
|
-
return new JSXElement(
|
|
1169
|
+
static createInstance(type, props, key) {
|
|
1170
|
+
return new JSXElement(type, props, key);
|
|
1108
1171
|
}
|
|
1109
1172
|
constructor(type, props, key) {
|
|
1110
1173
|
this.type = type;
|
|
@@ -1112,16 +1175,10 @@ class JSXElement {
|
|
|
1112
1175
|
this.key = key;
|
|
1113
1176
|
this.$$typeOf = this.type;
|
|
1114
1177
|
}
|
|
1115
|
-
is(target) {
|
|
1116
|
-
return target.$$typeOf === this.$$typeOf;
|
|
1117
|
-
}
|
|
1118
1178
|
}
|
|
1119
1179
|
class JSXComponent {
|
|
1120
|
-
|
|
1121
|
-
return
|
|
1122
|
-
}
|
|
1123
|
-
get changed() {
|
|
1124
|
-
return this._changed;
|
|
1180
|
+
static createInstance(type, props, factory, key) {
|
|
1181
|
+
return new JSXComponent(type, props, factory, key);
|
|
1125
1182
|
}
|
|
1126
1183
|
constructor(type, props, factory, key) {
|
|
1127
1184
|
this.type = type;
|
|
@@ -1129,37 +1186,9 @@ class JSXComponent {
|
|
|
1129
1186
|
this.factory = factory;
|
|
1130
1187
|
this.key = key;
|
|
1131
1188
|
this.$$typeOf = this.type;
|
|
1132
|
-
this.parentComponent = null;
|
|
1133
|
-
this.changedSubComponents = new Set();
|
|
1134
|
-
this._dirty = true;
|
|
1135
|
-
this._changed = true;
|
|
1136
1189
|
}
|
|
1137
|
-
|
|
1138
|
-
this.
|
|
1139
|
-
this.markAsChanged();
|
|
1140
|
-
}
|
|
1141
|
-
markAsChanged(changedComponent) {
|
|
1142
|
-
if (changedComponent) {
|
|
1143
|
-
this.changedSubComponents.add(changedComponent);
|
|
1144
|
-
}
|
|
1145
|
-
if (this._changed) {
|
|
1146
|
-
return;
|
|
1147
|
-
}
|
|
1148
|
-
this._changed = true;
|
|
1149
|
-
this.parentComponent.markAsChanged(this);
|
|
1150
|
-
}
|
|
1151
|
-
reset() {
|
|
1152
|
-
this.changedSubComponents.clear();
|
|
1153
|
-
this.instance.rendered();
|
|
1154
|
-
this._dirty = this._changed = false;
|
|
1155
|
-
}
|
|
1156
|
-
is(target) {
|
|
1157
|
-
return target.$$typeOf === this.$$typeOf;
|
|
1158
|
-
}
|
|
1159
|
-
createInstance(injector) {
|
|
1160
|
-
this.parentComponent = injector.jsxNode;
|
|
1161
|
-
this.instance = this.factory(injector, this);
|
|
1162
|
-
return this.instance;
|
|
1190
|
+
createInstance(parentComponent) {
|
|
1191
|
+
return this.factory(parentComponent);
|
|
1163
1192
|
}
|
|
1164
1193
|
}
|
|
1165
1194
|
|
|
@@ -1170,37 +1199,33 @@ function withMemo(canUseMemo, render) {
|
|
|
1170
1199
|
};
|
|
1171
1200
|
}
|
|
1172
1201
|
|
|
1173
|
-
function createRenderer(
|
|
1202
|
+
function createRenderer(component, nativeRenderer) {
|
|
1174
1203
|
let isInit = true;
|
|
1175
1204
|
return function render(host) {
|
|
1176
1205
|
if (isInit) {
|
|
1177
1206
|
isInit = false;
|
|
1178
1207
|
const atom = {
|
|
1179
|
-
jsxNode:
|
|
1208
|
+
jsxNode: component,
|
|
1180
1209
|
parent: null,
|
|
1181
1210
|
sibling: null,
|
|
1182
1211
|
child: null,
|
|
1183
1212
|
nativeNode: null
|
|
1184
1213
|
};
|
|
1185
|
-
|
|
1214
|
+
componentRender(nativeRenderer, component, atom, {
|
|
1186
1215
|
isParent: true,
|
|
1187
1216
|
host
|
|
1188
1217
|
});
|
|
1189
1218
|
}
|
|
1190
1219
|
else {
|
|
1191
|
-
updateView(nativeRenderer,
|
|
1220
|
+
updateView(nativeRenderer, component);
|
|
1192
1221
|
}
|
|
1193
1222
|
};
|
|
1194
1223
|
}
|
|
1195
1224
|
function buildView(nativeRenderer, parentComponent, atom, context) {
|
|
1196
1225
|
if (atom.jsxNode instanceof JSXComponent) {
|
|
1197
|
-
const component =
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
buildView(nativeRenderer, component, child, context);
|
|
1201
|
-
child = child.sibling;
|
|
1202
|
-
}
|
|
1203
|
-
atom.jsxNode.reset();
|
|
1226
|
+
const component = atom.jsxNode.createInstance(parentComponent);
|
|
1227
|
+
atom.jsxNode = component;
|
|
1228
|
+
componentRender(nativeRenderer, component, atom, context);
|
|
1204
1229
|
}
|
|
1205
1230
|
else {
|
|
1206
1231
|
let nativeNode;
|
|
@@ -1238,24 +1263,24 @@ function buildView(nativeRenderer, parentComponent, atom, context) {
|
|
|
1238
1263
|
}
|
|
1239
1264
|
}
|
|
1240
1265
|
}
|
|
1241
|
-
function updateView(nativeRenderer,
|
|
1242
|
-
if (
|
|
1243
|
-
applyChanges(nativeRenderer,
|
|
1244
|
-
|
|
1266
|
+
function updateView(nativeRenderer, component) {
|
|
1267
|
+
if (component.dirty) {
|
|
1268
|
+
applyChanges(nativeRenderer, component);
|
|
1269
|
+
component.rendered();
|
|
1245
1270
|
}
|
|
1246
|
-
else if (
|
|
1247
|
-
|
|
1271
|
+
else if (component.changed) {
|
|
1272
|
+
component.changedSubComponents.forEach(child => {
|
|
1248
1273
|
updateView(nativeRenderer, child);
|
|
1249
1274
|
});
|
|
1250
|
-
|
|
1275
|
+
component.rendered();
|
|
1251
1276
|
}
|
|
1252
1277
|
}
|
|
1253
|
-
function applyChanges(nativeRenderer,
|
|
1254
|
-
const { atom, host, isParent } =
|
|
1278
|
+
function applyChanges(nativeRenderer, component) {
|
|
1279
|
+
const { atom, host, isParent } = component.$$view;
|
|
1255
1280
|
const diffAtom = atom.child;
|
|
1256
|
-
const template =
|
|
1281
|
+
const template = component.update(component.props, true);
|
|
1257
1282
|
if (template) {
|
|
1258
|
-
linkTemplate(template,
|
|
1283
|
+
linkTemplate(template, component, atom);
|
|
1259
1284
|
}
|
|
1260
1285
|
else {
|
|
1261
1286
|
atom.child = null;
|
|
@@ -1264,34 +1289,47 @@ function applyChanges(nativeRenderer, jsxComponent) {
|
|
|
1264
1289
|
host,
|
|
1265
1290
|
isParent
|
|
1266
1291
|
};
|
|
1267
|
-
diff(nativeRenderer,
|
|
1292
|
+
diff(nativeRenderer, component, atom.child, diffAtom, context, 0, 0);
|
|
1268
1293
|
const next = atom.sibling;
|
|
1269
|
-
if (next && next.jsxNode instanceof
|
|
1294
|
+
if (next && next.jsxNode instanceof Component) {
|
|
1270
1295
|
next.jsxNode.$$view.host = context.host;
|
|
1271
1296
|
next.jsxNode.$$view.isParent = context.isParent;
|
|
1272
1297
|
}
|
|
1273
1298
|
}
|
|
1274
1299
|
function diff(nativeRenderer, parentComponent, newAtom, oldAtom, context, expectIndex, index) {
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1300
|
+
let prevDiffAtom = null;
|
|
1301
|
+
let firstDiffAtomIndexed = null;
|
|
1302
|
+
if (oldAtom) {
|
|
1303
|
+
prevDiffAtom = {
|
|
1278
1304
|
index,
|
|
1279
|
-
atom: oldAtom
|
|
1280
|
-
|
|
1281
|
-
|
|
1305
|
+
atom: oldAtom,
|
|
1306
|
+
prev: null
|
|
1307
|
+
};
|
|
1282
1308
|
index++;
|
|
1309
|
+
firstDiffAtomIndexed = prevDiffAtom;
|
|
1310
|
+
oldAtom = oldAtom.sibling;
|
|
1311
|
+
while (oldAtom) {
|
|
1312
|
+
const diffAtom = {
|
|
1313
|
+
index,
|
|
1314
|
+
atom: oldAtom,
|
|
1315
|
+
prev: prevDiffAtom
|
|
1316
|
+
};
|
|
1317
|
+
prevDiffAtom.next = diffAtom;
|
|
1318
|
+
prevDiffAtom = diffAtom;
|
|
1319
|
+
oldAtom = oldAtom.sibling;
|
|
1320
|
+
index++;
|
|
1321
|
+
}
|
|
1283
1322
|
}
|
|
1284
1323
|
const commits = [];
|
|
1285
1324
|
const changeCommits = {
|
|
1286
1325
|
updateComponent: (newAtom, reusedAtom, expectIndex, diffIndex) => {
|
|
1287
1326
|
commits.push((offset) => {
|
|
1288
|
-
const
|
|
1289
|
-
const instance = oldJSXComponent.instance;
|
|
1327
|
+
const instance = reusedAtom.jsxNode;
|
|
1290
1328
|
const newProps = newAtom.jsxNode.props;
|
|
1291
1329
|
const oldTemplate = instance.template;
|
|
1292
1330
|
const newTemplate = instance.update(newProps);
|
|
1293
|
-
|
|
1294
|
-
newAtom.jsxNode =
|
|
1331
|
+
instance.$$view = Object.assign({ atom: newAtom }, context);
|
|
1332
|
+
newAtom.jsxNode = instance;
|
|
1295
1333
|
if (newTemplate === oldTemplate) {
|
|
1296
1334
|
reuseComponentView(nativeRenderer, newAtom, reusedAtom, context, expectIndex !== diffIndex - offset);
|
|
1297
1335
|
return;
|
|
@@ -1309,7 +1347,7 @@ function diff(nativeRenderer, parentComponent, newAtom, oldAtom, context, expect
|
|
|
1309
1347
|
atom = atom.sibling;
|
|
1310
1348
|
}
|
|
1311
1349
|
}
|
|
1312
|
-
|
|
1350
|
+
instance.rendered();
|
|
1313
1351
|
});
|
|
1314
1352
|
},
|
|
1315
1353
|
updateElement: (newAtom, oldAtom, expectIndex, oldIndex) => {
|
|
@@ -1361,23 +1399,22 @@ function diff(nativeRenderer, parentComponent, newAtom, oldAtom, context, expect
|
|
|
1361
1399
|
}
|
|
1362
1400
|
};
|
|
1363
1401
|
while (newAtom) {
|
|
1364
|
-
createChanges(newAtom, expectIndex,
|
|
1402
|
+
firstDiffAtomIndexed = createChanges(newAtom, expectIndex, firstDiffAtomIndexed, changeCommits);
|
|
1365
1403
|
newAtom = newAtom.sibling;
|
|
1366
1404
|
expectIndex++;
|
|
1367
1405
|
}
|
|
1368
|
-
|
|
1369
|
-
|
|
1406
|
+
let dirtyDiffAtom = firstDiffAtomIndexed;
|
|
1407
|
+
while (dirtyDiffAtom) {
|
|
1408
|
+
cleanView(nativeRenderer, dirtyDiffAtom.atom, false);
|
|
1409
|
+
dirtyDiffAtom = dirtyDiffAtom.next;
|
|
1370
1410
|
}
|
|
1371
|
-
let j = 0;
|
|
1372
1411
|
let offset = 0;
|
|
1373
|
-
const len = oldChildren.length;
|
|
1374
1412
|
for (let i = 0; i < commits.length; i++) {
|
|
1375
1413
|
const commit = commits[i];
|
|
1376
|
-
while (
|
|
1377
|
-
|
|
1378
|
-
if (current.index <= i) {
|
|
1414
|
+
while (firstDiffAtomIndexed) {
|
|
1415
|
+
if (firstDiffAtomIndexed.index <= i) {
|
|
1379
1416
|
offset++;
|
|
1380
|
-
|
|
1417
|
+
firstDiffAtomIndexed = firstDiffAtomIndexed.next;
|
|
1381
1418
|
continue;
|
|
1382
1419
|
}
|
|
1383
1420
|
break;
|
|
@@ -1395,7 +1432,7 @@ function reuseComponentView(nativeRenderer, newAtom, reusedAtom, context, moveVi
|
|
|
1395
1432
|
child = child.sibling;
|
|
1396
1433
|
}
|
|
1397
1434
|
const updateContext = (atom) => {
|
|
1398
|
-
if (atom.jsxNode instanceof
|
|
1435
|
+
if (atom.jsxNode instanceof Component) {
|
|
1399
1436
|
let child = atom.child;
|
|
1400
1437
|
while (child) {
|
|
1401
1438
|
updateContext(child);
|
|
@@ -1419,17 +1456,19 @@ function reuseComponentView(nativeRenderer, newAtom, reusedAtom, context, moveVi
|
|
|
1419
1456
|
updateContext(atom);
|
|
1420
1457
|
}
|
|
1421
1458
|
}
|
|
1422
|
-
function createChanges(newAtom, expectIndex,
|
|
1423
|
-
|
|
1424
|
-
|
|
1459
|
+
function createChanges(newAtom, expectIndex, diffAtomIndexed, changeCommits) {
|
|
1460
|
+
const startDiffAtom = diffAtomIndexed;
|
|
1461
|
+
while (diffAtomIndexed) {
|
|
1462
|
+
const { atom: diffAtom, index: diffIndex } = diffAtomIndexed;
|
|
1425
1463
|
const key = newAtom.jsxNode.key;
|
|
1426
1464
|
const diffKey = diffAtom.jsxNode.key;
|
|
1427
1465
|
if (key !== undefined && diffKey !== undefined) {
|
|
1428
1466
|
if (diffKey !== key) {
|
|
1467
|
+
diffAtomIndexed = diffAtomIndexed.next;
|
|
1429
1468
|
continue;
|
|
1430
1469
|
}
|
|
1431
1470
|
}
|
|
1432
|
-
if (newAtom.jsxNode
|
|
1471
|
+
if (newAtom.jsxNode.$$typeOf === diffAtom.jsxNode.$$typeOf) {
|
|
1433
1472
|
if (newAtom.jsxNode instanceof JSXElement) {
|
|
1434
1473
|
changeCommits.updateElement(newAtom, diffAtom, expectIndex, diffIndex);
|
|
1435
1474
|
}
|
|
@@ -1439,11 +1478,25 @@ function createChanges(newAtom, expectIndex, oldChildren, changeCommits) {
|
|
|
1439
1478
|
else {
|
|
1440
1479
|
changeCommits.updateComponent(newAtom, diffAtom, expectIndex, diffIndex);
|
|
1441
1480
|
}
|
|
1442
|
-
|
|
1443
|
-
|
|
1481
|
+
const next = diffAtomIndexed.next;
|
|
1482
|
+
const prev = diffAtomIndexed.prev;
|
|
1483
|
+
if (!prev) {
|
|
1484
|
+
diffAtomIndexed = next;
|
|
1485
|
+
if (diffAtomIndexed) {
|
|
1486
|
+
diffAtomIndexed.prev = null;
|
|
1487
|
+
}
|
|
1488
|
+
return diffAtomIndexed;
|
|
1489
|
+
}
|
|
1490
|
+
prev.next = next;
|
|
1491
|
+
if (next) {
|
|
1492
|
+
next.prev = prev;
|
|
1493
|
+
}
|
|
1494
|
+
return startDiffAtom;
|
|
1444
1495
|
}
|
|
1496
|
+
diffAtomIndexed = diffAtomIndexed.next;
|
|
1445
1497
|
}
|
|
1446
1498
|
changeCommits.create(newAtom);
|
|
1499
|
+
return startDiffAtom;
|
|
1447
1500
|
}
|
|
1448
1501
|
function cleanView(nativeRenderer, atom, isClean) {
|
|
1449
1502
|
if (atom.nativeNode) {
|
|
@@ -1461,18 +1514,22 @@ function cleanView(nativeRenderer, atom, isClean) {
|
|
|
1461
1514
|
cleanView(nativeRenderer, child, isClean);
|
|
1462
1515
|
child = child.sibling;
|
|
1463
1516
|
}
|
|
1464
|
-
if (atom.jsxNode instanceof
|
|
1465
|
-
atom.jsxNode.
|
|
1517
|
+
if (atom.jsxNode instanceof Component) {
|
|
1518
|
+
atom.jsxNode.destroy();
|
|
1466
1519
|
}
|
|
1467
1520
|
}
|
|
1468
|
-
function componentRender(
|
|
1469
|
-
const component = jsxComponent.createInstance(parentComponent);
|
|
1521
|
+
function componentRender(nativeRenderer, component, from, context) {
|
|
1470
1522
|
const template = component.render();
|
|
1471
1523
|
if (template) {
|
|
1472
|
-
linkTemplate(template,
|
|
1524
|
+
linkTemplate(template, component, from);
|
|
1473
1525
|
}
|
|
1474
|
-
|
|
1475
|
-
|
|
1526
|
+
component.$$view = Object.assign({ atom: from }, context);
|
|
1527
|
+
let child = from.child;
|
|
1528
|
+
while (child) {
|
|
1529
|
+
buildView(nativeRenderer, component, child, context);
|
|
1530
|
+
child = child.sibling;
|
|
1531
|
+
}
|
|
1532
|
+
component.rendered();
|
|
1476
1533
|
}
|
|
1477
1534
|
function createChainByComponentFactory(jsxComponent, parent) {
|
|
1478
1535
|
return {
|
|
@@ -1483,7 +1540,7 @@ function createChainByComponentFactory(jsxComponent, parent) {
|
|
|
1483
1540
|
nativeNode: null
|
|
1484
1541
|
};
|
|
1485
1542
|
}
|
|
1486
|
-
function createChainByJSXElement(
|
|
1543
|
+
function createChainByJSXElement(component, element, parent) {
|
|
1487
1544
|
const atom = {
|
|
1488
1545
|
jsxNode: element,
|
|
1489
1546
|
parent,
|
|
@@ -1493,7 +1550,7 @@ function createChainByJSXElement(jsxComponent, element, parent) {
|
|
|
1493
1550
|
};
|
|
1494
1551
|
if (Reflect.has(element.props, 'children')) {
|
|
1495
1552
|
const jsxChildren = element.props.children;
|
|
1496
|
-
const children = createChainByChildren(
|
|
1553
|
+
const children = createChainByChildren(component, Array.isArray(jsxChildren) ? jsxChildren : [jsxChildren], atom, []);
|
|
1497
1554
|
link(atom, children);
|
|
1498
1555
|
}
|
|
1499
1556
|
return atom;
|
|
@@ -1507,34 +1564,34 @@ function createChainByJSXText(node, parent) {
|
|
|
1507
1564
|
nativeNode: null
|
|
1508
1565
|
};
|
|
1509
1566
|
}
|
|
1510
|
-
function createChainByChildren(
|
|
1567
|
+
function createChainByChildren(component, children, parent, atoms) {
|
|
1511
1568
|
for (const item of children) {
|
|
1512
|
-
if (item instanceof JSXElement) {
|
|
1513
|
-
atoms.push(createChainByJSXElement(jsxComponent, item, parent));
|
|
1514
|
-
continue;
|
|
1515
|
-
}
|
|
1516
|
-
if (item instanceof JSXComponent) {
|
|
1517
|
-
const childAtom = createChainByComponentFactory(item, parent);
|
|
1518
|
-
atoms.push(childAtom);
|
|
1519
|
-
continue;
|
|
1520
|
-
}
|
|
1521
|
-
if (typeof item === 'string' && item.length) {
|
|
1522
|
-
atoms.push(createChainByJSXText(new JSXText(item), parent));
|
|
1523
|
-
continue;
|
|
1524
|
-
}
|
|
1525
|
-
if (Array.isArray(item)) {
|
|
1526
|
-
createChainByChildren(jsxComponent, item, parent, atoms);
|
|
1527
|
-
continue;
|
|
1528
|
-
}
|
|
1529
1569
|
if (item !== null && typeof item !== 'undefined') {
|
|
1570
|
+
if (item instanceof JSXElement) {
|
|
1571
|
+
atoms.push(createChainByJSXElement(component, item, parent));
|
|
1572
|
+
continue;
|
|
1573
|
+
}
|
|
1574
|
+
if (item instanceof JSXComponent) {
|
|
1575
|
+
const childAtom = createChainByComponentFactory(item, parent);
|
|
1576
|
+
atoms.push(childAtom);
|
|
1577
|
+
continue;
|
|
1578
|
+
}
|
|
1579
|
+
if (typeof item === 'string' && item.length) {
|
|
1580
|
+
atoms.push(createChainByJSXText(new JSXText(item), parent));
|
|
1581
|
+
continue;
|
|
1582
|
+
}
|
|
1583
|
+
if (Array.isArray(item)) {
|
|
1584
|
+
createChainByChildren(component, item, parent, atoms);
|
|
1585
|
+
continue;
|
|
1586
|
+
}
|
|
1530
1587
|
atoms.push(createChainByJSXText(new JSXText(String(item)), parent));
|
|
1531
1588
|
}
|
|
1532
1589
|
}
|
|
1533
1590
|
return atoms;
|
|
1534
1591
|
}
|
|
1535
|
-
function linkTemplate(template,
|
|
1592
|
+
function linkTemplate(template, component, parent) {
|
|
1536
1593
|
const children = Array.isArray(template) ? template : [template];
|
|
1537
|
-
const newChildren = createChainByChildren(
|
|
1594
|
+
const newChildren = createChainByChildren(component, children, parent, []);
|
|
1538
1595
|
link(parent, newChildren);
|
|
1539
1596
|
}
|
|
1540
1597
|
function link(parent, children) {
|
|
@@ -1718,11 +1775,9 @@ function bindEvent(nativeRenderer, vNode, key, nativeNode, listenFn) {
|
|
|
1718
1775
|
/**
|
|
1719
1776
|
* Viewfly 根组件,用于实现组件状态更新事件通知
|
|
1720
1777
|
*/
|
|
1721
|
-
class RootComponent extends
|
|
1722
|
-
constructor(
|
|
1723
|
-
super(factory, {}
|
|
1724
|
-
return new Component(parentComponent, jsxNode, {});
|
|
1725
|
-
});
|
|
1778
|
+
class RootComponent extends Component {
|
|
1779
|
+
constructor(parentInjector, factory) {
|
|
1780
|
+
super(parentInjector, factory, {});
|
|
1726
1781
|
this.onChange = null;
|
|
1727
1782
|
}
|
|
1728
1783
|
markAsChanged(changedComponent) {
|
|
@@ -1739,13 +1794,13 @@ const viewflyErrorFn = makeError('Viewfly');
|
|
|
1739
1794
|
function viewfly({ context, nativeRenderer, autoUpdate, root }) {
|
|
1740
1795
|
const appProviders = [];
|
|
1741
1796
|
let destroyed = false;
|
|
1742
|
-
const rootComponent = new RootComponent(() => {
|
|
1797
|
+
const rootComponent = new RootComponent(context || null, () => {
|
|
1743
1798
|
provide(appProviders);
|
|
1744
1799
|
return () => {
|
|
1745
1800
|
return destroyed ? null : root;
|
|
1746
1801
|
};
|
|
1747
|
-
}
|
|
1748
|
-
const render = createRenderer(rootComponent, nativeRenderer
|
|
1802
|
+
});
|
|
1803
|
+
const render = createRenderer(rootComponent, nativeRenderer);
|
|
1749
1804
|
let isStarted = false;
|
|
1750
1805
|
let task = null;
|
|
1751
1806
|
function microTask(callback) {
|
package/bundles/viewfly.d.ts
CHANGED