@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.esm.js
CHANGED
|
@@ -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
|
|
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
|
|
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(
|
|
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
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
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
|
-
|
|
1197
|
+
buildView(nativeRenderer, atom, {
|
|
1232
1198
|
isParent: true,
|
|
1233
1199
|
host
|
|
1234
1200
|
});
|
|
1235
1201
|
}
|
|
1236
1202
|
else {
|
|
1237
|
-
|
|
1238
|
-
host,
|
|
1239
|
-
isParent: true
|
|
1240
|
-
});
|
|
1203
|
+
updateView(nativeRenderer, component);
|
|
1241
1204
|
}
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
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
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
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
|
-
|
|
1256
|
-
if (prevSibling) {
|
|
1257
|
-
context.isParent = false;
|
|
1258
|
-
context.host = prevSibling;
|
|
1259
|
-
}
|
|
1226
|
+
nativeNode = createTextNode(nativeRenderer, atom.jsxNode);
|
|
1260
1227
|
}
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
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
|
-
|
|
1270
|
-
|
|
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
|
-
|
|
1279
|
-
const
|
|
1280
|
-
|
|
1281
|
-
|
|
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
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
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
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
}
|
|
1314
|
-
|
|
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
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
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
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
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
|
-
|
|
1451
|
-
|
|
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
|
-
|
|
1332
|
+
nativeRenderer.prependChild(host, newAtom.nativeNode);
|
|
1454
1333
|
}
|
|
1455
1334
|
else {
|
|
1456
|
-
|
|
1335
|
+
nativeRenderer.insertAfter(newAtom.nativeNode, host);
|
|
1457
1336
|
}
|
|
1458
1337
|
}
|
|
1338
|
+
context.host = newAtom.nativeNode;
|
|
1459
1339
|
context.isParent = false;
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
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
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
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
|
-
|
|
1485
|
-
|
|
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
|
-
|
|
1488
|
-
|
|
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
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1412
|
+
updateContext(child);
|
|
1519
1413
|
child = child.sibling;
|
|
1520
1414
|
}
|
|
1521
|
-
atom.jsxNode.rendered();
|
|
1522
1415
|
}
|
|
1523
1416
|
else {
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
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
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
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
|
-
|
|
1539
|
-
|
|
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 (
|
|
1542
|
-
|
|
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
|
-
|
|
1553
|
-
|
|
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
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
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
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
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
|
-
|
|
1582
|
-
|
|
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
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
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
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
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
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
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
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
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
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
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
|
-
|
|
1672
|
-
bindingRefs = props[key];
|
|
1673
|
-
continue;
|
|
1674
|
-
}
|
|
1675
|
-
this.nativeRenderer.setProperty(nativeNode, key, props[key]);
|
|
1586
|
+
continue;
|
|
1676
1587
|
}
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
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
|
-
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
|
|
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
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
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
|
-
|
|
1756
|
-
if (
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
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
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
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
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
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
|
-
|
|
1777
|
-
|
|
1778
|
-
continue;
|
|
1654
|
+
for (const [styleName, styleValue] of [...styleChanges.add, ...styleChanges.replace]) {
|
|
1655
|
+
nativeRenderer.setStyle(nativeNode, styleName, styleValue);
|
|
1779
1656
|
}
|
|
1780
|
-
|
|
1657
|
+
continue;
|
|
1781
1658
|
}
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
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
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
|
|
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
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
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
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
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
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
|
|
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
|
-
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
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,
|
|
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 };
|