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