@viewfly/core 0.0.25 → 0.0.27

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.
@@ -1,5 +1,3 @@
1
- import 'reflect-metadata';
2
-
3
1
  class ForwardRef {
4
2
  constructor(forwardRefFn) {
5
3
  this.forwardRefFn = forwardRefFn;
@@ -660,6 +658,7 @@ class Component extends ReflectiveInjector {
660
658
  this.mountCallbacks = [];
661
659
  this.propsChangedCallbacks = [];
662
660
  this.updatedCallbacks = [];
661
+ this.changedSubComponents = new Set();
663
662
  this._dirty = true;
664
663
  this._changed = true;
665
664
  this.updatedDestroyCallbacks = [];
@@ -755,14 +754,18 @@ class Component extends ReflectiveInjector {
755
754
  this._dirty = true;
756
755
  this.markAsChanged();
757
756
  }
758
- markAsChanged() {
757
+ markAsChanged(changedComponent) {
758
+ if (changedComponent) {
759
+ this.changedSubComponents.add(changedComponent);
760
+ }
759
761
  if (this._changed) {
760
762
  return;
761
763
  }
762
764
  this._changed = true;
763
- this.parentComponent.markAsChanged();
765
+ this.parentComponent.markAsChanged(this);
764
766
  }
765
767
  rendered() {
768
+ this.changedSubComponents.clear();
766
769
  const is = this.isFirstRending;
767
770
  this.isFirstRending = false;
768
771
  this._dirty = this._changed = false;
@@ -1108,9 +1111,9 @@ function provide(provider) {
1108
1111
  /**
1109
1112
  * 通过组件上下文获取 IoC 容器内数据的勾子方法
1110
1113
  */
1111
- function inject(token, notFoundValue, flags) {
1114
+ function inject(token, notFoundValue = THROW_IF_NOT_FOUND, flags = InjectFlags.SkipSelf) {
1112
1115
  const component = getSetupContext();
1113
- return component.get(token, notFoundValue, flags || InjectFlags.SkipSelf);
1116
+ return component.get(token, notFoundValue, flags);
1114
1117
  }
1115
1118
 
1116
1119
  function Fragment(props) {
@@ -1120,7 +1123,7 @@ function Fragment(props) {
1120
1123
  }
1121
1124
  function jsx(setup, props, key) {
1122
1125
  if (typeof setup === 'string') {
1123
- return new JSXElement(setup, props, key);
1126
+ return JSXElement.create(setup, props, key);
1124
1127
  }
1125
1128
  return new JSXComponent(props, function (context, props) {
1126
1129
  return new Component(context, setup, props, key);
@@ -1137,6 +1140,9 @@ class JSXText {
1137
1140
  }
1138
1141
  }
1139
1142
  class JSXElement {
1143
+ static create(name, props, key) {
1144
+ return new JSXElement(name, props, key);
1145
+ }
1140
1146
  constructor(type, props, key) {
1141
1147
  this.type = type;
1142
1148
  this.props = props;
@@ -1159,13 +1165,16 @@ function withMemo(shouldUpdate, render) {
1159
1165
  * Viewfly 根组件,用于实现组件状态更新事件通知
1160
1166
  */
1161
1167
  class RootComponent extends Component {
1162
- constructor(factory, parentInjector) {
1168
+ constructor(parentInjector, factory) {
1163
1169
  super(parentInjector, factory, {});
1164
1170
  this.onChange = null;
1165
1171
  }
1166
- markAsChanged() {
1172
+ markAsChanged(changedComponent) {
1167
1173
  var _a;
1168
1174
  this._changed = true;
1175
+ if (changedComponent) {
1176
+ this.changedSubComponents.add(changedComponent);
1177
+ }
1169
1178
  (_a = this.onChange) === null || _a === void 0 ? void 0 : _a.call(this);
1170
1179
  }
1171
1180
  }
@@ -1173,54 +1182,11 @@ class RootComponent extends Component {
1173
1182
  class NativeRenderer {
1174
1183
  }
1175
1184
 
1176
- /******************************************************************************
1177
- Copyright (c) Microsoft Corporation.
1178
-
1179
- Permission to use, copy, modify, and/or distribute this software for any
1180
- purpose with or without fee is hereby granted.
1181
-
1182
- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
1183
- REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
1184
- AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
1185
- INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
1186
- LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
1187
- OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
1188
- PERFORMANCE OF THIS SOFTWARE.
1189
- ***************************************************************************** */
1190
- /* global Reflect, Promise, SuppressedError, Symbol */
1191
-
1192
-
1193
- function __decorate(decorators, target, key, desc) {
1194
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1195
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
1196
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
1197
- return c > 3 && r && Object.defineProperty(target, key, r), r;
1198
- }
1199
-
1200
- function __metadata(metadataKey, metadataValue) {
1201
- if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue);
1202
- }
1203
-
1204
- typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
1205
- var e = new Error(message);
1206
- return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
1207
- };
1208
-
1209
- class RootComponentRef {
1210
- }
1211
- class HostRef {
1212
- }
1213
- let Renderer = class Renderer {
1214
- constructor(nativeRenderer, rootComponentRef, hostRef) {
1215
- this.nativeRenderer = nativeRenderer;
1216
- this.rootComponentRef = rootComponentRef;
1217
- this.hostRef = hostRef;
1218
- this.isInit = true;
1219
- }
1220
- render() {
1221
- const component = this.rootComponentRef.component;
1222
- const host = this.hostRef.host;
1223
- if (this.isInit) {
1185
+ function createRenderer(component, nativeRenderer) {
1186
+ let isInit = true;
1187
+ return function render(host) {
1188
+ if (isInit) {
1189
+ isInit = false;
1224
1190
  const atom = {
1225
1191
  jsxNode: component,
1226
1192
  parent: null,
@@ -1228,687 +1194,604 @@ let Renderer = class Renderer {
1228
1194
  child: null,
1229
1195
  nativeNode: null
1230
1196
  };
1231
- this.buildView(atom, {
1197
+ buildView(nativeRenderer, atom, {
1232
1198
  isParent: true,
1233
1199
  host
1234
1200
  });
1235
1201
  }
1236
1202
  else {
1237
- this.reconcile(component, {
1238
- host,
1239
- isParent: true
1240
- });
1203
+ updateView(nativeRenderer, component);
1241
1204
  }
1242
- this.isInit = false;
1243
- }
1244
- reconcile(component, context) {
1245
- if (component.dirty) {
1246
- this.applyChanges(component, context);
1247
- component.rendered();
1205
+ };
1206
+ }
1207
+ function buildView(nativeRenderer, atom, context) {
1208
+ if (atom.jsxNode instanceof Component) {
1209
+ componentRender(atom.jsxNode, atom, context);
1210
+ let child = atom.child;
1211
+ while (child) {
1212
+ buildView(nativeRenderer, child, context);
1213
+ child = child.sibling;
1248
1214
  }
1249
- else if (component.changed) {
1250
- const atom = component.$$view.atom.child;
1251
- this.reconcileElement(atom, context);
1252
- component.rendered();
1215
+ atom.jsxNode.rendered();
1216
+ }
1217
+ else {
1218
+ let nativeNode;
1219
+ let applyRefs = null;
1220
+ if (atom.jsxNode instanceof JSXElement) {
1221
+ const { nativeNode: n, applyRefs: a } = createElement(nativeRenderer, atom.jsxNode);
1222
+ nativeNode = n;
1223
+ applyRefs = a;
1253
1224
  }
1254
1225
  else {
1255
- const prevSibling = this.getPrevSibling(component);
1256
- if (prevSibling) {
1257
- context.isParent = false;
1258
- context.host = prevSibling;
1259
- }
1226
+ nativeNode = createTextNode(nativeRenderer, atom.jsxNode);
1260
1227
  }
1261
- }
1262
- getPrevSibling(component) {
1263
- let atom = component.$$view.atom.child;
1264
- const childAtoms = [];
1265
- while (atom) {
1266
- childAtoms.push(atom);
1267
- atom = atom.sibling;
1228
+ atom.nativeNode = nativeNode;
1229
+ if (context.isParent) {
1230
+ nativeRenderer.prependChild(context.host, nativeNode);
1268
1231
  }
1269
- const components = [];
1270
- while (childAtoms.length) {
1271
- const last = childAtoms.pop();
1272
- if (last.jsxNode instanceof Component) {
1273
- components.push(last.jsxNode);
1274
- continue;
1275
- }
1276
- return last.nativeNode;
1232
+ else {
1233
+ nativeRenderer.insertAfter(nativeNode, context.host);
1277
1234
  }
1278
- for (const component of components) {
1279
- const nativeNode = this.getPrevSibling(component);
1280
- if (nativeNode) {
1281
- return nativeNode;
1235
+ if (atom.jsxNode instanceof JSXElement) {
1236
+ const childContext = {
1237
+ isParent: true,
1238
+ host: nativeNode
1239
+ };
1240
+ let child = atom.child;
1241
+ while (child) {
1242
+ buildView(nativeRenderer, child, childContext);
1243
+ child = child.sibling;
1282
1244
  }
1283
1245
  }
1284
- return null;
1285
- }
1286
- reconcileElement(atom, context) {
1287
- while (atom) {
1288
- if (atom.jsxNode instanceof Component) {
1289
- this.reconcile(atom.jsxNode, context);
1290
- atom = atom.sibling;
1291
- continue;
1292
- }
1293
- if (atom.jsxNode instanceof JSXElement) {
1294
- this.reconcileElement(atom.child, {
1295
- host: atom.nativeNode,
1296
- isParent: true
1297
- });
1298
- context.host = atom.nativeNode;
1299
- context.isParent = false;
1300
- }
1301
- atom = atom.sibling;
1246
+ context.host = nativeNode;
1247
+ context.isParent = false;
1248
+ if (applyRefs) {
1249
+ applyRefs();
1302
1250
  }
1303
1251
  }
1304
- applyChanges(component, context) {
1305
- const { atom, render } = component.$$view;
1306
- const diffAtom = atom.child;
1307
- const template = render(component.props, component.props);
1308
- if (template) {
1309
- this.linkTemplate(template, component, atom);
1310
- }
1311
- else {
1312
- atom.child = null;
1313
- }
1314
- this.diff(atom.child, diffAtom, context, 0, 0);
1252
+ }
1253
+ function updateView(nativeRenderer, component) {
1254
+ if (component.dirty) {
1255
+ applyChanges(nativeRenderer, component);
1256
+ component.rendered();
1257
+ }
1258
+ else if (component.changed) {
1259
+ component.changedSubComponents.forEach(child => {
1260
+ updateView(nativeRenderer, child);
1261
+ });
1262
+ component.rendered();
1315
1263
  }
1316
- diff(newAtom, oldAtom, context, expectIndex, index) {
1317
- const oldChildren = [];
1318
- while (oldAtom) {
1319
- oldChildren.push({
1320
- index,
1321
- atom: oldAtom
1322
- });
1323
- oldAtom = oldAtom.sibling;
1324
- index++;
1325
- }
1326
- const commits = [];
1327
- const changeCommits = {
1328
- updateComponent: (newAtom, reusedAtom, expectIndex, diffIndex) => {
1329
- commits.push((offset) => {
1330
- const { render, template } = reusedAtom.jsxNode.$$view;
1331
- const newProps = newAtom.jsxNode.props;
1332
- const oldProps = reusedAtom.jsxNode.props;
1333
- newAtom.jsxNode = reusedAtom.jsxNode;
1334
- const newTemplate = render(newProps, oldProps);
1335
- newAtom.jsxNode.$$view = {
1336
- render,
1337
- template: newTemplate,
1338
- atom: newAtom
1339
- };
1340
- if (newTemplate === template) {
1341
- this.reuseComponentView(newAtom, reusedAtom, context, expectIndex !== diffIndex - offset);
1342
- return;
1343
- }
1344
- if (newTemplate) {
1345
- this.linkTemplate(newTemplate, newAtom.jsxNode, newAtom);
1346
- }
1347
- if (newAtom.child) {
1348
- this.diff(newAtom.child, reusedAtom.child, context, expectIndex, diffIndex);
1349
- }
1350
- else if (reusedAtom.child) {
1351
- let atom = reusedAtom.child;
1352
- while (atom) {
1353
- this.cleanView(atom, false);
1354
- atom = atom.sibling;
1355
- }
1356
- }
1357
- newAtom.jsxNode.rendered();
1358
- });
1359
- },
1360
- updateElement: (newAtom, oldAtom, expectIndex, oldIndex) => {
1361
- commits.push((offset) => {
1362
- newAtom.nativeNode = oldAtom.nativeNode;
1363
- const host = context.host;
1364
- if (expectIndex !== oldIndex - offset) {
1365
- if (context.isParent) {
1366
- this.nativeRenderer.prependChild(host, newAtom.nativeNode);
1367
- }
1368
- else {
1369
- this.nativeRenderer.insertAfter(newAtom.nativeNode, host);
1370
- }
1371
- }
1372
- context.host = newAtom.nativeNode;
1373
- context.isParent = false;
1374
- const applyRefs = this.updateNativeNodeProperties(newAtom.jsxNode, oldAtom.jsxNode, newAtom.nativeNode);
1375
- if (newAtom.child) {
1376
- this.diff(newAtom.child, oldAtom.child, {
1377
- host: newAtom.nativeNode,
1378
- isParent: true
1379
- }, 0, 0);
1380
- }
1381
- else if (oldAtom.child) {
1382
- let atom = oldAtom.child;
1383
- while (atom) {
1384
- this.cleanView(atom, false);
1385
- atom = atom.sibling;
1386
- }
1387
- }
1388
- applyRefs();
1389
- });
1390
- },
1391
- updateText: (newAtom, oldAtom) => {
1392
- commits.push(() => {
1393
- const nativeNode = oldAtom.nativeNode;
1394
- if (newAtom.jsxNode.text !== oldAtom.jsxNode.text) {
1395
- this.nativeRenderer.syncTextContent(nativeNode, newAtom.jsxNode.text);
1396
- }
1397
- newAtom.nativeNode = nativeNode;
1398
- context.host = nativeNode;
1399
- context.isParent = false;
1400
- });
1401
- },
1402
- create: (start) => {
1403
- commits.push(() => {
1404
- this.buildView(start, context);
1405
- });
1406
- }
1407
- };
1408
- while (newAtom) {
1409
- this.createChanges(newAtom, expectIndex, oldChildren, changeCommits);
1410
- newAtom = newAtom.sibling;
1411
- expectIndex++;
1412
- }
1413
- for (const item of oldChildren) {
1414
- this.cleanView(item.atom, false);
1415
- }
1416
- let j = 0;
1417
- let offset = 0;
1418
- const len = oldChildren.length;
1419
- for (let i = 0; i < commits.length; i++) {
1420
- const commit = commits[i];
1421
- while (j < len) {
1422
- const current = oldChildren[j];
1423
- if (current.index <= i) {
1424
- offset++;
1425
- j++;
1426
- continue;
1427
- }
1428
- break;
1429
- }
1430
- commit(offset);
1431
- }
1264
+ }
1265
+ function applyChanges(nativeRenderer, component) {
1266
+ const { atom, render, host, isParent } = component.$$view;
1267
+ const diffAtom = atom.child;
1268
+ const template = render(component.props, component.props);
1269
+ if (template) {
1270
+ linkTemplate(template, component, atom);
1432
1271
  }
1433
- reuseComponentView(newAtom, reusedAtom, context, moveView) {
1434
- let child = reusedAtom.child;
1435
- newAtom.child = child;
1436
- const children = [];
1437
- while (child) {
1438
- children.push(child);
1439
- child.parent = newAtom;
1440
- child = child.sibling;
1441
- }
1442
- const updateContext = (atom) => {
1443
- if (atom.jsxNode instanceof Component) {
1444
- let child = atom.child;
1445
- while (child) {
1446
- updateContext(child);
1447
- child = child.sibling;
1272
+ else {
1273
+ atom.child = null;
1274
+ }
1275
+ const context = {
1276
+ host,
1277
+ isParent
1278
+ };
1279
+ diff(nativeRenderer, atom.child, diffAtom, context, 0, 0);
1280
+ const next = atom.sibling;
1281
+ if (next && next.jsxNode instanceof Component) {
1282
+ next.jsxNode.$$view.host = context.host;
1283
+ next.jsxNode.$$view.isParent = context.isParent;
1284
+ }
1285
+ }
1286
+ function diff(nativeRenderer, newAtom, oldAtom, context, expectIndex, index) {
1287
+ const oldChildren = [];
1288
+ while (oldAtom) {
1289
+ oldChildren.push({
1290
+ index,
1291
+ atom: oldAtom
1292
+ });
1293
+ oldAtom = oldAtom.sibling;
1294
+ index++;
1295
+ }
1296
+ const commits = [];
1297
+ const changeCommits = {
1298
+ updateComponent: (newAtom, reusedAtom, expectIndex, diffIndex) => {
1299
+ commits.push((offset) => {
1300
+ const { render, template } = reusedAtom.jsxNode.$$view;
1301
+ const newProps = newAtom.jsxNode.props;
1302
+ const oldProps = reusedAtom.jsxNode.props;
1303
+ newAtom.jsxNode = reusedAtom.jsxNode;
1304
+ const newTemplate = render(newProps, oldProps);
1305
+ newAtom.jsxNode.$$view = Object.assign({ render, template: newTemplate, atom: newAtom }, context);
1306
+ if (newTemplate === template) {
1307
+ reuseComponentView(nativeRenderer, newAtom, reusedAtom, context, expectIndex !== diffIndex - offset);
1308
+ return;
1448
1309
  }
1449
- }
1450
- else {
1451
- if (moveView) {
1310
+ if (newTemplate) {
1311
+ linkTemplate(newTemplate, newAtom.jsxNode, newAtom);
1312
+ }
1313
+ if (newAtom.child) {
1314
+ diff(nativeRenderer, newAtom.child, reusedAtom.child, context, expectIndex, diffIndex);
1315
+ }
1316
+ else if (reusedAtom.child) {
1317
+ let atom = reusedAtom.child;
1318
+ while (atom) {
1319
+ cleanView(nativeRenderer, atom, false);
1320
+ atom = atom.sibling;
1321
+ }
1322
+ }
1323
+ newAtom.jsxNode.rendered();
1324
+ });
1325
+ },
1326
+ updateElement: (newAtom, oldAtom, expectIndex, oldIndex) => {
1327
+ commits.push((offset) => {
1328
+ newAtom.nativeNode = oldAtom.nativeNode;
1329
+ const host = context.host;
1330
+ if (expectIndex !== oldIndex - offset) {
1452
1331
  if (context.isParent) {
1453
- this.nativeRenderer.prependChild(context.host, atom.nativeNode);
1332
+ nativeRenderer.prependChild(host, newAtom.nativeNode);
1454
1333
  }
1455
1334
  else {
1456
- this.nativeRenderer.insertAfter(atom.nativeNode, context.host);
1335
+ nativeRenderer.insertAfter(newAtom.nativeNode, host);
1457
1336
  }
1458
1337
  }
1338
+ context.host = newAtom.nativeNode;
1459
1339
  context.isParent = false;
1460
- context.host = atom.nativeNode;
1461
- }
1462
- };
1463
- for (const atom of children) {
1464
- updateContext(atom);
1465
- }
1466
- }
1467
- createChanges(newAtom, expectIndex, oldChildren, changeCommits) {
1468
- for (let i = 0; i < oldChildren.length; i++) {
1469
- const { atom: diffAtom, index: diffIndex } = oldChildren[i];
1470
- const key = newAtom.jsxNode.key;
1471
- const diffKey = diffAtom.jsxNode.key;
1472
- if (key !== undefined && diffKey !== undefined) {
1473
- if (diffKey !== key) {
1474
- continue;
1340
+ const applyRefs = updateNativeNodeProperties(nativeRenderer, newAtom.jsxNode, oldAtom.jsxNode, newAtom.nativeNode);
1341
+ if (newAtom.child) {
1342
+ diff(nativeRenderer, newAtom.child, oldAtom.child, {
1343
+ host: newAtom.nativeNode,
1344
+ isParent: true
1345
+ }, 0, 0);
1475
1346
  }
1476
- }
1477
- if (newAtom.jsxNode.is(diffAtom.jsxNode)) {
1478
- if (newAtom.jsxNode instanceof JSXElement) {
1479
- changeCommits.updateElement(newAtom, diffAtom, expectIndex, diffIndex);
1480
- }
1481
- else if (newAtom.jsxNode instanceof JSXText) {
1482
- changeCommits.updateText(newAtom, diffAtom);
1347
+ else if (oldAtom.child) {
1348
+ let atom = oldAtom.child;
1349
+ while (atom) {
1350
+ cleanView(nativeRenderer, atom, false);
1351
+ atom = atom.sibling;
1352
+ }
1483
1353
  }
1484
- else {
1485
- changeCommits.updateComponent(newAtom, diffAtom, expectIndex, diffIndex);
1354
+ applyRefs();
1355
+ });
1356
+ },
1357
+ updateText: (newAtom, oldAtom) => {
1358
+ commits.push(() => {
1359
+ const nativeNode = oldAtom.nativeNode;
1360
+ if (newAtom.jsxNode.text !== oldAtom.jsxNode.text) {
1361
+ nativeRenderer.syncTextContent(nativeNode, newAtom.jsxNode.text);
1486
1362
  }
1487
- oldChildren.splice(i, 1);
1488
- return;
1489
- }
1363
+ newAtom.nativeNode = nativeNode;
1364
+ context.host = nativeNode;
1365
+ context.isParent = false;
1366
+ });
1367
+ },
1368
+ create: (start) => {
1369
+ commits.push(() => {
1370
+ buildView(nativeRenderer, start, context);
1371
+ });
1490
1372
  }
1491
- changeCommits.create(newAtom);
1492
- }
1493
- cleanView(atom, isClean) {
1494
- if (atom.nativeNode) {
1495
- if (!isClean) {
1496
- this.nativeRenderer.remove(atom.nativeNode);
1497
- isClean = true;
1498
- }
1499
- if (atom.jsxNode instanceof JSXElement) {
1500
- const ref = atom.jsxNode.props[refKey];
1501
- this.applyRefs(ref, atom.nativeNode, false);
1373
+ };
1374
+ while (newAtom) {
1375
+ createChanges(newAtom, expectIndex, oldChildren, changeCommits);
1376
+ newAtom = newAtom.sibling;
1377
+ expectIndex++;
1378
+ }
1379
+ for (const item of oldChildren) {
1380
+ cleanView(nativeRenderer, item.atom, false);
1381
+ }
1382
+ let j = 0;
1383
+ let offset = 0;
1384
+ const len = oldChildren.length;
1385
+ for (let i = 0; i < commits.length; i++) {
1386
+ const commit = commits[i];
1387
+ while (j < len) {
1388
+ const current = oldChildren[j];
1389
+ if (current.index <= i) {
1390
+ offset++;
1391
+ j++;
1392
+ continue;
1502
1393
  }
1394
+ break;
1503
1395
  }
1504
- let child = atom.child;
1505
- while (child) {
1506
- this.cleanView(child, isClean);
1507
- child = child.sibling;
1508
- }
1509
- if (atom.jsxNode instanceof Component) {
1510
- atom.jsxNode.destroy();
1511
- }
1396
+ commit(offset);
1512
1397
  }
1513
- buildView(atom, context) {
1398
+ }
1399
+ function reuseComponentView(nativeRenderer, newAtom, reusedAtom, context, moveView) {
1400
+ let child = reusedAtom.child;
1401
+ newAtom.child = child;
1402
+ const children = [];
1403
+ while (child) {
1404
+ children.push(child);
1405
+ child.parent = newAtom;
1406
+ child = child.sibling;
1407
+ }
1408
+ const updateContext = (atom) => {
1514
1409
  if (atom.jsxNode instanceof Component) {
1515
- this.componentRender(atom.jsxNode, atom);
1516
1410
  let child = atom.child;
1517
1411
  while (child) {
1518
- this.buildView(child, context);
1412
+ updateContext(child);
1519
1413
  child = child.sibling;
1520
1414
  }
1521
- atom.jsxNode.rendered();
1522
1415
  }
1523
1416
  else {
1524
- let nativeNode;
1525
- let applyRefs = null;
1526
- if (atom.jsxNode instanceof JSXElement) {
1527
- const { nativeNode: n, applyRefs: a } = this.createElement(atom.jsxNode);
1528
- nativeNode = n;
1529
- applyRefs = a;
1530
- }
1531
- else {
1532
- nativeNode = this.createTextNode(atom.jsxNode);
1417
+ if (moveView) {
1418
+ if (context.isParent) {
1419
+ nativeRenderer.prependChild(context.host, atom.nativeNode);
1420
+ }
1421
+ else {
1422
+ nativeRenderer.insertAfter(atom.nativeNode, context.host);
1423
+ }
1533
1424
  }
1534
- atom.nativeNode = nativeNode;
1535
- if (context.isParent) {
1536
- this.nativeRenderer.prependChild(context.host, nativeNode);
1425
+ context.isParent = false;
1426
+ context.host = atom.nativeNode;
1427
+ }
1428
+ };
1429
+ for (const atom of children) {
1430
+ updateContext(atom);
1431
+ }
1432
+ }
1433
+ function createChanges(newAtom, expectIndex, oldChildren, changeCommits) {
1434
+ for (let i = 0; i < oldChildren.length; i++) {
1435
+ const { atom: diffAtom, index: diffIndex } = oldChildren[i];
1436
+ const key = newAtom.jsxNode.key;
1437
+ const diffKey = diffAtom.jsxNode.key;
1438
+ if (key !== undefined && diffKey !== undefined) {
1439
+ if (diffKey !== key) {
1440
+ continue;
1537
1441
  }
1538
- else {
1539
- this.nativeRenderer.insertAfter(nativeNode, context.host);
1442
+ }
1443
+ if (newAtom.jsxNode.is(diffAtom.jsxNode)) {
1444
+ if (newAtom.jsxNode instanceof JSXElement) {
1445
+ changeCommits.updateElement(newAtom, diffAtom, expectIndex, diffIndex);
1540
1446
  }
1541
- if (atom.jsxNode instanceof JSXElement) {
1542
- const childContext = {
1543
- isParent: true,
1544
- host: nativeNode
1545
- };
1546
- let child = atom.child;
1547
- while (child) {
1548
- this.buildView(child, childContext);
1549
- child = child.sibling;
1550
- }
1447
+ else if (newAtom.jsxNode instanceof JSXText) {
1448
+ changeCommits.updateText(newAtom, diffAtom);
1551
1449
  }
1552
- context.host = nativeNode;
1553
- context.isParent = false;
1554
- if (applyRefs) {
1555
- applyRefs();
1450
+ else {
1451
+ changeCommits.updateComponent(newAtom, diffAtom, expectIndex, diffIndex);
1556
1452
  }
1453
+ oldChildren.splice(i, 1);
1454
+ return;
1557
1455
  }
1558
1456
  }
1559
- componentRender(component, from) {
1560
- const { template, render } = component.setup();
1561
- if (template) {
1562
- this.linkTemplate(template, component, from);
1457
+ changeCommits.create(newAtom);
1458
+ }
1459
+ function cleanView(nativeRenderer, atom, isClean) {
1460
+ if (atom.nativeNode) {
1461
+ if (!isClean) {
1462
+ nativeRenderer.remove(atom.nativeNode);
1463
+ isClean = true;
1464
+ }
1465
+ if (atom.jsxNode instanceof JSXElement) {
1466
+ const ref = atom.jsxNode.props[refKey];
1467
+ applyRefs(ref, atom.nativeNode, false);
1563
1468
  }
1564
- component.$$view = {
1565
- render,
1566
- template,
1567
- atom: from
1568
- };
1569
- return from;
1570
1469
  }
1571
- createChainByComponentFactory(context, factory, parent) {
1572
- const component = factory.createInstance(context);
1573
- return {
1574
- jsxNode: component,
1575
- parent,
1576
- sibling: null,
1577
- child: null,
1578
- nativeNode: null
1579
- };
1470
+ let child = atom.child;
1471
+ while (child) {
1472
+ cleanView(nativeRenderer, child, isClean);
1473
+ child = child.sibling;
1580
1474
  }
1581
- createChainByJSXElement(context, element, parent) {
1582
- const atom = {
1583
- jsxNode: element,
1584
- parent,
1585
- sibling: null,
1586
- child: null,
1587
- nativeNode: null
1588
- };
1589
- if (Reflect.has(element.props, 'children')) {
1590
- const jsxChildren = element.props.children;
1591
- const children = this.createChainByChildren(context, Array.isArray(jsxChildren) ? jsxChildren : [jsxChildren], atom, []);
1592
- this.link(atom, children);
1593
- }
1594
- return atom;
1475
+ if (atom.jsxNode instanceof Component) {
1476
+ atom.jsxNode.destroy();
1595
1477
  }
1596
- createChainByJSXText(node, parent) {
1597
- return {
1598
- jsxNode: node,
1599
- parent,
1600
- sibling: null,
1601
- child: null,
1602
- nativeNode: null
1603
- };
1478
+ }
1479
+ function componentRender(component, from, context) {
1480
+ const { template, render } = component.setup();
1481
+ if (template) {
1482
+ linkTemplate(template, component, from);
1483
+ }
1484
+ component.$$view = Object.assign({ render,
1485
+ template, atom: from }, context);
1486
+ return from;
1487
+ }
1488
+ function createChainByComponentFactory(context, factory, parent) {
1489
+ const component = factory.createInstance(context);
1490
+ return {
1491
+ jsxNode: component,
1492
+ parent,
1493
+ sibling: null,
1494
+ child: null,
1495
+ nativeNode: null
1496
+ };
1497
+ }
1498
+ function createChainByJSXElement(context, element, parent) {
1499
+ const atom = {
1500
+ jsxNode: element,
1501
+ parent,
1502
+ sibling: null,
1503
+ child: null,
1504
+ nativeNode: null
1505
+ };
1506
+ if (Reflect.has(element.props, 'children')) {
1507
+ const jsxChildren = element.props.children;
1508
+ const children = createChainByChildren(context, Array.isArray(jsxChildren) ? jsxChildren : [jsxChildren], atom, []);
1509
+ link(atom, children);
1604
1510
  }
1605
- createChainByChildren(context, children, parent, atoms) {
1606
- for (const item of children) {
1607
- if (item instanceof JSXElement) {
1608
- atoms.push(this.createChainByJSXElement(context, item, parent));
1609
- continue;
1610
- }
1611
- if (item instanceof JSXComponent) {
1612
- const childAtom = this.createChainByComponentFactory(context, item, parent);
1613
- atoms.push(childAtom);
1614
- continue;
1615
- }
1616
- if (typeof item === 'string' && item.length) {
1617
- atoms.push(this.createChainByJSXText(new JSXText(item), parent));
1618
- continue;
1619
- }
1620
- if (Array.isArray(item)) {
1621
- this.createChainByChildren(context, item, parent, atoms);
1622
- continue;
1623
- }
1624
- if (item !== null && typeof item !== 'undefined') {
1625
- atoms.push(this.createChainByJSXText(new JSXText(String(item)), parent));
1626
- }
1511
+ return atom;
1512
+ }
1513
+ function createChainByJSXText(node, parent) {
1514
+ return {
1515
+ jsxNode: node,
1516
+ parent,
1517
+ sibling: null,
1518
+ child: null,
1519
+ nativeNode: null
1520
+ };
1521
+ }
1522
+ function createChainByChildren(context, children, parent, atoms) {
1523
+ for (const item of children) {
1524
+ if (item instanceof JSXElement) {
1525
+ atoms.push(createChainByJSXElement(context, item, parent));
1526
+ continue;
1527
+ }
1528
+ if (item instanceof JSXComponent) {
1529
+ const childAtom = createChainByComponentFactory(context, item, parent);
1530
+ atoms.push(childAtom);
1531
+ continue;
1532
+ }
1533
+ if (typeof item === 'string' && item.length) {
1534
+ atoms.push(createChainByJSXText(new JSXText(item), parent));
1535
+ continue;
1536
+ }
1537
+ if (Array.isArray(item)) {
1538
+ createChainByChildren(context, item, parent, atoms);
1539
+ continue;
1540
+ }
1541
+ if (item !== null && typeof item !== 'undefined') {
1542
+ atoms.push(createChainByJSXText(new JSXText(String(item)), parent));
1627
1543
  }
1628
- return atoms;
1629
1544
  }
1630
- linkTemplate(template, component, parent) {
1631
- const children = Array.isArray(template) ? template : [template];
1632
- this.link(parent, this.createChainByChildren(component, children, parent, []));
1545
+ return atoms;
1546
+ }
1547
+ function linkTemplate(template, component, parent) {
1548
+ const children = Array.isArray(template) ? template : [template];
1549
+ link(parent, createChainByChildren(component, children, parent, []));
1550
+ }
1551
+ function link(parent, children) {
1552
+ for (let i = 1; i < children.length; i++) {
1553
+ const prev = children[i - 1];
1554
+ prev.sibling = children[i];
1633
1555
  }
1634
- link(parent, children) {
1635
- for (let i = 1; i < children.length; i++) {
1636
- const prev = children[i - 1];
1637
- prev.sibling = children[i];
1556
+ parent.child = children[0] || null;
1557
+ }
1558
+ function createElement(nativeRenderer, vNode) {
1559
+ const nativeNode = nativeRenderer.createElement(vNode.type);
1560
+ const props = vNode.props;
1561
+ let bindingRefs;
1562
+ const keys = Object.keys(props);
1563
+ for (const key of keys) {
1564
+ if (key === 'children') {
1565
+ continue;
1566
+ }
1567
+ if (key === 'class') {
1568
+ const className = classToString(props[key]);
1569
+ if (className) {
1570
+ nativeRenderer.setClass(nativeNode, className);
1571
+ }
1572
+ continue;
1573
+ }
1574
+ if (key === 'style') {
1575
+ const style = styleToObject(props.style);
1576
+ Object.keys(style).forEach(key => {
1577
+ nativeRenderer.setStyle(nativeNode, key, style[key]);
1578
+ });
1579
+ continue;
1638
1580
  }
1639
- parent.child = children[0] || null;
1640
- }
1641
- createElement(vNode) {
1642
- const nativeNode = this.nativeRenderer.createElement(vNode.type);
1643
- const props = vNode.props;
1644
- let bindingRefs;
1645
- const keys = Object.keys(props);
1646
- for (const key of keys) {
1647
- if (key === 'children') {
1648
- continue;
1649
- }
1650
- if (key === 'class') {
1651
- const className = classToString(props[key]);
1652
- if (className) {
1653
- this.nativeRenderer.setClass(nativeNode, className);
1654
- }
1655
- continue;
1656
- }
1657
- if (key === 'style') {
1658
- const style = styleToObject(props.style);
1659
- Object.keys(style).forEach(key => {
1660
- this.nativeRenderer.setStyle(nativeNode, key, style[key]);
1661
- });
1662
- continue;
1663
- }
1664
- if (/^on[A-Z]/.test(key)) {
1665
- const listener = props[key];
1666
- if (typeof listener === 'function') {
1667
- this.bindEvent(vNode, key, nativeNode, listener);
1668
- }
1669
- continue;
1581
+ if (/^on[A-Z]/.test(key)) {
1582
+ const listener = props[key];
1583
+ if (typeof listener === 'function') {
1584
+ bindEvent(nativeRenderer, vNode, key, nativeNode, listener);
1670
1585
  }
1671
- if (key === refKey) {
1672
- bindingRefs = props[key];
1673
- continue;
1674
- }
1675
- this.nativeRenderer.setProperty(nativeNode, key, props[key]);
1586
+ continue;
1676
1587
  }
1677
- return {
1678
- nativeNode,
1679
- applyRefs: () => {
1680
- this.applyRefs(bindingRefs, nativeNode, true);
1681
- }
1682
- };
1683
- }
1684
- createTextNode(child) {
1685
- return this.nativeRenderer.createTextNode(child.text);
1588
+ if (key === refKey) {
1589
+ bindingRefs = props[key];
1590
+ continue;
1591
+ }
1592
+ nativeRenderer.setProperty(nativeNode, key, props[key]);
1686
1593
  }
1687
- updateNativeNodeProperties(newVNode, oldVNode, nativeNode) {
1688
- const changes = getObjectChanges(newVNode.props, oldVNode.props);
1689
- let unBindRefs;
1690
- let bindRefs;
1691
- for (const [key, value] of changes.remove) {
1692
- if (key === 'children') {
1693
- continue;
1694
- }
1695
- if (key === 'class') {
1696
- this.nativeRenderer.setClass(nativeNode, '');
1697
- continue;
1698
- }
1699
- if (key === 'style') {
1700
- Object.keys(styleToObject(value)).forEach(styleName => {
1701
- this.nativeRenderer.removeStyle(nativeNode, styleName);
1702
- });
1703
- continue;
1704
- }
1705
- if (/^on[A-Z]/.test(key)) {
1706
- if (typeof value === 'function') {
1707
- const type = key.replace(/^on/, '').toLowerCase();
1708
- const oldOn = oldVNode.on;
1709
- this.nativeRenderer.unListen(nativeNode, type, oldOn[type].delegate);
1710
- Reflect.deleteProperty(oldOn, type);
1711
- }
1712
- continue;
1713
- }
1714
- if (key === refKey) {
1715
- unBindRefs = value;
1716
- continue;
1717
- }
1718
- this.nativeRenderer.removeProperty(nativeNode, key);
1594
+ return {
1595
+ nativeNode,
1596
+ applyRefs: () => {
1597
+ applyRefs(bindingRefs, nativeNode, true);
1719
1598
  }
1720
- for (const [key, newValue, oldValue] of changes.replace) {
1721
- if (key === 'children') {
1722
- continue;
1723
- }
1724
- if (key === 'class') {
1725
- const oldClassName = classToString(oldValue);
1726
- const newClassName = classToString(newValue);
1727
- if (oldClassName !== newClassName) {
1728
- this.nativeRenderer.setClass(nativeNode, newClassName);
1729
- }
1730
- continue;
1731
- }
1732
- if (key === 'style') {
1733
- const styleChanges = getObjectChanges(styleToObject(newValue) || {}, styleToObject(oldValue) || {});
1734
- for (const [styleName] of styleChanges.remove) {
1735
- this.nativeRenderer.removeStyle(nativeNode, styleName);
1736
- }
1737
- for (const [styleName, styleValue] of [...styleChanges.add, ...styleChanges.replace]) {
1738
- this.nativeRenderer.setStyle(nativeNode, styleName, styleValue);
1739
- }
1740
- continue;
1741
- }
1742
- if (/^on[A-Z]/.test(key)) {
1743
- const listenType = key.replace(/^on/, '').toLowerCase();
1744
- newVNode.on = oldVNode.on;
1745
- newVNode.on[listenType].listenFn = newValue;
1746
- continue;
1747
- }
1748
- if (key === refKey) {
1749
- unBindRefs = oldValue;
1750
- bindRefs = newValue;
1751
- continue;
1752
- }
1753
- this.nativeRenderer.setProperty(nativeNode, key, newValue);
1599
+ };
1600
+ }
1601
+ function createTextNode(nativeRenderer, child) {
1602
+ return nativeRenderer.createTextNode(child.text);
1603
+ }
1604
+ function updateNativeNodeProperties(nativeRenderer, newVNode, oldVNode, nativeNode) {
1605
+ const changes = getObjectChanges(newVNode.props, oldVNode.props);
1606
+ let unBindRefs;
1607
+ let bindRefs;
1608
+ for (const [key, value] of changes.remove) {
1609
+ if (key === 'children') {
1610
+ continue;
1611
+ }
1612
+ if (key === 'class') {
1613
+ nativeRenderer.setClass(nativeNode, '');
1614
+ continue;
1615
+ }
1616
+ if (key === 'style') {
1617
+ Object.keys(styleToObject(value)).forEach(styleName => {
1618
+ nativeRenderer.removeStyle(nativeNode, styleName);
1619
+ });
1620
+ continue;
1754
1621
  }
1755
- for (const [key, value] of changes.add) {
1756
- if (key === 'children') {
1757
- continue;
1758
- }
1759
- if (key === 'class') {
1760
- this.nativeRenderer.setClass(nativeNode, classToString(value));
1761
- continue;
1622
+ if (/^on[A-Z]/.test(key)) {
1623
+ if (typeof value === 'function') {
1624
+ const type = key.replace(/^on/, '').toLowerCase();
1625
+ const oldOn = oldVNode.on;
1626
+ nativeRenderer.unListen(nativeNode, type, oldOn[type].delegate);
1627
+ Reflect.deleteProperty(oldOn, type);
1762
1628
  }
1763
- if (key === 'style') {
1764
- const styleObj = styleToObject(value);
1765
- Object.keys(styleObj).forEach(styleName => {
1766
- this.nativeRenderer.setStyle(nativeNode, styleName, styleObj[styleName]);
1767
- });
1768
- continue;
1629
+ continue;
1630
+ }
1631
+ if (key === refKey) {
1632
+ unBindRefs = value;
1633
+ continue;
1634
+ }
1635
+ nativeRenderer.removeProperty(nativeNode, key);
1636
+ }
1637
+ for (const [key, newValue, oldValue] of changes.replace) {
1638
+ if (key === 'children') {
1639
+ continue;
1640
+ }
1641
+ if (key === 'class') {
1642
+ const oldClassName = classToString(oldValue);
1643
+ const newClassName = classToString(newValue);
1644
+ if (oldClassName !== newClassName) {
1645
+ nativeRenderer.setClass(nativeNode, newClassName);
1769
1646
  }
1770
- if (/^on[A-Z]/.test(key)) {
1771
- if (typeof value === 'function') {
1772
- this.bindEvent(newVNode, key, nativeNode, value);
1773
- }
1774
- continue;
1647
+ continue;
1648
+ }
1649
+ if (key === 'style') {
1650
+ const styleChanges = getObjectChanges(styleToObject(newValue) || {}, styleToObject(oldValue) || {});
1651
+ for (const [styleName] of styleChanges.remove) {
1652
+ nativeRenderer.removeStyle(nativeNode, styleName);
1775
1653
  }
1776
- if (key === refKey) {
1777
- bindRefs = value;
1778
- continue;
1654
+ for (const [styleName, styleValue] of [...styleChanges.add, ...styleChanges.replace]) {
1655
+ nativeRenderer.setStyle(nativeNode, styleName, styleValue);
1779
1656
  }
1780
- this.nativeRenderer.setProperty(nativeNode, key, value);
1657
+ continue;
1781
1658
  }
1782
- return () => {
1783
- this.applyRefs(unBindRefs, nativeNode, false);
1784
- this.applyRefs(bindRefs, nativeNode, true);
1785
- };
1659
+ if (/^on[A-Z]/.test(key)) {
1660
+ const listenType = key.replace(/^on/, '').toLowerCase();
1661
+ newVNode.on = oldVNode.on;
1662
+ newVNode.on[listenType].listenFn = newValue;
1663
+ continue;
1664
+ }
1665
+ if (key === refKey) {
1666
+ unBindRefs = oldValue;
1667
+ bindRefs = newValue;
1668
+ continue;
1669
+ }
1670
+ nativeRenderer.setProperty(nativeNode, key, newValue);
1786
1671
  }
1787
- applyRefs(refs, nativeNode, binding) {
1788
- const refList = Array.isArray(refs) ? refs : [refs];
1789
- for (const item of refList) {
1790
- if (item instanceof Ref) {
1791
- binding ? item.bind(nativeNode) : item.unBind(nativeNode);
1672
+ for (const [key, value] of changes.add) {
1673
+ if (key === 'children') {
1674
+ continue;
1675
+ }
1676
+ if (key === 'class') {
1677
+ nativeRenderer.setClass(nativeNode, classToString(value));
1678
+ continue;
1679
+ }
1680
+ if (key === 'style') {
1681
+ const styleObj = styleToObject(value);
1682
+ Object.keys(styleObj).forEach(styleName => {
1683
+ nativeRenderer.setStyle(nativeNode, styleName, styleObj[styleName]);
1684
+ });
1685
+ continue;
1686
+ }
1687
+ if (/^on[A-Z]/.test(key)) {
1688
+ if (typeof value === 'function') {
1689
+ bindEvent(nativeRenderer, newVNode, key, nativeNode, value);
1792
1690
  }
1691
+ continue;
1692
+ }
1693
+ if (key === refKey) {
1694
+ bindRefs = value;
1695
+ continue;
1793
1696
  }
1697
+ nativeRenderer.setProperty(nativeNode, key, value);
1794
1698
  }
1795
- bindEvent(vNode, key, nativeNode, listenFn) {
1796
- let on = vNode.on;
1797
- if (!on) {
1798
- vNode.on = on = {};
1699
+ return () => {
1700
+ applyRefs(unBindRefs, nativeNode, false);
1701
+ applyRefs(bindRefs, nativeNode, true);
1702
+ };
1703
+ }
1704
+ function applyRefs(refs, nativeNode, binding) {
1705
+ const refList = Array.isArray(refs) ? refs : [refs];
1706
+ for (const item of refList) {
1707
+ if (item instanceof Ref) {
1708
+ binding ? item.bind(nativeNode) : item.unBind(nativeNode);
1799
1709
  }
1800
- const type = key.replace(/^on/, '').toLowerCase();
1801
- const delegate = function (...args) {
1802
- return delegateObj.listenFn.apply(this, args);
1803
- };
1804
- const delegateObj = {
1805
- delegate,
1806
- listenFn
1807
- };
1808
- on[type] = delegateObj;
1809
- this.nativeRenderer.listen(nativeNode, type, delegate);
1810
1710
  }
1811
- };
1812
- Renderer = __decorate([
1813
- Injectable(),
1814
- __metadata("design:paramtypes", [NativeRenderer,
1815
- RootComponentRef,
1816
- HostRef])
1817
- ], Renderer);
1711
+ }
1712
+ function bindEvent(nativeRenderer, vNode, key, nativeNode, listenFn) {
1713
+ let on = vNode.on;
1714
+ if (!on) {
1715
+ vNode.on = on = {};
1716
+ }
1717
+ const type = key.replace(/^on/, '').toLowerCase();
1718
+ const delegate = function (...args) {
1719
+ return delegateObj.listenFn.apply(this, args);
1720
+ };
1721
+ const delegateObj = {
1722
+ delegate,
1723
+ listenFn
1724
+ };
1725
+ on[type] = delegateObj;
1726
+ nativeRenderer.listen(nativeNode, type, delegate);
1727
+ }
1818
1728
 
1819
1729
  const viewflyErrorFn = makeError('Viewfly');
1820
- /**
1821
- * Viewfly 核心类,用于启动一个 Viewfly 应用
1822
- */
1823
- class Viewfly extends ReflectiveInjector {
1824
- constructor(config) {
1825
- super(config.context || new NullInjector(), [
1826
- Renderer,
1827
- {
1828
- provide: RootComponentRef,
1829
- useFactory: () => {
1830
- return {
1831
- component: this.rootComponent
1832
- };
1833
- }
1834
- },
1835
- {
1836
- provide: NativeRenderer,
1837
- useFactory() {
1838
- throw viewflyErrorFn('You must implement the `NativeRenderer` interface to start Viewfly!');
1839
- }
1840
- },
1841
- {
1842
- provide: HostRef,
1843
- useFactory() {
1844
- throw viewflyErrorFn('Viewfly has not mounted!');
1845
- }
1846
- }
1847
- ]);
1848
- this.config = config;
1849
- this.destroyed = false;
1850
- this.task = null;
1851
- this.rootComponent = this.createRootComponent(config.root);
1852
- }
1853
- provide(providers) {
1854
- providers = Array.isArray(providers) ? providers : [providers];
1855
- this.normalizedProviders.unshift(...providers.map(i => normalizeProvider(i)));
1856
- return this;
1857
- }
1858
- /**
1859
- * 启动 Viewfly
1860
- * @param host 应用根节点
1861
- */
1862
- mount(host) {
1863
- this.provide({
1864
- provide: HostRef,
1865
- useValue: {
1866
- host
1867
- }
1868
- });
1869
- const renderer = this.get(Renderer);
1870
- renderer.render();
1871
- if (this.config.autoUpdate === false) {
1872
- return this;
1873
- }
1874
- const refresh = () => {
1875
- if (this.destroyed) {
1876
- return;
1877
- }
1878
- renderer.render();
1879
- };
1880
- this.rootComponent.onChange = () => {
1881
- this.microTask(refresh);
1730
+ function viewfly({ context, nativeRenderer, autoUpdate, root }) {
1731
+ const appProviders = [];
1732
+ let destroyed = false;
1733
+ const rootComponent = new RootComponent(context || null, () => {
1734
+ provide(appProviders);
1735
+ return () => {
1736
+ return destroyed ? null : root;
1882
1737
  };
1883
- return this;
1884
- }
1885
- render() {
1886
- const renderer = this.get(Renderer);
1887
- renderer.render();
1888
- }
1889
- /**
1890
- * 销毁 Viewfly 实例
1891
- */
1892
- destroy() {
1893
- this.destroyed = true;
1894
- this.rootComponent.markAsDirtied();
1895
- this.render();
1896
- }
1897
- createRootComponent(rootNode) {
1898
- return new RootComponent(() => {
1899
- return () => {
1900
- return this.destroyed ? null : rootNode;
1901
- };
1902
- }, this);
1903
- }
1904
- microTask(callback) {
1905
- if (!this.task) {
1906
- this.task = Promise.resolve().then(() => {
1907
- this.task = null;
1738
+ });
1739
+ const render = createRenderer(rootComponent, nativeRenderer);
1740
+ let isStarted = false;
1741
+ let task = null;
1742
+ function microTask(callback) {
1743
+ if (!task) {
1744
+ task = Promise.resolve().then(() => {
1745
+ task = null;
1908
1746
  callback();
1909
1747
  });
1910
1748
  }
1911
1749
  }
1750
+ let appHost = null;
1751
+ const app = {
1752
+ provide(providers) {
1753
+ if (Array.isArray(providers)) {
1754
+ appProviders.unshift(...providers);
1755
+ }
1756
+ else {
1757
+ appProviders.unshift(providers);
1758
+ }
1759
+ return app;
1760
+ },
1761
+ mount(host) {
1762
+ if (isStarted) {
1763
+ throw viewflyErrorFn('application has already started.');
1764
+ }
1765
+ isStarted = true;
1766
+ appHost = host;
1767
+ render(host);
1768
+ if (!autoUpdate) {
1769
+ return app;
1770
+ }
1771
+ const refresh = () => {
1772
+ if (destroyed) {
1773
+ return;
1774
+ }
1775
+ render(host);
1776
+ };
1777
+ rootComponent.onChange = function () {
1778
+ microTask(refresh);
1779
+ };
1780
+ return app;
1781
+ },
1782
+ render() {
1783
+ if (appHost) {
1784
+ render(appHost);
1785
+ }
1786
+ return app;
1787
+ },
1788
+ destroy() {
1789
+ destroyed = true;
1790
+ rootComponent.markAsDirtied();
1791
+ app.render();
1792
+ }
1793
+ };
1794
+ return app;
1912
1795
  }
1913
1796
 
1914
- export { Component, ForwardRef, Fragment, HostRef, Inject, InjectFlags, Injectable, InjectionToken, Injector, JSXComponent, JSXElement, JSXText, NativeRenderer, NullInjector, Optional, Prop, Ref, ReflectiveInjector, Renderer, RootComponent, RootComponentRef, Scope, Self, SkipSelf, THROW_IF_NOT_FOUND, Type, Viewfly, forwardRef, inject, jsx, jsxs, makeError, normalizeProvider, onDestroy, onMounted, onPropsChanged, onUpdated, provide, useDerived, useEffect, useRef, useSignal, withMemo };
1797
+ export { Component, ForwardRef, Fragment, Inject, InjectFlags, Injectable, InjectionToken, Injector, JSXComponent, JSXElement, JSXText, NativeRenderer, NullInjector, Optional, Prop, Ref, ReflectiveInjector, RootComponent, Scope, Self, SkipSelf, THROW_IF_NOT_FOUND, Type, createRenderer, forwardRef, inject, jsx, jsxs, makeError, normalizeProvider, onDestroy, onMounted, onPropsChanged, onUpdated, provide, useDerived, useEffect, useRef, useSignal, viewfly, withMemo };