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