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