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