@weapp-vite/miniprogram-automator 1.2.18 → 1.2.20
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/dist/index.mjs
CHANGED
|
@@ -943,7 +943,7 @@ var Connection = class Connection extends EventEmitter {
|
|
|
943
943
|
//#endregion
|
|
944
944
|
//#region src/headless.ts
|
|
945
945
|
async function launchHeadlessAutomator(options) {
|
|
946
|
-
return await (await import("./launch-
|
|
946
|
+
return await (await import("./launch-BNQZTcKo.mjs")).launch({ projectPath: options.projectPath });
|
|
947
947
|
}
|
|
948
948
|
//#endregion
|
|
949
949
|
//#region src/launcher/portLease.ts
|
|
@@ -1098,7 +1098,7 @@ function resolveWechatDevtoolsBootstrapArgs(args) {
|
|
|
1098
1098
|
}
|
|
1099
1099
|
//#endregion
|
|
1100
1100
|
//#region package.json
|
|
1101
|
-
var version = "1.2.
|
|
1101
|
+
var version = "1.2.20";
|
|
1102
1102
|
//#endregion
|
|
1103
1103
|
//#region src/Native.ts
|
|
1104
1104
|
/** Native 的实现。 */
|
|
@@ -1194,7 +1194,7 @@ function linkRenderedParents(root, parent = null) {
|
|
|
1194
1194
|
for (const child of root.children ?? []) linkRenderedParents(child, root);
|
|
1195
1195
|
}
|
|
1196
1196
|
//#endregion
|
|
1197
|
-
//#region ../../node_modules/.pnpm/@babel+parser@8.0.
|
|
1197
|
+
//#region ../../node_modules/.pnpm/@babel+parser@8.0.6/node_modules/@babel/parser/lib/index.js
|
|
1198
1198
|
var Position = class {
|
|
1199
1199
|
constructor(line, col, index) {
|
|
1200
1200
|
this.line = void 0;
|
|
@@ -2209,16 +2209,30 @@ const types = {
|
|
|
2209
2209
|
j_cTag: new TokContext("</tag"),
|
|
2210
2210
|
j_expr: new TokContext("<tag>...</tag>", true)
|
|
2211
2211
|
};
|
|
2212
|
-
const bmpIdentifierStart = /[\p{ID_Start}\u088f\u0c5c\u0cdc\ua7ce\ua7cf\ua7d2\ua7d4\ua7f1]/u;
|
|
2213
|
-
const bmpIdentifier = /[\p{ID_Continue}\u088f\u0c5c\u0cdc\ua7ce\ua7cf\ua7d2\ua7d4\ua7f1\u1acf-\
|
|
2212
|
+
const bmpIdentifierStart = /[\p{ID_Start}\u0558\u058b\u058c\u088f\u0c5c\u0cdc\u208f\u209d-\u209f\ua7ce\ua7cf\ua7d2\ua7d4\ua7dd\ua7e2\ua7f1\uab6c\uab6d]/u;
|
|
2213
|
+
const bmpIdentifier = /[\p{ID_Continue}\u0558\u058b\u058c\u088f\u0c5c\u0cdc\u208f\u209d-\u209f\ua7ce\ua7cf\ua7d2\ua7d4\ua7dd\ua7e2\ua7f1\uab6c\uab6d\u05c8\u05c9\u0b53\u0b54\u1acf-\u1af0]/u;
|
|
2214
2214
|
const supplementaryIdentifierStartCodes = [
|
|
2215
|
-
|
|
2215
|
+
1979,
|
|
2216
|
+
4,
|
|
2217
|
+
385,
|
|
2216
2218
|
25,
|
|
2217
2219
|
1388,
|
|
2218
2220
|
2,
|
|
2219
|
-
|
|
2221
|
+
18,
|
|
2222
|
+
21,
|
|
2223
|
+
3100,
|
|
2224
|
+
0,
|
|
2225
|
+
678,
|
|
2220
2226
|
43,
|
|
2221
|
-
|
|
2227
|
+
22,
|
|
2228
|
+
0,
|
|
2229
|
+
1662,
|
|
2230
|
+
0,
|
|
2231
|
+
6,
|
|
2232
|
+
10,
|
|
2233
|
+
209,
|
|
2234
|
+
310,
|
|
2235
|
+
18458,
|
|
2222
2236
|
24,
|
|
2223
2237
|
3,
|
|
2224
2238
|
24,
|
|
@@ -2226,11 +2240,31 @@ const supplementaryIdentifierStartCodes = [
|
|
|
2226
2240
|
4,
|
|
2227
2241
|
6146,
|
|
2228
2242
|
7,
|
|
2229
|
-
|
|
2230
|
-
|
|
2231
|
-
|
|
2243
|
+
1239,
|
|
2244
|
+
4,
|
|
2245
|
+
47,
|
|
2246
|
+
23,
|
|
2247
|
+
96,
|
|
2232
2248
|
114,
|
|
2233
|
-
|
|
2249
|
+
14,
|
|
2250
|
+
913,
|
|
2251
|
+
15,
|
|
2252
|
+
50,
|
|
2253
|
+
8017,
|
|
2254
|
+
5,
|
|
2255
|
+
64,
|
|
2256
|
+
0,
|
|
2257
|
+
9534,
|
|
2258
|
+
0,
|
|
2259
|
+
2169,
|
|
2260
|
+
5,
|
|
2261
|
+
7,
|
|
2262
|
+
86,
|
|
2263
|
+
15,
|
|
2264
|
+
6,
|
|
2265
|
+
55,
|
|
2266
|
+
50,
|
|
2267
|
+
1729,
|
|
2234
2268
|
30,
|
|
2235
2269
|
2,
|
|
2236
2270
|
2,
|
|
@@ -2244,19 +2278,37 @@ const supplementaryIdentifierStartCodes = [
|
|
|
2244
2278
|
1,
|
|
2245
2279
|
53307,
|
|
2246
2280
|
5,
|
|
2247
|
-
|
|
2281
|
+
223,
|
|
2282
|
+
0,
|
|
2283
|
+
5764,
|
|
2248
2284
|
11,
|
|
2249
2285
|
21763,
|
|
2250
|
-
4297
|
|
2286
|
+
4297,
|
|
2287
|
+
39815,
|
|
2288
|
+
11327
|
|
2251
2289
|
];
|
|
2252
2290
|
const supplementaryIdentifierCodes = [
|
|
2253
|
-
|
|
2254
|
-
|
|
2291
|
+
3787,
|
|
2292
|
+
4,
|
|
2293
|
+
33,
|
|
2294
|
+
11,
|
|
2255
2295
|
3173,
|
|
2256
2296
|
7,
|
|
2257
2297
|
633,
|
|
2258
2298
|
9,
|
|
2259
|
-
|
|
2299
|
+
7,
|
|
2300
|
+
0,
|
|
2301
|
+
45879,
|
|
2302
|
+
1,
|
|
2303
|
+
296,
|
|
2304
|
+
2,
|
|
2305
|
+
9,
|
|
2306
|
+
1,
|
|
2307
|
+
3,
|
|
2308
|
+
0,
|
|
2309
|
+
33,
|
|
2310
|
+
1,
|
|
2311
|
+
5218,
|
|
2260
2312
|
0,
|
|
2261
2313
|
3,
|
|
2262
2314
|
0,
|
|
@@ -3649,10 +3701,10 @@ const flow = (superClass) => class FlowParserMixin extends superClass {
|
|
|
3649
3701
|
const arrows = [];
|
|
3650
3702
|
while (stack.length !== 0) {
|
|
3651
3703
|
const node = stack.pop();
|
|
3652
|
-
if (node.type === "ArrowFunctionExpression"
|
|
3704
|
+
if (node.type === "ArrowFunctionExpression") {
|
|
3653
3705
|
if (node.typeParameters || !node.returnType) this.finishArrowValidation(node);
|
|
3654
3706
|
else arrows.push(node);
|
|
3655
|
-
stack.push(node.body);
|
|
3707
|
+
if (node.body.type !== "BlockStatement") stack.push(node.body);
|
|
3656
3708
|
} else if (node.type === "ConditionalExpression") {
|
|
3657
3709
|
stack.push(node.consequent);
|
|
3658
3710
|
stack.push(node.alternate);
|
|
@@ -4720,7 +4772,7 @@ const entities = {
|
|
|
4720
4772
|
hearts: "♥",
|
|
4721
4773
|
diams: "♦"
|
|
4722
4774
|
};
|
|
4723
|
-
const lineBreakG =
|
|
4775
|
+
const lineBreakG = /\r\n|[\r\n\u2028\u2029]/g;
|
|
4724
4776
|
function isNewLine(code) {
|
|
4725
4777
|
switch (code) {
|
|
4726
4778
|
case 10:
|
|
@@ -5685,12 +5737,14 @@ function readInt(input, pos, lineStart, curLine, radix, len, forceLen, allowNumS
|
|
|
5685
5737
|
else if (_isDigit(code)) val = code - 48;
|
|
5686
5738
|
else val = Infinity;
|
|
5687
5739
|
if (val >= radix) {
|
|
5688
|
-
if (val <= 9
|
|
5689
|
-
|
|
5690
|
-
|
|
5691
|
-
|
|
5692
|
-
|
|
5693
|
-
|
|
5740
|
+
if (val <= 9) {
|
|
5741
|
+
if (bailOnError) return {
|
|
5742
|
+
n: null,
|
|
5743
|
+
pos
|
|
5744
|
+
};
|
|
5745
|
+
errors.invalidDigit(pos, lineStart, curLine, radix);
|
|
5746
|
+
val = 0;
|
|
5747
|
+
} else if (forceLen) {
|
|
5694
5748
|
val = 0;
|
|
5695
5749
|
invalid = true;
|
|
5696
5750
|
} else break;
|
|
@@ -6520,9 +6574,7 @@ var Tokenizer$1 = class extends CommentsParser {
|
|
|
6520
6574
|
}
|
|
6521
6575
|
errorHandlers_readInt = {
|
|
6522
6576
|
invalidDigit: (pos, lineStart, curLine, radix) => {
|
|
6523
|
-
if (!(this.optionFlags & 4096)) return false;
|
|
6524
6577
|
this.raise(Errors.InvalidDigit, buildPosition(pos, lineStart, curLine), { radix });
|
|
6525
|
-
return true;
|
|
6526
6578
|
},
|
|
6527
6579
|
numericSeparatorInEscapeSequence: this.errorBuilder(Errors.NumericSeparatorInEscapeSequence),
|
|
6528
6580
|
unexpectedNumericSeparator: this.errorBuilder(Errors.UnexpectedNumericSeparator)
|
|
@@ -12103,6 +12155,9 @@ const typescript = (superClass) => class TypeScriptParserMixin extends superClas
|
|
|
12103
12155
|
}
|
|
12104
12156
|
fillOptionalPropertiesForTSESLint(node) {
|
|
12105
12157
|
switch (node.type) {
|
|
12158
|
+
case "ImportDeclaration":
|
|
12159
|
+
node.phase ??= null;
|
|
12160
|
+
return;
|
|
12106
12161
|
case "ExpressionStatement":
|
|
12107
12162
|
node.directive ??= void 0;
|
|
12108
12163
|
return;
|
|
@@ -12634,13 +12689,13 @@ const BLOCKED_MEMBER_KEYS = /* @__PURE__ */ new Set([
|
|
|
12634
12689
|
"prototype"
|
|
12635
12690
|
]);
|
|
12636
12691
|
const NUMERIC_DOT_PATH_RE = /\.(\d+)(?=[.[\s,}\]]|$)/g;
|
|
12637
|
-
function isMustacheOnly$
|
|
12692
|
+
function isMustacheOnly$2(value) {
|
|
12638
12693
|
const trimmed = value.trim();
|
|
12639
12694
|
return trimmed.startsWith("{{") && trimmed.endsWith("}}") && !trimmed.includes("{{", 2);
|
|
12640
12695
|
}
|
|
12641
12696
|
function unwrapMustacheExpression(expression) {
|
|
12642
12697
|
const normalized = expression.trim();
|
|
12643
|
-
if (isMustacheOnly$
|
|
12698
|
+
if (isMustacheOnly$2(normalized)) return normalized.slice(2, -2).trim();
|
|
12644
12699
|
return normalized;
|
|
12645
12700
|
}
|
|
12646
12701
|
function parseTemplateExpression(expression) {
|
|
@@ -12845,6 +12900,26 @@ function flushComponentAttachments(instances, attach) {
|
|
|
12845
12900
|
return pending.length > 0;
|
|
12846
12901
|
}
|
|
12847
12902
|
//#endregion
|
|
12903
|
+
//#region ../../mpcore/packages/simulator/src/runtime/componentInstance/discardedReady.ts
|
|
12904
|
+
const discardedReady = /* @__PURE__ */ new WeakMap();
|
|
12905
|
+
/** 初始模板分支被 props 替换时,微信仍发送 ready,但不发送 attached 或 detached。 */
|
|
12906
|
+
function scheduleDiscardedComponentReady(cache, scopeId, instance) {
|
|
12907
|
+
const pending = discardedReady.get(cache) ?? /* @__PURE__ */ new Map();
|
|
12908
|
+
pending.set(scopeId, instance);
|
|
12909
|
+
discardedReady.set(cache, pending);
|
|
12910
|
+
}
|
|
12911
|
+
function flushDiscardedComponentReady(cache, pageScopeId, ready) {
|
|
12912
|
+
const pending = discardedReady.get(cache);
|
|
12913
|
+
if (!pending) return;
|
|
12914
|
+
const current = [...pending].filter(([scopeId]) => scopeId.startsWith(`${pageScopeId}/`));
|
|
12915
|
+
for (const [scopeId, instance] of current) {
|
|
12916
|
+
pending.delete(scopeId);
|
|
12917
|
+
instance.__ready__ = true;
|
|
12918
|
+
}
|
|
12919
|
+
for (const [, instance] of current) ready(instance);
|
|
12920
|
+
if (!pending.size) discardedReady.delete(cache);
|
|
12921
|
+
}
|
|
12922
|
+
//#endregion
|
|
12848
12923
|
//#region ../../mpcore/packages/simulator/src/runtime/pageLifecycle.ts
|
|
12849
12924
|
const loadingPages = /* @__PURE__ */ new WeakSet();
|
|
12850
12925
|
function isPageBeforeReady(page) {
|
|
@@ -13045,6 +13120,20 @@ function resolveSelectorQueryScopeSnapshot(scope, snapshots) {
|
|
|
13045
13120
|
return null;
|
|
13046
13121
|
}
|
|
13047
13122
|
//#endregion
|
|
13123
|
+
//#region ../../mpcore/packages/simulator/src/runtime/componentInstance/selection.ts
|
|
13124
|
+
function hasExportBehavior(definition, visited = /* @__PURE__ */ new Set()) {
|
|
13125
|
+
if (visited.has(definition)) return false;
|
|
13126
|
+
visited.add(definition);
|
|
13127
|
+
return (Array.isArray(definition.behaviors) ? definition.behaviors : []).some((behavior) => behavior === "wx://component-export" || behavior !== null && typeof behavior === "object" && hasExportBehavior(behavior, visited));
|
|
13128
|
+
}
|
|
13129
|
+
/** 原生选择器尊重组件导出行为;测试桥接继续保留完整组件实例。 */
|
|
13130
|
+
function resolveNativeComponentSelection(instance) {
|
|
13131
|
+
if (!instance) return null;
|
|
13132
|
+
const definition = instance.__definition__;
|
|
13133
|
+
if (!definition || !hasExportBehavior(definition) || typeof instance.export !== "function") return instance;
|
|
13134
|
+
return instance.export();
|
|
13135
|
+
}
|
|
13136
|
+
//#endregion
|
|
13048
13137
|
//#region ../../mpcore/packages/simulator/src/runtime/moduleResolution.ts
|
|
13049
13138
|
function resolveMiniProgramModule(importer, request, miniprogramRootPath, hasFile) {
|
|
13050
13139
|
function resolveFile(basePath) {
|
|
@@ -13079,6 +13168,21 @@ function resolveMiniProgramComponent(ownerFilePath, request, miniprogramRootPath
|
|
|
13079
13168
|
return npmPath ? relative(miniprogramRootPath, npmPath).slice(0, -3) : localPath;
|
|
13080
13169
|
}
|
|
13081
13170
|
//#endregion
|
|
13171
|
+
//#region ../../mpcore/packages/simulator/src/view/nodeDataset.ts
|
|
13172
|
+
const DATASET_NAME_RE = /-([a-z])/g;
|
|
13173
|
+
function isDatasetAttribute(attributeName) {
|
|
13174
|
+
return attributeName.startsWith("data-") && !attributeName.startsWith("data-sim-");
|
|
13175
|
+
}
|
|
13176
|
+
function toDatasetKey(attributeName) {
|
|
13177
|
+
return attributeName.slice(5).replace(DATASET_NAME_RE, (_match, char) => char.toUpperCase());
|
|
13178
|
+
}
|
|
13179
|
+
function collectNodeDataset(node) {
|
|
13180
|
+
if (node.dataset) return { ...node.dataset };
|
|
13181
|
+
const dataset = {};
|
|
13182
|
+
for (const [key, value] of Object.entries(node.attribs ?? {})) if (isDatasetAttribute(key)) dataset[toDatasetKey(key)] = value;
|
|
13183
|
+
return dataset;
|
|
13184
|
+
}
|
|
13185
|
+
//#endregion
|
|
13082
13186
|
//#region ../../mpcore/packages/simulator/src/view/templateImports.ts
|
|
13083
13187
|
function createImportedTemplateState(root, filePath, loadImport, loadWxs) {
|
|
13084
13188
|
const documents = /* @__PURE__ */ new Map();
|
|
@@ -13108,7 +13212,8 @@ function createImportedTemplateState(root, filePath, loadImport, loadWxs) {
|
|
|
13108
13212
|
return;
|
|
13109
13213
|
}
|
|
13110
13214
|
if (child.name === "import" && child.attribs?.src) {
|
|
13111
|
-
const
|
|
13215
|
+
const source = child.attribs.src;
|
|
13216
|
+
const imported = loadImport(owner, source.endsWith(".wxml") ? source : `${source}.wxml`);
|
|
13112
13217
|
const importedDocument = collect(imported.root, imported.filePath);
|
|
13113
13218
|
for (const [name, definition] of importedDocument.exports) state.definitions.set(name, definition);
|
|
13114
13219
|
}
|
|
@@ -16936,7 +17041,6 @@ function parseWxsTemplateDocument(templateSource) {
|
|
|
16936
17041
|
//#endregion
|
|
16937
17042
|
//#region ../../mpcore/packages/simulator/src/runtime/render/shared.ts
|
|
16938
17043
|
const TEMPLATE_INTERPOLATION_RE$1 = /\{\{([^{}]+)\}\}/g;
|
|
16939
|
-
const DATASET_NAME_RE$3 = /-([a-z])/g;
|
|
16940
17044
|
const LEADING_SLASH_RE$4 = /^\/+/;
|
|
16941
17045
|
const EVENT_BINDING_ATTRS = [
|
|
16942
17046
|
"bindtap",
|
|
@@ -16955,19 +17059,16 @@ const STRUCTURAL_ATTRS = [
|
|
|
16955
17059
|
];
|
|
16956
17060
|
const CLASS_SPLIT_RE = /\s+/;
|
|
16957
17061
|
const JS_FILE_RE = /\.js$/;
|
|
16958
|
-
function isMustacheOnly(value) {
|
|
17062
|
+
function isMustacheOnly$1(value) {
|
|
16959
17063
|
const trimmed = value.trim();
|
|
16960
17064
|
return trimmed.startsWith("{{") && trimmed.endsWith("}}") && !trimmed.includes("{{", 2);
|
|
16961
17065
|
}
|
|
16962
|
-
function
|
|
16963
|
-
|
|
16964
|
-
}
|
|
16965
|
-
function collectDataset$3(node, source) {
|
|
17066
|
+
function collectDataset(node, source) {
|
|
17067
|
+
if (node.dataset) return collectNodeDataset(node);
|
|
16966
17068
|
const dataset = {};
|
|
16967
17069
|
for (const [key, value] of Object.entries(node.attribs ?? {})) {
|
|
16968
|
-
if (!
|
|
16969
|
-
|
|
16970
|
-
dataset[toDatasetKey$3(key)] = String(resolvedValue ?? "");
|
|
17070
|
+
if (!isDatasetAttribute(key)) continue;
|
|
17071
|
+
dataset[toDatasetKey(key)] = source && isMustacheOnly$1(value) ? resolveTemplateExpression(source, value) : value;
|
|
16971
17072
|
}
|
|
16972
17073
|
return dataset;
|
|
16973
17074
|
}
|
|
@@ -16981,13 +17082,14 @@ function cloneNode(node) {
|
|
|
16981
17082
|
return {
|
|
16982
17083
|
...node,
|
|
16983
17084
|
attribs: node.attribs ? { ...node.attribs } : void 0,
|
|
17085
|
+
dataset: node.dataset ? { ...node.dataset } : void 0,
|
|
16984
17086
|
children: node.children?.map((child) => cloneNode(child))
|
|
16985
17087
|
};
|
|
16986
17088
|
}
|
|
16987
17089
|
function resolveValueByPath$1(source, expression) {
|
|
16988
17090
|
return resolveTemplateExpression(source, expression) ?? "";
|
|
16989
17091
|
}
|
|
16990
|
-
function resolveRawValueByPath(source, expression) {
|
|
17092
|
+
function resolveRawValueByPath$1(source, expression) {
|
|
16991
17093
|
return resolveTemplateExpression(source, expression);
|
|
16992
17094
|
}
|
|
16993
17095
|
function interpolateTemplate$1(input, data) {
|
|
@@ -17030,16 +17132,16 @@ function isTagNode(node) {
|
|
|
17030
17132
|
return node.type === "tag" && typeof node.name === "string";
|
|
17031
17133
|
}
|
|
17032
17134
|
function resolveAttributeValue(value, scope) {
|
|
17033
|
-
if (isMustacheOnly(value)) {
|
|
17135
|
+
if (isMustacheOnly$1(value)) {
|
|
17034
17136
|
const expression = value.trim().slice(2, -2);
|
|
17035
|
-
return
|
|
17137
|
+
return resolveRawValueByPath$1(wxsScopeData(scope), expression);
|
|
17036
17138
|
}
|
|
17037
17139
|
return interpolateTemplate$1(value, wxsScopeData(scope));
|
|
17038
17140
|
}
|
|
17039
17141
|
function resolveComponentAttributeValue(value, scope) {
|
|
17040
|
-
if (isMustacheOnly(value)) {
|
|
17142
|
+
if (isMustacheOnly$1(value)) {
|
|
17041
17143
|
const expression = value.trim().slice(2, -2);
|
|
17042
|
-
return resolveRawValueByPath(wxsScopeData(scope), expression) ?? null;
|
|
17144
|
+
return resolveRawValueByPath$1(wxsScopeData(scope), expression) ?? null;
|
|
17043
17145
|
}
|
|
17044
17146
|
return interpolateTemplate$1(value, wxsScopeData(scope));
|
|
17045
17147
|
}
|
|
@@ -17051,18 +17153,25 @@ function applyNodeBindings(node, scope) {
|
|
|
17051
17153
|
node.attribs ??= {};
|
|
17052
17154
|
node.attribs["data-sim-scope"] = scope.getScopeId();
|
|
17053
17155
|
for (const key of STRUCTURAL_ATTRS) delete node.attribs[key];
|
|
17156
|
+
let dataset;
|
|
17054
17157
|
for (const [key, value] of Object.entries({ ...node.attribs })) {
|
|
17055
17158
|
if (EVENT_BINDING_ATTRS.includes(key)) {
|
|
17056
17159
|
node.attribs["data-sim-tap"] = value;
|
|
17057
17160
|
continue;
|
|
17058
17161
|
}
|
|
17059
|
-
|
|
17162
|
+
const resolvedValue = typeof value === "string" ? resolveAttributeValue(value, scope) : value;
|
|
17163
|
+
node.attribs[key] = String(resolvedValue ?? "");
|
|
17164
|
+
if (isDatasetAttribute(key)) {
|
|
17165
|
+
dataset ??= {};
|
|
17166
|
+
dataset[toDatasetKey(key)] = resolvedValue;
|
|
17167
|
+
}
|
|
17060
17168
|
}
|
|
17169
|
+
node.dataset = dataset;
|
|
17061
17170
|
}
|
|
17062
17171
|
function evaluateConditionalBranch(node, scope) {
|
|
17063
17172
|
const condition = node.attribs?.["wx:if"] ?? node.attribs?.["wx:elif"];
|
|
17064
17173
|
if (condition == null) return true;
|
|
17065
|
-
return Boolean(resolveRawValueByPath(wxsScopeData(scope), condition));
|
|
17174
|
+
return Boolean(resolveRawValueByPath$1(wxsScopeData(scope), condition));
|
|
17066
17175
|
}
|
|
17067
17176
|
function createLoopScope(scope, itemName, indexName, item, index) {
|
|
17068
17177
|
return {
|
|
@@ -17138,7 +17247,7 @@ function collectComponentEventBindings(hostNode) {
|
|
|
17138
17247
|
return collectMiniProgramEventBindings(hostNode.attribs);
|
|
17139
17248
|
}
|
|
17140
17249
|
function buildComponentTrigger(componentScopeId, context, hostNode) {
|
|
17141
|
-
const hostDataset = collectDataset
|
|
17250
|
+
const hostDataset = collectDataset(hostNode);
|
|
17142
17251
|
const hostId = hostNode.attribs?.id ?? "";
|
|
17143
17252
|
return (instance, eventName, detail, triggerOptions) => {
|
|
17144
17253
|
const originScope = context.componentScopes.get(componentScopeId);
|
|
@@ -17200,7 +17309,7 @@ function createComponentScope(clonedNode, scope, componentScopeId, componentInst
|
|
|
17200
17309
|
alias: clonedNode.name,
|
|
17201
17310
|
classList: String(clonedNode.attribs?.class ?? "").split(CLASS_SPLIT_RE).map((item) => item.trim()).filter(Boolean),
|
|
17202
17311
|
data: { ...componentInstance.data },
|
|
17203
|
-
dataset: collectDataset
|
|
17312
|
+
dataset: collectDataset(clonedNode, wxsScopeData(scope)),
|
|
17204
17313
|
eventBindings: collectComponentEventBindings(clonedNode),
|
|
17205
17314
|
getMethod: (methodName) => {
|
|
17206
17315
|
const method = componentInstance?.[methodName];
|
|
@@ -17223,7 +17332,7 @@ function resolveComponentProperties(clonedNode, scope, definition) {
|
|
|
17223
17332
|
if (key.startsWith("bind") || key.startsWith("generic:")) continue;
|
|
17224
17333
|
const camelizedKey = key.replace(/-([a-z])/g, (_match, char) => char.toUpperCase());
|
|
17225
17334
|
const propertyKey = key in declaredProperties || !(camelizedKey in declaredProperties) ? key : camelizedKey;
|
|
17226
|
-
if (isMustacheOnly(String(value))) bindingExpressions[propertyKey] = String(value).trim().slice(2, -2).trim();
|
|
17335
|
+
if (isMustacheOnly$1(String(value))) bindingExpressions[propertyKey] = String(value).trim().slice(2, -2).trim();
|
|
17227
17336
|
nextProperties[propertyKey] = resolveComponentAttributeValue(String(value), scope);
|
|
17228
17337
|
}
|
|
17229
17338
|
return {
|
|
@@ -17231,7 +17340,7 @@ function resolveComponentProperties(clonedNode, scope, definition) {
|
|
|
17231
17340
|
bindingExpressions
|
|
17232
17341
|
};
|
|
17233
17342
|
}
|
|
17234
|
-
function createRuntimeComponentInstance(componentScopeId, context, clonedNode, componentEntry, nextProperties, ownerScopeId) {
|
|
17343
|
+
function createRuntimeComponentInstance(componentScopeId, context, clonedNode, componentEntry, nextProperties, ownerScopeId, beforeCreated) {
|
|
17235
17344
|
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;
|
|
17236
17345
|
const componentInstance = createComponentInstance({
|
|
17237
17346
|
definition: componentEntry.definition,
|
|
@@ -17243,10 +17352,11 @@ function createRuntimeComponentInstance(componentScopeId, context, clonedNode, c
|
|
|
17243
17352
|
componentInstance.createIntersectionObserver = (options) => context.session.createIntersectionObserver(componentInstance, options);
|
|
17244
17353
|
componentInstance.createMediaQueryObserver = () => context.session.createMediaQueryObserver(componentInstance);
|
|
17245
17354
|
componentInstance.createSelectorQuery = () => context.moduleLoader.wx.createSelectorQuery().in(componentInstance);
|
|
17246
|
-
componentInstance.selectComponent = (selector) => context.session.selectComponentWithin(componentScopeId, selector);
|
|
17247
|
-
componentInstance.selectAllComponents = (selector) => context.session.selectAllComponentsWithin(componentScopeId, selector);
|
|
17355
|
+
componentInstance.selectComponent = (selector) => resolveNativeComponentSelection(context.session.selectComponentWithin(componentScopeId, selector));
|
|
17356
|
+
componentInstance.selectAllComponents = (selector) => context.session.selectAllComponentsWithin(componentScopeId, selector).map(resolveNativeComponentSelection);
|
|
17248
17357
|
componentInstance.selectOwnerComponent = () => ownerScopeId ? context.componentCache.get(ownerScopeId) ?? null : null;
|
|
17249
17358
|
context.componentCache.set(componentScopeId, componentInstance);
|
|
17359
|
+
beforeCreated?.(componentInstance);
|
|
17250
17360
|
runComponentLifecycle(componentInstance, "created");
|
|
17251
17361
|
componentInstance.__propertySnapshots = Object.fromEntries(Object.entries(componentInstance.properties).map(([key, propertyValue]) => [key, cloneValue$1(propertyValue)]));
|
|
17252
17362
|
syncComponentProperties(componentInstance, componentInstance.__definition__ ?? componentEntry.definition, componentProperties, {}, []);
|
|
@@ -17267,7 +17377,7 @@ function expandNodeByFor(node, scope) {
|
|
|
17267
17377
|
scope,
|
|
17268
17378
|
instanceSuffix: ""
|
|
17269
17379
|
}];
|
|
17270
|
-
const items = resolveLoopEntries(resolveRawValueByPath(wxsScopeData(scope), forExpression));
|
|
17380
|
+
const items = resolveLoopEntries(resolveRawValueByPath$1(wxsScopeData(scope), forExpression));
|
|
17271
17381
|
const itemName = node.attribs?.["wx:for-item"]?.trim() || "item";
|
|
17272
17382
|
const indexName = node.attribs?.["wx:for-index"]?.trim() || "index";
|
|
17273
17383
|
return items.map(([index, item]) => ({
|
|
@@ -17382,12 +17492,16 @@ function renderNodeTree(node, scope, context, ownerJsonPath, ownerFilePath, inst
|
|
|
17382
17492
|
const componentScopeId = `${instancePath}/${clonedNode.name}`;
|
|
17383
17493
|
const ownerScopeId = scope.getScopeId().includes("/") ? scope.getScopeId() : void 0;
|
|
17384
17494
|
const { nextProperties, bindingExpressions } = resolveComponentProperties(clonedNode, scope, componentEntry.definition);
|
|
17495
|
+
const genericComponents = resolveComponentGenerics(context, clonedNode, ownerJsonPath, ownerFilePath, componentEntry.filePath);
|
|
17496
|
+
const slots = collectComponentSlots(clonedNode, scope, ownerJsonPath, ownerFilePath, componentScopeId, templateRenderState);
|
|
17385
17497
|
let componentInstance = context.componentCache.get(componentScopeId);
|
|
17386
|
-
if (!componentInstance) componentInstance = createRuntimeComponentInstance(componentScopeId, context, clonedNode, componentEntry, nextProperties, ownerScopeId)
|
|
17498
|
+
if (!componentInstance) componentInstance = createRuntimeComponentInstance(componentScopeId, context, clonedNode, componentEntry, nextProperties, ownerScopeId, (instance) => {
|
|
17499
|
+
const initialScope = createComponentScope(clonedNode, scope, componentScopeId, instance, genericComponents, slots);
|
|
17500
|
+
context.componentScopes.set(componentScopeId, initialScope);
|
|
17501
|
+
renderRuntimeComponentTemplate(context, componentEntry, renderNodeTree, initialScope, componentScopeId, /* @__PURE__ */ new Set());
|
|
17502
|
+
});
|
|
17387
17503
|
else syncComponentProperties(componentInstance, componentInstance.__definition__ ?? componentEntry.definition, nextProperties, bindingExpressions, context.changedPageKeys);
|
|
17388
17504
|
seenComponentScopes.add(componentScopeId);
|
|
17389
|
-
const genericComponents = resolveComponentGenerics(context, clonedNode, ownerJsonPath, ownerFilePath, componentEntry.filePath);
|
|
17390
|
-
const slots = collectComponentSlots(clonedNode, scope, ownerJsonPath, ownerFilePath, componentScopeId, templateRenderState);
|
|
17391
17505
|
const componentScope = createComponentScope(clonedNode, scope, componentScopeId, componentInstance, genericComponents, slots);
|
|
17392
17506
|
context.componentScopes.set(componentScopeId, componentScope);
|
|
17393
17507
|
const renderedComponentRoot = renderRuntimeComponentTemplate(context, componentEntry, renderNodeTree, componentScope, componentScopeId, seenComponentScopes);
|
|
@@ -17397,6 +17511,10 @@ function renderNodeTree(node, scope, context, ownerJsonPath, ownerFilePath, inst
|
|
|
17397
17511
|
...clonedNode.attribs,
|
|
17398
17512
|
...renderedComponentRoot.attribs
|
|
17399
17513
|
};
|
|
17514
|
+
if (clonedNode.dataset || renderedComponentRoot.dataset) renderedComponentRoot.dataset = {
|
|
17515
|
+
...clonedNode.dataset,
|
|
17516
|
+
...renderedComponentRoot.dataset
|
|
17517
|
+
};
|
|
17400
17518
|
renderedComponentRoot.attribs["data-sim-component"] = clonedNode.name;
|
|
17401
17519
|
renderedComponentRoot.attribs["data-sim-node"] = instancePath;
|
|
17402
17520
|
renderedComponentRoot.attribs["data-sim-scope"] = componentScopeId;
|
|
@@ -17440,7 +17558,8 @@ function renderRuntimePageTree(context, page) {
|
|
|
17440
17558
|
const pageAttaching = isComponentPageAttaching(page);
|
|
17441
17559
|
const attached = !pageAttaching && flushComponentAttachments([...seenComponentScopes].map((scopeId) => context.componentCache.get(scopeId)), (instance) => runComponentLifecycle(instance, "attached"));
|
|
17442
17560
|
const removed = [...context.componentCache].filter(([scopeId]) => scopeId.startsWith(`${pageScopeId}/`) && !seenComponentScopes.has(scopeId));
|
|
17443
|
-
for (const [, instance] of removed) runComponentLifecycle(instance, "detached");
|
|
17561
|
+
for (const [scopeId, instance] of removed) if (isComponentAttached(instance)) runComponentLifecycle(instance, "detached");
|
|
17562
|
+
else scheduleDiscardedComponentReady(context.componentCache, scopeId, instance);
|
|
17444
17563
|
const instances = [...seenComponentScopes].map((scopeId) => context.componentCache.get(scopeId));
|
|
17445
17564
|
const relationsChanged = !pageAttaching && !hasPendingComponentAttachments(instances) && syncComponentRelations(context.componentCache, seenComponentScopes, pageScopeId);
|
|
17446
17565
|
for (const [scopeId] of removed) {
|
|
@@ -17448,6 +17567,7 @@ function renderRuntimePageTree(context, page) {
|
|
|
17448
17567
|
context.componentScopes.delete(scopeId);
|
|
17449
17568
|
}
|
|
17450
17569
|
if (pageAttached || attached || relationsChanged) return renderRuntimePageTree(context, page);
|
|
17570
|
+
if (!isPageBeforeReady(page)) flushDiscardedComponentReady(context.componentCache, pageScopeId, (instance) => runComponentLifecycle(instance, "ready"));
|
|
17451
17571
|
if (!isPageBeforeReady(page) && flushComponentReady(instances, (instance) => {
|
|
17452
17572
|
runComponentLifecycle(instance, "ready");
|
|
17453
17573
|
if (instance !== context.componentCache.get(customTabBarScopeId(route))) instance.__definition__?.pageLifetimes?.show?.call(instance);
|
|
@@ -17633,6 +17753,57 @@ function createHeadlessLogManager(runtimeConsole) {
|
|
|
17633
17753
|
};
|
|
17634
17754
|
}
|
|
17635
17755
|
//#endregion
|
|
17756
|
+
//#region ../../mpcore/packages/simulator/src/host/wx/startupNavigation.ts
|
|
17757
|
+
const queues = /* @__PURE__ */ new WeakMap();
|
|
17758
|
+
/** 冷启动先完成 App 与首屏装载,再顺序提交启动钩子请求的导航。 */
|
|
17759
|
+
var StartupNavigationQueue = class {
|
|
17760
|
+
scheduler;
|
|
17761
|
+
collecting = false;
|
|
17762
|
+
pending = [];
|
|
17763
|
+
constructor(scheduler) {
|
|
17764
|
+
this.scheduler = scheduler;
|
|
17765
|
+
}
|
|
17766
|
+
capture(operation) {
|
|
17767
|
+
this.collecting = true;
|
|
17768
|
+
try {
|
|
17769
|
+
operation();
|
|
17770
|
+
} catch (error) {
|
|
17771
|
+
this.pending.length = 0;
|
|
17772
|
+
throw error;
|
|
17773
|
+
} finally {
|
|
17774
|
+
this.collecting = false;
|
|
17775
|
+
}
|
|
17776
|
+
}
|
|
17777
|
+
run(option, operation) {
|
|
17778
|
+
if (!this.collecting) return operation(option);
|
|
17779
|
+
const defer = (callback) => callback ? (...args) => {
|
|
17780
|
+
this.scheduler.setTimeout(() => callback(...args), 0);
|
|
17781
|
+
} : void 0;
|
|
17782
|
+
const deferred = option && {
|
|
17783
|
+
...option,
|
|
17784
|
+
success: defer(option.success),
|
|
17785
|
+
fail: defer(option.fail),
|
|
17786
|
+
complete: defer(option.complete)
|
|
17787
|
+
};
|
|
17788
|
+
this.pending.push(() => {
|
|
17789
|
+
operation(deferred);
|
|
17790
|
+
});
|
|
17791
|
+
}
|
|
17792
|
+
flush() {
|
|
17793
|
+
const pending = this.pending.splice(0);
|
|
17794
|
+
for (const operation of pending) operation();
|
|
17795
|
+
}
|
|
17796
|
+
};
|
|
17797
|
+
/** 内部绑定保持 driver 的公开形状不变,两种 runtime 共享启动调度。 */
|
|
17798
|
+
function bindStartupNavigation(driver, queue) {
|
|
17799
|
+
queues.set(driver, queue);
|
|
17800
|
+
return driver;
|
|
17801
|
+
}
|
|
17802
|
+
function runNavigationApi(driver, option, operation) {
|
|
17803
|
+
const queue = queues.get(driver);
|
|
17804
|
+
return queue ? queue.run(option, operation) : operation(option);
|
|
17805
|
+
}
|
|
17806
|
+
//#endregion
|
|
17636
17807
|
//#region ../../mpcore/packages/simulator/src/host/wx/index.ts
|
|
17637
17808
|
function invokeWxApi(operation, option) {
|
|
17638
17809
|
try {
|
|
@@ -18030,12 +18201,12 @@ function createHeadlessWx(driver, runtimeConsole = console) {
|
|
|
18030
18201
|
hideLoading: (option) => invokeWxApi(() => driver.hideLoading(), option),
|
|
18031
18202
|
hideToast: () => driver.hideToast(),
|
|
18032
18203
|
downloadFile: (option) => driver.downloadFile(option),
|
|
18033
|
-
navigateBack: (option) => invokeWxApi(() => {
|
|
18034
|
-
driver.navigateBack(
|
|
18035
|
-
},
|
|
18036
|
-
navigateTo: (option) => invokeWxApi(() => {
|
|
18037
|
-
driver.navigateTo(
|
|
18038
|
-
},
|
|
18204
|
+
navigateBack: (option) => runNavigationApi(driver, option, (deferred) => invokeWxApi(() => {
|
|
18205
|
+
driver.navigateBack(deferred);
|
|
18206
|
+
}, deferred)),
|
|
18207
|
+
navigateTo: (option) => runNavigationApi(driver, option, (deferred) => invokeWxApi(() => {
|
|
18208
|
+
driver.navigateTo(deferred);
|
|
18209
|
+
}, deferred)),
|
|
18039
18210
|
nextTick: (callback) => driver.nextTick(callback),
|
|
18040
18211
|
offAppHide: (callback) => driver.offAppHide(callback),
|
|
18041
18212
|
offAppShow: (callback) => driver.offAppShow(callback),
|
|
@@ -18048,12 +18219,12 @@ function createHeadlessWx(driver, runtimeConsole = console) {
|
|
|
18048
18219
|
driver.pageScrollTo(option);
|
|
18049
18220
|
}, option),
|
|
18050
18221
|
previewImage: (option) => invokeWxApi(() => driver.previewImage(option), option),
|
|
18051
|
-
reLaunch: (option) => invokeWxApi(() => {
|
|
18052
|
-
driver.reLaunch(
|
|
18053
|
-
},
|
|
18054
|
-
redirectTo: (option) => invokeWxApi(() => {
|
|
18055
|
-
driver.redirectTo(
|
|
18056
|
-
},
|
|
18222
|
+
reLaunch: (option) => runNavigationApi(driver, option, (deferred) => invokeWxApi(() => {
|
|
18223
|
+
driver.reLaunch(deferred);
|
|
18224
|
+
}, deferred)),
|
|
18225
|
+
redirectTo: (option) => runNavigationApi(driver, option, (deferred) => invokeWxApi(() => {
|
|
18226
|
+
driver.redirectTo(deferred);
|
|
18227
|
+
}, deferred)),
|
|
18057
18228
|
removeSavedFile: (option) => invokeWxApi(() => driver.removeSavedFile(option), option),
|
|
18058
18229
|
saveImageToPhotosAlbum: (option) => invokeWxApi(() => driver.saveImageToPhotosAlbum(option), option),
|
|
18059
18230
|
saveVideoToPhotosAlbum: (option) => invokeWxApi(() => driver.saveVideoToPhotosAlbum(option), option),
|
|
@@ -18089,7 +18260,7 @@ function createHeadlessWx(driver, runtimeConsole = console) {
|
|
|
18089
18260
|
showToast: (option) => invokeWxApi(() => driver.showToast(option), option),
|
|
18090
18261
|
startPullDownRefresh: (option) => invokeWxApi(() => driver.startPullDownRefresh(), option),
|
|
18091
18262
|
stopPullDownRefresh: () => driver.stopPullDownRefresh(),
|
|
18092
|
-
switchTab: (option) => driver.switchTab(
|
|
18263
|
+
switchTab: (option) => runNavigationApi(driver, option, (deferred) => driver.switchTab(deferred)),
|
|
18093
18264
|
uploadFile: (option) => driver.uploadFile(option),
|
|
18094
18265
|
removeTabBarBadge: (option) => invokeWxApi(() => driver.removeTabBarBadge(option), option),
|
|
18095
18266
|
setTabBarBadge: (option) => invokeWxApi(() => driver.setTabBarBadge(option), option),
|
|
@@ -18347,6 +18518,40 @@ function createProjectDescriptor(options) {
|
|
|
18347
18518
|
};
|
|
18348
18519
|
}
|
|
18349
18520
|
//#endregion
|
|
18521
|
+
//#region ../../mpcore/packages/simulator/src/project/hostConfig.ts
|
|
18522
|
+
/**
|
|
18523
|
+
* @description 根据构建后的 app.json 创建模拟器提供给小程序脚本读取的宿主配置。
|
|
18524
|
+
* 微信开发者工具的 tabBar 页面路径通常带有 `.html` 后缀,保留该形态以覆盖路由归一化边界。
|
|
18525
|
+
*/
|
|
18526
|
+
function createMiniProgramHostConfig(appConfig, override) {
|
|
18527
|
+
const appTabBar = appConfig.tabBar && typeof appConfig.tabBar === "object" ? appConfig.tabBar : void 0;
|
|
18528
|
+
const tabBar = appTabBar ? {
|
|
18529
|
+
...appTabBar,
|
|
18530
|
+
...Array.isArray(appTabBar.list) ? { list: appTabBar.list.map((item) => {
|
|
18531
|
+
if (!item || typeof item !== "object") return item;
|
|
18532
|
+
const pagePath = typeof item.pagePath === "string" ? item.pagePath.replace(/^\/+/, "").replace(/\.html$/, "") : void 0;
|
|
18533
|
+
return pagePath ? {
|
|
18534
|
+
...item,
|
|
18535
|
+
pagePath: `${pagePath}.html`
|
|
18536
|
+
} : { ...item };
|
|
18537
|
+
}) } : {}
|
|
18538
|
+
} : void 0;
|
|
18539
|
+
const generated = {
|
|
18540
|
+
...appConfig,
|
|
18541
|
+
...tabBar ? { tabBar } : {}
|
|
18542
|
+
};
|
|
18543
|
+
if (!override || typeof override !== "object" || Array.isArray(override)) return generated;
|
|
18544
|
+
const overrideRecord = override;
|
|
18545
|
+
return {
|
|
18546
|
+
...generated,
|
|
18547
|
+
...overrideRecord,
|
|
18548
|
+
...generated.tabBar || overrideRecord.tabBar ? { tabBar: {
|
|
18549
|
+
...generated.tabBar ?? {},
|
|
18550
|
+
...overrideRecord.tabBar ?? {}
|
|
18551
|
+
} } : {}
|
|
18552
|
+
};
|
|
18553
|
+
}
|
|
18554
|
+
//#endregion
|
|
18350
18555
|
//#region ../../mpcore/packages/simulator/src/project/loadProject.ts
|
|
18351
18556
|
function readJsonObject$1(filePath) {
|
|
18352
18557
|
try {
|
|
@@ -37714,23 +37919,11 @@ function queryXPathElements(root, expression) {
|
|
|
37714
37919
|
}
|
|
37715
37920
|
//#endregion
|
|
37716
37921
|
//#region ../../mpcore/packages/simulator/src/view/nodeHandle.ts
|
|
37717
|
-
const DATASET_NAME_RE$2 = /-([a-z])/g;
|
|
37718
37922
|
function escapeText$1(text) {
|
|
37719
37923
|
return text.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">");
|
|
37720
37924
|
}
|
|
37721
|
-
function toDatasetKey$2(attributeName) {
|
|
37722
|
-
return attributeName.slice(5).replace(DATASET_NAME_RE$2, (_match, char) => char.toUpperCase());
|
|
37723
|
-
}
|
|
37724
|
-
function collectDataset$2(node) {
|
|
37725
|
-
const dataset = {};
|
|
37726
|
-
for (const [key, value] of Object.entries(node.attribs ?? {})) {
|
|
37727
|
-
if (!key.startsWith("data-") || key.startsWith("data-sim-")) continue;
|
|
37728
|
-
dataset[toDatasetKey$2(key)] = value;
|
|
37729
|
-
}
|
|
37730
|
-
return dataset;
|
|
37731
|
-
}
|
|
37732
37925
|
function createEventPayload$1(node, eventName, event) {
|
|
37733
|
-
const dataset =
|
|
37926
|
+
const dataset = collectNodeDataset(node);
|
|
37734
37927
|
const nodeId = node.attribs?.id ?? "";
|
|
37735
37928
|
return {
|
|
37736
37929
|
bubbles: false,
|
|
@@ -37818,7 +38011,7 @@ var HeadlessTestingNodeHandle = class HeadlessTestingNodeHandle {
|
|
|
37818
38011
|
}
|
|
37819
38012
|
async dataset() {
|
|
37820
38013
|
this.assertActive();
|
|
37821
|
-
return
|
|
38014
|
+
return collectNodeDataset(this.node);
|
|
37822
38015
|
}
|
|
37823
38016
|
async scope() {
|
|
37824
38017
|
this.assertActive();
|
|
@@ -37893,13 +38086,19 @@ var HeadlessTestingNodeHandle = class HeadlessTestingNodeHandle {
|
|
|
37893
38086
|
//#region ../../mpcore/packages/simulator/src/view/render.ts
|
|
37894
38087
|
const LEADING_SLASH_RE$2 = /^\/+/;
|
|
37895
38088
|
const TEMPLATE_INTERPOLATION_RE = /\{\{([^{}]+)\}\}/g;
|
|
37896
|
-
function
|
|
38089
|
+
function resolveRawValueByPath(source, expression) {
|
|
37897
38090
|
const normalized = expression.trim();
|
|
37898
|
-
if (!normalized) return
|
|
38091
|
+
if (!normalized) return;
|
|
37899
38092
|
const segments = normalized.split(".").filter(Boolean);
|
|
37900
38093
|
let current = source;
|
|
37901
|
-
for (const segment of segments)
|
|
37902
|
-
|
|
38094
|
+
for (const segment of segments) {
|
|
38095
|
+
if (current == null || typeof current !== "object" && typeof current !== "function") return;
|
|
38096
|
+
current = Reflect.get(current, segment);
|
|
38097
|
+
}
|
|
38098
|
+
return current;
|
|
38099
|
+
}
|
|
38100
|
+
function resolveValueByPath(source, expression) {
|
|
38101
|
+
return resolveRawValueByPath(source, expression) ?? "";
|
|
37903
38102
|
}
|
|
37904
38103
|
function interpolateTemplate(input, data) {
|
|
37905
38104
|
return input.replace(TEMPLATE_INTERPOLATION_RE, (_match, expression) => {
|
|
@@ -37907,6 +38106,10 @@ function interpolateTemplate(input, data) {
|
|
|
37907
38106
|
return typeof value === "string" ? value : String(value);
|
|
37908
38107
|
});
|
|
37909
38108
|
}
|
|
38109
|
+
function isMustacheOnly(value) {
|
|
38110
|
+
const trimmed = value.trim();
|
|
38111
|
+
return trimmed.startsWith("{{") && trimmed.endsWith("}}") && !trimmed.includes("{{", 2);
|
|
38112
|
+
}
|
|
37910
38113
|
function visitDom(node, visitor) {
|
|
37911
38114
|
visitor(node);
|
|
37912
38115
|
for (const child of node.children ?? []) visitDom(child, visitor);
|
|
@@ -37914,7 +38117,18 @@ function visitDom(node, visitor) {
|
|
|
37914
38117
|
function interpolateDomTree(root, data) {
|
|
37915
38118
|
visitDom(root, (node) => {
|
|
37916
38119
|
if (typeof node.data === "string") node.data = interpolateTemplateText(node.data, data);
|
|
37917
|
-
if (node.attribs)
|
|
38120
|
+
if (node.attribs) {
|
|
38121
|
+
let dataset;
|
|
38122
|
+
for (const [key, value] of Object.entries(node.attribs)) {
|
|
38123
|
+
const resolvedValue = isMustacheOnly(value) ? resolveRawValueByPath(data, value.trim().slice(2, -2)) : interpolateTemplate(value, data);
|
|
38124
|
+
node.attribs[key] = String(resolvedValue ?? "");
|
|
38125
|
+
if (isDatasetAttribute(key)) {
|
|
38126
|
+
dataset ??= {};
|
|
38127
|
+
dataset[toDatasetKey(key)] = resolvedValue;
|
|
38128
|
+
}
|
|
38129
|
+
}
|
|
38130
|
+
node.dataset = dataset;
|
|
38131
|
+
}
|
|
37918
38132
|
});
|
|
37919
38133
|
}
|
|
37920
38134
|
function escapeText(text) {
|
|
@@ -37948,21 +38162,9 @@ function renderPageTree(project, page) {
|
|
|
37948
38162
|
}
|
|
37949
38163
|
//#endregion
|
|
37950
38164
|
//#region ../../mpcore/packages/simulator/src/view/selectorQuery.ts
|
|
37951
|
-
const DATASET_NAME_RE$1 = /-([a-z])/g;
|
|
37952
38165
|
const LEADING_MARK_PREFIX_RE = /^mark[:\-]?/;
|
|
37953
38166
|
const MARK_NAME_RE = /[:\-]([a-z])/g;
|
|
37954
38167
|
const NUMERIC_LIKE_VALUE_RE$1 = /-?\d+(?:\.\d+)?/;
|
|
37955
|
-
function toDatasetKey$1(attributeName) {
|
|
37956
|
-
return attributeName.slice(5).replace(DATASET_NAME_RE$1, (_match, char) => char.toUpperCase());
|
|
37957
|
-
}
|
|
37958
|
-
function collectDataset$1(node) {
|
|
37959
|
-
const dataset = {};
|
|
37960
|
-
for (const [key, value] of Object.entries(node.attribs ?? {})) {
|
|
37961
|
-
if (!key.startsWith("data-") || key.startsWith("data-sim-")) continue;
|
|
37962
|
-
dataset[toDatasetKey$1(key)] = value;
|
|
37963
|
-
}
|
|
37964
|
-
return dataset;
|
|
37965
|
-
}
|
|
37966
38168
|
function toMarkKey(attributeName) {
|
|
37967
38169
|
return attributeName.replace(LEADING_MARK_PREFIX_RE, "").replace(MARK_NAME_RE, (_match, char) => char.toUpperCase());
|
|
37968
38170
|
}
|
|
@@ -38039,7 +38241,7 @@ function resolvePropertyValue(node, propertyName) {
|
|
|
38039
38241
|
if (!normalizedPropertyName) return;
|
|
38040
38242
|
if (normalizedPropertyName === "id") return node.attribs?.id ?? "";
|
|
38041
38243
|
if (normalizedPropertyName === "class") return node.attribs?.class ?? "";
|
|
38042
|
-
if (normalizedPropertyName === "dataset") return
|
|
38244
|
+
if (normalizedPropertyName === "dataset") return collectNodeDataset(node);
|
|
38043
38245
|
return node.attribs?.[normalizedPropertyName];
|
|
38044
38246
|
}
|
|
38045
38247
|
function pickProperties(node, propertyNames) {
|
|
@@ -38056,7 +38258,7 @@ function pickComputedStyle(node, propertyNames) {
|
|
|
38056
38258
|
function resolveFieldsResult(node, fields, options) {
|
|
38057
38259
|
const result = {};
|
|
38058
38260
|
if (fields.id) result.id = node.attribs?.id ?? "";
|
|
38059
|
-
if (fields.dataset) result.dataset =
|
|
38261
|
+
if (fields.dataset) result.dataset = collectNodeDataset(node);
|
|
38060
38262
|
if (fields.mark) result.mark = collectMark(node);
|
|
38061
38263
|
if (fields.rect || fields.size) {
|
|
38062
38264
|
const rect = resolveRect$1(node, options.root.name === "page" ? options.windowInfo : void 0);
|
|
@@ -38761,20 +38963,8 @@ function createHeadlessMediaQueryObserver(driver, onDisconnect) {
|
|
|
38761
38963
|
}
|
|
38762
38964
|
//#endregion
|
|
38763
38965
|
//#region ../../mpcore/packages/simulator/src/view/videoContext.ts
|
|
38764
|
-
const DATASET_NAME_RE = /-([a-z])/g;
|
|
38765
|
-
function toDatasetKey(attributeName) {
|
|
38766
|
-
return attributeName.slice(5).replace(DATASET_NAME_RE, (_match, char) => char.toUpperCase());
|
|
38767
|
-
}
|
|
38768
|
-
function collectDataset(node) {
|
|
38769
|
-
const dataset = {};
|
|
38770
|
-
for (const [key, value] of Object.entries(node.attribs ?? {})) {
|
|
38771
|
-
if (!key.startsWith("data-") || key.startsWith("data-sim-")) continue;
|
|
38772
|
-
dataset[toDatasetKey(key)] = value;
|
|
38773
|
-
}
|
|
38774
|
-
return dataset;
|
|
38775
|
-
}
|
|
38776
38966
|
function createEventPayload(node, eventName, detail) {
|
|
38777
|
-
const dataset =
|
|
38967
|
+
const dataset = collectNodeDataset(node);
|
|
38778
38968
|
const nodeId = node.attribs?.id ?? "";
|
|
38779
38969
|
return {
|
|
38780
38970
|
bubbles: false,
|
|
@@ -39290,6 +39480,110 @@ function deriveMenuButtonBoundingClientRect(systemInfo) {
|
|
|
39290
39480
|
};
|
|
39291
39481
|
}
|
|
39292
39482
|
//#endregion
|
|
39483
|
+
//#region ../../mpcore/packages/simulator/src/runtime/request/task.ts
|
|
39484
|
+
/** mock 与显式网络桥接共用终止状态;终止后不再分发 headers/chunk。 */
|
|
39485
|
+
function createRequestTask(option, onAbort = () => {}) {
|
|
39486
|
+
const headers = /* @__PURE__ */ new Set();
|
|
39487
|
+
const chunks = /* @__PURE__ */ new Set();
|
|
39488
|
+
let settled = false;
|
|
39489
|
+
function finish(result, success) {
|
|
39490
|
+
if (settled) return;
|
|
39491
|
+
settled = true;
|
|
39492
|
+
headers.clear();
|
|
39493
|
+
chunks.clear();
|
|
39494
|
+
try {
|
|
39495
|
+
if (success) option.success?.(result);
|
|
39496
|
+
else option.fail?.(result);
|
|
39497
|
+
} finally {
|
|
39498
|
+
option.complete?.(result);
|
|
39499
|
+
}
|
|
39500
|
+
}
|
|
39501
|
+
return {
|
|
39502
|
+
task: {
|
|
39503
|
+
abort() {
|
|
39504
|
+
if (settled) return;
|
|
39505
|
+
const error = Object.assign(/* @__PURE__ */ new Error("request:fail abort"), { errMsg: "request:fail abort" });
|
|
39506
|
+
try {
|
|
39507
|
+
finish(error, false);
|
|
39508
|
+
} finally {
|
|
39509
|
+
onAbort();
|
|
39510
|
+
}
|
|
39511
|
+
},
|
|
39512
|
+
onHeadersReceived(callback) {
|
|
39513
|
+
headers.add(callback);
|
|
39514
|
+
},
|
|
39515
|
+
offHeadersReceived(callback) {
|
|
39516
|
+
if (callback) headers.delete(callback);
|
|
39517
|
+
else headers.clear();
|
|
39518
|
+
},
|
|
39519
|
+
onChunkReceived(callback) {
|
|
39520
|
+
chunks.add(callback);
|
|
39521
|
+
},
|
|
39522
|
+
offChunkReceived(callback) {
|
|
39523
|
+
if (callback) chunks.delete(callback);
|
|
39524
|
+
else chunks.clear();
|
|
39525
|
+
}
|
|
39526
|
+
},
|
|
39527
|
+
get settled() {
|
|
39528
|
+
return settled;
|
|
39529
|
+
},
|
|
39530
|
+
headers(result) {
|
|
39531
|
+
if (settled) return;
|
|
39532
|
+
for (const callback of Array.from(headers)) if (!settled && headers.has(callback)) callback(result);
|
|
39533
|
+
},
|
|
39534
|
+
chunk(data) {
|
|
39535
|
+
if (settled || !option.enableChunked) return;
|
|
39536
|
+
for (const callback of Array.from(chunks)) if (!settled && chunks.has(callback)) callback({ data: data.slice(0) });
|
|
39537
|
+
},
|
|
39538
|
+
succeed(result) {
|
|
39539
|
+
finish(result, true);
|
|
39540
|
+
},
|
|
39541
|
+
fail(error) {
|
|
39542
|
+
finish(Object.assign(error, { errMsg: "errMsg" in error ? error.errMsg : error.message }), false);
|
|
39543
|
+
}
|
|
39544
|
+
};
|
|
39545
|
+
}
|
|
39546
|
+
//#endregion
|
|
39547
|
+
//#region ../../mpcore/packages/simulator/src/runtime/request/mock.ts
|
|
39548
|
+
/** 仅模拟已声明的分块;不进行网络访问,也不把完整 response 拆成假分块。 */
|
|
39549
|
+
function createChunkedMockRequest(option, mock, response, scheduler, onSuccess) {
|
|
39550
|
+
let timer;
|
|
39551
|
+
const request = createRequestTask(option, () => scheduler.clearTimeout(timer));
|
|
39552
|
+
const chunks = (mock.chunks ?? []).map((chunk) => ({
|
|
39553
|
+
...chunk,
|
|
39554
|
+
data: chunk.data.slice(0)
|
|
39555
|
+
}));
|
|
39556
|
+
let index = 0;
|
|
39557
|
+
function next() {
|
|
39558
|
+
if (request.settled) return;
|
|
39559
|
+
const chunk = chunks[index++];
|
|
39560
|
+
if (chunk) timer = scheduler.setTimeout(() => {
|
|
39561
|
+
request.chunk(chunk.data);
|
|
39562
|
+
next();
|
|
39563
|
+
}, Math.max(0, chunk.delay ?? 0));
|
|
39564
|
+
else timer = scheduler.setTimeout(() => {
|
|
39565
|
+
if (request.settled) return;
|
|
39566
|
+
if (mock.error) request.fail(new Error(mock.error));
|
|
39567
|
+
else {
|
|
39568
|
+
onSuccess();
|
|
39569
|
+
request.succeed({
|
|
39570
|
+
...response,
|
|
39571
|
+
data: ""
|
|
39572
|
+
});
|
|
39573
|
+
}
|
|
39574
|
+
}, 0);
|
|
39575
|
+
}
|
|
39576
|
+
timer = scheduler.setTimeout(() => {
|
|
39577
|
+
request.headers({
|
|
39578
|
+
cookies: response.cookies,
|
|
39579
|
+
header: response.header,
|
|
39580
|
+
statusCode: response.statusCode
|
|
39581
|
+
});
|
|
39582
|
+
next();
|
|
39583
|
+
}, Math.max(0, mock.delay ?? 0));
|
|
39584
|
+
return request.task;
|
|
39585
|
+
}
|
|
39586
|
+
//#endregion
|
|
39293
39587
|
//#region ../../mpcore/packages/simulator/src/runtime/wxState.ts
|
|
39294
39588
|
const STORAGE_LIMIT_SIZE = 10240;
|
|
39295
39589
|
const DEFAULT_MODAL_CANCEL_COLOR = "#000000";
|
|
@@ -40611,6 +40905,7 @@ function createHeadlessWxState(scheduler = nativeScheduler, options = {}) {
|
|
|
40611
40905
|
request(option) {
|
|
40612
40906
|
const matchedMock = requestMocks.find((mock) => matchesRequestMock(mock, option));
|
|
40613
40907
|
if (!matchedMock) {
|
|
40908
|
+
const request = createRequestTask(option);
|
|
40614
40909
|
const logEntry = {
|
|
40615
40910
|
data: cloneValue(option.data),
|
|
40616
40911
|
header: { ...option.header ?? {} },
|
|
@@ -40621,9 +40916,8 @@ function createHeadlessWxState(scheduler = nativeScheduler, options = {}) {
|
|
|
40621
40916
|
requestLogs.push(logEntry);
|
|
40622
40917
|
const error = /* @__PURE__ */ new Error(`No request mock matched in headless runtime: ${normalizeMethod(option.method)} ${option.url}`);
|
|
40623
40918
|
if (options.strictMocks) throw error;
|
|
40624
|
-
|
|
40625
|
-
|
|
40626
|
-
return createNoopTask();
|
|
40919
|
+
request.fail(error);
|
|
40920
|
+
return request.task;
|
|
40627
40921
|
}
|
|
40628
40922
|
const response = resolveRequestResponse(matchedMock, option);
|
|
40629
40923
|
const requestLogEntry = {
|
|
@@ -40635,20 +40929,31 @@ function createHeadlessWxState(scheduler = nativeScheduler, options = {}) {
|
|
|
40635
40929
|
url: option.url
|
|
40636
40930
|
};
|
|
40637
40931
|
const delay = Number.isFinite(matchedMock.delay) ? Math.max(0, Math.trunc(matchedMock.delay ?? 0)) : 0;
|
|
40932
|
+
if (option.enableChunked) return createChunkedMockRequest(option, matchedMock, response, scheduler, () => {
|
|
40933
|
+
requestLogs.push({
|
|
40934
|
+
...requestLogEntry,
|
|
40935
|
+
response: {
|
|
40936
|
+
...response,
|
|
40937
|
+
data: ""
|
|
40938
|
+
}
|
|
40939
|
+
});
|
|
40940
|
+
});
|
|
40941
|
+
const request = createRequestTask(option);
|
|
40638
40942
|
if (delay <= 0) {
|
|
40639
40943
|
requestLogs.push(requestLogEntry);
|
|
40640
|
-
|
|
40641
|
-
|
|
40642
|
-
return createNoopTask();
|
|
40944
|
+
request.succeed(response);
|
|
40945
|
+
return request.task;
|
|
40643
40946
|
}
|
|
40644
|
-
|
|
40947
|
+
const delayed = runDelayedTask(delay, () => {
|
|
40645
40948
|
requestLogs.push(requestLogEntry);
|
|
40646
|
-
|
|
40647
|
-
option.complete?.(response);
|
|
40949
|
+
request.succeed(response);
|
|
40648
40950
|
}, (error) => {
|
|
40649
|
-
|
|
40650
|
-
option.complete?.();
|
|
40951
|
+
request.fail(error);
|
|
40651
40952
|
}, "request:fail abort");
|
|
40953
|
+
return {
|
|
40954
|
+
...request.task,
|
|
40955
|
+
abort: delayed.abort
|
|
40956
|
+
};
|
|
40652
40957
|
},
|
|
40653
40958
|
removeSavedFile(option) {
|
|
40654
40959
|
return removeSavedFile(option.filePath);
|
|
@@ -40865,7 +41170,7 @@ function matchesComponentSelector(scope, selector) {
|
|
|
40865
41170
|
if (dataAttrMatch) {
|
|
40866
41171
|
const [, key, value] = dataAttrMatch;
|
|
40867
41172
|
const datasetKey = key.replace(DATASET_KEY_RE, (_match, char) => char.toUpperCase());
|
|
40868
|
-
return scope.dataset
|
|
41173
|
+
return scope.dataset != null && Object.hasOwn(scope.dataset, datasetKey) && String(scope.dataset[datasetKey] ?? "") === value;
|
|
40869
41174
|
}
|
|
40870
41175
|
return scope.alias === part;
|
|
40871
41176
|
});
|
|
@@ -40891,6 +41196,7 @@ function resolveNavigationPath(targetPath, baseRoute) {
|
|
|
40891
41196
|
var HeadlessSession = class {
|
|
40892
41197
|
project;
|
|
40893
41198
|
kernel = new RuntimeKernel();
|
|
41199
|
+
startupNavigation = new StartupNavigationQueue(this.kernel.scheduler);
|
|
40894
41200
|
appDefinition = null;
|
|
40895
41201
|
appInstance = null;
|
|
40896
41202
|
appLifecycle = new HeadlessAppLifecycle();
|
|
@@ -40945,7 +41251,7 @@ var HeadlessSession = class {
|
|
|
40945
41251
|
});
|
|
40946
41252
|
});
|
|
40947
41253
|
this.tabBarVisible = this.tabBarRoutes.size > 0;
|
|
40948
|
-
this.moduleLoader = createModuleLoader(this.registries, () => this.pages.slice(), () => this.getApp(), {
|
|
41254
|
+
this.moduleLoader = createModuleLoader(this.registries, () => this.pages.slice(), () => this.getApp(), bindStartupNavigation({
|
|
40949
41255
|
chooseImage: (option) => this.wxState.chooseImage(option ?? {}),
|
|
40950
41256
|
chooseMessageFile: (option) => this.wxState.chooseMessageFile(option ?? {}),
|
|
40951
41257
|
chooseMedia: (option) => this.wxState.chooseMedia(option ?? {}),
|
|
@@ -41024,9 +41330,12 @@ var HeadlessSession = class {
|
|
|
41024
41330
|
removeTabBarBadge: (option) => this.removeTabBarBadge(option.index),
|
|
41025
41331
|
setTabBarBadge: (option) => this.setTabBarBadge(option.index, option.text),
|
|
41026
41332
|
updateShareMenu: (option) => this.wxState.updateShareMenu(option)
|
|
41027
|
-
}, {
|
|
41333
|
+
}, this.startupNavigation), {
|
|
41028
41334
|
artifactSource: this.project.artifactSource,
|
|
41029
|
-
globals:
|
|
41335
|
+
globals: {
|
|
41336
|
+
...options.globals,
|
|
41337
|
+
__wxConfig: createMiniProgramHostConfig(this.project.appConfig, options.globals?.__wxConfig)
|
|
41338
|
+
},
|
|
41030
41339
|
kernel: this.kernel,
|
|
41031
41340
|
miniprogramRootPath: this.project.miniprogramRootPath,
|
|
41032
41341
|
onConsole: (entry) => this.emit("console", entry),
|
|
@@ -41480,9 +41789,16 @@ var HeadlessSession = class {
|
|
|
41480
41789
|
if (Object.hasOwn(runtimeApp, "routes")) this.appInstance.routes = runtimeApp.routes;
|
|
41481
41790
|
}
|
|
41482
41791
|
bootstrapNavigation(launchOptions = createAppLaunchOptions("", {})) {
|
|
41483
|
-
|
|
41484
|
-
this.
|
|
41485
|
-
|
|
41792
|
+
if (this.appInstance) return null;
|
|
41793
|
+
this.startupNavigation.capture(() => {
|
|
41794
|
+
this.bootstrap(launchOptions);
|
|
41795
|
+
});
|
|
41796
|
+
if (launchOptions.path) {
|
|
41797
|
+
const query = new URLSearchParams(launchOptions.query).toString();
|
|
41798
|
+
this.reLaunch(`/${launchOptions.path}${query ? `?${query}` : ""}`);
|
|
41799
|
+
}
|
|
41800
|
+
this.startupNavigation.flush();
|
|
41801
|
+
return this.currentPageInstance;
|
|
41486
41802
|
}
|
|
41487
41803
|
reLaunch(url) {
|
|
41488
41804
|
const target = this.resolveNavigationTarget(url);
|
|
@@ -41683,8 +41999,8 @@ var HeadlessSession = class {
|
|
|
41683
41999
|
});
|
|
41684
42000
|
pageInstance.createIntersectionObserver = (options) => this.createIntersectionObserver(pageInstance, options);
|
|
41685
42001
|
pageInstance.createMediaQueryObserver = () => this.createMediaQueryObserver(pageInstance);
|
|
41686
|
-
pageInstance.selectComponent = (selector) => this.selectComponent(selector);
|
|
41687
|
-
pageInstance.selectAllComponents = (selector) => this.selectAllComponents(selector);
|
|
42002
|
+
pageInstance.selectComponent = (selector) => resolveNativeComponentSelection(this.selectComponent(selector));
|
|
42003
|
+
pageInstance.selectAllComponents = (selector) => this.selectAllComponents(selector).map(resolveNativeComponentSelection);
|
|
41688
42004
|
pageInstance.getTabBar = () => {
|
|
41689
42005
|
if (this.currentPageInstance === pageInstance) this.renderCurrentPage();
|
|
41690
42006
|
return this.componentCache.get(customTabBarScopeId(pageInstance.route)) ?? null;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@weapp-vite/miniprogram-automator",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "1.2.
|
|
4
|
+
"version": "1.2.20",
|
|
5
5
|
"description": "完全兼容微信 miniprogram-automator 的现代化替代实现",
|
|
6
6
|
"author": "ice breaker <1324318532@qq.com>",
|
|
7
7
|
"license": "MIT",
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
"node": "^20.19.0 || >=22.12.0"
|
|
45
45
|
},
|
|
46
46
|
"dependencies": {
|
|
47
|
-
"@weapp-vite/qr": "1.1.
|
|
47
|
+
"@weapp-vite/qr": "1.1.5",
|
|
48
48
|
"obug": "^3.0.0",
|
|
49
49
|
"ws": "^8.21.3"
|
|
50
50
|
},
|