@viewfly/core 1.0.0-alpha.2 → 1.0.0-alpha.20
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/index.d.ts +590 -0
- package/bundles/index.esm.js +239 -284
- package/bundles/index.js +239 -284
- package/jsx-runtime/index.d.ts +7 -7
- package/package.json +9 -6
- package/rollup-d.config.ts +14 -0
- package/bundles/_utils/make-error.d.ts +0 -1
- package/bundles/di/_api.d.ts +0 -10
- package/bundles/di/forward-ref.d.ts +0 -10
- package/bundles/di/injectable.d.ts +0 -20
- package/bundles/di/injection-token.d.ts +0 -8
- package/bundles/di/injector.d.ts +0 -26
- package/bundles/di/metadata.d.ts +0 -43
- package/bundles/di/null-injector.d.ts +0 -6
- package/bundles/di/provider.d.ts +0 -30
- package/bundles/di/reflective-injector.d.ts +0 -31
- package/bundles/di/reflective-provider.d.ts +0 -20
- package/bundles/di/type.d.ts +0 -7
- package/bundles/di/utils/_api.d.ts +0 -3
- package/bundles/di/utils/annotations.d.ts +0 -33
- package/bundles/di/utils/decorators.d.ts +0 -17
- package/bundles/di/utils/stringify.d.ts +0 -1
- package/bundles/foundation/_api.d.ts +0 -8
- package/bundles/foundation/_utils.d.ts +0 -52
- package/bundles/foundation/component.d.ts +0 -245
- package/bundles/foundation/injection-tokens.d.ts +0 -18
- package/bundles/foundation/jsx-element.d.ts +0 -19
- package/bundles/foundation/memo.d.ts +0 -2
- package/bundles/foundation/renderer.d.ts +0 -3
- package/bundles/foundation/root.component.d.ts +0 -10
- package/bundles/foundation/types.d.ts +0 -43
- package/bundles/public-api.d.ts +0 -5
- package/bundles/viewfly.d.ts +0 -29
package/bundles/index.js
CHANGED
|
@@ -163,6 +163,40 @@ exports.InjectFlags = void 0;
|
|
|
163
163
|
class Injector {
|
|
164
164
|
}
|
|
165
165
|
|
|
166
|
+
/**
|
|
167
|
+
* 构造函数参数装饰器,用于改变注入 token
|
|
168
|
+
*/
|
|
169
|
+
const Inject = function InjectDecorator(token) {
|
|
170
|
+
if (this instanceof Inject) {
|
|
171
|
+
this.token = token;
|
|
172
|
+
}
|
|
173
|
+
else {
|
|
174
|
+
return makeParamDecorator(Inject, new Inject(token));
|
|
175
|
+
}
|
|
176
|
+
};
|
|
177
|
+
const Self = function SelfDecorator() {
|
|
178
|
+
if (!(this instanceof Self)) {
|
|
179
|
+
return makeParamDecorator(Self, new Self());
|
|
180
|
+
}
|
|
181
|
+
};
|
|
182
|
+
const SkipSelf = function SkipSelfDecorator() {
|
|
183
|
+
if (!(this instanceof SkipSelf)) {
|
|
184
|
+
return makeParamDecorator(SkipSelf, new SkipSelf());
|
|
185
|
+
}
|
|
186
|
+
};
|
|
187
|
+
const Optional = function OptionalDecorator() {
|
|
188
|
+
if (!(this instanceof Optional)) {
|
|
189
|
+
return makeParamDecorator(Optional, new Optional());
|
|
190
|
+
}
|
|
191
|
+
};
|
|
192
|
+
const Prop = function PropDecorator(token, notFoundValue, flags) {
|
|
193
|
+
if (!(this instanceof Prop)) {
|
|
194
|
+
return makePropertyDecorator(Prop, token, function (instance, propertyName, token, injector) {
|
|
195
|
+
instance[propertyName] = injector.get(token instanceof ForwardRef ? token.getRef() : token, notFoundValue, flags);
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
};
|
|
199
|
+
|
|
166
200
|
function stringify(token) {
|
|
167
201
|
if (typeof token === 'string') {
|
|
168
202
|
return token;
|
|
@@ -202,12 +236,12 @@ const THROW_IF_NOT_FOUND = {
|
|
|
202
236
|
const nullInjectorErrorFn = (token) => {
|
|
203
237
|
return makeError('NullInjector')(`No provide for \`${stringify(token)}\`!`);
|
|
204
238
|
};
|
|
205
|
-
class NullInjector
|
|
239
|
+
class NullInjector {
|
|
206
240
|
constructor() {
|
|
207
|
-
super(...arguments);
|
|
208
241
|
this.parentInjector = null;
|
|
209
242
|
}
|
|
210
|
-
|
|
243
|
+
/* eslint-disable-next-line */
|
|
244
|
+
get(token, notFoundValue = THROW_IF_NOT_FOUND, _) {
|
|
211
245
|
if (notFoundValue === THROW_IF_NOT_FOUND) {
|
|
212
246
|
throw nullInjectorErrorFn(token);
|
|
213
247
|
}
|
|
@@ -215,40 +249,6 @@ class NullInjector extends Injector {
|
|
|
215
249
|
}
|
|
216
250
|
}
|
|
217
251
|
|
|
218
|
-
/**
|
|
219
|
-
* 构造函数参数装饰器,用于改变注入 token
|
|
220
|
-
*/
|
|
221
|
-
const Inject = function InjectDecorator(token) {
|
|
222
|
-
if (this instanceof Inject) {
|
|
223
|
-
this.token = token;
|
|
224
|
-
}
|
|
225
|
-
else {
|
|
226
|
-
return makeParamDecorator(Inject, new Inject(token));
|
|
227
|
-
}
|
|
228
|
-
};
|
|
229
|
-
const Self = function SelfDecorator() {
|
|
230
|
-
if (!(this instanceof Self)) {
|
|
231
|
-
return makeParamDecorator(Self, new Self());
|
|
232
|
-
}
|
|
233
|
-
};
|
|
234
|
-
const SkipSelf = function SkipSelfDecorator() {
|
|
235
|
-
if (!(this instanceof SkipSelf)) {
|
|
236
|
-
return makeParamDecorator(SkipSelf, new SkipSelf());
|
|
237
|
-
}
|
|
238
|
-
};
|
|
239
|
-
const Optional = function OptionalDecorator() {
|
|
240
|
-
if (!(this instanceof Optional)) {
|
|
241
|
-
return makeParamDecorator(Optional, new Optional());
|
|
242
|
-
}
|
|
243
|
-
};
|
|
244
|
-
const Prop = function PropDecorator(token, flags, notFoundValue = THROW_IF_NOT_FOUND) {
|
|
245
|
-
if (!(this instanceof Prop)) {
|
|
246
|
-
return makePropertyDecorator(Prop, token, function (instance, propertyName, token, injector) {
|
|
247
|
-
instance[propertyName] = injector.get(token instanceof ForwardRef ? token.getRef() : token, flags, notFoundValue);
|
|
248
|
-
});
|
|
249
|
-
}
|
|
250
|
-
};
|
|
251
|
-
|
|
252
252
|
/**
|
|
253
253
|
* 标准化 provide,并返回统一数据结构
|
|
254
254
|
* @param provider
|
|
@@ -412,11 +412,9 @@ const provideScopeError = (token) => {
|
|
|
412
412
|
/**
|
|
413
413
|
* 反射注入器
|
|
414
414
|
*/
|
|
415
|
-
class ReflectiveInjector
|
|
415
|
+
class ReflectiveInjector {
|
|
416
416
|
constructor(parentInjector, staticProviders, scope) {
|
|
417
|
-
super();
|
|
418
417
|
this.parentInjector = parentInjector;
|
|
419
|
-
this.staticProviders = staticProviders;
|
|
420
418
|
this.scope = scope;
|
|
421
419
|
this.recordValues = new Map();
|
|
422
420
|
this.normalizedProviders = staticProviders.map(provide => {
|
|
@@ -426,15 +424,15 @@ class ReflectiveInjector extends Injector {
|
|
|
426
424
|
/**
|
|
427
425
|
* 用于获取当前注入器上下文内的实例、对象或数据
|
|
428
426
|
* @param token 访问 token
|
|
429
|
-
* @param flags 查询规则
|
|
430
427
|
* @param notFoundValue 如未查找到的返回值
|
|
428
|
+
* @param flags 查询规则
|
|
431
429
|
*/
|
|
432
|
-
get(token,
|
|
430
|
+
get(token, notFoundValue = THROW_IF_NOT_FOUND, flags) {
|
|
433
431
|
var _a;
|
|
434
432
|
flags = flags || exports.InjectFlags.Default;
|
|
435
433
|
if (flags === exports.InjectFlags.SkipSelf) {
|
|
436
434
|
if (this.parentInjector) {
|
|
437
|
-
return this.parentInjector.get(token,
|
|
435
|
+
return this.parentInjector.get(token, notFoundValue);
|
|
438
436
|
}
|
|
439
437
|
if (notFoundValue !== THROW_IF_NOT_FOUND) {
|
|
440
438
|
return notFoundValue;
|
|
@@ -478,9 +476,12 @@ class ReflectiveInjector extends Injector {
|
|
|
478
476
|
return notFoundValue;
|
|
479
477
|
}
|
|
480
478
|
if (this.parentInjector) {
|
|
481
|
-
return this.parentInjector.get(token, flags === exports.InjectFlags.Optional ? exports.InjectFlags.Optional : exports.InjectFlags.Default
|
|
479
|
+
return this.parentInjector.get(token, notFoundValue, flags === exports.InjectFlags.Optional ? exports.InjectFlags.Optional : exports.InjectFlags.Default);
|
|
482
480
|
}
|
|
483
481
|
if (notFoundValue === THROW_IF_NOT_FOUND) {
|
|
482
|
+
// if (flags === InjectFlags.Optional) {
|
|
483
|
+
// return null as U
|
|
484
|
+
// }
|
|
484
485
|
throw reflectiveInjectorErrorFn(token);
|
|
485
486
|
}
|
|
486
487
|
return notFoundValue;
|
|
@@ -510,11 +511,11 @@ class ReflectiveInjector extends Injector {
|
|
|
510
511
|
const tryValue = {};
|
|
511
512
|
const injectToken = dep.injectKey instanceof ForwardRef ? dep.injectKey.getRef() : dep.injectKey;
|
|
512
513
|
if (dep.visibility instanceof Self) {
|
|
513
|
-
reflectiveValue = this.get(injectToken, exports.InjectFlags.Self
|
|
514
|
+
reflectiveValue = this.get(injectToken, tryValue, exports.InjectFlags.Self);
|
|
514
515
|
}
|
|
515
516
|
else if (dep.visibility instanceof SkipSelf) {
|
|
516
517
|
if (this.parentInjector) {
|
|
517
|
-
reflectiveValue = this.parentInjector.get(injectToken,
|
|
518
|
+
reflectiveValue = this.parentInjector.get(injectToken, tryValue);
|
|
518
519
|
}
|
|
519
520
|
else {
|
|
520
521
|
if (dep.optional) {
|
|
@@ -527,7 +528,7 @@ class ReflectiveInjector extends Injector {
|
|
|
527
528
|
}
|
|
528
529
|
}
|
|
529
530
|
else {
|
|
530
|
-
reflectiveValue = this.get(injectToken,
|
|
531
|
+
reflectiveValue = this.get(injectToken, tryValue);
|
|
531
532
|
}
|
|
532
533
|
if (reflectiveValue === tryValue) {
|
|
533
534
|
if (dep.optional) {
|
|
@@ -589,13 +590,13 @@ function getArrayChanges(left, right) {
|
|
|
589
590
|
return changes;
|
|
590
591
|
}
|
|
591
592
|
function classToString(config) {
|
|
592
|
-
if (!config) {
|
|
593
|
-
return '';
|
|
594
|
-
}
|
|
595
593
|
if (typeof config === 'string') {
|
|
596
594
|
return config;
|
|
597
595
|
}
|
|
598
|
-
|
|
596
|
+
if (!config) {
|
|
597
|
+
return '';
|
|
598
|
+
}
|
|
599
|
+
if (Array.isArray(config)) {
|
|
599
600
|
const classes = [];
|
|
600
601
|
for (const i of config) {
|
|
601
602
|
const v = classToString(i);
|
|
@@ -605,7 +606,7 @@ function classToString(config) {
|
|
|
605
606
|
}
|
|
606
607
|
return classes.join(' ');
|
|
607
608
|
}
|
|
608
|
-
|
|
609
|
+
if (typeof config === 'object') {
|
|
609
610
|
if (config.toString !== Object.prototype.toString && !config.toString.toString().includes('[native code]')) {
|
|
610
611
|
return config.toString();
|
|
611
612
|
}
|
|
@@ -632,6 +633,9 @@ function styleToObject(style) {
|
|
|
632
633
|
});
|
|
633
634
|
return obj;
|
|
634
635
|
}
|
|
636
|
+
const TextAtomType = Symbol('Text');
|
|
637
|
+
const ElementAtomType = Symbol('Element');
|
|
638
|
+
const ComponentAtomType = Symbol('Component');
|
|
635
639
|
|
|
636
640
|
const componentSetupStack = [];
|
|
637
641
|
const signalDepsStack = [];
|
|
@@ -740,28 +744,31 @@ class Component extends ReflectiveInjector {
|
|
|
740
744
|
}
|
|
741
745
|
update(newProps, forceUpdate = false) {
|
|
742
746
|
const oldProps = this.props;
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
747
|
+
if (!forceUpdate) {
|
|
748
|
+
const { add, remove, replace } = getObjectChanges(newProps, oldProps);
|
|
749
|
+
if (add.length || remove.length || replace.length) {
|
|
750
|
+
this.invokePropsChangedHooks(newProps);
|
|
751
|
+
}
|
|
752
|
+
else if (!this.dirty) {
|
|
753
|
+
this.props = newProps;
|
|
754
|
+
return this.template;
|
|
755
|
+
}
|
|
756
|
+
const newRefs = toRefs(newProps.ref);
|
|
757
|
+
if (this.refs) {
|
|
758
|
+
for (const oldRef of this.refs) {
|
|
759
|
+
if (!newRefs.includes(oldRef)) {
|
|
760
|
+
oldRef.unBind(this.instance);
|
|
761
|
+
}
|
|
755
762
|
}
|
|
756
763
|
}
|
|
764
|
+
for (const newRef of newRefs) {
|
|
765
|
+
newRef.bind(this.instance);
|
|
766
|
+
}
|
|
767
|
+
if (newRefs.length) {
|
|
768
|
+
this.refs = newRefs;
|
|
769
|
+
}
|
|
757
770
|
}
|
|
758
|
-
|
|
759
|
-
newRef.bind(this.instance);
|
|
760
|
-
}
|
|
761
|
-
if (newRefs.length) {
|
|
762
|
-
this.refs = newRefs;
|
|
763
|
-
}
|
|
764
|
-
if (!forceUpdate && typeof this.instance.$useMemo === 'function') {
|
|
771
|
+
if (typeof this.instance.$useMemo === 'function') {
|
|
765
772
|
if (this.instance.$useMemo(newProps, oldProps)) {
|
|
766
773
|
return this.template;
|
|
767
774
|
}
|
|
@@ -845,7 +852,12 @@ class Component extends ReflectiveInjector {
|
|
|
845
852
|
}
|
|
846
853
|
}
|
|
847
854
|
if (unmountedCallbacks.length) {
|
|
848
|
-
this.unmountedCallbacks
|
|
855
|
+
if (this.unmountedCallbacks) {
|
|
856
|
+
this.unmountedCallbacks.push(...unmountedCallbacks);
|
|
857
|
+
}
|
|
858
|
+
else {
|
|
859
|
+
this.unmountedCallbacks = unmountedCallbacks;
|
|
860
|
+
}
|
|
849
861
|
}
|
|
850
862
|
this.mountCallbacks = null;
|
|
851
863
|
}
|
|
@@ -1234,9 +1246,9 @@ function withAnnotation(annotation, componentSetup) {
|
|
|
1234
1246
|
/**
|
|
1235
1247
|
* 通过组件上下文获取 IoC 容器内数据的勾子方法
|
|
1236
1248
|
*/
|
|
1237
|
-
function inject(token,
|
|
1249
|
+
function inject(token, notFoundValue = THROW_IF_NOT_FOUND, flags) {
|
|
1238
1250
|
const component = getSetupContext();
|
|
1239
|
-
return component.get(token,
|
|
1251
|
+
return component.get(token, notFoundValue, flags);
|
|
1240
1252
|
}
|
|
1241
1253
|
/**
|
|
1242
1254
|
* 获取当前组件实例
|
|
@@ -1274,14 +1286,17 @@ function withMemo(canUseMemo, render) {
|
|
|
1274
1286
|
};
|
|
1275
1287
|
}
|
|
1276
1288
|
|
|
1277
|
-
const
|
|
1289
|
+
const componentViewCache = new WeakMap();
|
|
1290
|
+
const listenerReg = /^on[A-Z]/;
|
|
1278
1291
|
function createRenderer(component, nativeRenderer) {
|
|
1279
1292
|
let isInit = true;
|
|
1280
1293
|
return function render(host) {
|
|
1281
1294
|
if (isInit) {
|
|
1282
1295
|
isInit = false;
|
|
1283
1296
|
const atom = {
|
|
1284
|
-
type:
|
|
1297
|
+
type: ComponentAtomType,
|
|
1298
|
+
index: 0,
|
|
1299
|
+
nodeType: component.type,
|
|
1285
1300
|
jsxNode: component,
|
|
1286
1301
|
sibling: null,
|
|
1287
1302
|
child: null,
|
|
@@ -1301,41 +1316,28 @@ function createRenderer(component, nativeRenderer) {
|
|
|
1301
1316
|
}
|
|
1302
1317
|
function buildView(nativeRenderer, parentComponent, atom, context) {
|
|
1303
1318
|
const { jsxNode, type } = atom;
|
|
1304
|
-
if (type ===
|
|
1319
|
+
if (type === ComponentAtomType) {
|
|
1305
1320
|
const component = new Component(parentComponent, jsxNode.type, jsxNode.props, jsxNode.key);
|
|
1306
1321
|
atom.jsxNode = component;
|
|
1307
1322
|
componentRender(nativeRenderer, component, atom, context);
|
|
1308
1323
|
}
|
|
1324
|
+
else if (type === ElementAtomType) {
|
|
1325
|
+
createElement(nativeRenderer, atom, parentComponent, context);
|
|
1326
|
+
}
|
|
1309
1327
|
else {
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
const childContext = {
|
|
1324
|
-
isParent: true,
|
|
1325
|
-
host: nativeNode,
|
|
1326
|
-
rootHost: context.rootHost
|
|
1327
|
-
};
|
|
1328
|
-
let child = atom.child;
|
|
1329
|
-
while (child) {
|
|
1330
|
-
buildView(nativeRenderer, parentComponent, child, childContext);
|
|
1331
|
-
child = child.sibling;
|
|
1332
|
-
}
|
|
1333
|
-
}
|
|
1334
|
-
context.host = nativeNode;
|
|
1335
|
-
context.isParent = false;
|
|
1336
|
-
if (applyRefs) {
|
|
1337
|
-
applyRefs();
|
|
1338
|
-
}
|
|
1328
|
+
createTextNode(nativeRenderer, atom, context);
|
|
1329
|
+
}
|
|
1330
|
+
}
|
|
1331
|
+
function buildElementChildren(atom, nativeRenderer, parentComponent, context) {
|
|
1332
|
+
const childContext = {
|
|
1333
|
+
isParent: true,
|
|
1334
|
+
host: atom.nativeNode,
|
|
1335
|
+
rootHost: context.rootHost
|
|
1336
|
+
};
|
|
1337
|
+
let child = atom.child;
|
|
1338
|
+
while (child) {
|
|
1339
|
+
buildView(nativeRenderer, parentComponent, child, childContext);
|
|
1340
|
+
child = child.sibling;
|
|
1339
1341
|
}
|
|
1340
1342
|
}
|
|
1341
1343
|
function updateView(nativeRenderer, component) {
|
|
@@ -1351,7 +1353,7 @@ function updateView(nativeRenderer, component) {
|
|
|
1351
1353
|
}
|
|
1352
1354
|
}
|
|
1353
1355
|
function applyChanges(nativeRenderer, component) {
|
|
1354
|
-
const { atom, host, isParent, rootHost } = component
|
|
1356
|
+
const { atom, host, isParent, rootHost } = componentViewCache.get(component);
|
|
1355
1357
|
const diffAtom = atom.child;
|
|
1356
1358
|
const template = component.update(component.props, true);
|
|
1357
1359
|
atom.child = createChildChain(template, atom.isSvg);
|
|
@@ -1360,58 +1362,35 @@ function applyChanges(nativeRenderer, component) {
|
|
|
1360
1362
|
isParent,
|
|
1361
1363
|
rootHost
|
|
1362
1364
|
};
|
|
1363
|
-
diff(nativeRenderer, component, atom.child, diffAtom, context
|
|
1365
|
+
diff(nativeRenderer, component, atom.child, diffAtom, context);
|
|
1364
1366
|
const next = atom.sibling;
|
|
1365
1367
|
if (next && next.jsxNode instanceof Component) {
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
}
|
|
1370
|
-
function diff(nativeRenderer, parentComponent, newAtom, oldAtom, context, expectIndex, index) {
|
|
1371
|
-
let prevDiffAtom = null;
|
|
1372
|
-
let firstDiffAtomIndexed = null;
|
|
1373
|
-
if (oldAtom) {
|
|
1374
|
-
prevDiffAtom = {
|
|
1375
|
-
index,
|
|
1376
|
-
atom: oldAtom,
|
|
1377
|
-
prev: null
|
|
1378
|
-
};
|
|
1379
|
-
index++;
|
|
1380
|
-
firstDiffAtomIndexed = prevDiffAtom;
|
|
1381
|
-
oldAtom = oldAtom.sibling;
|
|
1382
|
-
while (oldAtom) {
|
|
1383
|
-
const diffAtom = {
|
|
1384
|
-
index,
|
|
1385
|
-
atom: oldAtom,
|
|
1386
|
-
prev: prevDiffAtom
|
|
1387
|
-
};
|
|
1388
|
-
prevDiffAtom.next = diffAtom;
|
|
1389
|
-
prevDiffAtom = diffAtom;
|
|
1390
|
-
oldAtom = oldAtom.sibling;
|
|
1391
|
-
index++;
|
|
1392
|
-
}
|
|
1368
|
+
const view = componentViewCache.get(next.jsxNode);
|
|
1369
|
+
view.host = context.host;
|
|
1370
|
+
view.isParent = context.isParent;
|
|
1393
1371
|
}
|
|
1372
|
+
}
|
|
1373
|
+
function diff(nativeRenderer, parentComponent, newAtom, oldAtom, context) {
|
|
1394
1374
|
const commits = [];
|
|
1395
1375
|
function changeOffset() {
|
|
1396
1376
|
offset++;
|
|
1397
1377
|
}
|
|
1398
1378
|
while (newAtom) {
|
|
1399
|
-
|
|
1379
|
+
oldAtom = createChanges(newAtom, oldAtom, nativeRenderer, commits, context, parentComponent, changeOffset);
|
|
1400
1380
|
newAtom = newAtom.sibling;
|
|
1401
|
-
expectIndex++;
|
|
1402
1381
|
}
|
|
1403
|
-
let dirtyDiffAtom =
|
|
1382
|
+
let dirtyDiffAtom = oldAtom;
|
|
1404
1383
|
while (dirtyDiffAtom) {
|
|
1405
|
-
cleanView(nativeRenderer, dirtyDiffAtom
|
|
1406
|
-
dirtyDiffAtom = dirtyDiffAtom.
|
|
1384
|
+
cleanView(nativeRenderer, dirtyDiffAtom, true);
|
|
1385
|
+
dirtyDiffAtom = dirtyDiffAtom.sibling;
|
|
1407
1386
|
}
|
|
1408
1387
|
let offset = 0;
|
|
1409
1388
|
for (let i = 0; i < commits.length; i++) {
|
|
1410
1389
|
const commit = commits[i];
|
|
1411
|
-
while (
|
|
1412
|
-
if (
|
|
1390
|
+
while (oldAtom) {
|
|
1391
|
+
if (oldAtom.index <= i) {
|
|
1413
1392
|
offset--;
|
|
1414
|
-
|
|
1393
|
+
oldAtom = oldAtom.sibling;
|
|
1415
1394
|
continue;
|
|
1416
1395
|
}
|
|
1417
1396
|
break;
|
|
@@ -1419,47 +1398,32 @@ function diff(nativeRenderer, parentComponent, newAtom, oldAtom, context, expect
|
|
|
1419
1398
|
commit(offset);
|
|
1420
1399
|
}
|
|
1421
1400
|
}
|
|
1422
|
-
function createChanges(newAtom,
|
|
1423
|
-
const startDiffAtom =
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
if (type === diffAtom.type) {
|
|
1401
|
+
function createChanges(newAtom, oldAtom, nativeRenderer, commits, context, parentComponent, effect) {
|
|
1402
|
+
const startDiffAtom = oldAtom;
|
|
1403
|
+
let prev = null;
|
|
1404
|
+
while (oldAtom) {
|
|
1405
|
+
const newAtomType = newAtom.type;
|
|
1406
|
+
if (oldAtom.type === newAtomType && oldAtom.nodeType === newAtom.nodeType && oldAtom.key === newAtom.key) {
|
|
1429
1407
|
let commit;
|
|
1430
|
-
if (
|
|
1431
|
-
commit = updateText(newAtom,
|
|
1408
|
+
if (newAtomType === TextAtomType) {
|
|
1409
|
+
commit = updateText(newAtom, oldAtom, nativeRenderer, context);
|
|
1410
|
+
}
|
|
1411
|
+
else if (newAtomType === ComponentAtomType) {
|
|
1412
|
+
commit = updateComponent(newAtom, oldAtom, nativeRenderer, context);
|
|
1432
1413
|
}
|
|
1433
1414
|
else {
|
|
1434
|
-
|
|
1435
|
-
if (diffKey !== key || newJsxNode.type !== diffType) {
|
|
1436
|
-
diffAtomIndexed = diffAtomIndexed.next;
|
|
1437
|
-
continue;
|
|
1438
|
-
}
|
|
1439
|
-
if (type === 'component') {
|
|
1440
|
-
commit = updateComponent(newAtom, diffAtom, expectIndex, diffIndex, nativeRenderer, context);
|
|
1441
|
-
}
|
|
1442
|
-
else {
|
|
1443
|
-
commit = updateElement(newAtom, diffAtom, expectIndex, diffIndex, nativeRenderer, context, parentComponent);
|
|
1444
|
-
}
|
|
1415
|
+
commit = updateElement(newAtom, oldAtom, nativeRenderer, context, parentComponent);
|
|
1445
1416
|
}
|
|
1446
1417
|
commits.push(commit);
|
|
1447
|
-
const next =
|
|
1448
|
-
const prev = diffAtomIndexed.prev;
|
|
1418
|
+
const next = oldAtom.sibling;
|
|
1449
1419
|
if (!prev) {
|
|
1450
|
-
|
|
1451
|
-
if (diffAtomIndexed) {
|
|
1452
|
-
diffAtomIndexed.prev = null;
|
|
1453
|
-
}
|
|
1454
|
-
return diffAtomIndexed;
|
|
1455
|
-
}
|
|
1456
|
-
prev.next = next;
|
|
1457
|
-
if (next) {
|
|
1458
|
-
next.prev = prev;
|
|
1420
|
+
return next;
|
|
1459
1421
|
}
|
|
1422
|
+
prev.sibling = next;
|
|
1460
1423
|
return startDiffAtom;
|
|
1461
1424
|
}
|
|
1462
|
-
|
|
1425
|
+
prev = oldAtom;
|
|
1426
|
+
oldAtom = oldAtom.sibling;
|
|
1463
1427
|
}
|
|
1464
1428
|
commits.push(createNewView(newAtom, nativeRenderer, context, parentComponent, effect));
|
|
1465
1429
|
return startDiffAtom;
|
|
@@ -1471,44 +1435,28 @@ function createNewView(start, nativeRenderer, context, parentComponent, effect)
|
|
|
1471
1435
|
};
|
|
1472
1436
|
}
|
|
1473
1437
|
function updateText(newAtom, oldAtom, nativeRenderer, context) {
|
|
1474
|
-
return function () {
|
|
1438
|
+
return function (offset) {
|
|
1475
1439
|
const nativeNode = oldAtom.nativeNode;
|
|
1476
|
-
if (newAtom.jsxNode !== oldAtom.jsxNode) {
|
|
1477
|
-
nativeRenderer.syncTextContent(nativeNode, newAtom.jsxNode, newAtom.isSvg);
|
|
1478
|
-
}
|
|
1479
1440
|
newAtom.nativeNode = nativeNode;
|
|
1441
|
+
if (newAtom.index - offset !== oldAtom.index) {
|
|
1442
|
+
insertNode(nativeRenderer, newAtom, context);
|
|
1443
|
+
}
|
|
1480
1444
|
context.host = nativeNode;
|
|
1481
1445
|
context.isParent = false;
|
|
1482
1446
|
};
|
|
1483
1447
|
}
|
|
1484
|
-
function updateElement(newAtom, oldAtom,
|
|
1448
|
+
function updateElement(newAtom, oldAtom, nativeRenderer, context, parentComponent) {
|
|
1485
1449
|
return function (offset) {
|
|
1486
1450
|
newAtom.nativeNode = oldAtom.nativeNode;
|
|
1487
|
-
if (
|
|
1451
|
+
if (newAtom.index - offset !== oldAtom.index) {
|
|
1488
1452
|
insertNode(nativeRenderer, newAtom, context);
|
|
1489
1453
|
}
|
|
1490
1454
|
context.host = newAtom.nativeNode;
|
|
1491
1455
|
context.isParent = false;
|
|
1492
|
-
|
|
1493
|
-
if (newAtom.child) {
|
|
1494
|
-
diff(nativeRenderer, parentComponent, newAtom.child, oldAtom.child, {
|
|
1495
|
-
host: newAtom.nativeNode,
|
|
1496
|
-
isParent: true,
|
|
1497
|
-
rootHost: context.rootHost
|
|
1498
|
-
}, 0, 0);
|
|
1499
|
-
}
|
|
1500
|
-
else if (oldAtom.child) {
|
|
1501
|
-
let atom = oldAtom.child;
|
|
1502
|
-
nativeRenderer.cleanChildren(oldAtom.nativeNode, oldAtom.isSvg);
|
|
1503
|
-
while (atom) {
|
|
1504
|
-
cleanView(nativeRenderer, atom, true);
|
|
1505
|
-
atom = atom.sibling;
|
|
1506
|
-
}
|
|
1507
|
-
}
|
|
1508
|
-
applyRefs();
|
|
1456
|
+
updateNativeNodeProperties(nativeRenderer, newAtom, oldAtom, parentComponent, context);
|
|
1509
1457
|
};
|
|
1510
1458
|
}
|
|
1511
|
-
function updateComponent(newAtom, reusedAtom,
|
|
1459
|
+
function updateComponent(newAtom, reusedAtom, nativeRenderer, context) {
|
|
1512
1460
|
return function (offset) {
|
|
1513
1461
|
const component = reusedAtom.jsxNode;
|
|
1514
1462
|
const newProps = newAtom.jsxNode.props;
|
|
@@ -1516,10 +1464,10 @@ function updateComponent(newAtom, reusedAtom, expectIndex, oldIndex, nativeRende
|
|
|
1516
1464
|
const newTemplate = component.update(newProps);
|
|
1517
1465
|
const portalHost = component.instance.$portalHost;
|
|
1518
1466
|
context = portalHost ? { isParent: true, host: portalHost, rootHost: portalHost } : context;
|
|
1519
|
-
component
|
|
1467
|
+
componentViewCache.set(component, Object.assign({ atom: newAtom }, context));
|
|
1520
1468
|
newAtom.jsxNode = component;
|
|
1521
1469
|
if (newTemplate === oldTemplate) {
|
|
1522
|
-
reuseComponentView(nativeRenderer, newAtom, reusedAtom, context,
|
|
1470
|
+
reuseComponentView(nativeRenderer, newAtom, reusedAtom, context, newAtom.index - offset !== reusedAtom.index);
|
|
1523
1471
|
updateView(nativeRenderer, component);
|
|
1524
1472
|
return;
|
|
1525
1473
|
}
|
|
@@ -1527,12 +1475,12 @@ function updateComponent(newAtom, reusedAtom, expectIndex, oldIndex, nativeRende
|
|
|
1527
1475
|
newAtom.child = createChildChain(newTemplate, newAtom.isSvg);
|
|
1528
1476
|
}
|
|
1529
1477
|
if (newAtom.child) {
|
|
1530
|
-
diff(nativeRenderer, component, newAtom.child, reusedAtom.child, context
|
|
1478
|
+
diff(nativeRenderer, component, newAtom.child, reusedAtom.child, context);
|
|
1531
1479
|
}
|
|
1532
1480
|
else if (reusedAtom.child) {
|
|
1533
1481
|
let atom = reusedAtom.child;
|
|
1534
1482
|
while (atom) {
|
|
1535
|
-
cleanView(nativeRenderer, atom,
|
|
1483
|
+
cleanView(nativeRenderer, atom, true);
|
|
1536
1484
|
atom = atom.sibling;
|
|
1537
1485
|
}
|
|
1538
1486
|
}
|
|
@@ -1563,13 +1511,21 @@ function reuseComponentView(nativeRenderer, newAtom, reusedAtom, context, moveVi
|
|
|
1563
1511
|
child = child.sibling;
|
|
1564
1512
|
}
|
|
1565
1513
|
}
|
|
1514
|
+
function cleanElementChildren(atom, nativeRenderer) {
|
|
1515
|
+
let child = atom.child;
|
|
1516
|
+
nativeRenderer.cleanChildren(atom.nativeNode, atom.isSvg);
|
|
1517
|
+
while (child) {
|
|
1518
|
+
cleanView(nativeRenderer, child, false);
|
|
1519
|
+
child = child.sibling;
|
|
1520
|
+
}
|
|
1521
|
+
}
|
|
1566
1522
|
function cleanView(nativeRenderer, atom, needClean) {
|
|
1567
1523
|
if (atom.nativeNode) {
|
|
1568
|
-
if (
|
|
1524
|
+
if (needClean) {
|
|
1569
1525
|
nativeRenderer.remove(atom.nativeNode, atom.isSvg);
|
|
1570
|
-
needClean =
|
|
1526
|
+
needClean = false;
|
|
1571
1527
|
}
|
|
1572
|
-
if (atom.type ===
|
|
1528
|
+
if (atom.type === ElementAtomType) {
|
|
1573
1529
|
const ref = atom.jsxNode.props[refKey];
|
|
1574
1530
|
applyRefs(ref, atom.nativeNode, false);
|
|
1575
1531
|
}
|
|
@@ -1577,7 +1533,7 @@ function cleanView(nativeRenderer, atom, needClean) {
|
|
|
1577
1533
|
let child = atom.child;
|
|
1578
1534
|
while (child) {
|
|
1579
1535
|
if (child.jsxNode instanceof Component && child.jsxNode.instance.$portalHost) {
|
|
1580
|
-
needClean =
|
|
1536
|
+
needClean = true;
|
|
1581
1537
|
}
|
|
1582
1538
|
cleanView(nativeRenderer, child, needClean);
|
|
1583
1539
|
child = child.sibling;
|
|
@@ -1590,7 +1546,7 @@ function componentRender(nativeRenderer, component, from, context) {
|
|
|
1590
1546
|
const { template, portalHost } = component.render();
|
|
1591
1547
|
from.child = createChildChain(template, from.isSvg);
|
|
1592
1548
|
context = portalHost ? { isParent: true, host: portalHost, rootHost: portalHost } : context;
|
|
1593
|
-
component
|
|
1549
|
+
componentViewCache.set(component, Object.assign({ atom: from }, context));
|
|
1594
1550
|
let child = from.child;
|
|
1595
1551
|
while (child) {
|
|
1596
1552
|
buildView(nativeRenderer, component, child, context);
|
|
@@ -1598,49 +1554,26 @@ function componentRender(nativeRenderer, component, from, context) {
|
|
|
1598
1554
|
}
|
|
1599
1555
|
component.rendered();
|
|
1600
1556
|
}
|
|
1601
|
-
function
|
|
1602
|
-
const atom = {
|
|
1603
|
-
type: 'component',
|
|
1604
|
-
jsxNode,
|
|
1605
|
-
sibling: null,
|
|
1606
|
-
child: null,
|
|
1607
|
-
nativeNode: null,
|
|
1608
|
-
isSvg
|
|
1609
|
-
};
|
|
1610
|
-
prevAtom.sibling = atom;
|
|
1611
|
-
return atom;
|
|
1612
|
-
}
|
|
1613
|
-
function createChainByJSXText(jsxNode, prevAtom, isSvg) {
|
|
1557
|
+
function createChainByJSXNode(type, jsxNode, nodeType, prevAtom, isSvg, key) {
|
|
1614
1558
|
const atom = {
|
|
1615
|
-
type
|
|
1559
|
+
type,
|
|
1560
|
+
index: prevAtom.index + 1,
|
|
1616
1561
|
jsxNode,
|
|
1617
1562
|
sibling: null,
|
|
1618
1563
|
child: null,
|
|
1619
1564
|
nativeNode: null,
|
|
1620
|
-
isSvg
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
return atom;
|
|
1624
|
-
}
|
|
1625
|
-
function createChainByJSXElement(element, prevAtom, isSvg) {
|
|
1626
|
-
isSvg = isSvg || element.type === 'svg';
|
|
1627
|
-
const atom = {
|
|
1628
|
-
type: 'element',
|
|
1629
|
-
jsxNode: element,
|
|
1630
|
-
sibling: null,
|
|
1631
|
-
child: null,
|
|
1632
|
-
nativeNode: null,
|
|
1633
|
-
isSvg
|
|
1565
|
+
isSvg,
|
|
1566
|
+
nodeType,
|
|
1567
|
+
key
|
|
1634
1568
|
};
|
|
1635
1569
|
prevAtom.sibling = atom;
|
|
1636
|
-
atom.child = createChildChain(element.props.children, isSvg);
|
|
1637
1570
|
return atom;
|
|
1638
1571
|
}
|
|
1639
1572
|
function createChainByNode(jsxNode, prevAtom, isSvg) {
|
|
1640
1573
|
const type = typeof jsxNode;
|
|
1641
1574
|
if (jsxNode !== null && type !== 'undefined' && type !== 'boolean') {
|
|
1642
1575
|
if (typeof jsxNode === 'string') {
|
|
1643
|
-
return
|
|
1576
|
+
return createChainByJSXNode(TextAtomType, jsxNode, jsxNode, prevAtom, isSvg);
|
|
1644
1577
|
}
|
|
1645
1578
|
if (Array.isArray(jsxNode)) {
|
|
1646
1579
|
return createChainByChildren(jsxNode, prevAtom, isSvg);
|
|
@@ -1648,13 +1581,14 @@ function createChainByNode(jsxNode, prevAtom, isSvg) {
|
|
|
1648
1581
|
if (type === 'object') {
|
|
1649
1582
|
const nodeType = typeof jsxNode.type;
|
|
1650
1583
|
if (nodeType === 'string') {
|
|
1651
|
-
return
|
|
1584
|
+
return createChainByJSXNode(ElementAtomType, jsxNode, jsxNode.type, prevAtom, isSvg || jsxNode.type === 'svg', jsxNode.key);
|
|
1652
1585
|
}
|
|
1653
1586
|
else if (nodeType === 'function') {
|
|
1654
|
-
return
|
|
1587
|
+
return createChainByJSXNode(ComponentAtomType, jsxNode, jsxNode.type, prevAtom, isSvg, jsxNode.key);
|
|
1655
1588
|
}
|
|
1656
1589
|
}
|
|
1657
|
-
|
|
1590
|
+
const text = String(jsxNode);
|
|
1591
|
+
return createChainByJSXNode(TextAtomType, text, text, prevAtom, isSvg);
|
|
1658
1592
|
}
|
|
1659
1593
|
return prevAtom;
|
|
1660
1594
|
}
|
|
@@ -1665,7 +1599,7 @@ function createChainByChildren(children, prevAtom, isSvg) {
|
|
|
1665
1599
|
return prevAtom;
|
|
1666
1600
|
}
|
|
1667
1601
|
function createChildChain(template, isSvg) {
|
|
1668
|
-
const beforeAtom = { sibling: null };
|
|
1602
|
+
const beforeAtom = { sibling: null, index: -1 };
|
|
1669
1603
|
createChainByNode(template, beforeAtom, isSvg);
|
|
1670
1604
|
return beforeAtom.sibling;
|
|
1671
1605
|
}
|
|
@@ -1682,12 +1616,14 @@ function insertNode(nativeRenderer, atom, context) {
|
|
|
1682
1616
|
nativeRenderer.insertAfter(atom.nativeNode, context.host, atom.isSvg);
|
|
1683
1617
|
}
|
|
1684
1618
|
}
|
|
1685
|
-
function createElement(nativeRenderer,
|
|
1686
|
-
const
|
|
1687
|
-
const
|
|
1619
|
+
function createElement(nativeRenderer, atom, parentComponent, context) {
|
|
1620
|
+
const { isSvg, jsxNode } = atom;
|
|
1621
|
+
const nativeNode = nativeRenderer.createElement(jsxNode.type, isSvg);
|
|
1622
|
+
const props = jsxNode.props;
|
|
1688
1623
|
let bindingRefs;
|
|
1689
1624
|
for (const key in props) {
|
|
1690
1625
|
if (key === 'children') {
|
|
1626
|
+
atom.child = createChildChain(jsxNode.props.children, isSvg);
|
|
1691
1627
|
continue;
|
|
1692
1628
|
}
|
|
1693
1629
|
if (key === 'class') {
|
|
@@ -1707,7 +1643,7 @@ function createElement(nativeRenderer, vNode, isSvg) {
|
|
|
1707
1643
|
if (listenerReg.test(key)) {
|
|
1708
1644
|
const listener = props[key];
|
|
1709
1645
|
if (typeof listener === 'function') {
|
|
1710
|
-
|
|
1646
|
+
nativeRenderer.listen(nativeNode, key, listener, isSvg);
|
|
1711
1647
|
}
|
|
1712
1648
|
continue;
|
|
1713
1649
|
}
|
|
@@ -1717,21 +1653,32 @@ function createElement(nativeRenderer, vNode, isSvg) {
|
|
|
1717
1653
|
}
|
|
1718
1654
|
nativeRenderer.setProperty(nativeNode, key, props[key], isSvg);
|
|
1719
1655
|
}
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
}
|
|
1727
|
-
function createTextNode(nativeRenderer,
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1656
|
+
atom.nativeNode = nativeNode;
|
|
1657
|
+
insertNode(nativeRenderer, atom, context);
|
|
1658
|
+
buildElementChildren(atom, nativeRenderer, parentComponent, context);
|
|
1659
|
+
context.host = nativeNode;
|
|
1660
|
+
context.isParent = false;
|
|
1661
|
+
applyRefs(bindingRefs, nativeNode, true);
|
|
1662
|
+
}
|
|
1663
|
+
function createTextNode(nativeRenderer, atom, context) {
|
|
1664
|
+
const nativeNode = nativeRenderer.createTextNode(atom.jsxNode, atom.isSvg);
|
|
1665
|
+
atom.nativeNode = nativeNode;
|
|
1666
|
+
insertNode(nativeRenderer, atom, context);
|
|
1667
|
+
context.host = nativeNode;
|
|
1668
|
+
context.isParent = false;
|
|
1669
|
+
}
|
|
1670
|
+
function updateNativeNodeProperties(nativeRenderer, newAtom, oldAtom, parentComponent, context) {
|
|
1671
|
+
const newVNode = newAtom.jsxNode;
|
|
1672
|
+
const isSvg = newAtom.isSvg;
|
|
1673
|
+
const nativeNode = newAtom.nativeNode;
|
|
1674
|
+
const oldVNode = oldAtom.jsxNode;
|
|
1675
|
+
if (newVNode === oldVNode) {
|
|
1676
|
+
updateElementChildren(newAtom, oldAtom, nativeRenderer, parentComponent, context, isSvg);
|
|
1677
|
+
return;
|
|
1678
|
+
}
|
|
1731
1679
|
const changes = getObjectChanges(newVNode.props, oldVNode.props);
|
|
1732
1680
|
let unBindRefs;
|
|
1733
1681
|
let bindRefs;
|
|
1734
|
-
newVNode.on = oldVNode.on;
|
|
1735
1682
|
for (const [key, value] of changes.remove) {
|
|
1736
1683
|
if (key === 'children') {
|
|
1737
1684
|
continue;
|
|
@@ -1748,10 +1695,7 @@ function updateNativeNodeProperties(nativeRenderer, newVNode, oldVNode, nativeNo
|
|
|
1748
1695
|
}
|
|
1749
1696
|
if (listenerReg.test(key)) {
|
|
1750
1697
|
if (typeof value === 'function') {
|
|
1751
|
-
|
|
1752
|
-
const oldOn = oldVNode.on;
|
|
1753
|
-
nativeRenderer.unListen(nativeNode, type, oldOn[type].delegate, isSvg);
|
|
1754
|
-
Reflect.deleteProperty(oldOn, type);
|
|
1698
|
+
nativeRenderer.unListen(nativeNode, key, value, isSvg);
|
|
1755
1699
|
}
|
|
1756
1700
|
continue;
|
|
1757
1701
|
}
|
|
@@ -1784,8 +1728,8 @@ function updateNativeNodeProperties(nativeRenderer, newVNode, oldVNode, nativeNo
|
|
|
1784
1728
|
continue;
|
|
1785
1729
|
}
|
|
1786
1730
|
if (listenerReg.test(key)) {
|
|
1787
|
-
|
|
1788
|
-
|
|
1731
|
+
nativeRenderer.unListen(nativeNode, key, oldValue, isSvg);
|
|
1732
|
+
nativeRenderer.listen(nativeNode, key, newValue, isSvg);
|
|
1789
1733
|
continue;
|
|
1790
1734
|
}
|
|
1791
1735
|
if (key === refKey) {
|
|
@@ -1812,7 +1756,7 @@ function updateNativeNodeProperties(nativeRenderer, newVNode, oldVNode, nativeNo
|
|
|
1812
1756
|
}
|
|
1813
1757
|
if (listenerReg.test(key)) {
|
|
1814
1758
|
if (typeof value === 'function') {
|
|
1815
|
-
|
|
1759
|
+
nativeRenderer.listen(nativeNode, key, value, isSvg);
|
|
1816
1760
|
}
|
|
1817
1761
|
continue;
|
|
1818
1762
|
}
|
|
@@ -1822,10 +1766,36 @@ function updateNativeNodeProperties(nativeRenderer, newVNode, oldVNode, nativeNo
|
|
|
1822
1766
|
}
|
|
1823
1767
|
nativeRenderer.setProperty(nativeNode, key, value, isSvg);
|
|
1824
1768
|
}
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
|
|
1769
|
+
updateElementChildren(newAtom, oldAtom, nativeRenderer, parentComponent, context, isSvg);
|
|
1770
|
+
applyRefs(unBindRefs, nativeNode, false);
|
|
1771
|
+
applyRefs(bindRefs, nativeNode, true);
|
|
1772
|
+
}
|
|
1773
|
+
function updateElementChildren(newAtom, oldAtom, nativeRenderer, parentComponent, context, isSvg) {
|
|
1774
|
+
/**
|
|
1775
|
+
* 不能仅依赖 children 是否相等的判断来确定是否要继续向下 diff
|
|
1776
|
+
* 如:
|
|
1777
|
+
* ```tsx
|
|
1778
|
+
* <Comp>
|
|
1779
|
+
* <div>
|
|
1780
|
+
* {props.children}
|
|
1781
|
+
* </div>
|
|
1782
|
+
* </Comp>
|
|
1783
|
+
* ```
|
|
1784
|
+
* 其中当 Comp 产生变化时,children 来自父组件,这时 children 是相等的,
|
|
1785
|
+
* 但,children 内可能有子组件也发生了变化,如果不继续 diff,那么,子组件
|
|
1786
|
+
* 的视图更新将不会发生
|
|
1787
|
+
*/
|
|
1788
|
+
newAtom.child = createChildChain(newAtom.jsxNode.props.children, isSvg);
|
|
1789
|
+
if (!newAtom.child) {
|
|
1790
|
+
cleanElementChildren(oldAtom, nativeRenderer);
|
|
1791
|
+
}
|
|
1792
|
+
else {
|
|
1793
|
+
diff(nativeRenderer, parentComponent, newAtom.child, oldAtom.child, {
|
|
1794
|
+
host: newAtom.nativeNode,
|
|
1795
|
+
isParent: true,
|
|
1796
|
+
rootHost: context.rootHost
|
|
1797
|
+
});
|
|
1798
|
+
}
|
|
1829
1799
|
}
|
|
1830
1800
|
function applyRefs(refs, nativeNode, binding) {
|
|
1831
1801
|
if (refs) {
|
|
@@ -1837,21 +1807,6 @@ function applyRefs(refs, nativeNode, binding) {
|
|
|
1837
1807
|
}
|
|
1838
1808
|
}
|
|
1839
1809
|
}
|
|
1840
|
-
function bindEvent(nativeRenderer, vNode, key, nativeNode, listenFn, isSvg) {
|
|
1841
|
-
let on = vNode.on;
|
|
1842
|
-
if (!on) {
|
|
1843
|
-
vNode.on = on = {};
|
|
1844
|
-
}
|
|
1845
|
-
const type = key.replace(listenerReg, '').toLowerCase();
|
|
1846
|
-
const delegateObj = {
|
|
1847
|
-
delegate(...args) {
|
|
1848
|
-
return delegateObj.listenFn.apply(this, args);
|
|
1849
|
-
},
|
|
1850
|
-
listenFn
|
|
1851
|
-
};
|
|
1852
|
-
on[type] = delegateObj;
|
|
1853
|
-
nativeRenderer.listen(nativeNode, type, delegateObj.delegate, isSvg);
|
|
1854
|
-
}
|
|
1855
1810
|
|
|
1856
1811
|
/**
|
|
1857
1812
|
* Viewfly 根组件,用于实现组件状态更新事件通知
|