@weapp-vite/miniprogram-automator 1.2.23 → 1.3.0
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/README.md +22 -0
- package/dist/index.d.mts +36 -3
- package/dist/index.mjs +320 -164
- package/dist/{launch-CSjvON-f.mjs → launch-anJvfi-6.mjs} +1025 -332
- package/dist/operation.d.mts +64 -0
- package/dist/operation.mjs +233 -0
- package/package.json +15 -4
|
@@ -58,6 +58,41 @@ function createAppInstance(definition) {
|
|
|
58
58
|
return instance;
|
|
59
59
|
}
|
|
60
60
|
//#endregion
|
|
61
|
+
//#region ../../mpcore/packages/simulator/src/host/attachmentBindingUpdates.ts
|
|
62
|
+
const bindingUpdates = /* @__PURE__ */ new WeakMap();
|
|
63
|
+
const instanceScopes = /* @__PURE__ */ new WeakMap();
|
|
64
|
+
/** 实例经渲染上下文归属页面,不扩展公开 renderer context 的参数契约。 */
|
|
65
|
+
function bindAttachmentBindingScope(instance, scope) {
|
|
66
|
+
instanceScopes.set(instance, instanceScopes.get(scope) ?? scope);
|
|
67
|
+
}
|
|
68
|
+
/** 仅在挂载回调内同步逻辑绑定,不接管视图提交和 setData 回调。 */
|
|
69
|
+
function runWithAttachmentBindingUpdates(scope, update, callback, value) {
|
|
70
|
+
const previous = bindingUpdates.get(scope);
|
|
71
|
+
const state = previous ?? {
|
|
72
|
+
revision: 0,
|
|
73
|
+
update
|
|
74
|
+
};
|
|
75
|
+
const previousUpdate = state.update;
|
|
76
|
+
state.update = update;
|
|
77
|
+
bindingUpdates.set(scope, state);
|
|
78
|
+
try {
|
|
79
|
+
return callback(value);
|
|
80
|
+
} finally {
|
|
81
|
+
if (previous) state.update = previousUpdate;
|
|
82
|
+
else bindingUpdates.delete(scope);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
function getAttachmentBindingRevision(instance) {
|
|
86
|
+
return bindingUpdates.get(instanceScopes.get(instance) ?? instance);
|
|
87
|
+
}
|
|
88
|
+
function synchronizeAttachmentBindings(instance) {
|
|
89
|
+
const state = bindingUpdates.get(instanceScopes.get(instance) ?? instance);
|
|
90
|
+
if (state) {
|
|
91
|
+
state.revision++;
|
|
92
|
+
state.update();
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
//#endregion
|
|
61
96
|
//#region ../../mpcore/packages/simulator/src/runtime/componentInstance/shared.ts
|
|
62
97
|
const ARRAY_INDEX_PATH_RE$1 = /\[(\d+)\]/g;
|
|
63
98
|
const ARRAY_INDEX_SEGMENT_RE$1 = /^\d+$/;
|
|
@@ -905,6 +940,7 @@ function createComponentInstance(options) {
|
|
|
905
940
|
const previousProperties = Object.fromEntries(propertyKeys.map((key) => [key, cloneValue$1(instance.properties[key])]));
|
|
906
941
|
for (const [key, value] of Object.entries(patch)) assignByPath$1(instance.data, key, value);
|
|
907
942
|
for (const key of dataKeys) instance.properties[key] = instance.data[key];
|
|
943
|
+
synchronizeAttachmentBindings(instance);
|
|
908
944
|
runComponentObservers(definition, instance, changedKeys, previousProperties);
|
|
909
945
|
if (options.requestRender) options.requestRender(callback);
|
|
910
946
|
else callback?.();
|
|
@@ -946,8 +982,11 @@ const componentPageInstances = /* @__PURE__ */ new WeakSet();
|
|
|
946
982
|
function isComponentPageAttaching(instance) {
|
|
947
983
|
return attachingInstances.has(instance);
|
|
948
984
|
}
|
|
949
|
-
function registerComponentPageAttachment(definition,
|
|
950
|
-
definitionAttachments.set(definition,
|
|
985
|
+
function registerComponentPageAttachment(definition, created, attached) {
|
|
986
|
+
definitionAttachments.set(definition, {
|
|
987
|
+
created,
|
|
988
|
+
attached
|
|
989
|
+
});
|
|
951
990
|
}
|
|
952
991
|
function bindComponentPageAttachment(instance, definition) {
|
|
953
992
|
const attach = definitionAttachments.get(definition);
|
|
@@ -958,13 +997,14 @@ function bindComponentPageAttachment(instance, definition) {
|
|
|
958
997
|
if (typeof options?.styleIsolation === "string") instanceStyleIsolation.set(instance, options.styleIsolation);
|
|
959
998
|
}
|
|
960
999
|
}
|
|
961
|
-
function attachComponentPage(instance) {
|
|
1000
|
+
function attachComponentPage(instance, updateBindings) {
|
|
962
1001
|
const attach = instanceAttachments.get(instance);
|
|
963
1002
|
if (!attach) return false;
|
|
964
1003
|
instanceAttachments.delete(instance);
|
|
965
1004
|
attachingInstances.add(instance);
|
|
966
1005
|
try {
|
|
967
|
-
attach.
|
|
1006
|
+
attach.created(instance);
|
|
1007
|
+
runWithAttachmentBindingUpdates(instance, updateBindings, attach.attached, instance);
|
|
968
1008
|
} finally {
|
|
969
1009
|
attachingInstances.delete(instance);
|
|
970
1010
|
}
|
|
@@ -1114,6 +1154,7 @@ function createPageInstance(route, definition, options = {}, pageState = {}) {
|
|
|
1114
1154
|
const rootKey = parseDataPath(key)[0];
|
|
1115
1155
|
if (rootKey) instance.properties[rootKey] = instance.data[rootKey];
|
|
1116
1156
|
}
|
|
1157
|
+
synchronizeAttachmentBindings(instance);
|
|
1117
1158
|
if (pageState.requestRender) pageState.requestRender(callback);
|
|
1118
1159
|
else callback?.();
|
|
1119
1160
|
}
|
|
@@ -1126,6 +1167,262 @@ function createPageInstance(route, definition, options = {}, pageState = {}) {
|
|
|
1126
1167
|
return instance;
|
|
1127
1168
|
}
|
|
1128
1169
|
//#endregion
|
|
1170
|
+
//#region ../../mpcore/packages/simulator/src/view/eventBindingParser.ts
|
|
1171
|
+
const LEGACY_EVENT_NAME_RE = /^\w+$/;
|
|
1172
|
+
const EVENT_BINDING_PREFIXES = [
|
|
1173
|
+
{
|
|
1174
|
+
prefix: "capture-bind:",
|
|
1175
|
+
priority: 0,
|
|
1176
|
+
stopAfter: false,
|
|
1177
|
+
phase: "capture"
|
|
1178
|
+
},
|
|
1179
|
+
{
|
|
1180
|
+
prefix: "capture-catch:",
|
|
1181
|
+
priority: 0,
|
|
1182
|
+
stopAfter: true,
|
|
1183
|
+
phase: "capture"
|
|
1184
|
+
},
|
|
1185
|
+
{
|
|
1186
|
+
prefix: "capture-bind",
|
|
1187
|
+
priority: 1,
|
|
1188
|
+
stopAfter: false,
|
|
1189
|
+
phase: "capture"
|
|
1190
|
+
},
|
|
1191
|
+
{
|
|
1192
|
+
prefix: "capture-catch",
|
|
1193
|
+
priority: 1,
|
|
1194
|
+
stopAfter: true,
|
|
1195
|
+
phase: "capture"
|
|
1196
|
+
},
|
|
1197
|
+
{
|
|
1198
|
+
prefix: "bind:",
|
|
1199
|
+
priority: 0,
|
|
1200
|
+
stopAfter: false,
|
|
1201
|
+
phase: "bubble"
|
|
1202
|
+
},
|
|
1203
|
+
{
|
|
1204
|
+
prefix: "catch:",
|
|
1205
|
+
priority: 0,
|
|
1206
|
+
stopAfter: true,
|
|
1207
|
+
phase: "bubble"
|
|
1208
|
+
},
|
|
1209
|
+
{
|
|
1210
|
+
prefix: "bind",
|
|
1211
|
+
priority: 1,
|
|
1212
|
+
stopAfter: false,
|
|
1213
|
+
phase: "bubble"
|
|
1214
|
+
},
|
|
1215
|
+
{
|
|
1216
|
+
prefix: "catch",
|
|
1217
|
+
priority: 1,
|
|
1218
|
+
stopAfter: true,
|
|
1219
|
+
phase: "bubble"
|
|
1220
|
+
}
|
|
1221
|
+
];
|
|
1222
|
+
function parseEventBinding(attributeName, method) {
|
|
1223
|
+
const definition = EVENT_BINDING_PREFIXES.find((item) => attributeName.startsWith(item.prefix));
|
|
1224
|
+
if (!definition) return null;
|
|
1225
|
+
const eventName = attributeName.slice(definition.prefix.length);
|
|
1226
|
+
if (!eventName || !definition.prefix.endsWith(":") && !LEGACY_EVENT_NAME_RE.test(eventName)) return null;
|
|
1227
|
+
return {
|
|
1228
|
+
eventName,
|
|
1229
|
+
method,
|
|
1230
|
+
phase: definition.phase,
|
|
1231
|
+
priority: definition.priority,
|
|
1232
|
+
stopAfter: definition.stopAfter
|
|
1233
|
+
};
|
|
1234
|
+
}
|
|
1235
|
+
function collectEventBindings(attributes = {}, includeCapture = true) {
|
|
1236
|
+
const eventBindings = /* @__PURE__ */ new Map();
|
|
1237
|
+
let captureEventBindings;
|
|
1238
|
+
const priorities = /* @__PURE__ */ new Map();
|
|
1239
|
+
for (const [attributeName, method] of Object.entries(attributes)) {
|
|
1240
|
+
const candidate = parseEventBinding(attributeName, method);
|
|
1241
|
+
if (!candidate || !includeCapture && candidate.phase === "capture") continue;
|
|
1242
|
+
const eventPriorities = priorities.get(candidate.eventName) ?? {};
|
|
1243
|
+
if (candidate.priority < (eventPriorities[candidate.phase] ?? -1)) continue;
|
|
1244
|
+
(candidate.phase === "bubble" ? eventBindings : captureEventBindings ??= /* @__PURE__ */ new Map()).set(candidate.eventName, {
|
|
1245
|
+
method: candidate.method,
|
|
1246
|
+
stopAfter: candidate.stopAfter
|
|
1247
|
+
});
|
|
1248
|
+
eventPriorities[candidate.phase] = candidate.priority;
|
|
1249
|
+
priorities.set(candidate.eventName, eventPriorities);
|
|
1250
|
+
}
|
|
1251
|
+
return {
|
|
1252
|
+
eventBindings,
|
|
1253
|
+
captureEventBindings
|
|
1254
|
+
};
|
|
1255
|
+
}
|
|
1256
|
+
/** 单事件查询只保留命中的绑定,原生交互不构造整张事件表。 */
|
|
1257
|
+
function resolveEventBindingPhases(attributes, eventName, includeCapture = true) {
|
|
1258
|
+
if (!attributes) return null;
|
|
1259
|
+
let bindings = null;
|
|
1260
|
+
let bubblePriority = -1;
|
|
1261
|
+
let capturePriority = -1;
|
|
1262
|
+
for (const [attributeName, method] of Object.entries(attributes)) {
|
|
1263
|
+
const candidate = parseEventBinding(attributeName, method);
|
|
1264
|
+
if (!candidate || candidate.eventName !== eventName || !includeCapture && candidate.phase === "capture") continue;
|
|
1265
|
+
const priority = candidate.phase === "bubble" ? bubblePriority : capturePriority;
|
|
1266
|
+
if (candidate.priority < priority) continue;
|
|
1267
|
+
bindings ??= {};
|
|
1268
|
+
bindings[candidate.phase] = {
|
|
1269
|
+
method: candidate.method,
|
|
1270
|
+
stopAfter: candidate.stopAfter
|
|
1271
|
+
};
|
|
1272
|
+
if (candidate.phase === "bubble") bubblePriority = candidate.priority;
|
|
1273
|
+
else capturePriority = candidate.priority;
|
|
1274
|
+
}
|
|
1275
|
+
return bindings;
|
|
1276
|
+
}
|
|
1277
|
+
//#endregion
|
|
1278
|
+
//#region ../../mpcore/packages/simulator/src/view/nodeDataset.ts
|
|
1279
|
+
const DATASET_NAME_RE = /-([a-z])/g;
|
|
1280
|
+
function isDatasetAttribute(attributeName) {
|
|
1281
|
+
return attributeName.startsWith("data-") && !attributeName.startsWith("data-sim-");
|
|
1282
|
+
}
|
|
1283
|
+
function toDatasetKey(attributeName) {
|
|
1284
|
+
return attributeName.slice(5).replace(DATASET_NAME_RE, (_match, char) => char.toUpperCase());
|
|
1285
|
+
}
|
|
1286
|
+
function collectNodeDataset(node) {
|
|
1287
|
+
if (node.dataset) return { ...node.dataset };
|
|
1288
|
+
const dataset = {};
|
|
1289
|
+
for (const [key, value] of Object.entries(node.attribs ?? {})) if (isDatasetAttribute(key)) dataset[toDatasetKey(key)] = value;
|
|
1290
|
+
return dataset;
|
|
1291
|
+
}
|
|
1292
|
+
//#endregion
|
|
1293
|
+
//#region ../../mpcore/packages/simulator/src/view/componentEvent.ts
|
|
1294
|
+
const eventNodes = /* @__PURE__ */ new WeakMap();
|
|
1295
|
+
/** 在构造子树之前建立父链,created/observer 中的事件也能访问声明树。 */
|
|
1296
|
+
function registerComponentEventNode(node, scope, parent) {
|
|
1297
|
+
node.parent = parent ?? null;
|
|
1298
|
+
eventNodes.set(node, {
|
|
1299
|
+
scope,
|
|
1300
|
+
target: node
|
|
1301
|
+
});
|
|
1302
|
+
}
|
|
1303
|
+
/** 宿主与作用域共享同一份分阶段绑定,eventBindings 仍是原有的冒泡存储。 */
|
|
1304
|
+
function bindComponentEventHost(node) {
|
|
1305
|
+
const bindings = collectEventBindings(node.attribs);
|
|
1306
|
+
eventNodes.get(node).bindings = bindings;
|
|
1307
|
+
return bindings;
|
|
1308
|
+
}
|
|
1309
|
+
/** 渲染会把宿主折叠进模板根;事件仍保留两层独立的绑定和声明所有者。 */
|
|
1310
|
+
function mergeComponentEventRoot(root, host) {
|
|
1311
|
+
const entry = eventNodes.get(root);
|
|
1312
|
+
if (entry.target === root) entry.target = {
|
|
1313
|
+
attribs: root.attribs,
|
|
1314
|
+
dataset: root.dataset
|
|
1315
|
+
};
|
|
1316
|
+
entry.hosts ??= [];
|
|
1317
|
+
entry.hosts.push(host);
|
|
1318
|
+
root.parent = host.parent;
|
|
1319
|
+
}
|
|
1320
|
+
/** 按渲染完成后的实际宿主父链排序;输入只包含本轮存活的组件作用域。 */
|
|
1321
|
+
function orderComponentAttachmentScopes(scopeIds, componentScopes) {
|
|
1322
|
+
const hostScopes = /* @__PURE__ */ new Map();
|
|
1323
|
+
for (const scopeId of scopeIds) hostScopes.set(componentScopes.get(scopeId).hostNode, scopeId);
|
|
1324
|
+
const ordered = [];
|
|
1325
|
+
const visited = /* @__PURE__ */ new Set();
|
|
1326
|
+
const visit = (node) => {
|
|
1327
|
+
if (!node || visited.has(node)) return;
|
|
1328
|
+
visited.add(node);
|
|
1329
|
+
visit(node.parent);
|
|
1330
|
+
const hosts = eventNodes.get(node)?.hosts;
|
|
1331
|
+
if (hosts) for (let index = hosts.length - 1; index >= 0; index--) visit(hosts[index]);
|
|
1332
|
+
const scopeId = hostScopes.get(node);
|
|
1333
|
+
if (scopeId !== void 0) ordered.push(scopeId);
|
|
1334
|
+
};
|
|
1335
|
+
for (const host of hostScopes.keys()) visit(host);
|
|
1336
|
+
return ordered;
|
|
1337
|
+
}
|
|
1338
|
+
function buildComponentTrigger(componentScopeId, context) {
|
|
1339
|
+
return (instance, eventName, detail, triggerOptions) => {
|
|
1340
|
+
const originScope = context.componentScopes.get(componentScopeId);
|
|
1341
|
+
const origin = originScope?.hostNode;
|
|
1342
|
+
if (!originScope || !origin) return;
|
|
1343
|
+
const bubbles = triggerOptions?.bubbles ?? false;
|
|
1344
|
+
const capturePhase = triggerOptions?.capturePhase ?? false;
|
|
1345
|
+
const composed = triggerOptions?.composed ?? false;
|
|
1346
|
+
const target = {
|
|
1347
|
+
dataset: originScope.dataset ?? collectNodeDataset(origin),
|
|
1348
|
+
id: originScope.hostId ?? ""
|
|
1349
|
+
};
|
|
1350
|
+
const mark = instance.__lastInteractionEvent__?.mark;
|
|
1351
|
+
const listeners = [];
|
|
1352
|
+
const collect = (entry, isOrigin) => {
|
|
1353
|
+
if (!composed && entry.scope.getScopeId() !== originScope.listenerScopeId) return false;
|
|
1354
|
+
const bindings = entry.bindings ? {
|
|
1355
|
+
bubble: entry.bindings.eventBindings?.get(eventName),
|
|
1356
|
+
capture: entry.bindings.captureEventBindings?.get(eventName)
|
|
1357
|
+
} : resolveEventBindingPhases(entry.target.attribs, eventName);
|
|
1358
|
+
if (bindings?.bubble || bindings?.capture) listeners.push({
|
|
1359
|
+
scope: entry.scope,
|
|
1360
|
+
bindings,
|
|
1361
|
+
currentTarget: isOrigin ? target : {
|
|
1362
|
+
dataset: collectNodeDataset(entry.target),
|
|
1363
|
+
id: entry.target.attribs?.id ?? ""
|
|
1364
|
+
},
|
|
1365
|
+
origin: isOrigin
|
|
1366
|
+
});
|
|
1367
|
+
return true;
|
|
1368
|
+
};
|
|
1369
|
+
let current = origin;
|
|
1370
|
+
while (current) {
|
|
1371
|
+
const entry = eventNodes.get(current);
|
|
1372
|
+
if (entry) {
|
|
1373
|
+
if (!collect(entry, current === origin)) break;
|
|
1374
|
+
let crossedBoundary = false;
|
|
1375
|
+
for (const host of entry.hosts ?? []) if (!collect(eventNodes.get(host), false)) {
|
|
1376
|
+
crossedBoundary = true;
|
|
1377
|
+
break;
|
|
1378
|
+
}
|
|
1379
|
+
if (crossedBoundary) break;
|
|
1380
|
+
}
|
|
1381
|
+
if (!bubbles && !capturePhase) break;
|
|
1382
|
+
current = current.parent;
|
|
1383
|
+
}
|
|
1384
|
+
const handlers = [];
|
|
1385
|
+
let stopped = false;
|
|
1386
|
+
if (capturePhase) for (let index = listeners.length - 1; index >= 0; index--) {
|
|
1387
|
+
const listener = listeners[index];
|
|
1388
|
+
const binding = listener.bindings.capture;
|
|
1389
|
+
if (binding) {
|
|
1390
|
+
handlers.push({
|
|
1391
|
+
scope: listener.scope,
|
|
1392
|
+
binding,
|
|
1393
|
+
currentTarget: listener.currentTarget
|
|
1394
|
+
});
|
|
1395
|
+
if (binding.stopAfter) {
|
|
1396
|
+
stopped = true;
|
|
1397
|
+
break;
|
|
1398
|
+
}
|
|
1399
|
+
}
|
|
1400
|
+
}
|
|
1401
|
+
if (!stopped) for (const listener of listeners) {
|
|
1402
|
+
if (!bubbles && !listener.origin) continue;
|
|
1403
|
+
const binding = listener.bindings.bubble;
|
|
1404
|
+
if (binding) {
|
|
1405
|
+
handlers.push({
|
|
1406
|
+
scope: listener.scope,
|
|
1407
|
+
binding,
|
|
1408
|
+
currentTarget: listener.currentTarget
|
|
1409
|
+
});
|
|
1410
|
+
if (binding.stopAfter) break;
|
|
1411
|
+
}
|
|
1412
|
+
}
|
|
1413
|
+
for (const { scope, binding, currentTarget } of handlers) scope.getMethod(binding.method)?.({
|
|
1414
|
+
bubbles,
|
|
1415
|
+
capturePhase,
|
|
1416
|
+
composed,
|
|
1417
|
+
currentTarget,
|
|
1418
|
+
detail,
|
|
1419
|
+
mark,
|
|
1420
|
+
target,
|
|
1421
|
+
type: eventName
|
|
1422
|
+
});
|
|
1423
|
+
};
|
|
1424
|
+
}
|
|
1425
|
+
//#endregion
|
|
1129
1426
|
//#region ../../mpcore/packages/simulator/src/view/conditionalChildren.ts
|
|
1130
1427
|
function selectConditionalChildren(children, evaluate) {
|
|
1131
1428
|
const selected = [];
|
|
@@ -1181,11 +1478,77 @@ function customTabBarHostScope() {
|
|
|
1181
1478
|
};
|
|
1182
1479
|
}
|
|
1183
1480
|
//#endregion
|
|
1481
|
+
//#region ../../mpcore/packages/simulator/src/view/inspectionTree.ts
|
|
1482
|
+
const inspectionChildren = /* @__PURE__ */ new WeakMap();
|
|
1483
|
+
const inspectionParents = /* @__PURE__ */ new WeakMap();
|
|
1484
|
+
const emptyChildren = [];
|
|
1485
|
+
function getInspectionChildren(node) {
|
|
1486
|
+
return inspectionChildren.get(node) ?? node.children ?? emptyChildren;
|
|
1487
|
+
}
|
|
1488
|
+
function getInspectionParent(node) {
|
|
1489
|
+
return inspectionParents.get(node) ?? node.parent ?? null;
|
|
1490
|
+
}
|
|
1491
|
+
function collectRenderedNodes(node, nodes) {
|
|
1492
|
+
if (nodes.has(node)) return;
|
|
1493
|
+
nodes.add(node);
|
|
1494
|
+
for (const child of node.children ?? emptyChildren) collectRenderedNodes(child, nodes);
|
|
1495
|
+
}
|
|
1496
|
+
/** 原生检查器保留未投影声明;可见 DOM、WXML 和事件父链不因此增加节点。 */
|
|
1497
|
+
function registerInspectionTrees(root, pass, scopes) {
|
|
1498
|
+
if (!pass.hasUnprojectedSlots) return;
|
|
1499
|
+
const rendered = /* @__PURE__ */ new Set();
|
|
1500
|
+
collectRenderedNodes(root, rendered);
|
|
1501
|
+
const candidates = /* @__PURE__ */ new Map();
|
|
1502
|
+
for (const [entries, group] of pass.slotDeclarations) {
|
|
1503
|
+
if (scopes.get(group.scopeId)?.hostNode !== group.parent) continue;
|
|
1504
|
+
const host = pass.componentRoots.get(group.scopeId);
|
|
1505
|
+
if (!host) continue;
|
|
1506
|
+
for (const entry of entries) for (const node of pass.renderedSlots.get(entry) ?? emptyChildren) candidates.set(node, host);
|
|
1507
|
+
}
|
|
1508
|
+
const nested = /* @__PURE__ */ new Set();
|
|
1509
|
+
const visited = /* @__PURE__ */ new Set();
|
|
1510
|
+
const indexChildren = (node) => {
|
|
1511
|
+
if (visited.has(node)) return;
|
|
1512
|
+
visited.add(node);
|
|
1513
|
+
for (const child of node.children ?? emptyChildren) {
|
|
1514
|
+
nested.add(child);
|
|
1515
|
+
if (!rendered.has(child)) inspectionParents.set(child, node);
|
|
1516
|
+
indexChildren(child);
|
|
1517
|
+
}
|
|
1518
|
+
};
|
|
1519
|
+
for (const node of candidates.keys()) indexChildren(node);
|
|
1520
|
+
for (const [node, host] of candidates) {
|
|
1521
|
+
if (rendered.has(node) || nested.has(node) || node === host) continue;
|
|
1522
|
+
let children = inspectionChildren.get(host);
|
|
1523
|
+
if (!children) {
|
|
1524
|
+
children = [...host.children ?? emptyChildren];
|
|
1525
|
+
inspectionChildren.set(host, children);
|
|
1526
|
+
}
|
|
1527
|
+
children.push(node);
|
|
1528
|
+
inspectionParents.set(node, host);
|
|
1529
|
+
}
|
|
1530
|
+
}
|
|
1531
|
+
//#endregion
|
|
1184
1532
|
//#region ../../mpcore/packages/simulator/src/view/loopEntries.ts
|
|
1533
|
+
const LOOP_SCOPE_ESCAPE_RE = /[^\w-]/g;
|
|
1534
|
+
function escapeScopeCodeUnit(character) {
|
|
1535
|
+
return `~${character.charCodeAt(0).toString(16).padStart(4, "0")}`;
|
|
1536
|
+
}
|
|
1537
|
+
function encodeLoopCoordinate(value) {
|
|
1538
|
+
return value.replace(LOOP_SCOPE_ESCAPE_RE, escapeScopeCodeUnit);
|
|
1539
|
+
}
|
|
1185
1540
|
function resolveLoopEntries(value) {
|
|
1186
1541
|
if (Array.isArray(value)) return value.map((item, index) => [index, item]);
|
|
1187
1542
|
return value !== null && typeof value === "object" ? Object.entries(value) : [];
|
|
1188
1543
|
}
|
|
1544
|
+
function resolveLoopInstanceSuffix(item, index, key, occurrences) {
|
|
1545
|
+
if (!key || !occurrences) return `:for-${encodeLoopCoordinate(String(index))}`;
|
|
1546
|
+
const value = key === "*this" ? item : item?.[key];
|
|
1547
|
+
const normalized = encodeLoopCoordinate(String(value ?? ""));
|
|
1548
|
+
const occurrence = occurrences.get(normalized) ?? 0;
|
|
1549
|
+
occurrences.set(normalized, occurrence + 1);
|
|
1550
|
+
return `:key-${normalized}${occurrence ? `:duplicate-${occurrence}` : ""}`;
|
|
1551
|
+
}
|
|
1189
1552
|
//#endregion
|
|
1190
1553
|
//#region ../../mpcore/packages/simulator/src/view/renderedTree.ts
|
|
1191
1554
|
/** 在循环展开和组件替换完成后,让父节点关系指向本次渲染树。 */
|
|
@@ -1194,7 +1557,45 @@ function linkRenderedParents(root, parent = null) {
|
|
|
1194
1557
|
for (const child of root.children ?? []) linkRenderedParents(child, root);
|
|
1195
1558
|
}
|
|
1196
1559
|
//#endregion
|
|
1197
|
-
//#region ../../
|
|
1560
|
+
//#region ../../mpcore/packages/simulator/src/view/renderPass.ts
|
|
1561
|
+
const initializedPages = /* @__PURE__ */ new WeakMap();
|
|
1562
|
+
function createRenderPass(propertyUpdate = false, parent) {
|
|
1563
|
+
return {
|
|
1564
|
+
seenComponentScopes: /* @__PURE__ */ new Set(),
|
|
1565
|
+
componentRoots: /* @__PURE__ */ new Map(),
|
|
1566
|
+
slotDeclarations: /* @__PURE__ */ new Map(),
|
|
1567
|
+
renderedSlots: /* @__PURE__ */ new Map(),
|
|
1568
|
+
hasUnprojectedSlots: false,
|
|
1569
|
+
propertyUpdate,
|
|
1570
|
+
bindingUpdate: parent?.bindingUpdate,
|
|
1571
|
+
bindingRevision: parent?.bindingUpdate?.revision ?? 0
|
|
1572
|
+
};
|
|
1573
|
+
}
|
|
1574
|
+
function createPageRenderPass(page, cache) {
|
|
1575
|
+
const pass = createRenderPass(initializedPages.get(cache)?.has(page) ?? false);
|
|
1576
|
+
pass.bindingUpdate = getAttachmentBindingRevision(page);
|
|
1577
|
+
pass.bindingRevision = pass.bindingUpdate?.revision ?? 0;
|
|
1578
|
+
return pass;
|
|
1579
|
+
}
|
|
1580
|
+
function isRenderPassStale(pass) {
|
|
1581
|
+
return pass.bindingUpdate !== void 0 && pass.bindingUpdate.revision !== pass.bindingRevision;
|
|
1582
|
+
}
|
|
1583
|
+
function markPageTreeConstructed(page, cache) {
|
|
1584
|
+
let pages = initializedPages.get(cache);
|
|
1585
|
+
if (!pages) {
|
|
1586
|
+
pages = /* @__PURE__ */ new WeakSet();
|
|
1587
|
+
initializedPages.set(cache, pages);
|
|
1588
|
+
}
|
|
1589
|
+
pages.add(page);
|
|
1590
|
+
}
|
|
1591
|
+
function registerSlotDeclarations(pass, slots, parent, scopeId) {
|
|
1592
|
+
for (const entries of slots.values()) if (!pass.slotDeclarations.has(entries)) pass.slotDeclarations.set(entries, {
|
|
1593
|
+
parent,
|
|
1594
|
+
scopeId
|
|
1595
|
+
});
|
|
1596
|
+
}
|
|
1597
|
+
//#endregion
|
|
1598
|
+
//#region ../../node_modules/.pnpm/@babel+parser@8.0.7/node_modules/@babel/parser/lib/index.js
|
|
1198
1599
|
var Position = class {
|
|
1199
1600
|
constructor(line, col, index) {
|
|
1200
1601
|
this.line = void 0;
|
|
@@ -9263,7 +9664,11 @@ var StatementParser = class extends ExpressionParser {
|
|
|
9263
9664
|
if (isDeclaration) node.id = this.parseFunctionId(requireId);
|
|
9264
9665
|
this.scope.enter(514);
|
|
9265
9666
|
this.prodParam.enter(functionFlags(isAsync, node.generator));
|
|
9266
|
-
if (!isDeclaration
|
|
9667
|
+
if (!isDeclaration && tokenIsIdentifier(this.state.type)) {
|
|
9668
|
+
this.expressionScope.enter(newExpressionScope());
|
|
9669
|
+
node.id = this.parseFunctionId();
|
|
9670
|
+
this.expressionScope.exit();
|
|
9671
|
+
}
|
|
9267
9672
|
this.parseFunctionParams(node, false);
|
|
9268
9673
|
this.parseFunctionBodyAndFinish(node, isDeclaration ? "FunctionDeclaration" : "FunctionExpression");
|
|
9269
9674
|
this.prodParam.exit();
|
|
@@ -12913,7 +13318,8 @@ function isComponentAttached(instance) {
|
|
|
12913
13318
|
return attachmentStates.get(instance) === "attached";
|
|
12914
13319
|
}
|
|
12915
13320
|
function hasPendingComponentAttachments(instances) {
|
|
12916
|
-
|
|
13321
|
+
for (const instance of instances) if (attachmentStates.get(instance) === "attaching") return true;
|
|
13322
|
+
return false;
|
|
12917
13323
|
}
|
|
12918
13324
|
function flushComponentReady(instances, ready) {
|
|
12919
13325
|
const all = [...instances];
|
|
@@ -12923,19 +13329,71 @@ function flushComponentReady(instances, ready) {
|
|
|
12923
13329
|
for (const instance of pending) ready(instance);
|
|
12924
13330
|
return pending.length > 0;
|
|
12925
13331
|
}
|
|
12926
|
-
function flushComponentAttachments(
|
|
12927
|
-
const pending =
|
|
12928
|
-
for (const
|
|
13332
|
+
function flushComponentAttachments(componentCache, scopeIds, attach) {
|
|
13333
|
+
const pending = /* @__PURE__ */ new Map();
|
|
13334
|
+
for (const scopeId of scopeIds) {
|
|
13335
|
+
const instance = componentCache.get(scopeId);
|
|
13336
|
+
if (!instance) continue;
|
|
13337
|
+
const state = attachmentStates.get(instance);
|
|
13338
|
+
if (state === "attaching") return false;
|
|
13339
|
+
if (!state) pending.set(scopeId, instance);
|
|
13340
|
+
}
|
|
13341
|
+
for (const instance of pending.values()) attachmentStates.set(instance, "attaching");
|
|
12929
13342
|
try {
|
|
12930
|
-
for (const instance of pending)
|
|
12931
|
-
|
|
12932
|
-
|
|
12933
|
-
|
|
13343
|
+
for (const [scopeId, instance] of pending) {
|
|
13344
|
+
if (componentCache.get(scopeId) !== instance) return "restart";
|
|
13345
|
+
let restart;
|
|
13346
|
+
try {
|
|
13347
|
+
restart = attach(instance);
|
|
13348
|
+
} finally {
|
|
13349
|
+
attachmentStates.set(instance, "attached");
|
|
13350
|
+
}
|
|
13351
|
+
if (restart) return "restart";
|
|
12934
13352
|
}
|
|
12935
13353
|
} finally {
|
|
12936
|
-
for (const instance of pending) if (attachmentStates.get(instance) === "attaching") attachmentStates.delete(instance);
|
|
13354
|
+
for (const instance of pending.values()) if (attachmentStates.get(instance) === "attaching") attachmentStates.delete(instance);
|
|
13355
|
+
}
|
|
13356
|
+
return pending.size > 0 ? "attached" : false;
|
|
13357
|
+
}
|
|
13358
|
+
//#endregion
|
|
13359
|
+
//#region ../../mpcore/packages/simulator/src/runtime/componentInstance/construction.ts
|
|
13360
|
+
const constructionStates = /* @__PURE__ */ new WeakMap();
|
|
13361
|
+
const constructingInstances = /* @__PURE__ */ new WeakSet();
|
|
13362
|
+
function isComponentConstructing(instance) {
|
|
13363
|
+
return instance !== void 0 && constructingInstances.has(instance);
|
|
13364
|
+
}
|
|
13365
|
+
function hasPendingComponentConstruction(componentCache) {
|
|
13366
|
+
return constructionStates.has(componentCache);
|
|
13367
|
+
}
|
|
13368
|
+
function beginComponentConstruction(componentCache, scopeId, instance) {
|
|
13369
|
+
let state = constructionStates.get(componentCache);
|
|
13370
|
+
if (!state) {
|
|
13371
|
+
state = {
|
|
13372
|
+
depth: 0,
|
|
13373
|
+
created: /* @__PURE__ */ new Map()
|
|
13374
|
+
};
|
|
13375
|
+
constructionStates.set(componentCache, state);
|
|
13376
|
+
}
|
|
13377
|
+
state.depth++;
|
|
13378
|
+
state.created.set(scopeId, instance);
|
|
13379
|
+
constructingInstances.add(instance);
|
|
13380
|
+
}
|
|
13381
|
+
function discardComponentConstruction(componentCache, componentScopes, scopeId) {
|
|
13382
|
+
const state = constructionStates.get(componentCache);
|
|
13383
|
+
const prefix = `${scopeId}/`;
|
|
13384
|
+
for (const [createdScopeId, instance] of state.created) {
|
|
13385
|
+
if (createdScopeId !== scopeId && !createdScopeId.startsWith(prefix)) continue;
|
|
13386
|
+
if (componentCache.get(createdScopeId) === instance) {
|
|
13387
|
+
componentCache.delete(createdScopeId);
|
|
13388
|
+
componentScopes.delete(createdScopeId);
|
|
13389
|
+
}
|
|
13390
|
+
state.created.delete(createdScopeId);
|
|
12937
13391
|
}
|
|
12938
|
-
|
|
13392
|
+
}
|
|
13393
|
+
function finishComponentConstruction(componentCache, instance) {
|
|
13394
|
+
constructingInstances.delete(instance);
|
|
13395
|
+
const state = constructionStates.get(componentCache);
|
|
13396
|
+
if (--state.depth === 0) constructionStates.delete(componentCache);
|
|
12939
13397
|
}
|
|
12940
13398
|
//#endregion
|
|
12941
13399
|
//#region ../../mpcore/packages/simulator/src/runtime/componentInstance/discardedReady.ts
|
|
@@ -12958,6 +13416,35 @@ function flushDiscardedComponentReady(cache, pageScopeId, ready) {
|
|
|
12958
13416
|
if (!pending.size) discardedReady.delete(cache);
|
|
12959
13417
|
}
|
|
12960
13418
|
//#endregion
|
|
13419
|
+
//#region ../../mpcore/packages/simulator/src/runtime/componentInstance/propertyBindings.ts
|
|
13420
|
+
const consumedPageChanges = /* @__PURE__ */ new WeakMap();
|
|
13421
|
+
function syncComponentProperties(instance, definition, nextProperties, bindingExpressions, changedPageKeys, beforeObservers) {
|
|
13422
|
+
const freshPageChanges = changedPageKeys.length > 0 && consumedPageChanges.get(instance) !== changedPageKeys;
|
|
13423
|
+
if (freshPageChanges) consumedPageChanges.set(instance, changedPageKeys);
|
|
13424
|
+
const changedRootKeys = [];
|
|
13425
|
+
const previousProperties = {};
|
|
13426
|
+
for (const [key, value] of Object.entries(nextProperties)) {
|
|
13427
|
+
const nextValue = normalizeComponentPropertyValue(definition, key, value);
|
|
13428
|
+
const bindingExpression = bindingExpressions[key];
|
|
13429
|
+
const bindingAffected = freshPageChanges && !!bindingExpression && changedPageKeys.some((changedKey) => {
|
|
13430
|
+
return changedKey === bindingExpression || changedKey.startsWith(`${bindingExpression}.`) || changedKey.startsWith(`${bindingExpression}[`);
|
|
13431
|
+
});
|
|
13432
|
+
const previousSnapshot = instance.__propertySnapshots?.[key];
|
|
13433
|
+
if (hasComponentPropertyValueChanged(instance.properties[key], previousSnapshot, nextValue, bindingAffected)) {
|
|
13434
|
+
previousProperties[key] = instance.properties[key];
|
|
13435
|
+
const deliveredValue = cloneValue$1(nextValue);
|
|
13436
|
+
instance.properties[key] = deliveredValue;
|
|
13437
|
+
if (Object.hasOwn(definition.properties ?? {}, key)) instance.data[key] = deliveredValue;
|
|
13438
|
+
changedRootKeys.push(key);
|
|
13439
|
+
}
|
|
13440
|
+
instance.__propertySnapshots ??= {};
|
|
13441
|
+
instance.__propertySnapshots[key] = cloneValue$1(nextValue);
|
|
13442
|
+
}
|
|
13443
|
+
if (changedRootKeys.length === 0) return;
|
|
13444
|
+
beforeObservers?.(instance, "properties");
|
|
13445
|
+
runComponentObservers(definition, instance, changedRootKeys, previousProperties);
|
|
13446
|
+
}
|
|
13447
|
+
//#endregion
|
|
12961
13448
|
//#region ../../mpcore/packages/simulator/src/runtime/pageLifecycle.ts
|
|
12962
13449
|
const loadingPages = /* @__PURE__ */ new WeakSet();
|
|
12963
13450
|
function isPageBeforeReady(page) {
|
|
@@ -13046,98 +13533,6 @@ function createPluginArtifactSource(fallback, miniprogramRootPath, plugins) {
|
|
|
13046
13533
|
readText: (filePath) => fallback.readText(resolvePhysicalPath(filePath))
|
|
13047
13534
|
};
|
|
13048
13535
|
}
|
|
13049
|
-
//#endregion
|
|
13050
|
-
//#region ../../mpcore/packages/simulator/src/view/nodeDataset.ts
|
|
13051
|
-
const DATASET_NAME_RE = /-([a-z])/g;
|
|
13052
|
-
function isDatasetAttribute(attributeName) {
|
|
13053
|
-
return attributeName.startsWith("data-") && !attributeName.startsWith("data-sim-");
|
|
13054
|
-
}
|
|
13055
|
-
function toDatasetKey(attributeName) {
|
|
13056
|
-
return attributeName.slice(5).replace(DATASET_NAME_RE, (_match, char) => char.toUpperCase());
|
|
13057
|
-
}
|
|
13058
|
-
function collectNodeDataset(node) {
|
|
13059
|
-
if (node.dataset) return { ...node.dataset };
|
|
13060
|
-
const dataset = {};
|
|
13061
|
-
for (const [key, value] of Object.entries(node.attribs ?? {})) if (isDatasetAttribute(key)) dataset[toDatasetKey(key)] = value;
|
|
13062
|
-
return dataset;
|
|
13063
|
-
}
|
|
13064
|
-
//#endregion
|
|
13065
|
-
//#region ../../mpcore/packages/simulator/src/view/eventBinding.ts
|
|
13066
|
-
const LEGACY_EVENT_NAME_RE = /^\w+$/;
|
|
13067
|
-
const EVENT_BINDING_PREFIXES = [
|
|
13068
|
-
{
|
|
13069
|
-
prefix: "bind:",
|
|
13070
|
-
priority: 0,
|
|
13071
|
-
stopAfter: false
|
|
13072
|
-
},
|
|
13073
|
-
{
|
|
13074
|
-
prefix: "catch:",
|
|
13075
|
-
priority: 0,
|
|
13076
|
-
stopAfter: true
|
|
13077
|
-
},
|
|
13078
|
-
{
|
|
13079
|
-
prefix: "bind",
|
|
13080
|
-
priority: 1,
|
|
13081
|
-
stopAfter: false
|
|
13082
|
-
},
|
|
13083
|
-
{
|
|
13084
|
-
prefix: "catch",
|
|
13085
|
-
priority: 1,
|
|
13086
|
-
stopAfter: true
|
|
13087
|
-
}
|
|
13088
|
-
];
|
|
13089
|
-
function parseEventBinding(attributeName, method) {
|
|
13090
|
-
const definition = EVENT_BINDING_PREFIXES.find((item) => attributeName.startsWith(item.prefix));
|
|
13091
|
-
if (!definition) return null;
|
|
13092
|
-
const eventName = attributeName.slice(definition.prefix.length);
|
|
13093
|
-
if (!eventName || !definition.prefix.endsWith(":") && !LEGACY_EVENT_NAME_RE.test(eventName)) return null;
|
|
13094
|
-
return {
|
|
13095
|
-
eventName,
|
|
13096
|
-
method,
|
|
13097
|
-
priority: definition.priority,
|
|
13098
|
-
stopAfter: definition.stopAfter
|
|
13099
|
-
};
|
|
13100
|
-
}
|
|
13101
|
-
function collectMiniProgramEventBindings(attributes = {}) {
|
|
13102
|
-
const bindings = /* @__PURE__ */ new Map();
|
|
13103
|
-
const priorities = /* @__PURE__ */ new Map();
|
|
13104
|
-
for (const [attributeName, method] of Object.entries(attributes)) {
|
|
13105
|
-
const candidate = parseEventBinding(attributeName, method);
|
|
13106
|
-
if (!candidate || candidate.priority < (priorities.get(candidate.eventName) ?? -1)) continue;
|
|
13107
|
-
bindings.set(candidate.eventName, {
|
|
13108
|
-
method: candidate.method,
|
|
13109
|
-
stopAfter: candidate.stopAfter
|
|
13110
|
-
});
|
|
13111
|
-
priorities.set(candidate.eventName, candidate.priority);
|
|
13112
|
-
}
|
|
13113
|
-
return bindings;
|
|
13114
|
-
}
|
|
13115
|
-
function resolveMiniProgramEventBinding(attributes, eventName) {
|
|
13116
|
-
return collectMiniProgramEventBindings(attributes).get(eventName) ?? null;
|
|
13117
|
-
}
|
|
13118
|
-
/** 冒泡时保留原始 target,currentTarget 则属于当前执行绑定的节点。 */
|
|
13119
|
-
function createMiniProgramEventPayload(node, eventName, event, origin = node) {
|
|
13120
|
-
const dataset = collectNodeDataset(node);
|
|
13121
|
-
const nodeId = node.attribs?.id ?? "";
|
|
13122
|
-
const isOrigin = node === origin;
|
|
13123
|
-
return {
|
|
13124
|
-
bubbles: false,
|
|
13125
|
-
capturePhase: false,
|
|
13126
|
-
composed: false,
|
|
13127
|
-
currentTarget: {
|
|
13128
|
-
dataset: isOrigin ? event.currentTarget?.dataset ?? event.dataset ?? dataset : dataset,
|
|
13129
|
-
id: isOrigin ? event.currentTarget?.id ?? event.id ?? nodeId : nodeId
|
|
13130
|
-
},
|
|
13131
|
-
detail: event.detail,
|
|
13132
|
-
mark: event.mark,
|
|
13133
|
-
target: {
|
|
13134
|
-
dataset: event.target?.dataset ?? event.dataset ?? (isOrigin ? dataset : collectNodeDataset(origin)),
|
|
13135
|
-
id: event.target?.id ?? event.id ?? origin.attribs?.id ?? ""
|
|
13136
|
-
},
|
|
13137
|
-
timeStamp: Date.now(),
|
|
13138
|
-
type: eventName
|
|
13139
|
-
};
|
|
13140
|
-
}
|
|
13141
13536
|
const WEVU_NATIVE_INSTANCE_KEY = "__wevuNativeInstance";
|
|
13142
13537
|
/** 宿主值为 1 时,实现带 routeEventId 的路由阶段契约;不代表微信 SDK 版本。 */
|
|
13143
13538
|
const WEVU_ROUTE_EVENT_CONTRACT_KEY = "__wevuRouteEventContract";
|
|
@@ -17140,9 +17535,10 @@ function maskTemplateAttributes(source) {
|
|
|
17140
17535
|
const INLINE_WXS_RE = /<wxs\b([^>]*)(?<!\/)>([\s\S]*?)<\/wxs\s*>/g;
|
|
17141
17536
|
function parseWxsTemplateDocument(templateSource) {
|
|
17142
17537
|
const scripts = [];
|
|
17143
|
-
const
|
|
17538
|
+
const source = templateSource.replace(INLINE_WXS_RE, (_match, attributes, script) => {
|
|
17144
17539
|
return `<wxs data-sim-wxs="${scripts.push(script) - 1}"${attributes}>wxs-source</wxs>`;
|
|
17145
|
-
})
|
|
17540
|
+
});
|
|
17541
|
+
const masked = maskTemplateAttributes(source);
|
|
17146
17542
|
const document = parseDocument(`<page>${masked.source}</page>`, {
|
|
17147
17543
|
xmlMode: false,
|
|
17148
17544
|
decodeEntities: false,
|
|
@@ -17150,7 +17546,7 @@ function parseWxsTemplateDocument(templateSource) {
|
|
|
17150
17546
|
lowerCaseTags: false,
|
|
17151
17547
|
recognizeSelfClosing: true
|
|
17152
17548
|
});
|
|
17153
|
-
if (!scripts.length && !masked.attributes.size) return document;
|
|
17549
|
+
if (!scripts.length && !masked.attributes.size && !/[\r\n]/.test(source)) return document;
|
|
17154
17550
|
const hasAttributes = masked.attributes.size > 0;
|
|
17155
17551
|
const restore = (node) => {
|
|
17156
17552
|
if (hasAttributes && node.attribs) {
|
|
@@ -17159,7 +17555,9 @@ function parseWxsTemplateDocument(templateSource) {
|
|
|
17159
17555
|
if (node.name === "wxs" && Object.hasOwn(node.attribs ?? {}, "data-sim-wxs")) {
|
|
17160
17556
|
node.children[0].data = scripts[Number(node.attribs["data-sim-wxs"])];
|
|
17161
17557
|
delete node.attribs["data-sim-wxs"];
|
|
17558
|
+
return;
|
|
17162
17559
|
}
|
|
17560
|
+
if (node.children) node.children = node.children.filter((child) => child.type !== "text" || !/^[\t\r\n ]+$/.test(child.data ?? "") || !/[\r\n]/.test(child.data ?? ""));
|
|
17163
17561
|
for (const child of node.children ?? []) restore(child);
|
|
17164
17562
|
};
|
|
17165
17563
|
restore(document);
|
|
@@ -17362,67 +17760,6 @@ function resolveComponentGenerics(context, hostNode, ownerJsonPath, ownerFilePat
|
|
|
17362
17760
|
}
|
|
17363
17761
|
return resolved.size > 0 ? resolved : void 0;
|
|
17364
17762
|
}
|
|
17365
|
-
function collectComponentEventBindings(hostNode) {
|
|
17366
|
-
return collectMiniProgramEventBindings(hostNode.attribs);
|
|
17367
|
-
}
|
|
17368
|
-
function buildComponentTrigger(componentScopeId, context, hostNode) {
|
|
17369
|
-
const hostDataset = collectDataset(hostNode);
|
|
17370
|
-
const hostId = hostNode.attribs?.id ?? "";
|
|
17371
|
-
return (instance, eventName, detail, triggerOptions) => {
|
|
17372
|
-
const originScope = context.componentScopes.get(componentScopeId);
|
|
17373
|
-
const interactionMark = instance.__lastInteractionEvent__?.mark;
|
|
17374
|
-
const target = {
|
|
17375
|
-
dataset: originScope?.dataset ?? hostDataset,
|
|
17376
|
-
id: originScope?.hostId ?? hostId
|
|
17377
|
-
};
|
|
17378
|
-
let currentScopeId = componentScopeId;
|
|
17379
|
-
while (currentScopeId) {
|
|
17380
|
-
const currentScope = context.componentScopes.get(currentScopeId);
|
|
17381
|
-
const binding = currentScope?.eventBindings?.get(eventName);
|
|
17382
|
-
const listenerScope = currentScope?.listenerScopeId ? context.componentScopes.get(currentScope.listenerScopeId) : null;
|
|
17383
|
-
const handler = binding && listenerScope ? listenerScope.getMethod(binding.method) : void 0;
|
|
17384
|
-
if (handler) handler({
|
|
17385
|
-
bubbles: triggerOptions?.bubbles ?? false,
|
|
17386
|
-
capturePhase: false,
|
|
17387
|
-
composed: triggerOptions?.composed ?? false,
|
|
17388
|
-
currentTarget: {
|
|
17389
|
-
dataset: currentScope?.dataset ?? hostDataset,
|
|
17390
|
-
id: currentScope?.hostId ?? hostId
|
|
17391
|
-
},
|
|
17392
|
-
detail,
|
|
17393
|
-
mark: interactionMark,
|
|
17394
|
-
target,
|
|
17395
|
-
type: eventName
|
|
17396
|
-
});
|
|
17397
|
-
if (binding?.stopAfter) break;
|
|
17398
|
-
if (!triggerOptions?.bubbles || !triggerOptions?.composed) break;
|
|
17399
|
-
currentScopeId = currentScope?.ownerScopeId;
|
|
17400
|
-
}
|
|
17401
|
-
};
|
|
17402
|
-
}
|
|
17403
|
-
function syncComponentProperties(instance, definition, nextProperties, bindingExpressions, changedPageKeys) {
|
|
17404
|
-
const changedRootKeys = [];
|
|
17405
|
-
const previousProperties = {};
|
|
17406
|
-
for (const [key, value] of Object.entries(nextProperties)) {
|
|
17407
|
-
const nextValue = normalizeComponentPropertyValue(definition, key, value);
|
|
17408
|
-
const bindingExpression = bindingExpressions[key];
|
|
17409
|
-
const bindingAffected = !!bindingExpression && changedPageKeys.some((changedKey) => {
|
|
17410
|
-
return changedKey === bindingExpression || changedKey.startsWith(`${bindingExpression}.`) || changedKey.startsWith(`${bindingExpression}[`);
|
|
17411
|
-
});
|
|
17412
|
-
const previousSnapshot = instance.__propertySnapshots?.[key];
|
|
17413
|
-
if (hasComponentPropertyValueChanged(instance.properties[key], previousSnapshot, nextValue, bindingAffected)) {
|
|
17414
|
-
previousProperties[key] = instance.properties[key];
|
|
17415
|
-
const deliveredValue = cloneValue$1(nextValue);
|
|
17416
|
-
instance.properties[key] = deliveredValue;
|
|
17417
|
-
if (Object.hasOwn(definition.properties ?? {}, key)) instance.data[key] = deliveredValue;
|
|
17418
|
-
changedRootKeys.push(key);
|
|
17419
|
-
}
|
|
17420
|
-
instance.__propertySnapshots ??= {};
|
|
17421
|
-
instance.__propertySnapshots[key] = cloneValue$1(nextValue);
|
|
17422
|
-
}
|
|
17423
|
-
if (changedRootKeys.length === 0) return;
|
|
17424
|
-
runComponentObservers(definition, instance, changedRootKeys, previousProperties);
|
|
17425
|
-
}
|
|
17426
17763
|
function createComponentScope(clonedNode, scope, componentScopeId, componentInstance, genericComponents, slots) {
|
|
17427
17764
|
const ownerScopeId = scope.getScopeId().includes("/") ? scope.getScopeId() : void 0;
|
|
17428
17765
|
return {
|
|
@@ -17430,7 +17767,7 @@ function createComponentScope(clonedNode, scope, componentScopeId, componentInst
|
|
|
17430
17767
|
classList: String(clonedNode.attribs?.class ?? "").split(CLASS_SPLIT_RE).map((item) => item.trim()).filter(Boolean),
|
|
17431
17768
|
data: { ...componentInstance.data },
|
|
17432
17769
|
dataset: collectDataset(clonedNode, wxsScopeData(scope)),
|
|
17433
|
-
|
|
17770
|
+
...bindComponentEventHost(clonedNode),
|
|
17434
17771
|
getMethod: (methodName) => {
|
|
17435
17772
|
const method = componentInstance?.[methodName];
|
|
17436
17773
|
return typeof method === "function" ? method.bind(componentInstance) : void 0;
|
|
@@ -17438,6 +17775,7 @@ function createComponentScope(clonedNode, scope, componentScopeId, componentInst
|
|
|
17438
17775
|
getScopeId: () => componentScopeId,
|
|
17439
17776
|
genericComponents,
|
|
17440
17777
|
hostId: typeof clonedNode.attribs?.id === "string" ? clonedNode.attribs.id : void 0,
|
|
17778
|
+
hostNode: clonedNode,
|
|
17441
17779
|
id: typeof clonedNode.attribs?.id === "string" ? clonedNode.attribs.id : void 0,
|
|
17442
17780
|
listenerScopeId: scope.getScopeId(),
|
|
17443
17781
|
ownerScopeId,
|
|
@@ -17460,13 +17798,14 @@ function resolveComponentProperties(clonedNode, scope, definition) {
|
|
|
17460
17798
|
bindingExpressions
|
|
17461
17799
|
};
|
|
17462
17800
|
}
|
|
17463
|
-
function createRuntimeComponentInstance(componentScopeId, context,
|
|
17801
|
+
function createRuntimeComponentInstance(componentScopeId, context, componentEntry, nextProperties, ownerScopeId, renderTemplate, bindEventsBeforeProperties = false) {
|
|
17464
17802
|
const componentProperties = Object.keys(componentEntry.definition.methods ?? {}).some((key) => key.startsWith("__weapp_vite_")) || Object.hasOwn(componentEntry.definition.properties ?? {}, "__wvSlotOwnerId") ? Object.fromEntries(Object.keys(componentEntry.definition.properties ?? {}).filter((key) => Object.hasOwn(nextProperties, key)).map((key) => [key, nextProperties[key]])) : nextProperties;
|
|
17465
|
-
const
|
|
17803
|
+
const instanceOptions = {
|
|
17466
17804
|
definition: componentEntry.definition,
|
|
17467
|
-
requestRender: (callback) => context.session.requestRender(callback)
|
|
17468
|
-
|
|
17469
|
-
|
|
17805
|
+
requestRender: (callback) => context.session.requestRender(callback)
|
|
17806
|
+
};
|
|
17807
|
+
const componentInstance = createComponentInstance(instanceOptions);
|
|
17808
|
+
bindAttachmentBindingScope(componentInstance, context);
|
|
17470
17809
|
setSelectorQueryScopeId(componentInstance, componentScopeId);
|
|
17471
17810
|
componentInstance.is = componentEntry.filePath.replace(JS_FILE_RE, "");
|
|
17472
17811
|
componentInstance.createIntersectionObserver = (options) => context.session.createIntersectionObserver(componentInstance, options);
|
|
@@ -17474,19 +17813,29 @@ function createRuntimeComponentInstance(componentScopeId, context, clonedNode, c
|
|
|
17474
17813
|
componentInstance.createSelectorQuery = () => context.moduleLoader.wx.createSelectorQuery().in(componentInstance);
|
|
17475
17814
|
componentInstance.selectComponent = (selector) => resolveNativeComponentSelection(context.session.selectComponentWithin(componentScopeId, selector));
|
|
17476
17815
|
componentInstance.selectAllComponents = (selector) => context.session.selectAllComponentsWithin(componentScopeId, selector).map(resolveNativeComponentSelection);
|
|
17477
|
-
componentInstance.selectOwnerComponent = () => ownerScopeId ? context.componentCache.get(ownerScopeId)
|
|
17816
|
+
componentInstance.selectOwnerComponent = () => ownerScopeId ? resolveNativeComponentSelection(context.componentCache.get(ownerScopeId)) : null;
|
|
17817
|
+
beginComponentConstruction(context.componentCache, componentScopeId, componentInstance);
|
|
17478
17818
|
context.componentCache.set(componentScopeId, componentInstance);
|
|
17479
|
-
|
|
17480
|
-
|
|
17481
|
-
|
|
17482
|
-
|
|
17483
|
-
|
|
17819
|
+
try {
|
|
17820
|
+
renderTemplate?.(componentInstance, "defaults");
|
|
17821
|
+
runComponentLifecycle(componentInstance, "created");
|
|
17822
|
+
if (bindEventsBeforeProperties) instanceOptions.triggerEvent = buildComponentTrigger(componentScopeId, context);
|
|
17823
|
+
componentInstance.__propertySnapshots = Object.fromEntries(Object.entries(componentInstance.properties).map(([key, propertyValue]) => [key, cloneValue$1(propertyValue)]));
|
|
17824
|
+
syncComponentProperties(componentInstance, componentInstance.__definition__ ?? componentEntry.definition, componentProperties, {}, [], renderTemplate);
|
|
17825
|
+
if (!bindEventsBeforeProperties) instanceOptions.triggerEvent = buildComponentTrigger(componentScopeId, context);
|
|
17826
|
+
return componentInstance;
|
|
17827
|
+
} catch (error) {
|
|
17828
|
+
discardComponentConstruction(context.componentCache, context.componentScopes, componentScopeId);
|
|
17829
|
+
throw error;
|
|
17830
|
+
} finally {
|
|
17831
|
+
finishComponentConstruction(context.componentCache, componentInstance);
|
|
17832
|
+
}
|
|
17484
17833
|
}
|
|
17485
|
-
function renderRuntimeComponentTemplate(context, componentEntry, renderNodeTree, componentScope, componentScopeId,
|
|
17834
|
+
function renderRuntimeComponentTemplate(context, componentEntry, renderNodeTree, componentScope, componentScopeId, renderPass) {
|
|
17486
17835
|
const componentDocument = parseTemplateDocument(readTemplateSource(context.artifactSource, componentEntry.absoluteTemplatePath));
|
|
17487
17836
|
const componentRoot = (componentDocument.children ?? [])[0] ?? componentDocument;
|
|
17488
17837
|
const templateRenderState = prepareTemplateRenderState(context.artifactSource, componentRoot, componentEntry.absoluteTemplatePath, context.project.miniprogramRootPath, getRuntimeWxsLoader(context.moduleLoader, context.artifactSource));
|
|
17489
|
-
return renderNodeTree(componentRoot, componentScope, context, path.resolve(context.project.miniprogramRootPath, `${componentEntry.filePath.replace(JS_FILE_RE, "")}.json`), componentEntry.filePath, componentScopeId,
|
|
17838
|
+
return renderNodeTree(componentRoot, componentScope, context, path.resolve(context.project.miniprogramRootPath, `${componentEntry.filePath.replace(JS_FILE_RE, "")}.json`), componentEntry.filePath, componentScopeId, renderPass, templateRenderState, componentScope.hostNode);
|
|
17490
17839
|
}
|
|
17491
17840
|
//#endregion
|
|
17492
17841
|
//#region ../../mpcore/packages/simulator/src/runtime/render/index.ts
|
|
@@ -17500,24 +17849,33 @@ function expandNodeByFor(node, scope) {
|
|
|
17500
17849
|
const items = resolveLoopEntries(resolveRawValueByPath$1(wxsScopeData(scope), forExpression));
|
|
17501
17850
|
const itemName = node.attribs?.["wx:for-item"]?.trim() || "item";
|
|
17502
17851
|
const indexName = node.attribs?.["wx:for-index"]?.trim() || "index";
|
|
17852
|
+
const key = node.attribs?.["wx:key"]?.trim();
|
|
17853
|
+
const keyOccurrences = key ? /* @__PURE__ */ new Map() : void 0;
|
|
17503
17854
|
return items.map(([index, item]) => ({
|
|
17504
17855
|
node: cloneNode(node),
|
|
17505
17856
|
scope: createLoopScope(scope, itemName, indexName, item, index),
|
|
17506
|
-
instanceSuffix:
|
|
17857
|
+
instanceSuffix: resolveLoopInstanceSuffix(item, index, key, keyOccurrences)
|
|
17507
17858
|
}));
|
|
17508
17859
|
}
|
|
17509
|
-
function renderNodeVariants(node, scope, context, ownerJsonPath, ownerFilePath, instancePath,
|
|
17510
|
-
|
|
17860
|
+
function renderNodeVariants(node, scope, context, ownerJsonPath, ownerFilePath, instancePath, renderPass, templateRenderState, parent) {
|
|
17861
|
+
const nodes = [];
|
|
17862
|
+
if (isRenderPassStale(renderPass)) return nodes;
|
|
17863
|
+
for (const { node: expandedNode, scope: expandedScope, instanceSuffix } of expandNodeByFor(node, scope)) {
|
|
17864
|
+
if (isRenderPassStale(renderPass)) break;
|
|
17865
|
+
nodes.push(renderNodeTree(expandedNode, expandedScope, context, ownerJsonPath, ownerFilePath, `${instancePath}${instanceSuffix}`, renderPass, templateRenderState, parent));
|
|
17866
|
+
}
|
|
17867
|
+
return nodes;
|
|
17511
17868
|
}
|
|
17512
|
-
function renderChildren(children, scope, context, ownerJsonPath, ownerFilePath, instancePath,
|
|
17869
|
+
function renderChildren(children, scope, context, ownerJsonPath, ownerFilePath, instancePath, renderPass, templateRenderState, parent) {
|
|
17513
17870
|
const renderedChildren = [];
|
|
17514
17871
|
for (const { node: child, index } of selectConditionalChildren(children, (node) => evaluateConditionalBranch(node, scope))) {
|
|
17872
|
+
if (isRenderPassStale(renderPass)) break;
|
|
17515
17873
|
if (!isTagNode(child)) {
|
|
17516
|
-
renderedChildren.push(...renderNodeVariants(child, scope, context, ownerJsonPath, ownerFilePath, `${instancePath}/node-${index}`,
|
|
17874
|
+
renderedChildren.push(...renderNodeVariants(child, scope, context, ownerJsonPath, ownerFilePath, `${instancePath}/node-${index}`, renderPass, templateRenderState, parent));
|
|
17517
17875
|
continue;
|
|
17518
17876
|
}
|
|
17519
17877
|
if (isTemplateDefinition(child) || child.name === "import" || child.name === "wxs") continue;
|
|
17520
|
-
renderedChildren.push(...renderNodeVariants(child, scope, context, ownerJsonPath, ownerFilePath, `${instancePath}/node-${index}`,
|
|
17878
|
+
renderedChildren.push(...renderNodeVariants(child, scope, context, ownerJsonPath, ownerFilePath, `${instancePath}/node-${index}`, renderPass, templateRenderState, parent));
|
|
17521
17879
|
}
|
|
17522
17880
|
return renderedChildren;
|
|
17523
17881
|
}
|
|
@@ -17549,22 +17907,38 @@ function collectComponentSlots(componentNode, scope, ownerJsonPath, ownerFilePat
|
|
|
17549
17907
|
}
|
|
17550
17908
|
return slots;
|
|
17551
17909
|
}
|
|
17552
|
-
function
|
|
17910
|
+
function reconcileSlotDeclarations(context, renderPass) {
|
|
17911
|
+
for (const [entries, { parent, scopeId }] of renderPass.slotDeclarations) {
|
|
17912
|
+
if (isRenderPassStale(renderPass)) return;
|
|
17913
|
+
if (isComponentConstructing(context.componentCache.get(scopeId))) continue;
|
|
17914
|
+
for (const { index } of selectConditionalChildren(entries.map((entry) => entry.node), (node, index) => evaluateConditionalBranch(node, entries[index].scope))) {
|
|
17915
|
+
if (isRenderPassStale(renderPass)) return;
|
|
17916
|
+
const entry = entries[index];
|
|
17917
|
+
if (renderPass.renderedSlots.has(entry)) continue;
|
|
17918
|
+
const nodes = renderNodeVariants(entry.node, entry.scope, context, entry.ownerJsonPath, entry.ownerFilePath, entry.instancePath, renderPass, entry.templateRenderState, parent);
|
|
17919
|
+
renderPass.renderedSlots.set(entry, nodes);
|
|
17920
|
+
renderPass.hasUnprojectedSlots ||= nodes.length > 0;
|
|
17921
|
+
}
|
|
17922
|
+
}
|
|
17923
|
+
}
|
|
17924
|
+
function renderNodeTree(node, scope, context, ownerJsonPath, ownerFilePath, instancePath, renderPass, templateRenderState, parent) {
|
|
17925
|
+
if (isRenderPassStale(renderPass)) return node;
|
|
17553
17926
|
if (scope.wxs !== templateRenderState.wxsModules) scope = {
|
|
17554
17927
|
...scope,
|
|
17555
17928
|
wxs: templateRenderState.wxsModules
|
|
17556
17929
|
};
|
|
17557
17930
|
const clonedNode = cloneNode(node);
|
|
17931
|
+
registerComponentEventNode(clonedNode, scope, parent);
|
|
17558
17932
|
if (!isTagNode(clonedNode)) {
|
|
17559
17933
|
applyNodeBindings(clonedNode, scope);
|
|
17560
17934
|
return clonedNode;
|
|
17561
17935
|
}
|
|
17562
|
-
if (isTemplateDefinition(clonedNode))
|
|
17563
|
-
|
|
17564
|
-
|
|
17565
|
-
|
|
17566
|
-
|
|
17567
|
-
}
|
|
17936
|
+
if (isTemplateDefinition(clonedNode)) {
|
|
17937
|
+
clonedNode.name = "block";
|
|
17938
|
+
clonedNode.attribs = {};
|
|
17939
|
+
clonedNode.children = [];
|
|
17940
|
+
return clonedNode;
|
|
17941
|
+
}
|
|
17568
17942
|
const templateName = resolveTemplateCall(clonedNode, wxsScopeData(scope));
|
|
17569
17943
|
if (templateName) {
|
|
17570
17944
|
const definition = templateRenderState.definitions.get(templateName);
|
|
@@ -17573,39 +17947,42 @@ function renderNodeTree(node, scope, context, ownerJsonPath, ownerFilePath, inst
|
|
|
17573
17947
|
data: resolveTemplateData(clonedNode, wxsScopeData(scope)),
|
|
17574
17948
|
wxs: definition && templateRenderState.definitionWxsScopes?.get(definition)
|
|
17575
17949
|
};
|
|
17576
|
-
|
|
17950
|
+
clonedNode.name = "block";
|
|
17951
|
+
clonedNode.attribs = {
|
|
17952
|
+
"data-sim-node": instancePath,
|
|
17953
|
+
"data-sim-scope": scope.getScopeId()
|
|
17954
|
+
};
|
|
17955
|
+
clonedNode.children = definition && !templateRenderState.stack.includes(templateName) ? renderChildren(definition.children ?? [], templateScope, context, ownerJsonPath, ownerFilePath, `${instancePath}/template-${templateName}`, renderPass, {
|
|
17577
17956
|
definitions: templateRenderState.definitionScopes?.get(definition) ?? templateRenderState.definitions,
|
|
17578
17957
|
definitionScopes: templateRenderState.definitionScopes,
|
|
17579
17958
|
definitionWxsScopes: templateRenderState.definitionWxsScopes,
|
|
17580
17959
|
wxsModules: templateScope.wxs,
|
|
17581
17960
|
stack: [...templateRenderState.stack, templateName]
|
|
17582
|
-
}) : [];
|
|
17583
|
-
return
|
|
17584
|
-
type: "tag",
|
|
17585
|
-
name: "block",
|
|
17586
|
-
attribs: {
|
|
17587
|
-
"data-sim-node": instancePath,
|
|
17588
|
-
"data-sim-scope": scope.getScopeId()
|
|
17589
|
-
},
|
|
17590
|
-
children
|
|
17591
|
-
};
|
|
17961
|
+
}, clonedNode) : [];
|
|
17962
|
+
return clonedNode;
|
|
17592
17963
|
}
|
|
17593
17964
|
if (clonedNode.name === "slot") {
|
|
17594
17965
|
const slotName = clonedNode.attribs?.name?.trim() || "default";
|
|
17595
17966
|
const projected = scope.slots?.get(slotName) ?? [];
|
|
17596
|
-
const
|
|
17597
|
-
|
|
17598
|
-
|
|
17599
|
-
|
|
17600
|
-
|
|
17601
|
-
|
|
17602
|
-
name: "block",
|
|
17603
|
-
attribs: {
|
|
17604
|
-
"data-sim-node": instancePath,
|
|
17605
|
-
"data-sim-scope": scope.getScopeId()
|
|
17606
|
-
},
|
|
17607
|
-
children
|
|
17967
|
+
const fallbackChildren = clonedNode.children ?? [];
|
|
17968
|
+
bindComponentEventHost(clonedNode);
|
|
17969
|
+
clonedNode.name = "block";
|
|
17970
|
+
clonedNode.attribs = {
|
|
17971
|
+
"data-sim-node": instancePath,
|
|
17972
|
+
"data-sim-scope": scope.getScopeId()
|
|
17608
17973
|
};
|
|
17974
|
+
const slotOwner = scope.getScopeId();
|
|
17975
|
+
if (projected.length && slotOwner && isComponentConstructing(context.componentCache.get(slotOwner))) {
|
|
17976
|
+
clonedNode.children = [];
|
|
17977
|
+
return clonedNode;
|
|
17978
|
+
}
|
|
17979
|
+
clonedNode.children = projected.length ? selectConditionalChildren(projected.map((entry) => entry.node), (node, index) => evaluateConditionalBranch(node, projected[index].scope)).flatMap(({ index }) => {
|
|
17980
|
+
const entry = projected[index];
|
|
17981
|
+
const nodes = renderNodeVariants(entry.node, entry.scope, context, entry.ownerJsonPath, entry.ownerFilePath, entry.instancePath, renderPass, entry.templateRenderState, clonedNode);
|
|
17982
|
+
renderPass.renderedSlots.set(entry, nodes);
|
|
17983
|
+
return nodes;
|
|
17984
|
+
}) : renderChildren(fallbackChildren, scope, context, ownerJsonPath, ownerFilePath, `${instancePath}/slot-fallback-${slotName}`, renderPass, templateRenderState, clonedNode);
|
|
17985
|
+
return clonedNode;
|
|
17609
17986
|
}
|
|
17610
17987
|
const componentEntry = resolveComponentRegistryEntry(context, ownerJsonPath, ownerFilePath, clonedNode.name, scope.genericComponents?.get(clonedNode.name));
|
|
17611
17988
|
if (componentEntry) {
|
|
@@ -17614,19 +17991,31 @@ function renderNodeTree(node, scope, context, ownerJsonPath, ownerFilePath, inst
|
|
|
17614
17991
|
const { nextProperties, bindingExpressions } = resolveComponentProperties(clonedNode, scope, componentEntry.definition);
|
|
17615
17992
|
const genericComponents = resolveComponentGenerics(context, clonedNode, ownerJsonPath, ownerFilePath, componentEntry.filePath, scope.genericComponents);
|
|
17616
17993
|
const slots = collectComponentSlots(clonedNode, scope, ownerJsonPath, ownerFilePath, componentScopeId, templateRenderState);
|
|
17994
|
+
registerSlotDeclarations(renderPass, slots, clonedNode, componentScopeId);
|
|
17995
|
+
applyNodeBindings(clonedNode, scope);
|
|
17996
|
+
const reconcilePrivateTemplate = (instance, phase) => {
|
|
17997
|
+
let bindingPass;
|
|
17998
|
+
do {
|
|
17999
|
+
const bindingScope = createComponentScope(clonedNode, scope, componentScopeId, instance, genericComponents, slots);
|
|
18000
|
+
context.componentScopes.set(componentScopeId, bindingScope);
|
|
18001
|
+
bindingPass = createRenderPass(phase === "properties", renderPass);
|
|
18002
|
+
renderRuntimeComponentTemplate(context, componentEntry, renderNodeTree, bindingScope, componentScopeId, bindingPass);
|
|
18003
|
+
reconcileSlotDeclarations(context, bindingPass);
|
|
18004
|
+
} while (isRenderPassStale(bindingPass));
|
|
18005
|
+
};
|
|
17617
18006
|
let componentInstance = context.componentCache.get(componentScopeId);
|
|
17618
|
-
if (!componentInstance) componentInstance = createRuntimeComponentInstance(componentScopeId, context,
|
|
17619
|
-
|
|
17620
|
-
context.componentScopes.set(componentScopeId,
|
|
17621
|
-
|
|
17622
|
-
}
|
|
17623
|
-
|
|
17624
|
-
seenComponentScopes.add(componentScopeId);
|
|
18007
|
+
if (!componentInstance) componentInstance = createRuntimeComponentInstance(componentScopeId, context, componentEntry, nextProperties, ownerScopeId, reconcilePrivateTemplate, renderPass.propertyUpdate);
|
|
18008
|
+
else {
|
|
18009
|
+
context.componentScopes.set(componentScopeId, createComponentScope(clonedNode, scope, componentScopeId, componentInstance, genericComponents, slots));
|
|
18010
|
+
syncComponentProperties(componentInstance, componentInstance.__definition__ ?? componentEntry.definition, nextProperties, bindingExpressions, context.changedPageKeys, reconcilePrivateTemplate);
|
|
18011
|
+
}
|
|
18012
|
+
if (isRenderPassStale(renderPass)) return clonedNode;
|
|
18013
|
+
renderPass.seenComponentScopes.add(componentScopeId);
|
|
17625
18014
|
const componentScope = createComponentScope(clonedNode, scope, componentScopeId, componentInstance, genericComponents, slots);
|
|
17626
18015
|
context.componentScopes.set(componentScopeId, componentScope);
|
|
17627
|
-
const renderedComponentRoot = renderRuntimeComponentTemplate(context, componentEntry, renderNodeTree, componentScope, componentScopeId,
|
|
18016
|
+
const renderedComponentRoot = renderRuntimeComponentTemplate(context, componentEntry, renderNodeTree, componentScope, componentScopeId, renderPass);
|
|
18017
|
+
mergeComponentEventRoot(renderedComponentRoot, clonedNode);
|
|
17628
18018
|
if (renderedComponentRoot.attribs) {
|
|
17629
|
-
applyNodeBindings(clonedNode, scope);
|
|
17630
18019
|
renderedComponentRoot.attribs = {
|
|
17631
18020
|
...clonedNode.attribs,
|
|
17632
18021
|
...renderedComponentRoot.attribs
|
|
@@ -17639,66 +18028,99 @@ function renderNodeTree(node, scope, context, ownerJsonPath, ownerFilePath, inst
|
|
|
17639
18028
|
renderedComponentRoot.attribs["data-sim-node"] = instancePath;
|
|
17640
18029
|
renderedComponentRoot.attribs["data-sim-scope"] = componentScopeId;
|
|
17641
18030
|
}
|
|
18031
|
+
renderPass.componentRoots.set(componentScopeId, renderedComponentRoot);
|
|
17642
18032
|
return renderedComponentRoot;
|
|
17643
18033
|
}
|
|
17644
18034
|
applyNodeBindings(clonedNode, scope);
|
|
17645
18035
|
clonedNode.attribs["data-sim-node"] = instancePath;
|
|
17646
|
-
clonedNode.children = renderChildren(clonedNode.children ?? [], scope, context, ownerJsonPath, ownerFilePath, `${instancePath}/${clonedNode.name}`,
|
|
18036
|
+
clonedNode.children = renderChildren(clonedNode.children ?? [], scope, context, ownerJsonPath, ownerFilePath, `${instancePath}/${clonedNode.name}`, renderPass, templateRenderState, clonedNode);
|
|
17647
18037
|
return clonedNode;
|
|
17648
18038
|
}
|
|
18039
|
+
function reconcileRuntimePageTree(context, page, bindingsOnly = false) {
|
|
18040
|
+
for (;;) {
|
|
18041
|
+
bindAttachmentBindingScope(context, page);
|
|
18042
|
+
if (page.__lastChangedKeys__) context.changedPageKeys = page.__lastChangedKeys__;
|
|
18043
|
+
const route = page.route.replace(LEADING_SLASH_RE$4, "");
|
|
18044
|
+
const resourcePath = context.project.routes.find((item) => item.route === route)?.resourcePath ?? route;
|
|
18045
|
+
const templatePath = path.resolve(context.project.miniprogramRootPath, `${resourcePath}.wxml`);
|
|
18046
|
+
const document = parseTemplateDocument(readTemplateSource(context.artifactSource, templatePath));
|
|
18047
|
+
const pageScopeId = `page:${route}`;
|
|
18048
|
+
const pageScope = {
|
|
18049
|
+
data: page.data,
|
|
18050
|
+
getMethod: (methodName) => {
|
|
18051
|
+
const method = page[methodName];
|
|
18052
|
+
return typeof method === "function" ? method.bind(page) : void 0;
|
|
18053
|
+
},
|
|
18054
|
+
getScopeId: () => pageScopeId,
|
|
18055
|
+
id: "page-root"
|
|
18056
|
+
};
|
|
18057
|
+
for (const scopeId of context.componentScopes.keys()) if (scopeId === pageScopeId || scopeId.startsWith(`${pageScopeId}/`)) context.componentScopes.delete(scopeId);
|
|
18058
|
+
context.componentScopes.set(pageScopeId, pageScope);
|
|
18059
|
+
const renderPass = createPageRenderPass(page, context.componentCache);
|
|
18060
|
+
const root = (document.children ?? [])[0] ?? document;
|
|
18061
|
+
const templateRenderState = prepareTemplateRenderState(context.artifactSource, root, templatePath, context.project.miniprogramRootPath, getRuntimeWxsLoader(context.moduleLoader, context.artifactSource));
|
|
18062
|
+
const renderedRoot = renderNodeTree(root, pageScope, context, path.resolve(context.project.miniprogramRootPath, `${resourcePath}.json`), `${resourcePath}.js`, pageScopeId, renderPass, templateRenderState);
|
|
18063
|
+
const roots = [renderedRoot];
|
|
18064
|
+
if (hasCustomTabBar(context.project.appConfig, route)) roots.push(renderNodeTree({
|
|
18065
|
+
type: "tag",
|
|
18066
|
+
name: "custom-tab-bar",
|
|
18067
|
+
attribs: {},
|
|
18068
|
+
children: []
|
|
18069
|
+
}, customTabBarHostScope(), context, path.resolve(context.project.miniprogramRootPath, "app.json"), "app.js", pageScopeId, renderPass, templateRenderState));
|
|
18070
|
+
reconcileSlotDeclarations(context, renderPass);
|
|
18071
|
+
if (isRenderPassStale(renderPass)) continue;
|
|
18072
|
+
markPageTreeConstructed(page, context.componentCache);
|
|
18073
|
+
const treeRoot = roots.length > 1 ? {
|
|
18074
|
+
type: "root",
|
|
18075
|
+
children: roots
|
|
18076
|
+
} : renderedRoot;
|
|
18077
|
+
linkRenderedParents(treeRoot);
|
|
18078
|
+
registerInspectionTrees(treeRoot, renderPass, context.componentScopes);
|
|
18079
|
+
if (bindingsOnly) return {
|
|
18080
|
+
root: treeRoot,
|
|
18081
|
+
roots
|
|
18082
|
+
};
|
|
18083
|
+
let bindingsRefreshed = false;
|
|
18084
|
+
const updateBindings = () => {
|
|
18085
|
+
bindingsRefreshed = true;
|
|
18086
|
+
if (hasPendingComponentConstruction(context.componentCache)) return;
|
|
18087
|
+
reconcileRuntimePageTree(context, page, true);
|
|
18088
|
+
};
|
|
18089
|
+
const pageAttached = attachComponentPage(page, updateBindings);
|
|
18090
|
+
if (bindingsRefreshed) continue;
|
|
18091
|
+
const pageAttaching = isComponentPageAttaching(page);
|
|
18092
|
+
const scopeIds = orderComponentAttachmentScopes(renderPass.seenComponentScopes, context.componentScopes);
|
|
18093
|
+
const instances = scopeIds.map((scopeId) => context.componentCache.get(scopeId));
|
|
18094
|
+
const attached = !pageAttaching && runWithAttachmentBindingUpdates(page, updateBindings, (scopes) => flushComponentAttachments(context.componentCache, scopes, (instance) => {
|
|
18095
|
+
runComponentLifecycle(instance, "attached");
|
|
18096
|
+
return bindingsRefreshed;
|
|
18097
|
+
}), scopeIds);
|
|
18098
|
+
if (attached === "restart") continue;
|
|
18099
|
+
const canFinalize = !pageAttaching && !hasPendingComponentAttachments(instances);
|
|
18100
|
+
const removed = canFinalize ? [...context.componentCache].filter(([scopeId]) => scopeId.startsWith(`${pageScopeId}/`) && !renderPass.seenComponentScopes.has(scopeId)) : [];
|
|
18101
|
+
for (const [scopeId, instance] of removed) if (isComponentAttached(instance)) runComponentLifecycle(instance, "detached");
|
|
18102
|
+
else scheduleDiscardedComponentReady(context.componentCache, scopeId, instance);
|
|
18103
|
+
const relationsChanged = canFinalize && syncComponentRelations(context.componentCache, renderPass.seenComponentScopes, pageScopeId);
|
|
18104
|
+
for (const [scopeId] of removed) {
|
|
18105
|
+
context.componentCache.delete(scopeId);
|
|
18106
|
+
context.componentScopes.delete(scopeId);
|
|
18107
|
+
}
|
|
18108
|
+
if (pageAttached || attached || relationsChanged) continue;
|
|
18109
|
+
if (canFinalize && !isPageBeforeReady(page)) flushDiscardedComponentReady(context.componentCache, pageScopeId, (instance) => runComponentLifecycle(instance, "ready"));
|
|
18110
|
+
if (canFinalize && !isPageBeforeReady(page) && flushComponentReady(instances, (instance) => {
|
|
18111
|
+
runComponentLifecycle(instance, "ready");
|
|
18112
|
+
if (instance !== context.componentCache.get(customTabBarScopeId(route))) instance.__definition__?.pageLifetimes?.show?.call(instance);
|
|
18113
|
+
})) continue;
|
|
18114
|
+
return {
|
|
18115
|
+
root: treeRoot,
|
|
18116
|
+
roots
|
|
18117
|
+
};
|
|
18118
|
+
}
|
|
18119
|
+
}
|
|
17649
18120
|
function renderRuntimePageTree(context, page) {
|
|
17650
|
-
const
|
|
17651
|
-
const resourcePath = context.project.routes.find((item) => item.route === route)?.resourcePath ?? route;
|
|
17652
|
-
const templatePath = path.resolve(context.project.miniprogramRootPath, `${resourcePath}.wxml`);
|
|
17653
|
-
const document = parseTemplateDocument(readTemplateSource(context.artifactSource, templatePath));
|
|
17654
|
-
const pageScopeId = `page:${route}`;
|
|
17655
|
-
const pageScope = {
|
|
17656
|
-
data: page.data,
|
|
17657
|
-
getMethod: (methodName) => {
|
|
17658
|
-
const method = page[methodName];
|
|
17659
|
-
return typeof method === "function" ? method.bind(page) : void 0;
|
|
17660
|
-
},
|
|
17661
|
-
getScopeId: () => pageScopeId,
|
|
17662
|
-
id: "page-root"
|
|
17663
|
-
};
|
|
17664
|
-
for (const scopeId of context.componentScopes.keys()) if (scopeId === pageScopeId || scopeId.startsWith(`${pageScopeId}/`)) context.componentScopes.delete(scopeId);
|
|
17665
|
-
context.componentScopes.set(pageScopeId, pageScope);
|
|
17666
|
-
const seenComponentScopes = /* @__PURE__ */ new Set();
|
|
17667
|
-
const root = (document.children ?? [])[0] ?? document;
|
|
17668
|
-
const templateRenderState = prepareTemplateRenderState(context.artifactSource, root, templatePath, context.project.miniprogramRootPath, getRuntimeWxsLoader(context.moduleLoader, context.artifactSource));
|
|
17669
|
-
const renderedRoot = renderNodeTree(root, pageScope, context, path.resolve(context.project.miniprogramRootPath, `${resourcePath}.json`), `${resourcePath}.js`, pageScopeId, seenComponentScopes, templateRenderState);
|
|
17670
|
-
const roots = [renderedRoot];
|
|
17671
|
-
if (hasCustomTabBar(context.project.appConfig, route)) roots.push(renderNodeTree({
|
|
17672
|
-
type: "tag",
|
|
17673
|
-
name: "custom-tab-bar",
|
|
17674
|
-
attribs: {},
|
|
17675
|
-
children: []
|
|
17676
|
-
}, customTabBarHostScope(), context, path.resolve(context.project.miniprogramRootPath, "app.json"), "app.js", pageScopeId, seenComponentScopes, templateRenderState));
|
|
17677
|
-
const pageAttached = attachComponentPage(page);
|
|
17678
|
-
const pageAttaching = isComponentPageAttaching(page);
|
|
17679
|
-
const attached = !pageAttaching && flushComponentAttachments([...seenComponentScopes].map((scopeId) => context.componentCache.get(scopeId)), (instance) => runComponentLifecycle(instance, "attached"));
|
|
17680
|
-
const removed = [...context.componentCache].filter(([scopeId]) => scopeId.startsWith(`${pageScopeId}/`) && !seenComponentScopes.has(scopeId));
|
|
17681
|
-
for (const [scopeId, instance] of removed) if (isComponentAttached(instance)) runComponentLifecycle(instance, "detached");
|
|
17682
|
-
else scheduleDiscardedComponentReady(context.componentCache, scopeId, instance);
|
|
17683
|
-
const instances = [...seenComponentScopes].map((scopeId) => context.componentCache.get(scopeId));
|
|
17684
|
-
const relationsChanged = !pageAttaching && !hasPendingComponentAttachments(instances) && syncComponentRelations(context.componentCache, seenComponentScopes, pageScopeId);
|
|
17685
|
-
for (const [scopeId] of removed) {
|
|
17686
|
-
context.componentCache.delete(scopeId);
|
|
17687
|
-
context.componentScopes.delete(scopeId);
|
|
17688
|
-
}
|
|
17689
|
-
if (pageAttached || attached || relationsChanged) return renderRuntimePageTree(context, page);
|
|
17690
|
-
if (!isPageBeforeReady(page)) flushDiscardedComponentReady(context.componentCache, pageScopeId, (instance) => runComponentLifecycle(instance, "ready"));
|
|
17691
|
-
if (!isPageBeforeReady(page) && flushComponentReady(instances, (instance) => {
|
|
17692
|
-
runComponentLifecycle(instance, "ready");
|
|
17693
|
-
if (instance !== context.componentCache.get(customTabBarScopeId(route))) instance.__definition__?.pageLifetimes?.show?.call(instance);
|
|
17694
|
-
})) return renderRuntimePageTree(context, page);
|
|
17695
|
-
const treeRoot = roots.length > 1 ? {
|
|
17696
|
-
type: "root",
|
|
17697
|
-
children: roots
|
|
17698
|
-
} : renderedRoot;
|
|
17699
|
-
linkRenderedParents(treeRoot);
|
|
18121
|
+
const { root, roots } = reconcileRuntimePageTree(context, page);
|
|
17700
18122
|
return {
|
|
17701
|
-
root
|
|
18123
|
+
root,
|
|
17702
18124
|
wxml: roots.map(serializeDomNode$1).join("")
|
|
17703
18125
|
};
|
|
17704
18126
|
}
|
|
@@ -17722,15 +18144,23 @@ function createDuplicateRegistrationError(kind, id) {
|
|
|
17722
18144
|
function callDefinitionMethod(instance, method, args) {
|
|
17723
18145
|
if (typeof method === "function") return method.apply(instance, args);
|
|
17724
18146
|
}
|
|
18147
|
+
function composeDefinitionMethods(primary, secondary) {
|
|
18148
|
+
if (typeof primary !== "function" || typeof secondary !== "function" || primary === secondary) return primary ?? secondary;
|
|
18149
|
+
return function composedDefinitionMethod(...args) {
|
|
18150
|
+
const result = primary.apply(this, args);
|
|
18151
|
+
secondary.apply(this, args);
|
|
18152
|
+
return result;
|
|
18153
|
+
};
|
|
18154
|
+
}
|
|
17725
18155
|
function normalizeComponentPageDefinition(definition) {
|
|
17726
18156
|
const { lifetimes = {}, methods = {}, pageLifetimes = {}, ...rest } = definition;
|
|
17727
18157
|
const created = lifetimes.created ?? rest.created;
|
|
17728
18158
|
const attached = lifetimes.attached ?? rest.attached;
|
|
17729
|
-
const ready = lifetimes.ready ?? rest.ready
|
|
18159
|
+
const ready = composeDefinitionMethods(lifetimes.ready ?? rest.ready, methods.onReady ?? rest.onReady);
|
|
17730
18160
|
const detached = lifetimes.detached ?? rest.detached ?? methods.onUnload ?? rest.onUnload;
|
|
17731
18161
|
const load = methods.onLoad ?? rest.onLoad;
|
|
17732
|
-
const show = pageLifetimes.show
|
|
17733
|
-
const hide = pageLifetimes.hide
|
|
18162
|
+
const show = typeof pageLifetimes.show === "function" ? composeDefinitionMethods(pageLifetimes.show, methods.onShow) : methods.onShow ?? rest.onShow;
|
|
18163
|
+
const hide = typeof pageLifetimes.hide === "function" ? composeDefinitionMethods(pageLifetimes.hide, methods.onHide) : methods.onHide ?? rest.onHide;
|
|
17734
18164
|
const resize = pageLifetimes.resize ?? methods.onResize ?? rest.onResize;
|
|
17735
18165
|
const routeDone = pageLifetimes.routeDone ?? methods.onRouteDone ?? rest.onRouteDone;
|
|
17736
18166
|
const pageDefinition = {
|
|
@@ -17758,10 +18188,7 @@ function normalizeComponentPageDefinition(definition) {
|
|
|
17758
18188
|
return callDefinitionMethod(this, routeDone, args);
|
|
17759
18189
|
}
|
|
17760
18190
|
};
|
|
17761
|
-
registerComponentPageAttachment(pageDefinition,
|
|
17762
|
-
callDefinitionMethod(this, created, []);
|
|
17763
|
-
callDefinitionMethod(this, attached, []);
|
|
17764
|
-
});
|
|
18191
|
+
registerComponentPageAttachment(pageDefinition, (instance) => callDefinitionMethod(instance, created, []), (instance) => callDefinitionMethod(instance, attached, []));
|
|
17765
18192
|
return pageDefinition;
|
|
17766
18193
|
}
|
|
17767
18194
|
function createHostRegistries() {
|
|
@@ -17952,7 +18379,7 @@ function resolveCapabilityValue(source, schema) {
|
|
|
17952
18379
|
}
|
|
17953
18380
|
return current;
|
|
17954
18381
|
}
|
|
17955
|
-
function createHeadlessWx(driver, runtimeConsole = console) {
|
|
18382
|
+
function createHeadlessWx(driver, runtimeConsole = console, workers) {
|
|
17956
18383
|
const eventBus = createHeadlessUniEventBus();
|
|
17957
18384
|
const rpx2px = (value) => {
|
|
17958
18385
|
const width = driver.getWindowInfoSync().windowWidth;
|
|
@@ -17960,6 +18387,10 @@ function createHeadlessWx(driver, runtimeConsole = console) {
|
|
|
17960
18387
|
};
|
|
17961
18388
|
const capabilityTree = {
|
|
17962
18389
|
canIUse: true,
|
|
18390
|
+
...workers ? {
|
|
18391
|
+
createWorker: true,
|
|
18392
|
+
preDownloadSubpackage: true
|
|
18393
|
+
} : {},
|
|
17963
18394
|
canvasToTempFilePath: true,
|
|
17964
18395
|
chooseImage: { return: {
|
|
17965
18396
|
errMsg: true,
|
|
@@ -18217,6 +18648,14 @@ function createHeadlessWx(driver, runtimeConsole = console) {
|
|
|
18217
18648
|
...eventBus,
|
|
18218
18649
|
[WEVU_ROUTE_EVENT_CONTRACT_KEY]: 1,
|
|
18219
18650
|
[WEVU_PAGE_SCROLL_EVENT_CONTRACT_KEY]: 1,
|
|
18651
|
+
createWorker: (script) => {
|
|
18652
|
+
if (!workers) throw new Error("Worker host is unavailable");
|
|
18653
|
+
return workers.createWorker(script);
|
|
18654
|
+
},
|
|
18655
|
+
preDownloadSubpackage: (option) => {
|
|
18656
|
+
if (!workers) throw new Error("Worker host is unavailable");
|
|
18657
|
+
workers.preDownloadSubpackage(option);
|
|
18658
|
+
},
|
|
18220
18659
|
canIUse: (schema) => typeof schema === "string" && schema.trim() !== "" && resolveCapabilityValue(capabilityTree, schema.trim()) != null,
|
|
18221
18660
|
canvasToTempFilePath: (option) => invokeWxApi(() => driver.canvasToTempFilePath(option), option),
|
|
18222
18661
|
chooseImage: (option) => invokeWxApi(() => driver.chooseImage(option ?? {}), option),
|
|
@@ -18340,9 +18779,7 @@ function createHeadlessWx(driver, runtimeConsole = console) {
|
|
|
18340
18779
|
navigateBack: (option) => runNavigationApi(driver, option, (deferred) => invokeWxApi(() => {
|
|
18341
18780
|
driver.navigateBack(deferred);
|
|
18342
18781
|
}, deferred)),
|
|
18343
|
-
navigateTo: (option) => runNavigationApi(driver, option, (deferred) =>
|
|
18344
|
-
driver.navigateTo(deferred);
|
|
18345
|
-
}, deferred)),
|
|
18782
|
+
navigateTo: (option) => runNavigationApi(driver, option, (deferred) => driver.navigateTo(deferred)),
|
|
18346
18783
|
nextTick: (callback) => driver.nextTick(callback),
|
|
18347
18784
|
offBeforeAppRoute: (listener) => driver.offBeforeAppRoute(listener),
|
|
18348
18785
|
offBeforePageUnload: (listener) => driver.offBeforePageUnload(listener),
|
|
@@ -18798,6 +19235,34 @@ function loadProject(projectPath) {
|
|
|
18798
19235
|
});
|
|
18799
19236
|
}
|
|
18800
19237
|
//#endregion
|
|
19238
|
+
//#region ../../mpcore/packages/simulator/src/view/eventBinding.ts
|
|
19239
|
+
function resolveMiniProgramEventBinding(attributes, eventName) {
|
|
19240
|
+
return resolveEventBindingPhases(attributes, eventName, false)?.bubble ?? null;
|
|
19241
|
+
}
|
|
19242
|
+
/** 冒泡时保留原始 target,currentTarget 则属于当前执行绑定的节点。 */
|
|
19243
|
+
function createMiniProgramEventPayload(node, eventName, event, origin = node) {
|
|
19244
|
+
const dataset = collectNodeDataset(node);
|
|
19245
|
+
const nodeId = node.attribs?.id ?? "";
|
|
19246
|
+
const isOrigin = node === origin;
|
|
19247
|
+
return {
|
|
19248
|
+
bubbles: false,
|
|
19249
|
+
capturePhase: false,
|
|
19250
|
+
composed: false,
|
|
19251
|
+
currentTarget: {
|
|
19252
|
+
dataset: isOrigin ? event.currentTarget?.dataset ?? event.dataset ?? dataset : dataset,
|
|
19253
|
+
id: isOrigin ? event.currentTarget?.id ?? event.id ?? nodeId : nodeId
|
|
19254
|
+
},
|
|
19255
|
+
detail: event.detail,
|
|
19256
|
+
mark: event.mark,
|
|
19257
|
+
target: {
|
|
19258
|
+
dataset: event.target?.dataset ?? event.dataset ?? (isOrigin ? dataset : collectNodeDataset(origin)),
|
|
19259
|
+
id: event.target?.id ?? event.id ?? origin.attribs?.id ?? ""
|
|
19260
|
+
},
|
|
19261
|
+
timeStamp: Date.now(),
|
|
19262
|
+
type: eventName
|
|
19263
|
+
};
|
|
19264
|
+
}
|
|
19265
|
+
//#endregion
|
|
18801
19266
|
//#region ../../node_modules/.pnpm/boolbase@2.0.0/node_modules/boolbase/dist/index.js
|
|
18802
19267
|
function trueFunc() {
|
|
18803
19268
|
return true;
|
|
@@ -20224,23 +20689,31 @@ function appendNextSiblings(element, adapter) {
|
|
|
20224
20689
|
const selectAll = getSelectorFunction((query, elements, options) => query === falseFunc || !elements || elements.length === 0 ? [] : findAll(query, elements, options));
|
|
20225
20690
|
//#endregion
|
|
20226
20691
|
//#region ../../mpcore/packages/simulator/src/view/selectors.ts
|
|
20227
|
-
|
|
20228
|
-
|
|
20229
|
-
|
|
20230
|
-
|
|
20231
|
-
|
|
20232
|
-
|
|
20233
|
-
|
|
20234
|
-
|
|
20235
|
-
|
|
20236
|
-
|
|
20237
|
-
|
|
20238
|
-
|
|
20239
|
-
|
|
20240
|
-
|
|
20241
|
-
|
|
20242
|
-
|
|
20243
|
-
|
|
20692
|
+
function createAdapter(getChildren, getParent) {
|
|
20693
|
+
const adapter = {
|
|
20694
|
+
isTag: (node) => node.type === "tag",
|
|
20695
|
+
getAttributeValue: (node, name) => node.attribs?.[name],
|
|
20696
|
+
getChildren,
|
|
20697
|
+
getName: (node) => node.name ?? "",
|
|
20698
|
+
getParent,
|
|
20699
|
+
getSiblings: (node) => {
|
|
20700
|
+
const parent = getParent(node);
|
|
20701
|
+
return parent ? getChildren(parent) : [node];
|
|
20702
|
+
},
|
|
20703
|
+
getText: (node) => node.type === "text" ? node.data ?? "" : getChildren(node).map((child) => adapter.getText(child)).join(""),
|
|
20704
|
+
hasAttrib: (node, name) => Object.hasOwn(node.attribs ?? {}, name),
|
|
20705
|
+
removeSubsets: (nodes) => {
|
|
20706
|
+
const unique = new Set(nodes);
|
|
20707
|
+
return [...unique].filter((node) => {
|
|
20708
|
+
for (let parent = getParent(node); parent; parent = getParent(parent)) if (unique.has(parent)) return false;
|
|
20709
|
+
return true;
|
|
20710
|
+
});
|
|
20711
|
+
}
|
|
20712
|
+
};
|
|
20713
|
+
return adapter;
|
|
20714
|
+
}
|
|
20715
|
+
const renderedAdapter = createAdapter((node) => node.children ?? [], (node) => node.parent ?? null);
|
|
20716
|
+
const inspectionAdapter = createAdapter(getInspectionChildren, getInspectionParent);
|
|
20244
20717
|
function resolveComponentTags(selectors) {
|
|
20245
20718
|
return selectors.map((group) => group.map((token) => {
|
|
20246
20719
|
if (token.type === SelectorType.Pseudo && Array.isArray(token.data)) return {
|
|
@@ -20263,7 +20736,7 @@ function resolveComponentTags(selectors) {
|
|
|
20263
20736
|
};
|
|
20264
20737
|
}));
|
|
20265
20738
|
}
|
|
20266
|
-
function
|
|
20739
|
+
function queryWithAdapter(root, selector, adapter) {
|
|
20267
20740
|
const parsed = parse$1(selector);
|
|
20268
20741
|
const query = resolveComponentTags(parsed);
|
|
20269
20742
|
const includesPageRoot = root.type === "tag" && root.name === "page" && parsed.some((group) => group.some((token) => token.type === SelectorType.Tag && token.name === "page"));
|
|
@@ -20272,6 +20745,12 @@ function querySelectorAll(root, selector) {
|
|
|
20272
20745
|
cacheResults: false
|
|
20273
20746
|
});
|
|
20274
20747
|
}
|
|
20748
|
+
function querySelectorAll(root, selector) {
|
|
20749
|
+
return queryWithAdapter(root, selector, renderedAdapter);
|
|
20750
|
+
}
|
|
20751
|
+
function queryInspectionSelectorAll(root, selector) {
|
|
20752
|
+
return queryWithAdapter(root, selector, inspectionAdapter);
|
|
20753
|
+
}
|
|
20275
20754
|
//#endregion
|
|
20276
20755
|
//#region ../../node_modules/.pnpm/whynot@5.0.0/node_modules/whynot/dist/whynot.umd.cjs
|
|
20277
20756
|
var require_whynot_umd = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
@@ -38019,7 +38498,10 @@ var import_fontoxpath = /* @__PURE__ */ __toESM((/* @__PURE__ */ __commonJSMin((
|
|
|
38019
38498
|
});
|
|
38020
38499
|
})))(), 1);
|
|
38021
38500
|
const xpathEngine = Reflect.get(import_fontoxpath, "default") ?? import_fontoxpath;
|
|
38022
|
-
function
|
|
38501
|
+
function getRenderedChildren(node) {
|
|
38502
|
+
return node.children ?? [];
|
|
38503
|
+
}
|
|
38504
|
+
function wrapNode(source, getChildren, parent = null) {
|
|
38023
38505
|
const node = {
|
|
38024
38506
|
attributes: [],
|
|
38025
38507
|
children: [],
|
|
@@ -38042,7 +38524,7 @@ function wrapNode(source, parent = null) {
|
|
|
38042
38524
|
prefix: null,
|
|
38043
38525
|
value
|
|
38044
38526
|
}));
|
|
38045
|
-
node.children = (source
|
|
38527
|
+
node.children = getChildren(source).map((child) => wrapNode(child, getChildren, node));
|
|
38046
38528
|
return node;
|
|
38047
38529
|
}
|
|
38048
38530
|
function sibling(node, offset) {
|
|
@@ -38062,14 +38544,20 @@ const domFacade = {
|
|
|
38062
38544
|
getParentNode: (node) => node.parent,
|
|
38063
38545
|
getPreviousSibling: (node) => sibling(node, -1)
|
|
38064
38546
|
};
|
|
38065
|
-
function
|
|
38547
|
+
function queryElements(root, expression, getChildren) {
|
|
38066
38548
|
if (!expression.trim()) throw new Error("XPath must be a non-empty expression in headless testing runtime.");
|
|
38067
38549
|
const document = wrapNode(root.type === "root" ? root : {
|
|
38068
38550
|
type: "root",
|
|
38069
38551
|
children: [root]
|
|
38070
|
-
});
|
|
38552
|
+
}, getChildren);
|
|
38071
38553
|
return xpathEngine.evaluateXPathToNodes(expression, document, domFacade).filter((node) => node.nodeType === 1).map((node) => node.source);
|
|
38072
38554
|
}
|
|
38555
|
+
function queryXPathElements(root, expression) {
|
|
38556
|
+
return queryElements(root, expression, getRenderedChildren);
|
|
38557
|
+
}
|
|
38558
|
+
function queryInspectionXPathElements(root, expression) {
|
|
38559
|
+
return queryElements(root, expression, getInspectionChildren);
|
|
38560
|
+
}
|
|
38073
38561
|
//#endregion
|
|
38074
38562
|
//#region ../../mpcore/packages/simulator/src/view/nodeHandle.ts
|
|
38075
38563
|
function escapeText$1(text) {
|
|
@@ -38116,7 +38604,7 @@ var HeadlessTestingNodeHandle = class HeadlessTestingNodeHandle {
|
|
|
38116
38604
|
this.interactions?.assertActive?.();
|
|
38117
38605
|
}
|
|
38118
38606
|
query(selector) {
|
|
38119
|
-
const nodes = querySelectorAll(this.node, selector);
|
|
38607
|
+
const nodes = (this.interactions?.projectionOnly ? querySelectorAll : queryInspectionSelectorAll)(this.node, selector);
|
|
38120
38608
|
const scope = this.node.attribs?.["data-sim-scope"];
|
|
38121
38609
|
if (!scope || !this.interactions) return nodes;
|
|
38122
38610
|
return nodes.filter((node) => {
|
|
@@ -38135,7 +38623,7 @@ var HeadlessTestingNodeHandle = class HeadlessTestingNodeHandle {
|
|
|
38135
38623
|
}
|
|
38136
38624
|
async getElementsByXpath(expression) {
|
|
38137
38625
|
this.assertActive();
|
|
38138
|
-
return queryXPathElements(this.node, expression).map((node) => new HeadlessTestingNodeHandle(node, this.interactions));
|
|
38626
|
+
return (this.interactions?.projectionOnly ? queryXPathElements : queryInspectionXPathElements)(this.node, expression).map((node) => new HeadlessTestingNodeHandle(node, this.interactions));
|
|
38139
38627
|
}
|
|
38140
38628
|
async attr(name) {
|
|
38141
38629
|
this.assertActive();
|
|
@@ -39416,6 +39904,136 @@ var HeadlessAppLifecycle = class {
|
|
|
39416
39904
|
}
|
|
39417
39905
|
};
|
|
39418
39906
|
//#endregion
|
|
39907
|
+
//#region ../../mpcore/packages/simulator/src/runtime/workerHost.ts
|
|
39908
|
+
/** 两种 simulator 共用消息与生命周期;每个 worker 独立模块缓存、全局对象及计时器。 */
|
|
39909
|
+
function createWorkerHost(options) {
|
|
39910
|
+
const active = /* @__PURE__ */ new Set();
|
|
39911
|
+
let closed = false;
|
|
39912
|
+
const configuredRoot = () => {
|
|
39913
|
+
return JSON.parse(options.read(join(options.root, "app.json")) ?? "{}").workers;
|
|
39914
|
+
};
|
|
39915
|
+
return {
|
|
39916
|
+
apis: {
|
|
39917
|
+
preDownloadSubpackage(option) {
|
|
39918
|
+
const config = configuredRoot();
|
|
39919
|
+
if (option.packageType !== "workers" || typeof config !== "object" || !config.isSubpackage) {
|
|
39920
|
+
const error = /* @__PURE__ */ new Error("preDownloadSubpackage:fail workers subpackage is not configured");
|
|
39921
|
+
option.fail?.(error);
|
|
39922
|
+
option.complete?.();
|
|
39923
|
+
return;
|
|
39924
|
+
}
|
|
39925
|
+
const result = { errMsg: "preDownloadSubpackage:ok" };
|
|
39926
|
+
option.success?.(result);
|
|
39927
|
+
option.complete?.(result);
|
|
39928
|
+
},
|
|
39929
|
+
createWorker(scriptPath) {
|
|
39930
|
+
if (closed) throw new Error("createWorker:fail runtime has closed");
|
|
39931
|
+
const config = configuredRoot();
|
|
39932
|
+
const directory = typeof config === "string" ? config : config?.path;
|
|
39933
|
+
if (!directory || typeof scriptPath !== "string" || !scriptPath.endsWith(".js")) throw new Error("createWorker:fail invalid worker path");
|
|
39934
|
+
const root = normalize(join(options.root, directory));
|
|
39935
|
+
const entry = normalize(join(options.root, scriptPath));
|
|
39936
|
+
const inside = (file) => file.startsWith(`${root}/`);
|
|
39937
|
+
if (!inside(entry) || options.read(entry) === void 0) throw new Error("createWorker:fail worker entry is outside the configured directory or missing");
|
|
39938
|
+
const messages = /* @__PURE__ */ new Set();
|
|
39939
|
+
const incoming = /* @__PURE__ */ new Set();
|
|
39940
|
+
const errors = /* @__PURE__ */ new Set();
|
|
39941
|
+
const cache = /* @__PURE__ */ new Map();
|
|
39942
|
+
let terminated = false;
|
|
39943
|
+
const scheduler = new RuntimeScheduler((error) => {
|
|
39944
|
+
const value = { message: error instanceof Error ? error.message : String(error) };
|
|
39945
|
+
if (errors.size) for (const listener of errors) listener(value);
|
|
39946
|
+
else options.console.error(value.message);
|
|
39947
|
+
});
|
|
39948
|
+
const post = (listeners, message) => {
|
|
39949
|
+
if (terminated) return;
|
|
39950
|
+
const copy = structuredClone(message);
|
|
39951
|
+
scheduler.setTimeout(() => {
|
|
39952
|
+
for (const listener of [...listeners]) {
|
|
39953
|
+
if (terminated) break;
|
|
39954
|
+
listener(copy);
|
|
39955
|
+
}
|
|
39956
|
+
}, 0);
|
|
39957
|
+
};
|
|
39958
|
+
const globals = {
|
|
39959
|
+
wx: void 0,
|
|
39960
|
+
App: void 0,
|
|
39961
|
+
Page: void 0,
|
|
39962
|
+
Component: void 0,
|
|
39963
|
+
getApp: void 0,
|
|
39964
|
+
console: options.console,
|
|
39965
|
+
worker: {
|
|
39966
|
+
onMessage: (listener) => incoming.add(listener),
|
|
39967
|
+
postMessage: (message) => post(messages, message)
|
|
39968
|
+
},
|
|
39969
|
+
setTimeout: scheduler.setTimeout.bind(scheduler),
|
|
39970
|
+
clearTimeout: scheduler.clearTimeout.bind(scheduler),
|
|
39971
|
+
setInterval: scheduler.setInterval.bind(scheduler),
|
|
39972
|
+
clearInterval: scheduler.clearInterval.bind(scheduler)
|
|
39973
|
+
};
|
|
39974
|
+
globals.globalThis = globals;
|
|
39975
|
+
const execute = options.createExecutor(globals);
|
|
39976
|
+
const load = (file) => {
|
|
39977
|
+
if (terminated) return;
|
|
39978
|
+
if (!inside(file)) throw new Error("Worker require cannot leave its configured directory");
|
|
39979
|
+
if (cache.has(file)) return cache.get(file).exports;
|
|
39980
|
+
const source = options.read(file);
|
|
39981
|
+
if (source === void 0) throw new Error(`Missing worker module: ${file}`);
|
|
39982
|
+
if (file.endsWith(".json")) return JSON.parse(source);
|
|
39983
|
+
const module = { exports: {} };
|
|
39984
|
+
cache.set(file, module);
|
|
39985
|
+
const require = Object.assign((request) => {
|
|
39986
|
+
const target = resolveMiniProgramModule(file, request, root, (candidate) => options.read(candidate) !== void 0);
|
|
39987
|
+
if (!target) throw new Error(`Cannot resolve worker module: ${request}`);
|
|
39988
|
+
return load(target);
|
|
39989
|
+
}, { async: (request) => Promise.resolve().then(() => require(request)) });
|
|
39990
|
+
try {
|
|
39991
|
+
execute(source, file, module, require);
|
|
39992
|
+
} catch (error) {
|
|
39993
|
+
cache.delete(file);
|
|
39994
|
+
throw error;
|
|
39995
|
+
}
|
|
39996
|
+
return module.exports;
|
|
39997
|
+
};
|
|
39998
|
+
const worker = {
|
|
39999
|
+
onMessage: (listener) => {
|
|
40000
|
+
messages.add(listener);
|
|
40001
|
+
},
|
|
40002
|
+
offMessage: (listener) => {
|
|
40003
|
+
if (listener) messages.delete(listener);
|
|
40004
|
+
else messages.clear();
|
|
40005
|
+
},
|
|
40006
|
+
postMessage: (message) => post(incoming, message),
|
|
40007
|
+
onError: (listener) => {
|
|
40008
|
+
errors.add(listener);
|
|
40009
|
+
},
|
|
40010
|
+
offError: (listener) => {
|
|
40011
|
+
if (listener) errors.delete(listener);
|
|
40012
|
+
else errors.clear();
|
|
40013
|
+
},
|
|
40014
|
+
terminate() {
|
|
40015
|
+
if (terminated) return;
|
|
40016
|
+
terminated = true;
|
|
40017
|
+
scheduler.close();
|
|
40018
|
+
messages.clear();
|
|
40019
|
+
incoming.clear();
|
|
40020
|
+
errors.clear();
|
|
40021
|
+
cache.clear();
|
|
40022
|
+
active.delete(worker);
|
|
40023
|
+
}
|
|
40024
|
+
};
|
|
40025
|
+
active.add(worker);
|
|
40026
|
+
scheduler.setTimeout(() => load(entry), 0);
|
|
40027
|
+
return worker;
|
|
40028
|
+
}
|
|
40029
|
+
},
|
|
40030
|
+
close() {
|
|
40031
|
+
closed = true;
|
|
40032
|
+
for (const worker of active) worker.terminate();
|
|
40033
|
+
}
|
|
40034
|
+
};
|
|
40035
|
+
}
|
|
40036
|
+
//#endregion
|
|
39419
40037
|
//#region ../../mpcore/packages/simulator/src/runtime/runtimeGlobals.ts
|
|
39420
40038
|
const MINI_PROGRAM_UNAVAILABLE_GLOBAL_NAMES = [
|
|
39421
40039
|
"window",
|
|
@@ -39558,9 +40176,9 @@ function transformEsmToCommonJs(source) {
|
|
|
39558
40176
|
function createRequireNotFoundError(request, importer) {
|
|
39559
40177
|
return /* @__PURE__ */ new Error(`Cannot resolve require("${request}") from ${normalize(importer)} in headless runtime.`);
|
|
39560
40178
|
}
|
|
39561
|
-
function createExecutionContext(registries, getCurrentPages, getApp, wxDriver, kernel, globals, onConsole) {
|
|
40179
|
+
function createExecutionContext(registries, getCurrentPages, getApp, wxDriver, kernel, globals, onConsole, workers) {
|
|
39562
40180
|
const runtimeConsole = kernel.diagnostics.createConsole(console, onConsole);
|
|
39563
|
-
const wx = createHeadlessWx(wxDriver, runtimeConsole);
|
|
40181
|
+
const wx = createHeadlessWx(wxDriver, runtimeConsole, workers);
|
|
39564
40182
|
return createMiniProgramRuntimeGlobals({
|
|
39565
40183
|
App(definition) {
|
|
39566
40184
|
return registerAppDefinition(registries, definition);
|
|
@@ -39593,8 +40211,19 @@ function createExecutionContext(registries, getCurrentPages, getApp, wxDriver, k
|
|
|
39593
40211
|
}, globals);
|
|
39594
40212
|
}
|
|
39595
40213
|
function createModuleLoader(registries, getCurrentPages, getApp, wxDriver, options) {
|
|
40214
|
+
const workers = createWorkerHost({
|
|
40215
|
+
root: options.miniprogramRootPath,
|
|
40216
|
+
read: (file) => options.artifactSource.readText(file),
|
|
40217
|
+
console: options.kernel.diagnostics.createConsole(console, options.onConsole),
|
|
40218
|
+
createExecutor(globals) {
|
|
40219
|
+
const realm = vm.createContext(globals);
|
|
40220
|
+
return (source, file, module, require) => {
|
|
40221
|
+
new vm.Script(`(function(module, exports, require) {${source}\n})`, { filename: file }).runInContext(realm)(module, module.exports, require);
|
|
40222
|
+
};
|
|
40223
|
+
}
|
|
40224
|
+
});
|
|
39596
40225
|
const moduleCache = /* @__PURE__ */ new Map();
|
|
39597
|
-
const executionContext = createExecutionContext(registries, getCurrentPages, getApp, wxDriver, options.kernel, options.globals ?? {}, options.onConsole);
|
|
40226
|
+
const executionContext = createExecutionContext(registries, getCurrentPages, getApp, wxDriver, options.kernel, options.globals ?? {}, options.onConsole, workers.apis);
|
|
39598
40227
|
executionContext.globalThis = executionContext;
|
|
39599
40228
|
function executeModule(filePath, loadContext) {
|
|
39600
40229
|
const resolvedPath = path.resolve(filePath);
|
|
@@ -39653,6 +40282,7 @@ function createModuleLoader(registries, getCurrentPages, getApp, wxDriver, optio
|
|
|
39653
40282
|
return callback(...args);
|
|
39654
40283
|
},
|
|
39655
40284
|
close() {
|
|
40285
|
+
workers.close();
|
|
39656
40286
|
moduleCache.clear();
|
|
39657
40287
|
closeRuntimeWxsLoader(loader);
|
|
39658
40288
|
},
|
|
@@ -39707,6 +40337,7 @@ var HeadlessRouteEvents = class {
|
|
|
39707
40337
|
nextRouteId = 0;
|
|
39708
40338
|
nextWebviewId = 0;
|
|
39709
40339
|
activeEvent;
|
|
40340
|
+
activeState;
|
|
39710
40341
|
constructor(requestRender, isCurrentPage) {
|
|
39711
40342
|
this.requestRender = requestRender;
|
|
39712
40343
|
this.isCurrentPage = isCurrentPage;
|
|
@@ -39718,6 +40349,7 @@ var HeadlessRouteEvents = class {
|
|
|
39718
40349
|
this.bus.$off(name, listener);
|
|
39719
40350
|
}
|
|
39720
40351
|
begin(path, query, openType, renderer, page) {
|
|
40352
|
+
this.cancel(this.activeState, /* @__PURE__ */ new Error("navigateTo:fail navigation was superseded"));
|
|
39721
40353
|
const previous = page ? this.pages.get(page) : void 0;
|
|
39722
40354
|
const event = {
|
|
39723
40355
|
path,
|
|
@@ -39734,12 +40366,28 @@ var HeadlessRouteEvents = class {
|
|
|
39734
40366
|
}
|
|
39735
40367
|
attach(page, event) {
|
|
39736
40368
|
const state = this.pages.get(page);
|
|
39737
|
-
|
|
40369
|
+
const next = {
|
|
39738
40370
|
webviewId: event.webviewId,
|
|
39739
40371
|
ready: state?.ready ?? false,
|
|
39740
40372
|
event,
|
|
39741
|
-
committed: false
|
|
39742
|
-
|
|
40373
|
+
committed: false,
|
|
40374
|
+
completed: false
|
|
40375
|
+
};
|
|
40376
|
+
this.pages.set(page, next);
|
|
40377
|
+
if (this.activeEvent === event) this.activeState = next;
|
|
40378
|
+
}
|
|
40379
|
+
/** 原生 navigateTo 的回调属于本次路由记录,不能以当前页面或提交栈代替完成。 */
|
|
40380
|
+
navigateTo(operation, callbacks) {
|
|
40381
|
+
let state;
|
|
40382
|
+
try {
|
|
40383
|
+
state = this.pages.get(operation());
|
|
40384
|
+
} catch (error) {
|
|
40385
|
+
this.settle(callbacks, error);
|
|
40386
|
+
return;
|
|
40387
|
+
}
|
|
40388
|
+
if (!state || state.canceled) this.settle(callbacks, state?.canceled ?? /* @__PURE__ */ new Error("navigateTo:fail target page was unloaded"));
|
|
40389
|
+
else if (state.completed) this.settle(callbacks);
|
|
40390
|
+
else state.callbacks = callbacks;
|
|
39743
40391
|
}
|
|
39744
40392
|
commit(page, event) {
|
|
39745
40393
|
const state = this.pages.get(page);
|
|
@@ -39756,10 +40404,32 @@ var HeadlessRouteEvents = class {
|
|
|
39756
40404
|
}
|
|
39757
40405
|
complete(page, state) {
|
|
39758
40406
|
this.requestRender(() => {
|
|
39759
|
-
if (this.pages.get(page) !== state || this.activeEvent !== state.event || !this.isCurrentPage(page)) return;
|
|
39760
|
-
|
|
40407
|
+
if (state.completed || state.canceled || this.pages.get(page) !== state || this.activeEvent !== state.event || !this.isCurrentPage(page)) return;
|
|
40408
|
+
state.completed = true;
|
|
40409
|
+
const callbacks = state.callbacks;
|
|
40410
|
+
state.callbacks = void 0;
|
|
40411
|
+
try {
|
|
40412
|
+
this.bus.$emit("appRouteDone", state.event);
|
|
40413
|
+
} finally {
|
|
40414
|
+
this.settle(callbacks);
|
|
40415
|
+
}
|
|
39761
40416
|
});
|
|
39762
40417
|
}
|
|
40418
|
+
settle(callbacks, error) {
|
|
40419
|
+
try {
|
|
40420
|
+
if (error) callbacks?.fail?.(error);
|
|
40421
|
+
else callbacks?.success?.();
|
|
40422
|
+
} finally {
|
|
40423
|
+
callbacks?.complete?.();
|
|
40424
|
+
}
|
|
40425
|
+
}
|
|
40426
|
+
cancel(state, error) {
|
|
40427
|
+
if (!state || state.completed || state.canceled) return;
|
|
40428
|
+
state.canceled = error;
|
|
40429
|
+
const callbacks = state.callbacks;
|
|
40430
|
+
state.callbacks = void 0;
|
|
40431
|
+
this.settle(callbacks, error);
|
|
40432
|
+
}
|
|
39763
40433
|
beforeUnload(page, event) {
|
|
39764
40434
|
const state = this.pages.get(page);
|
|
39765
40435
|
if (event && state) this.bus.$emit("beforePageUnload", {
|
|
@@ -39770,9 +40440,12 @@ var HeadlessRouteEvents = class {
|
|
|
39770
40440
|
webviewId: state.webviewId,
|
|
39771
40441
|
page
|
|
39772
40442
|
});
|
|
40443
|
+
this.cancel(state, /* @__PURE__ */ new Error("navigateTo:fail target page was unloaded"));
|
|
39773
40444
|
this.pages.delete(page);
|
|
39774
40445
|
}
|
|
39775
40446
|
close() {
|
|
40447
|
+
this.cancel(this.activeState, /* @__PURE__ */ new Error("navigateTo:fail runtime session closed"));
|
|
40448
|
+
this.activeState = void 0;
|
|
39776
40449
|
this.activeEvent = void 0;
|
|
39777
40450
|
this.bus.$off();
|
|
39778
40451
|
}
|
|
@@ -41701,7 +42374,7 @@ var HeadlessSession = class {
|
|
|
41701
42374
|
getMenuButtonBoundingClientRect: () => deriveMenuButtonBoundingClientRect(this.systemInfo),
|
|
41702
42375
|
getNetworkType: () => this.wxState.getNetworkType(),
|
|
41703
42376
|
navigateBack: (option) => this.navigateBack(option?.delta),
|
|
41704
|
-
navigateTo: (option) => this.navigateTo(option.url),
|
|
42377
|
+
navigateTo: (option) => this.routeEvents.navigateTo(() => this.navigateTo(option.url), option),
|
|
41705
42378
|
pageScrollTo: (option) => this.pageScrollTo(option),
|
|
41706
42379
|
openDocument: (option) => this.wxState.openDocument(option),
|
|
41707
42380
|
clearStorageSync: () => this.wxState.clearStorageSync(),
|
|
@@ -42016,19 +42689,19 @@ var HeadlessSession = class {
|
|
|
42016
42689
|
return this.wxState.getShareMenu();
|
|
42017
42690
|
}
|
|
42018
42691
|
selectComponent(selector) {
|
|
42019
|
-
this.renderCurrentPage();
|
|
42692
|
+
if (!hasPendingComponentConstruction(this.componentCache)) this.renderCurrentPage();
|
|
42020
42693
|
return this.selectComponentsWithin(null, selector)[0] ?? null;
|
|
42021
42694
|
}
|
|
42022
42695
|
selectAllComponents(selector) {
|
|
42023
|
-
this.renderCurrentPage();
|
|
42696
|
+
if (!hasPendingComponentConstruction(this.componentCache)) this.renderCurrentPage();
|
|
42024
42697
|
return this.selectComponentsWithin(null, selector);
|
|
42025
42698
|
}
|
|
42026
42699
|
selectComponentWithin(scopeId, selector) {
|
|
42027
|
-
this.renderCurrentPage();
|
|
42700
|
+
if (!hasPendingComponentConstruction(this.componentCache)) this.renderCurrentPage();
|
|
42028
42701
|
return this.selectComponentsWithin(scopeId, selector)[0] ?? null;
|
|
42029
42702
|
}
|
|
42030
42703
|
selectAllComponentsWithin(scopeId, selector) {
|
|
42031
|
-
this.renderCurrentPage();
|
|
42704
|
+
if (!hasPendingComponentConstruction(this.componentCache)) this.renderCurrentPage();
|
|
42032
42705
|
return this.selectComponentsWithin(scopeId, selector);
|
|
42033
42706
|
}
|
|
42034
42707
|
selectOwnerComponent(scopeId) {
|
|
@@ -42768,6 +43441,7 @@ function createPageRootNodeHandle(options) {
|
|
|
42768
43441
|
const tree = session?.getCurrentPages().includes(page) ? session.renderCurrentPage() : renderPageTree(project, page);
|
|
42769
43442
|
return new HeadlessTestingNodeHandle(tree.root.type === "root" && !options.includeHostRoots ? tree.root.children?.[0] ?? tree.root : tree.root, {
|
|
42770
43443
|
assertActive: options.assertActive,
|
|
43444
|
+
projectionOnly: options.projectionOnly,
|
|
42771
43445
|
dispatchNativeEvent: (node, eventName, event, onHandlerResult) => session?.getCurrentPages().at(-1) === page ? session.dispatchNativeNodeEvent(node, eventName, event, onHandlerResult) : false,
|
|
42772
43446
|
callMethod: (scopeId, methodName, event) => {
|
|
42773
43447
|
if (session?.getCurrentPages().includes(page)) return session.callScopeMethod(scopeId, methodName, event);
|
|
@@ -43130,7 +43804,18 @@ var HeadlessTestingPageHandle = class {
|
|
|
43130
43804
|
renderedAccess() {
|
|
43131
43805
|
return {
|
|
43132
43806
|
assertActive: () => this.assertActive(),
|
|
43133
|
-
findAll: async (selector) =>
|
|
43807
|
+
findAll: async (selector) => {
|
|
43808
|
+
this.assertActive();
|
|
43809
|
+
const root = createPageRootNodeHandle({
|
|
43810
|
+
assertActive: () => this.assertActive(),
|
|
43811
|
+
createPageHandle: () => this,
|
|
43812
|
+
page: this.page,
|
|
43813
|
+
project: this.project,
|
|
43814
|
+
projectionOnly: true,
|
|
43815
|
+
session: this.session
|
|
43816
|
+
});
|
|
43817
|
+
return selector === "page" ? [root] : await root.$$(selector);
|
|
43818
|
+
},
|
|
43134
43819
|
waitFor: async (ms) => await this.waitFor(ms),
|
|
43135
43820
|
wxml: async () => await this.wxml()
|
|
43136
43821
|
};
|
|
@@ -43217,6 +43902,10 @@ var HeadlessTestingSessionHandle = class {
|
|
|
43217
43902
|
});
|
|
43218
43903
|
}
|
|
43219
43904
|
async close() {
|
|
43905
|
+
this.disconnect();
|
|
43906
|
+
}
|
|
43907
|
+
/** 无头会话独占本地 runtime;同步释放与 automator 的连接清理契约一致。 */
|
|
43908
|
+
disconnect() {
|
|
43220
43909
|
this.session.close();
|
|
43221
43910
|
}
|
|
43222
43911
|
async toolInfo() {
|
|
@@ -43256,6 +43945,10 @@ var HeadlessTestingSessionHandle = class {
|
|
|
43256
43945
|
const normalizedMethodName = normalizeNonEmptyInput(methodName, "wx method name");
|
|
43257
43946
|
return await runWithTimeout(() => this.session.callWxMethod(normalizedMethodName, ...args), options.timeout, `Timed out calling wx.${normalizedMethodName} in headless testing runtime.`);
|
|
43258
43947
|
}
|
|
43948
|
+
/** 返回与 DevTools automator 兼容的运行时系统信息。 */
|
|
43949
|
+
async systemInfo() {
|
|
43950
|
+
return await this.callWxMethod("getSystemInfoSync");
|
|
43951
|
+
}
|
|
43259
43952
|
async scopeSnapshot(scopeId) {
|
|
43260
43953
|
const normalizedScopeId = normalizeNonEmptyInput(scopeId, "Scope id");
|
|
43261
43954
|
return this.session.getScopeSnapshot(normalizedScopeId);
|