@vue-jsx-vapor/compiler 2.4.8 → 2.5.1
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.cjs +1376 -82
- package/dist/index.d.cts +36 -11
- package/dist/index.d.ts +36 -11
- package/dist/index.js +1378 -85
- package/package.json +5 -4
package/dist/index.js
CHANGED
@@ -1,8 +1,9 @@
|
|
1
1
|
import { parse, parseExpression } from "@babel/parser";
|
2
|
-
import {
|
3
|
-
import {
|
4
|
-
import {
|
5
|
-
import { isLiteral, jsxClosingFragment, jsxExpressionContainer, jsxFragment, jsxOpeningFragment } from "@babel/types";
|
2
|
+
import { NOOP, camelize, canSetValueDirectly, capitalize, extend, isArray, isBuiltInDirective, isGloballyAllowed, isHTMLTag, isSVGTag, isString, isVoidTag, makeMap, remove, shouldSetAsAttr, toHandlerKey } from "@vue/shared";
|
3
|
+
import { DOMErrorCodes, ErrorCodes, NewlineType, NodeTypes, TS_NODE_TYPES, advancePositionWithClone, advancePositionWithMutation, createCompilerError, createDOMCompilerError, createSimpleExpression, defaultOnError, defaultOnWarn, isConstantNode, isFnExpression, isLiteralWhitelisted, isMemberExpression, isSimpleIdentifier, isStaticNode, isStaticProperty, isValidHTMLNesting, locStub, resolveModifiers, toValidAssetId, unwrapTSNode, walkIdentifiers } from "@vue/compiler-dom";
|
4
|
+
import { walkAST, walkIdentifiers as walkIdentifiers$1 } from "ast-kit";
|
5
|
+
import { isLiteral, isNodesEquivalent, jsxClosingFragment, jsxExpressionContainer, jsxFragment, jsxOpeningFragment } from "@babel/types";
|
6
|
+
import { SourceMapGenerator } from "source-map-js";
|
6
7
|
|
7
8
|
//#region src/ir/component.ts
|
8
9
|
let IRDynamicPropsKind = /* @__PURE__ */ function(IRDynamicPropsKind$1) {
|
@@ -66,32 +67,37 @@ function isBlockOperation(op) {
|
|
66
67
|
}
|
67
68
|
|
68
69
|
//#endregion
|
69
|
-
//#region src/
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
const { helper } = context;
|
76
|
-
const { element, values, generated } = oper;
|
77
|
-
return [NEWLINE, ...genCall(helper("setNodes"), `${generated ? "x" : "n"}${element}`, combineValues(values, context))];
|
70
|
+
//#region src/transforms/utils.ts
|
71
|
+
function newDynamic() {
|
72
|
+
return {
|
73
|
+
flags: DynamicFlag.REFERENCED,
|
74
|
+
children: []
|
75
|
+
};
|
78
76
|
}
|
79
|
-
function
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
77
|
+
function newBlock(node) {
|
78
|
+
return {
|
79
|
+
type: 1,
|
80
|
+
node,
|
81
|
+
dynamic: newDynamic(),
|
82
|
+
effect: [],
|
83
|
+
operation: [],
|
84
|
+
returns: [],
|
85
|
+
tempId: 0
|
86
|
+
};
|
87
87
|
}
|
88
|
-
function
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
88
|
+
function createBranch(node, context, isVFor) {
|
89
|
+
context.node = node = wrapFragment(node);
|
90
|
+
const branch = newBlock(node);
|
91
|
+
const exitBlock = context.enterBlock(branch, isVFor);
|
92
|
+
context.reference();
|
93
|
+
return [branch, exitBlock];
|
94
94
|
}
|
95
|
+
function wrapFragment(node) {
|
96
|
+
if (node.type === "JSXFragment" || isTemplate(node)) return node;
|
97
|
+
return jsxFragment(jsxOpeningFragment(), jsxClosingFragment(), [node.type === "JSXElement" ? node : jsxExpressionContainer(node)]);
|
98
|
+
}
|
99
|
+
const EMPTY_EXPRESSION = createSimpleExpression("", true);
|
100
|
+
const isFragmentNode = (node) => node.type === IRNodeTypes.ROOT || node.type === "JSXFragment" || node.type === "JSXElement" && !!isTemplate(node);
|
95
101
|
|
96
102
|
//#endregion
|
97
103
|
//#region src/utils.ts
|
@@ -148,22 +154,17 @@ function resolveSimpleExpressionNode(exp) {
|
|
148
154
|
}
|
149
155
|
return exp;
|
150
156
|
}
|
151
|
-
const resolvedExpressions = /* @__PURE__ */ new WeakSet();
|
152
157
|
function resolveExpression(node, context, effect = false) {
|
153
158
|
if (!node) return createSimpleExpression("", true);
|
154
159
|
node = unwrapTSNode(node.type === "JSXExpressionContainer" ? node.expression : node);
|
155
160
|
const isStatic = node.type === "StringLiteral" || node.type === "JSXText" || node.type === "JSXIdentifier";
|
156
161
|
let source = node.type === "JSXEmptyExpression" ? "" : node.type === "JSXIdentifier" ? node.name : node.type === "StringLiteral" ? node.value : node.type === "JSXText" ? resolveJSXText(node) : node.type === "Identifier" ? node.name : context.ir.source.slice(node.start, node.end);
|
157
162
|
const location = node.loc;
|
158
|
-
const isResolved = resolvedExpressions.has(node);
|
159
163
|
if (source && !isStatic && effect && !isConstant(node)) {
|
160
164
|
source = `() => (${source})`;
|
161
|
-
|
162
|
-
location.start.column -= 7;
|
163
|
-
node.start -= 7;
|
164
|
-
}
|
165
|
+
node._offset = 7;
|
165
166
|
}
|
166
|
-
return resolveSimpleExpression(source, isStatic, location, isStatic ? void 0 :
|
167
|
+
return resolveSimpleExpression(source, isStatic, location, isStatic ? void 0 : node);
|
167
168
|
}
|
168
169
|
function resolveSimpleExpression(source, isStatic, location, ast) {
|
169
170
|
const result = createSimpleExpression(source, isStatic, resolveLocation(location, source));
|
@@ -256,48 +257,1352 @@ function isTemplate(node) {
|
|
256
257
|
}
|
257
258
|
|
258
259
|
//#endregion
|
259
|
-
//#region src/
|
260
|
-
|
260
|
+
//#region src/generators/utils.ts
|
261
|
+
const NEWLINE = Symbol(`newline`);
|
262
|
+
const INDENT_START = Symbol(`indent start`);
|
263
|
+
const INDENT_END = Symbol(`indent end`);
|
264
|
+
function buildCodeFragment(...frag) {
|
265
|
+
const push = frag.push.bind(frag);
|
266
|
+
const unshift = frag.unshift.bind(frag);
|
267
|
+
return [
|
268
|
+
frag,
|
269
|
+
push,
|
270
|
+
unshift
|
271
|
+
];
|
272
|
+
}
|
273
|
+
function genMulti([left, right, seg, placeholder], ...frags) {
|
274
|
+
if (placeholder) {
|
275
|
+
while (frags.length > 0 && !frags.at(-1)) frags.pop();
|
276
|
+
frags = frags.map((frag$1) => frag$1 || placeholder);
|
277
|
+
} else frags = frags.filter(Boolean);
|
278
|
+
const frag = [];
|
279
|
+
push(left);
|
280
|
+
for (const [i, fn] of frags.entries()) {
|
281
|
+
push(fn);
|
282
|
+
if (i < frags.length - 1) push(seg);
|
283
|
+
}
|
284
|
+
push(right);
|
285
|
+
return frag;
|
286
|
+
function push(fn) {
|
287
|
+
if (!isArray(fn)) fn = [fn];
|
288
|
+
frag.push(...fn);
|
289
|
+
}
|
290
|
+
}
|
291
|
+
const DELIMITERS_ARRAY = [
|
292
|
+
"[",
|
293
|
+
"]",
|
294
|
+
", "
|
295
|
+
];
|
296
|
+
const DELIMITERS_ARRAY_NEWLINE = [
|
297
|
+
[
|
298
|
+
"[",
|
299
|
+
INDENT_START,
|
300
|
+
NEWLINE
|
301
|
+
],
|
302
|
+
[
|
303
|
+
INDENT_END,
|
304
|
+
NEWLINE,
|
305
|
+
"]"
|
306
|
+
],
|
307
|
+
[", ", NEWLINE]
|
308
|
+
];
|
309
|
+
const DELIMITERS_OBJECT = [
|
310
|
+
"{ ",
|
311
|
+
" }",
|
312
|
+
", "
|
313
|
+
];
|
314
|
+
const DELIMITERS_OBJECT_NEWLINE = [
|
315
|
+
[
|
316
|
+
"{",
|
317
|
+
INDENT_START,
|
318
|
+
NEWLINE
|
319
|
+
],
|
320
|
+
[
|
321
|
+
INDENT_END,
|
322
|
+
NEWLINE,
|
323
|
+
"}"
|
324
|
+
],
|
325
|
+
[", ", NEWLINE]
|
326
|
+
];
|
327
|
+
function genCall(name, ...frags) {
|
328
|
+
const hasPlaceholder = isArray(name);
|
329
|
+
const fnName = hasPlaceholder ? name[0] : name;
|
330
|
+
const placeholder = hasPlaceholder ? name[1] : "null";
|
331
|
+
return [fnName, ...genMulti([
|
332
|
+
"(",
|
333
|
+
")",
|
334
|
+
", ",
|
335
|
+
placeholder
|
336
|
+
], ...frags)];
|
337
|
+
}
|
338
|
+
function codeFragmentToString(code, context) {
|
339
|
+
const { options: { filename, sourceMap } } = context;
|
340
|
+
let map;
|
341
|
+
if (sourceMap) {
|
342
|
+
map = new SourceMapGenerator();
|
343
|
+
map.setSourceContent(filename, context.ir.source);
|
344
|
+
map._sources.add(filename);
|
345
|
+
}
|
346
|
+
let codegen = "";
|
347
|
+
const pos = {
|
348
|
+
line: 1,
|
349
|
+
column: 1,
|
350
|
+
offset: 0
|
351
|
+
};
|
352
|
+
let indentLevel = 0;
|
353
|
+
for (let frag of code) {
|
354
|
+
if (!frag) continue;
|
355
|
+
if (frag === NEWLINE) frag = [`\n${` `.repeat(indentLevel)}`, NewlineType.Start];
|
356
|
+
else if (frag === INDENT_START) {
|
357
|
+
indentLevel++;
|
358
|
+
continue;
|
359
|
+
} else if (frag === INDENT_END) {
|
360
|
+
indentLevel--;
|
361
|
+
continue;
|
362
|
+
}
|
363
|
+
if (isString(frag)) frag = [frag];
|
364
|
+
let [code$1, newlineIndex = NewlineType.None, loc, name] = frag;
|
365
|
+
codegen += code$1;
|
366
|
+
if (map) {
|
367
|
+
if (loc) addMapping(loc.start, name);
|
368
|
+
if (newlineIndex === NewlineType.Unknown) advancePositionWithMutation(pos, code$1);
|
369
|
+
else {
|
370
|
+
pos.offset += code$1.length;
|
371
|
+
if (newlineIndex === NewlineType.None) pos.column += code$1.length;
|
372
|
+
else {
|
373
|
+
if (newlineIndex === NewlineType.End) newlineIndex = code$1.length - 1;
|
374
|
+
pos.line++;
|
375
|
+
pos.column = code$1.length - newlineIndex;
|
376
|
+
}
|
377
|
+
}
|
378
|
+
if (loc && loc !== locStub) addMapping(loc.end);
|
379
|
+
}
|
380
|
+
}
|
381
|
+
return [codegen, map];
|
382
|
+
function addMapping(loc, name = null) {
|
383
|
+
const { _names, _mappings } = map;
|
384
|
+
if (name !== null && !_names.has(name)) _names.add(name);
|
385
|
+
_mappings.add({
|
386
|
+
originalLine: loc.line,
|
387
|
+
originalColumn: loc.column - 1,
|
388
|
+
generatedLine: pos.line,
|
389
|
+
generatedColumn: pos.column - 1,
|
390
|
+
source: filename,
|
391
|
+
name
|
392
|
+
});
|
393
|
+
}
|
394
|
+
}
|
395
|
+
|
396
|
+
//#endregion
|
397
|
+
//#region src/generators/expression.ts
|
398
|
+
function genExpression(node, context, assignment) {
|
399
|
+
const { content, ast, isStatic, loc } = node;
|
400
|
+
if (isStatic) return [[
|
401
|
+
JSON.stringify(content),
|
402
|
+
NewlineType.None,
|
403
|
+
loc
|
404
|
+
]];
|
405
|
+
if (!node.content.trim() || ast === false || isConstantExpression(node)) return [[
|
406
|
+
content,
|
407
|
+
NewlineType.None,
|
408
|
+
loc
|
409
|
+
], assignment && ` = ${assignment}`];
|
410
|
+
if (ast === null) return genIdentifier(content, context, loc, assignment);
|
411
|
+
const ids = [];
|
412
|
+
const parentStackMap = /* @__PURE__ */ new Map();
|
413
|
+
const parentStack = [];
|
414
|
+
walkIdentifiers$1(ast, (id) => {
|
415
|
+
ids.push(id);
|
416
|
+
parentStackMap.set(id, parentStack.slice());
|
417
|
+
}, false, parentStack);
|
418
|
+
let hasMemberExpression = false;
|
419
|
+
if (ids.length) {
|
420
|
+
const [frag, push] = buildCodeFragment();
|
421
|
+
const isTSNode = ast && TS_NODE_TYPES.includes(ast.type);
|
422
|
+
const offset = (ast?.start ? ast.start - 1 : 0) - (ast._offset || 0);
|
423
|
+
ids.sort((a, b) => a.start - b.start).forEach((id, i) => {
|
424
|
+
const start = id.start - 1 - offset;
|
425
|
+
const end = id.end - 1 - offset;
|
426
|
+
const last = ids[i - 1];
|
427
|
+
if (!isTSNode || i !== 0) {
|
428
|
+
const leadingText = content.slice(last ? last.end - 1 - offset : 0, start);
|
429
|
+
if (leadingText.length) push([leadingText, NewlineType.Unknown]);
|
430
|
+
}
|
431
|
+
const source = content.slice(start, end);
|
432
|
+
const parentStack$1 = parentStackMap.get(id);
|
433
|
+
const parent = parentStack$1.at(-1);
|
434
|
+
hasMemberExpression ||= !!parent && (parent.type === "MemberExpression" || parent.type === "OptionalMemberExpression");
|
435
|
+
push(...genIdentifier(source, context, {
|
436
|
+
start: advancePositionWithClone(node.loc.start, source, start),
|
437
|
+
end: advancePositionWithClone(node.loc.start, source, end),
|
438
|
+
source
|
439
|
+
}, hasMemberExpression ? void 0 : assignment, parent));
|
440
|
+
if (i === ids.length - 1 && end < content.length && !isTSNode) push([content.slice(end), NewlineType.Unknown]);
|
441
|
+
});
|
442
|
+
if (assignment && hasMemberExpression) push(` = ${assignment}`);
|
443
|
+
return frag;
|
444
|
+
} else return [[
|
445
|
+
content,
|
446
|
+
NewlineType.Unknown,
|
447
|
+
loc
|
448
|
+
]];
|
449
|
+
}
|
450
|
+
function genIdentifier(raw, context, loc, assignment, parent) {
|
451
|
+
const { identifiers } = context;
|
452
|
+
const name = raw;
|
453
|
+
const idMap = identifiers[raw];
|
454
|
+
if (idMap && idMap.length) {
|
455
|
+
const replacement = idMap[0];
|
456
|
+
if (isString(replacement)) if (parent && parent.type === "ObjectProperty" && parent.shorthand) return [[
|
457
|
+
`${name}: ${replacement}`,
|
458
|
+
NewlineType.None,
|
459
|
+
loc
|
460
|
+
]];
|
461
|
+
else return [[
|
462
|
+
replacement,
|
463
|
+
NewlineType.None,
|
464
|
+
loc
|
465
|
+
]];
|
466
|
+
else return genExpression(replacement, context, assignment);
|
467
|
+
}
|
468
|
+
let prefix;
|
469
|
+
if (isStaticProperty(parent) && parent.shorthand) prefix = `${raw}: `;
|
470
|
+
raw = withAssignment(raw);
|
471
|
+
return [prefix, [
|
472
|
+
raw,
|
473
|
+
NewlineType.None,
|
474
|
+
loc,
|
475
|
+
name
|
476
|
+
]];
|
477
|
+
function withAssignment(s) {
|
478
|
+
return assignment ? `${s} = ${assignment}` : s;
|
479
|
+
}
|
480
|
+
}
|
481
|
+
|
482
|
+
//#endregion
|
483
|
+
//#region src/generators/vModel.ts
|
484
|
+
const helperMap = {
|
485
|
+
text: "applyTextModel",
|
486
|
+
radio: "applyRadioModel",
|
487
|
+
checkbox: "applyCheckboxModel",
|
488
|
+
select: "applySelectModel",
|
489
|
+
dynamic: "applyDynamicModel"
|
490
|
+
};
|
491
|
+
function genVModel(oper, context) {
|
492
|
+
const { modelType, element, dir: { exp, modifiers } } = oper;
|
493
|
+
return [NEWLINE, ...genCall(context.helper(helperMap[modelType]), `n${element}`, [
|
494
|
+
`() => (`,
|
495
|
+
...genExpression(exp, context),
|
496
|
+
`)`
|
497
|
+
], genModelHandler(exp, context), modifiers.length ? `{ ${modifiers.map((e) => `${e.content}: true`).join(",")} }` : void 0)];
|
498
|
+
}
|
499
|
+
function genModelHandler(exp, context) {
|
500
|
+
return [
|
501
|
+
`${context.options.isTS ? `(_value: any)` : `_value`} => (`,
|
502
|
+
...genExpression(exp, context, "_value"),
|
503
|
+
")"
|
504
|
+
];
|
505
|
+
}
|
506
|
+
|
507
|
+
//#endregion
|
508
|
+
//#region src/generators/vShow.ts
|
509
|
+
function genVShow(oper, context) {
|
510
|
+
return [NEWLINE, ...genCall(context.helper("applyVShow"), `n${oper.element}`, [
|
511
|
+
`() => (`,
|
512
|
+
...genExpression(oper.dir.exp, context),
|
513
|
+
`)`
|
514
|
+
])];
|
515
|
+
}
|
516
|
+
|
517
|
+
//#endregion
|
518
|
+
//#region src/generators/directive.ts
|
519
|
+
function genBuiltinDirective(oper, context) {
|
520
|
+
switch (oper.name) {
|
521
|
+
case "show": return genVShow(oper, context);
|
522
|
+
case "model": return genVModel(oper, context);
|
523
|
+
default: return [];
|
524
|
+
}
|
525
|
+
}
|
526
|
+
/**
|
527
|
+
* user directives via `withVaporDirectives`
|
528
|
+
* TODO the compiler side is implemented but no runtime support yet
|
529
|
+
* it was removed due to perf issues
|
530
|
+
*/
|
531
|
+
function genDirectivesForElement(id, context) {
|
532
|
+
const dirs = filterCustomDirectives(id, context.block.operation);
|
533
|
+
return dirs.length ? genCustomDirectives(dirs, context) : [];
|
534
|
+
}
|
535
|
+
function genCustomDirectives(opers, context) {
|
536
|
+
const { helper } = context;
|
537
|
+
const element = `n${opers[0].element}`;
|
538
|
+
const directiveItems = opers.map(genDirectiveItem);
|
539
|
+
const directives = genMulti(DELIMITERS_ARRAY, ...directiveItems);
|
540
|
+
return [NEWLINE, ...genCall(helper("withVaporDirectives"), element, directives)];
|
541
|
+
function genDirectiveItem({ dir, name, asset }) {
|
542
|
+
const directiveVar = asset ? toValidAssetId(name, "directive") : genExpression(extend(createSimpleExpression(name, false), { ast: null }), context);
|
543
|
+
const value = dir.exp && ["() => ", ...genExpression(dir.exp, context)];
|
544
|
+
const argument = dir.arg && genExpression(dir.arg, context);
|
545
|
+
const modifiers = !!dir.modifiers.length && [
|
546
|
+
"{ ",
|
547
|
+
genDirectiveModifiers(dir.modifiers.map((m) => m.content)),
|
548
|
+
" }"
|
549
|
+
];
|
550
|
+
return genMulti(DELIMITERS_ARRAY.concat("void 0"), directiveVar, value, argument, modifiers);
|
551
|
+
}
|
552
|
+
}
|
553
|
+
function genDirectiveModifiers(modifiers) {
|
554
|
+
return modifiers.map((value) => `${isSimpleIdentifier(value) ? value : JSON.stringify(value)}: true`).join(", ");
|
555
|
+
}
|
556
|
+
function filterCustomDirectives(id, operations) {
|
557
|
+
return operations.filter((oper) => oper.type === IRNodeTypes.DIRECTIVE && oper.element === id && !oper.builtin);
|
558
|
+
}
|
559
|
+
|
560
|
+
//#endregion
|
561
|
+
//#region src/generators/event.ts
|
562
|
+
function genSetEvent(oper, context) {
|
563
|
+
const { helper } = context;
|
564
|
+
const { element, key, keyOverride, value, modifiers, delegate, effect } = oper;
|
565
|
+
const name = genName();
|
566
|
+
const handler = genEventHandler(context, value, modifiers);
|
567
|
+
const eventOptions = genEventOptions();
|
568
|
+
if (delegate) {
|
569
|
+
context.delegates.add(key.content);
|
570
|
+
if (!context.block.operation.some(isSameDelegateEvent)) return [
|
571
|
+
NEWLINE,
|
572
|
+
`n${element}.$evt${key.content} = `,
|
573
|
+
...handler
|
574
|
+
];
|
575
|
+
}
|
576
|
+
return [NEWLINE, ...genCall(helper(delegate ? "delegate" : "on"), `n${element}`, name, handler, eventOptions)];
|
577
|
+
function genName() {
|
578
|
+
const expr = genExpression(key, context);
|
579
|
+
if (keyOverride) {
|
580
|
+
const find = JSON.stringify(keyOverride[0]);
|
581
|
+
const replacement = JSON.stringify(keyOverride[1]);
|
582
|
+
const wrapped = [
|
583
|
+
"(",
|
584
|
+
...expr,
|
585
|
+
")"
|
586
|
+
];
|
587
|
+
return [
|
588
|
+
...wrapped,
|
589
|
+
` === ${find} ? ${replacement} : `,
|
590
|
+
...wrapped
|
591
|
+
];
|
592
|
+
} else return genExpression(key, context);
|
593
|
+
}
|
594
|
+
function genEventOptions() {
|
595
|
+
const { options } = modifiers;
|
596
|
+
if (!options.length && !effect) return;
|
597
|
+
return genMulti(DELIMITERS_OBJECT_NEWLINE, effect && ["effect: true"], ...options.map((option) => [`${option}: true`]));
|
598
|
+
}
|
599
|
+
function isSameDelegateEvent(op) {
|
600
|
+
if (op.type === IRNodeTypes.SET_EVENT && op !== oper && op.delegate && op.element === oper.element && op.key.content === key.content) return true;
|
601
|
+
}
|
602
|
+
}
|
603
|
+
function genSetDynamicEvents(oper, context) {
|
604
|
+
const { helper } = context;
|
605
|
+
return [NEWLINE, ...genCall(helper("setDynamicEvents"), `n${oper.element}`, genExpression(oper.event, context))];
|
606
|
+
}
|
607
|
+
function genEventHandler(context, value, modifiers = {
|
608
|
+
nonKeys: [],
|
609
|
+
keys: []
|
610
|
+
}, extraWrap = false) {
|
611
|
+
let handlerExp = [`() => {}`];
|
612
|
+
if (value && value.content.trim()) if (isMemberExpression(value, context.options)) {
|
613
|
+
handlerExp = genExpression(value, context);
|
614
|
+
if (!extraWrap) handlerExp = [
|
615
|
+
`e => `,
|
616
|
+
...handlerExp,
|
617
|
+
`(e)`
|
618
|
+
];
|
619
|
+
} else if (isFnExpression(value, context.options)) handlerExp = genExpression(value, context);
|
620
|
+
else {
|
621
|
+
const referencesEvent = value.content.includes("$event");
|
622
|
+
const hasMultipleStatements = value.content.includes(`;`);
|
623
|
+
const expr = referencesEvent ? context.withId(() => genExpression(value, context), { $event: null }) : genExpression(value, context);
|
624
|
+
handlerExp = [
|
625
|
+
referencesEvent ? "$event => " : "() => ",
|
626
|
+
hasMultipleStatements ? "{" : "(",
|
627
|
+
...expr,
|
628
|
+
hasMultipleStatements ? "}" : ")"
|
629
|
+
];
|
630
|
+
}
|
631
|
+
const { keys, nonKeys } = modifiers;
|
632
|
+
if (nonKeys.length) handlerExp = genWithModifiers(context, handlerExp, nonKeys);
|
633
|
+
if (keys.length) handlerExp = genWithKeys(context, handlerExp, keys);
|
634
|
+
if (extraWrap) handlerExp.unshift(`() => `);
|
635
|
+
return handlerExp;
|
636
|
+
}
|
637
|
+
function genWithModifiers(context, handler, nonKeys) {
|
638
|
+
return genCall(context.helper("withModifiers"), handler, JSON.stringify(nonKeys));
|
639
|
+
}
|
640
|
+
function genWithKeys(context, handler, keys) {
|
641
|
+
return genCall(context.helper("withKeys"), handler, JSON.stringify(keys));
|
642
|
+
}
|
643
|
+
|
644
|
+
//#endregion
|
645
|
+
//#region src/generators/prop.ts
|
646
|
+
const helpers = {
|
647
|
+
setText: { name: "setText" },
|
648
|
+
setHtml: { name: "setHtml" },
|
649
|
+
setClass: { name: "setClass" },
|
650
|
+
setStyle: { name: "setStyle" },
|
651
|
+
setValue: { name: "setValue" },
|
652
|
+
setAttr: {
|
653
|
+
name: "setAttr",
|
654
|
+
needKey: true
|
655
|
+
},
|
656
|
+
setProp: {
|
657
|
+
name: "setProp",
|
658
|
+
needKey: true
|
659
|
+
},
|
660
|
+
setDOMProp: {
|
661
|
+
name: "setDOMProp",
|
662
|
+
needKey: true
|
663
|
+
},
|
664
|
+
setDynamicProps: { name: "setDynamicProps" }
|
665
|
+
};
|
666
|
+
function genSetProp(oper, context) {
|
667
|
+
const { helper } = context;
|
668
|
+
const { prop: { key, values, modifier }, tag } = oper;
|
669
|
+
const resolvedHelper = getRuntimeHelper(tag, key.content, modifier);
|
670
|
+
const propValue = genPropValue(values, context);
|
671
|
+
return [NEWLINE, ...genCall([helper(resolvedHelper.name), null], `n${oper.element}`, resolvedHelper.needKey ? genExpression(key, context) : false, propValue)];
|
672
|
+
}
|
673
|
+
function genDynamicProps(oper, context) {
|
674
|
+
const { helper } = context;
|
675
|
+
const values = oper.props.map((props) => Array.isArray(props) ? genLiteralObjectProps(props, context) : props.kind === IRDynamicPropsKind.ATTRIBUTE ? genLiteralObjectProps([props], context) : genExpression(props.value, context));
|
676
|
+
return [NEWLINE, ...genCall(helper("setDynamicProps"), `n${oper.element}`, genMulti(DELIMITERS_ARRAY, ...values), oper.root && "true")];
|
677
|
+
}
|
678
|
+
function genLiteralObjectProps(props, context) {
|
679
|
+
return genMulti(DELIMITERS_OBJECT, ...props.map((prop) => [
|
680
|
+
...genPropKey(prop, context),
|
681
|
+
`: `,
|
682
|
+
...genPropValue(prop.values, context)
|
683
|
+
]));
|
684
|
+
}
|
685
|
+
function genPropKey({ key: node, modifier, runtimeCamelize, handler, handlerModifiers }, context) {
|
686
|
+
const { helper } = context;
|
687
|
+
const handlerModifierPostfix = handlerModifiers && handlerModifiers.options ? handlerModifiers.options.map(capitalize).join("") : "";
|
688
|
+
if (node.isStatic) {
|
689
|
+
const keyName = (handler ? toHandlerKey(node.content) : node.content) + handlerModifierPostfix;
|
690
|
+
return [[
|
691
|
+
isSimpleIdentifier(keyName) ? keyName : JSON.stringify(keyName),
|
692
|
+
NewlineType.None,
|
693
|
+
node.loc
|
694
|
+
]];
|
695
|
+
}
|
696
|
+
let key = genExpression(node, context);
|
697
|
+
if (runtimeCamelize) key = genCall(helper("camelize"), key);
|
698
|
+
if (handler) key = genCall(helper("toHandlerKey"), key);
|
699
|
+
return [
|
700
|
+
"[",
|
701
|
+
modifier && `${JSON.stringify(modifier)} + `,
|
702
|
+
...key,
|
703
|
+
handlerModifierPostfix ? ` + ${JSON.stringify(handlerModifierPostfix)}` : void 0,
|
704
|
+
"]"
|
705
|
+
];
|
706
|
+
}
|
707
|
+
function genPropValue(values, context) {
|
708
|
+
if (values.length === 1) return genExpression(values[0], context);
|
709
|
+
return genMulti(DELIMITERS_ARRAY, ...values.map((expr) => genExpression(expr, context)));
|
710
|
+
}
|
711
|
+
function getRuntimeHelper(tag, key, modifier) {
|
712
|
+
const tagName = tag.toUpperCase();
|
713
|
+
if (modifier) if (modifier === ".") return getSpecialHelper(key, tagName) || helpers.setDOMProp;
|
714
|
+
else return helpers.setAttr;
|
715
|
+
const helper = getSpecialHelper(key, tagName);
|
716
|
+
if (helper) return helper;
|
717
|
+
if (/aria[A-Z]/.test(key)) return helpers.setDOMProp;
|
718
|
+
if (isSVGTag(tag)) return helpers.setAttr;
|
719
|
+
if (shouldSetAsAttr(tagName, key) || key.includes("-")) return helpers.setAttr;
|
720
|
+
return helpers.setProp;
|
721
|
+
}
|
722
|
+
function getSpecialHelper(keyName, tagName) {
|
723
|
+
if (keyName === "value" && canSetValueDirectly(tagName)) return helpers.setValue;
|
724
|
+
else if (keyName === "class") return helpers.setClass;
|
725
|
+
else if (keyName === "style") return helpers.setStyle;
|
726
|
+
else if (keyName === "innerHTML") return helpers.setHtml;
|
727
|
+
else if (keyName === "textContent") return helpers.setText;
|
728
|
+
}
|
729
|
+
|
730
|
+
//#endregion
|
731
|
+
//#region src/generators/component.ts
|
732
|
+
function genCreateComponent(operation, context) {
|
733
|
+
const { helper } = context;
|
734
|
+
const tag = genTag();
|
735
|
+
const { root, props, slots, once } = operation;
|
736
|
+
const rawSlots = genRawSlots(slots, context);
|
737
|
+
const [ids, handlers] = processInlineHandlers(props, context);
|
738
|
+
const rawProps = context.withId(() => genRawProps(props, context), ids);
|
739
|
+
const inlineHandlers = handlers.reduce((acc, { name, value }) => {
|
740
|
+
const handler = genEventHandler(context, value, void 0, false);
|
741
|
+
return [
|
742
|
+
...acc,
|
743
|
+
`const ${name} = `,
|
744
|
+
...handler,
|
745
|
+
NEWLINE
|
746
|
+
];
|
747
|
+
}, []);
|
748
|
+
return [
|
749
|
+
NEWLINE,
|
750
|
+
...inlineHandlers,
|
751
|
+
`const n${operation.id} = `,
|
752
|
+
...genCall(operation.dynamic && !operation.dynamic.isStatic ? helper("createDynamicComponent") : operation.asset ? helper("createComponentWithFallback") : helper("createComponent"), tag, rawProps, rawSlots, root ? "true" : false, once && "true"),
|
753
|
+
...genDirectivesForElement(operation.id, context)
|
754
|
+
];
|
755
|
+
function genTag() {
|
756
|
+
if (operation.dynamic) if (operation.dynamic.isStatic) return genCall(helper("resolveDynamicComponent"), genExpression(operation.dynamic, context));
|
757
|
+
else return [
|
758
|
+
"() => (",
|
759
|
+
...genExpression(operation.dynamic, context),
|
760
|
+
")"
|
761
|
+
];
|
762
|
+
else if (operation.asset) return toValidAssetId(operation.tag, "component");
|
763
|
+
else return genExpression(extend(createSimpleExpression(operation.tag, false), { ast: null }), context);
|
764
|
+
}
|
765
|
+
}
|
766
|
+
function getUniqueHandlerName(context, name) {
|
767
|
+
const { seenInlineHandlerNames } = context;
|
768
|
+
const count = seenInlineHandlerNames[name] || 0;
|
769
|
+
seenInlineHandlerNames[name] = count + 1;
|
770
|
+
return count === 0 ? name : `${name}${count}`;
|
771
|
+
}
|
772
|
+
function processInlineHandlers(props, context) {
|
773
|
+
const ids = Object.create(null);
|
774
|
+
const handlers = [];
|
775
|
+
const staticProps = props[0];
|
776
|
+
if (isArray(staticProps)) for (const prop of staticProps) {
|
777
|
+
if (!prop.handler) continue;
|
778
|
+
prop.values.forEach((value, i) => {
|
779
|
+
const isMemberExp = isMemberExpression(value, context.options);
|
780
|
+
if (!isMemberExp) {
|
781
|
+
const name = getUniqueHandlerName(context, `_on_${prop.key.content.replace(":", "_")}`);
|
782
|
+
handlers.push({
|
783
|
+
name,
|
784
|
+
value
|
785
|
+
});
|
786
|
+
ids[name] = null;
|
787
|
+
prop.values[i] = extend({ ast: null }, createSimpleExpression(name));
|
788
|
+
}
|
789
|
+
});
|
790
|
+
}
|
791
|
+
return [ids, handlers];
|
792
|
+
}
|
793
|
+
function genRawProps(props, context) {
|
794
|
+
const staticProps = props[0];
|
795
|
+
if (isArray(staticProps)) {
|
796
|
+
if (!staticProps.length && props.length === 1) return;
|
797
|
+
return genStaticProps(staticProps, context, genDynamicProps$1(props.slice(1), context));
|
798
|
+
} else if (props.length) return genStaticProps([], context, genDynamicProps$1(props, context));
|
799
|
+
}
|
800
|
+
function genStaticProps(props, context, dynamicProps) {
|
801
|
+
const args = props.map((prop) => genProp(prop, context, true));
|
802
|
+
if (dynamicProps) args.push([`$: `, ...dynamicProps]);
|
803
|
+
return genMulti(args.length > 1 ? DELIMITERS_OBJECT_NEWLINE : DELIMITERS_OBJECT, ...args);
|
804
|
+
}
|
805
|
+
function genDynamicProps$1(props, context) {
|
806
|
+
const { helper } = context;
|
807
|
+
const frags = [];
|
808
|
+
for (const p of props) {
|
809
|
+
let expr;
|
810
|
+
if (isArray(p)) {
|
811
|
+
if (p.length) frags.push(genStaticProps(p, context));
|
812
|
+
continue;
|
813
|
+
} else if (p.kind === IRDynamicPropsKind.ATTRIBUTE) expr = genMulti(DELIMITERS_OBJECT, genProp(p, context));
|
814
|
+
else {
|
815
|
+
expr = genExpression(p.value, context);
|
816
|
+
if (p.handler) expr = genCall(helper("toHandlers"), expr);
|
817
|
+
}
|
818
|
+
frags.push([
|
819
|
+
"() => (",
|
820
|
+
...expr,
|
821
|
+
")"
|
822
|
+
]);
|
823
|
+
}
|
824
|
+
if (frags.length) return genMulti(DELIMITERS_ARRAY_NEWLINE, ...frags);
|
825
|
+
}
|
826
|
+
function genProp(prop, context, isStatic) {
|
827
|
+
const values = genPropValue(prop.values, context);
|
828
|
+
return [
|
829
|
+
...genPropKey(prop, context),
|
830
|
+
": ",
|
831
|
+
...prop.handler ? genEventHandler(context, prop.values[0], prop.handlerModifiers, true) : isStatic ? [
|
832
|
+
"() => (",
|
833
|
+
...values,
|
834
|
+
")"
|
835
|
+
] : values,
|
836
|
+
...prop.model ? [...genModelEvent(prop, context), ...genModelModifiers(prop, context)] : []
|
837
|
+
];
|
838
|
+
}
|
839
|
+
function genModelEvent(prop, context) {
|
840
|
+
const name = prop.key.isStatic ? [JSON.stringify(`onUpdate:${camelize(prop.key.content)}`)] : [
|
841
|
+
"[\"onUpdate:\" + ",
|
842
|
+
...genExpression(prop.key, context),
|
843
|
+
"]"
|
844
|
+
];
|
845
|
+
const handler = genModelHandler(prop.values[0], context);
|
846
|
+
return [
|
847
|
+
",",
|
848
|
+
NEWLINE,
|
849
|
+
...name,
|
850
|
+
": () => ",
|
851
|
+
...handler
|
852
|
+
];
|
853
|
+
}
|
854
|
+
function genModelModifiers(prop, context) {
|
855
|
+
const { key, modelModifiers } = prop;
|
856
|
+
if (!modelModifiers || !modelModifiers.length) return [];
|
857
|
+
const modifiersKey = key.isStatic ? [`${key.content}Modifiers`] : [
|
858
|
+
"[",
|
859
|
+
...genExpression(key, context),
|
860
|
+
" + \"Modifiers\"]"
|
861
|
+
];
|
862
|
+
const modifiersVal = genDirectiveModifiers(modelModifiers);
|
863
|
+
return [
|
864
|
+
",",
|
865
|
+
NEWLINE,
|
866
|
+
...modifiersKey,
|
867
|
+
`: () => ({ ${modifiersVal} })`
|
868
|
+
];
|
869
|
+
}
|
870
|
+
function genRawSlots(slots, context) {
|
871
|
+
if (!slots.length) return;
|
872
|
+
const staticSlots = slots[0];
|
873
|
+
if (staticSlots.slotType === IRSlotType.STATIC) return genStaticSlots(staticSlots, context, slots.length > 1 ? slots.slice(1) : void 0);
|
874
|
+
else return genStaticSlots({
|
875
|
+
slotType: IRSlotType.STATIC,
|
876
|
+
slots: {}
|
877
|
+
}, context, slots);
|
878
|
+
}
|
879
|
+
function genStaticSlots({ slots }, context, dynamicSlots) {
|
880
|
+
const args = Object.keys(slots).map((name) => [`${JSON.stringify(name)}: `, ...genSlotBlockWithProps(slots[name], context)]);
|
881
|
+
if (dynamicSlots) args.push([`$: `, ...genDynamicSlots(dynamicSlots, context)]);
|
882
|
+
return genMulti(DELIMITERS_OBJECT_NEWLINE, ...args);
|
883
|
+
}
|
884
|
+
function genDynamicSlots(slots, context) {
|
885
|
+
return genMulti(DELIMITERS_ARRAY_NEWLINE, ...slots.map((slot) => slot.slotType === IRSlotType.STATIC ? genStaticSlots(slot, context) : slot.slotType === IRSlotType.EXPRESSION ? slot.slots.content : genDynamicSlot(slot, context, true)));
|
886
|
+
}
|
887
|
+
function genDynamicSlot(slot, context, withFunction = false) {
|
888
|
+
let frag;
|
889
|
+
switch (slot.slotType) {
|
890
|
+
case IRSlotType.DYNAMIC:
|
891
|
+
frag = genBasicDynamicSlot(slot, context);
|
892
|
+
break;
|
893
|
+
case IRSlotType.LOOP:
|
894
|
+
frag = genLoopSlot(slot, context);
|
895
|
+
break;
|
896
|
+
case IRSlotType.CONDITIONAL:
|
897
|
+
frag = genConditionalSlot(slot, context);
|
898
|
+
break;
|
899
|
+
}
|
900
|
+
return withFunction ? [
|
901
|
+
"() => (",
|
902
|
+
...frag,
|
903
|
+
")"
|
904
|
+
] : frag;
|
905
|
+
}
|
906
|
+
function genBasicDynamicSlot(slot, context) {
|
907
|
+
const { name, fn } = slot;
|
908
|
+
return genMulti(DELIMITERS_OBJECT_NEWLINE, ["name: ", ...genExpression(name, context)], ["fn: ", ...genSlotBlockWithProps(fn, context)]);
|
909
|
+
}
|
910
|
+
function genLoopSlot(slot, context) {
|
911
|
+
const { name, fn, loop } = slot;
|
912
|
+
const { value, key, index, source } = loop;
|
913
|
+
const rawValue = value && value.content;
|
914
|
+
const rawKey = key && key.content;
|
915
|
+
const rawIndex = index && index.content;
|
916
|
+
const idMap = {};
|
917
|
+
if (rawValue) idMap[rawValue] = rawValue;
|
918
|
+
if (rawKey) idMap[rawKey] = rawKey;
|
919
|
+
if (rawIndex) idMap[rawIndex] = rawIndex;
|
920
|
+
const slotExpr = genMulti(DELIMITERS_OBJECT_NEWLINE, ["name: ", ...context.withId(() => genExpression(name, context), idMap)], ["fn: ", ...context.withId(() => genSlotBlockWithProps(fn, context), idMap)]);
|
921
|
+
return [...genCall(context.helper("createForSlots"), genExpression(source, context), [
|
922
|
+
...genMulti([
|
923
|
+
"(",
|
924
|
+
")",
|
925
|
+
", "
|
926
|
+
], rawValue ? rawValue : rawKey || rawIndex ? "_" : void 0, rawKey ? rawKey : rawIndex ? "__" : void 0, rawIndex),
|
927
|
+
" => (",
|
928
|
+
...slotExpr,
|
929
|
+
")"
|
930
|
+
])];
|
931
|
+
}
|
932
|
+
function genConditionalSlot(slot, context) {
|
933
|
+
const { condition, positive, negative } = slot;
|
934
|
+
return [
|
935
|
+
...genExpression(condition, context),
|
936
|
+
INDENT_START,
|
937
|
+
NEWLINE,
|
938
|
+
"? ",
|
939
|
+
...genDynamicSlot(positive, context),
|
940
|
+
NEWLINE,
|
941
|
+
": ",
|
942
|
+
...negative ? [...genDynamicSlot(negative, context)] : ["void 0"],
|
943
|
+
INDENT_END
|
944
|
+
];
|
945
|
+
}
|
946
|
+
function genSlotBlockWithProps(oper, context) {
|
947
|
+
let isDestructureAssignment = false;
|
948
|
+
let rawProps;
|
949
|
+
let propsName;
|
950
|
+
let exitScope;
|
951
|
+
let depth;
|
952
|
+
const { props } = oper;
|
953
|
+
const idsOfProps = /* @__PURE__ */ new Set();
|
954
|
+
if (props) {
|
955
|
+
rawProps = props.content;
|
956
|
+
if (isDestructureAssignment = !!props.ast) {
|
957
|
+
[depth, exitScope] = context.enterScope();
|
958
|
+
propsName = `_slotProps${depth}`;
|
959
|
+
walkIdentifiers$1(props.ast, (id, _, __, ___, isLocal) => {
|
960
|
+
if (isLocal) idsOfProps.add(id.name);
|
961
|
+
}, true);
|
962
|
+
} else idsOfProps.add(propsName = rawProps);
|
963
|
+
}
|
964
|
+
const idMap = {};
|
965
|
+
idsOfProps.forEach((id) => idMap[id] = isDestructureAssignment ? `${propsName}[${JSON.stringify(id)}]` : null);
|
966
|
+
const blockFn = context.withId(() => genBlock(oper, context, [propsName]), idMap);
|
967
|
+
exitScope && exitScope();
|
968
|
+
return blockFn;
|
969
|
+
}
|
970
|
+
|
971
|
+
//#endregion
|
972
|
+
//#region src/generators/dom.ts
|
973
|
+
function genInsertNode({ parent, elements, anchor }, { helper }) {
|
974
|
+
let element = elements.map((el) => `n${el}`).join(", ");
|
975
|
+
if (elements.length > 1) element = `[${element}]`;
|
976
|
+
return [NEWLINE, ...genCall(helper("insert"), element, `n${parent}`, anchor === void 0 ? void 0 : `n${anchor}`)];
|
977
|
+
}
|
978
|
+
function genPrependNode(oper, { helper }) {
|
979
|
+
return [NEWLINE, ...genCall(helper("prepend"), `n${oper.parent}`, ...oper.elements.map((el) => `n${el}`))];
|
980
|
+
}
|
981
|
+
|
982
|
+
//#endregion
|
983
|
+
//#region src/generators/for.ts
|
984
|
+
/**
|
985
|
+
* Flags to optimize vapor `createFor` runtime behavior, shared between the
|
986
|
+
* compiler and the runtime
|
987
|
+
*/
|
988
|
+
let VaporVForFlags = /* @__PURE__ */ function(VaporVForFlags$1) {
|
989
|
+
/**
|
990
|
+
* v-for is the only child of a parent container, so it can take the fast
|
991
|
+
* path with textContent = '' when the whole list is emptied
|
992
|
+
*/
|
993
|
+
VaporVForFlags$1[VaporVForFlags$1["FAST_REMOVE"] = 1] = "FAST_REMOVE";
|
994
|
+
/**
|
995
|
+
* v-for used on component - we can skip creating child scopes for each block
|
996
|
+
* because the component itself already has a scope.
|
997
|
+
*/
|
998
|
+
VaporVForFlags$1[VaporVForFlags$1["IS_COMPONENT"] = 2] = "IS_COMPONENT";
|
999
|
+
/**
|
1000
|
+
* v-for inside v-ince
|
1001
|
+
*/
|
1002
|
+
VaporVForFlags$1[VaporVForFlags$1["ONCE"] = 4] = "ONCE";
|
1003
|
+
return VaporVForFlags$1;
|
1004
|
+
}({});
|
1005
|
+
function genFor(oper, context) {
|
1006
|
+
const { helper } = context;
|
1007
|
+
const { source, value, key, index, render, keyProp, once, id, component, onlyChild } = oper;
|
1008
|
+
let rawValue = null;
|
1009
|
+
const rawKey = key && key.content;
|
1010
|
+
const rawIndex = index && index.content;
|
1011
|
+
const sourceExpr = [
|
1012
|
+
"() => (",
|
1013
|
+
...genExpression(source, context),
|
1014
|
+
")"
|
1015
|
+
];
|
1016
|
+
const idToPathMap = parseValueDestructure();
|
1017
|
+
const [depth, exitScope] = context.enterScope();
|
1018
|
+
const idMap = {};
|
1019
|
+
const itemVar = `_for_item${depth}`;
|
1020
|
+
idMap[itemVar] = null;
|
1021
|
+
idToPathMap.forEach((pathInfo, id$1) => {
|
1022
|
+
let path = `${itemVar}.value${pathInfo ? pathInfo.path : ""}`;
|
1023
|
+
if (pathInfo) {
|
1024
|
+
if (pathInfo.helper) {
|
1025
|
+
idMap[pathInfo.helper] = null;
|
1026
|
+
path = `${pathInfo.helper}(${path}, ${pathInfo.helperArgs})`;
|
1027
|
+
}
|
1028
|
+
if (pathInfo.dynamic) {
|
1029
|
+
const node = idMap[id$1] = createSimpleExpression(path);
|
1030
|
+
const plugins = context.options.expressionPlugins;
|
1031
|
+
node.ast = parseExpression(`(${path})`, { plugins: plugins ? [...plugins, "typescript"] : ["typescript"] });
|
1032
|
+
} else idMap[id$1] = path;
|
1033
|
+
} else idMap[id$1] = path;
|
1034
|
+
});
|
1035
|
+
const args = [itemVar];
|
1036
|
+
if (rawKey) {
|
1037
|
+
const keyVar = `_for_key${depth}`;
|
1038
|
+
args.push(`, ${keyVar}`);
|
1039
|
+
idMap[rawKey] = `${keyVar}.value`;
|
1040
|
+
idMap[keyVar] = null;
|
1041
|
+
}
|
1042
|
+
if (rawIndex) {
|
1043
|
+
const indexVar = `_for_index${depth}`;
|
1044
|
+
args.push(`, ${indexVar}`);
|
1045
|
+
idMap[rawIndex] = `${indexVar}.value`;
|
1046
|
+
idMap[indexVar] = null;
|
1047
|
+
}
|
1048
|
+
const { selectorPatterns, keyOnlyBindingPatterns } = matchPatterns(render, keyProp, idMap);
|
1049
|
+
const patternFrag = [];
|
1050
|
+
for (const [i, { selector }] of selectorPatterns.entries()) {
|
1051
|
+
const selectorName = `_selector${id}_${i}`;
|
1052
|
+
patternFrag.push(NEWLINE, `const ${selectorName} = `, ...genCall(`n${id}.useSelector`, [`() => `, ...genExpression(selector, context)]));
|
1053
|
+
}
|
1054
|
+
const blockFn = context.withId(() => {
|
1055
|
+
const frag = [];
|
1056
|
+
frag.push("(", ...args, ") => {", INDENT_START);
|
1057
|
+
if (selectorPatterns.length || keyOnlyBindingPatterns.length) frag.push(...genBlockContent(render, context, false, () => {
|
1058
|
+
const patternFrag$1 = [];
|
1059
|
+
for (const [i, { effect }] of selectorPatterns.entries()) {
|
1060
|
+
patternFrag$1.push(NEWLINE, `_selector${id}_${i}(() => {`, INDENT_START);
|
1061
|
+
for (const oper$1 of effect.operations) patternFrag$1.push(...genOperation(oper$1, context));
|
1062
|
+
patternFrag$1.push(INDENT_END, NEWLINE, `})`);
|
1063
|
+
}
|
1064
|
+
for (const { effect } of keyOnlyBindingPatterns) for (const oper$1 of effect.operations) patternFrag$1.push(...genOperation(oper$1, context));
|
1065
|
+
return patternFrag$1;
|
1066
|
+
}));
|
1067
|
+
else frag.push(...genBlockContent(render, context));
|
1068
|
+
frag.push(INDENT_END, NEWLINE, "}");
|
1069
|
+
return frag;
|
1070
|
+
}, idMap);
|
1071
|
+
exitScope();
|
1072
|
+
let flags = 0;
|
1073
|
+
if (onlyChild) flags |= VaporVForFlags.FAST_REMOVE;
|
1074
|
+
if (component) flags |= VaporVForFlags.IS_COMPONENT;
|
1075
|
+
if (once) flags |= VaporVForFlags.ONCE;
|
1076
|
+
return [
|
1077
|
+
NEWLINE,
|
1078
|
+
`const n${id} = `,
|
1079
|
+
...genCall(helper("createFor"), sourceExpr, blockFn, genCallback(keyProp), flags ? String(flags) : void 0),
|
1080
|
+
...patternFrag
|
1081
|
+
];
|
1082
|
+
function parseValueDestructure() {
|
1083
|
+
const map = /* @__PURE__ */ new Map();
|
1084
|
+
if (value) {
|
1085
|
+
rawValue = value && value.content;
|
1086
|
+
if (value.ast) walkIdentifiers(value.ast, (id$1, _, parentStack, ___, isLocal) => {
|
1087
|
+
if (isLocal) {
|
1088
|
+
let path = "";
|
1089
|
+
let isDynamic = false;
|
1090
|
+
let helper$1;
|
1091
|
+
let helperArgs;
|
1092
|
+
for (let i = 0; i < parentStack.length; i++) {
|
1093
|
+
const parent = parentStack[i];
|
1094
|
+
const child = parentStack[i + 1] || id$1;
|
1095
|
+
if (parent.type === "ObjectProperty" && parent.value === child) if (parent.key.type === "StringLiteral") path += `[${JSON.stringify(parent.key.value)}]`;
|
1096
|
+
else if (parent.computed) {
|
1097
|
+
isDynamic = true;
|
1098
|
+
path += `[${value.content.slice(parent.key.start - 1, parent.key.end - 1)}]`;
|
1099
|
+
} else path += `.${parent.key.name}`;
|
1100
|
+
else if (parent.type === "ArrayPattern") {
|
1101
|
+
const index$1 = parent.elements.indexOf(child);
|
1102
|
+
if (child.type === "RestElement") path += `.slice(${index$1})`;
|
1103
|
+
else path += `[${index$1}]`;
|
1104
|
+
} else if (parent.type === "ObjectPattern" && child.type === "RestElement") {
|
1105
|
+
helper$1 = context.helper("getRestElement");
|
1106
|
+
helperArgs = `[${parent.properties.filter((p) => p.type === "ObjectProperty").map((p) => {
|
1107
|
+
if (p.key.type === "StringLiteral") return JSON.stringify(p.key.value);
|
1108
|
+
else if (p.computed) {
|
1109
|
+
isDynamic = true;
|
1110
|
+
return value.content.slice(p.key.start - 1, p.key.end - 1);
|
1111
|
+
} else return JSON.stringify(p.key.name);
|
1112
|
+
}).join(", ")}]`;
|
1113
|
+
}
|
1114
|
+
if (child.type === "AssignmentPattern" && (parent.type === "ObjectProperty" || parent.type === "ArrayPattern")) {
|
1115
|
+
isDynamic = true;
|
1116
|
+
helper$1 = context.helper("getDefaultValue");
|
1117
|
+
helperArgs = value.content.slice(child.right.start - 1, child.right.end - 1);
|
1118
|
+
}
|
1119
|
+
}
|
1120
|
+
map.set(id$1.name, {
|
1121
|
+
path,
|
1122
|
+
dynamic: isDynamic,
|
1123
|
+
helper: helper$1,
|
1124
|
+
helperArgs
|
1125
|
+
});
|
1126
|
+
}
|
1127
|
+
}, true);
|
1128
|
+
else map.set(rawValue, null);
|
1129
|
+
}
|
1130
|
+
return map;
|
1131
|
+
}
|
1132
|
+
function genCallback(expr) {
|
1133
|
+
if (!expr) return false;
|
1134
|
+
const res = context.withId(() => genExpression(expr, context), genSimpleIdMap());
|
1135
|
+
return [
|
1136
|
+
...genMulti([
|
1137
|
+
"(",
|
1138
|
+
")",
|
1139
|
+
", "
|
1140
|
+
], rawValue ? rawValue : rawKey || rawIndex ? "_" : void 0, rawKey ? rawKey : rawIndex ? "__" : void 0, rawIndex),
|
1141
|
+
" => (",
|
1142
|
+
...res,
|
1143
|
+
")"
|
1144
|
+
];
|
1145
|
+
}
|
1146
|
+
function genSimpleIdMap() {
|
1147
|
+
const idMap$1 = {};
|
1148
|
+
if (rawKey) idMap$1[rawKey] = null;
|
1149
|
+
if (rawIndex) idMap$1[rawIndex] = null;
|
1150
|
+
idToPathMap.forEach((_, id$1) => idMap$1[id$1] = null);
|
1151
|
+
return idMap$1;
|
1152
|
+
}
|
1153
|
+
}
|
1154
|
+
function matchPatterns(render, keyProp, idMap) {
|
1155
|
+
const selectorPatterns = [];
|
1156
|
+
const keyOnlyBindingPatterns = [];
|
1157
|
+
render.effect = render.effect.filter((effect) => {
|
1158
|
+
if (keyProp !== void 0) {
|
1159
|
+
const selector = matchSelectorPattern(effect, keyProp.ast, idMap);
|
1160
|
+
if (selector) {
|
1161
|
+
selectorPatterns.push(selector);
|
1162
|
+
return false;
|
1163
|
+
}
|
1164
|
+
const keyOnly = matchKeyOnlyBindingPattern(effect, keyProp.ast);
|
1165
|
+
if (keyOnly) {
|
1166
|
+
keyOnlyBindingPatterns.push(keyOnly);
|
1167
|
+
return false;
|
1168
|
+
}
|
1169
|
+
}
|
1170
|
+
return true;
|
1171
|
+
});
|
261
1172
|
return {
|
262
|
-
|
263
|
-
|
1173
|
+
keyOnlyBindingPatterns,
|
1174
|
+
selectorPatterns
|
264
1175
|
};
|
265
1176
|
}
|
266
|
-
function
|
1177
|
+
function matchKeyOnlyBindingPattern(effect, keyAst) {
|
1178
|
+
if (effect.expressions.length === 1) {
|
1179
|
+
const ast = effect.expressions[0].ast;
|
1180
|
+
if (typeof ast === "object" && ast !== null && isKeyOnlyBinding(ast, keyAst)) return { effect };
|
1181
|
+
}
|
1182
|
+
}
|
1183
|
+
function matchSelectorPattern(effect, keyAst, idMap) {
|
1184
|
+
if (effect.expressions.length === 1) {
|
1185
|
+
const ast = effect.expressions[0].ast;
|
1186
|
+
const offset = effect.expressions[0].loc.start.offset;
|
1187
|
+
if (typeof ast === "object" && ast) {
|
1188
|
+
const matcheds = [];
|
1189
|
+
walkAST(ast, { enter(node) {
|
1190
|
+
if (typeof node === "object" && node && node.type === "BinaryExpression" && node.operator === "===" && node.left.type !== "PrivateName") {
|
1191
|
+
const { left, right } = node;
|
1192
|
+
for (const [a, b] of [[left, right], [right, left]]) {
|
1193
|
+
const aIsKey = isKeyOnlyBinding(a, keyAst);
|
1194
|
+
const bIsKey = isKeyOnlyBinding(b, keyAst);
|
1195
|
+
const bVars = analyzeVariableScopes(b, idMap);
|
1196
|
+
if (aIsKey && !bIsKey && !bVars.locals.length) matcheds.push([a, b]);
|
1197
|
+
}
|
1198
|
+
}
|
1199
|
+
} });
|
1200
|
+
if (matcheds.length === 1) {
|
1201
|
+
const [key, selector] = matcheds[0];
|
1202
|
+
const content$1 = effect.expressions[0].content;
|
1203
|
+
let hasExtraId = false;
|
1204
|
+
const parentStackMap = /* @__PURE__ */ new Map();
|
1205
|
+
const parentStack = [];
|
1206
|
+
walkIdentifiers(ast, (id) => {
|
1207
|
+
if (id.start !== key.start && id.start !== selector.start) hasExtraId = true;
|
1208
|
+
parentStackMap.set(id, parentStack.slice());
|
1209
|
+
}, false, parentStack);
|
1210
|
+
if (!hasExtraId) {
|
1211
|
+
const name = content$1.slice(selector.start - offset, selector.end - offset);
|
1212
|
+
return {
|
1213
|
+
effect,
|
1214
|
+
selector: {
|
1215
|
+
content: name,
|
1216
|
+
ast: extend({}, selector, {
|
1217
|
+
start: 1,
|
1218
|
+
end: name.length + 1
|
1219
|
+
}),
|
1220
|
+
loc: selector.loc,
|
1221
|
+
isStatic: false
|
1222
|
+
}
|
1223
|
+
};
|
1224
|
+
}
|
1225
|
+
}
|
1226
|
+
}
|
1227
|
+
const content = effect.expressions[0].content;
|
1228
|
+
if (typeof ast === "object" && ast && ast.type === "ConditionalExpression" && ast.test.type === "BinaryExpression" && ast.test.operator === "===" && ast.test.left.type !== "PrivateName" && isStaticNode(ast.consequent) && isStaticNode(ast.alternate)) {
|
1229
|
+
const left = ast.test.left;
|
1230
|
+
const right = ast.test.right;
|
1231
|
+
for (const [a, b] of [[left, right], [right, left]]) {
|
1232
|
+
const aIsKey = isKeyOnlyBinding(a, keyAst);
|
1233
|
+
const bIsKey = isKeyOnlyBinding(b, keyAst);
|
1234
|
+
const bVars = analyzeVariableScopes(b, idMap);
|
1235
|
+
if (aIsKey && !bIsKey && !bVars.locals.length) return {
|
1236
|
+
effect,
|
1237
|
+
selector: {
|
1238
|
+
content: content.slice(b.start - offset, b.end - offset),
|
1239
|
+
ast: b,
|
1240
|
+
loc: b.loc,
|
1241
|
+
isStatic: false
|
1242
|
+
}
|
1243
|
+
};
|
1244
|
+
}
|
1245
|
+
}
|
1246
|
+
}
|
1247
|
+
}
|
1248
|
+
function analyzeVariableScopes(ast, idMap) {
|
1249
|
+
const globals = [];
|
1250
|
+
const locals = [];
|
1251
|
+
const ids = [];
|
1252
|
+
const parentStackMap = /* @__PURE__ */ new Map();
|
1253
|
+
const parentStack = [];
|
1254
|
+
walkIdentifiers(ast, (id) => {
|
1255
|
+
ids.push(id);
|
1256
|
+
parentStackMap.set(id, parentStack.slice());
|
1257
|
+
}, false, parentStack);
|
1258
|
+
for (const id of ids) {
|
1259
|
+
if (isGloballyAllowed(id.name)) continue;
|
1260
|
+
if (idMap[id.name]) locals.push(id.name);
|
1261
|
+
else globals.push(id.name);
|
1262
|
+
}
|
267
1263
|
return {
|
268
|
-
|
269
|
-
|
270
|
-
dynamic: newDynamic(),
|
271
|
-
effect: [],
|
272
|
-
operation: [],
|
273
|
-
returns: [],
|
274
|
-
tempId: 0
|
1264
|
+
globals,
|
1265
|
+
locals
|
275
1266
|
};
|
276
1267
|
}
|
277
|
-
function
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
1268
|
+
function isKeyOnlyBinding(expr, keyAst) {
|
1269
|
+
let only = true;
|
1270
|
+
walkAST(expr, { enter(node) {
|
1271
|
+
if (isNodesEquivalent(node, keyAst)) {
|
1272
|
+
this.skip();
|
1273
|
+
return;
|
1274
|
+
}
|
1275
|
+
if (node.type === "Identifier") only = false;
|
1276
|
+
} });
|
1277
|
+
return only;
|
283
1278
|
}
|
284
|
-
|
285
|
-
|
286
|
-
|
1279
|
+
|
1280
|
+
//#endregion
|
1281
|
+
//#region src/generators/html.ts
|
1282
|
+
function genSetHtml(oper, context) {
|
1283
|
+
const { helper } = context;
|
1284
|
+
const { value, element } = oper;
|
1285
|
+
return [NEWLINE, ...genCall(helper("setHtml"), `n${element}`, genExpression(value, context))];
|
1286
|
+
}
|
1287
|
+
|
1288
|
+
//#endregion
|
1289
|
+
//#region src/generators/if.ts
|
1290
|
+
function genIf(oper, context, isNested = false) {
|
1291
|
+
const { helper } = context;
|
1292
|
+
const { condition, positive, negative, once } = oper;
|
1293
|
+
const [frag, push] = buildCodeFragment();
|
1294
|
+
const conditionExpr = [
|
1295
|
+
"() => (",
|
1296
|
+
...genExpression(condition, context),
|
1297
|
+
")"
|
1298
|
+
];
|
1299
|
+
const positiveArg = genBlock(positive, context);
|
1300
|
+
let negativeArg = false;
|
1301
|
+
if (negative) if (negative.type === IRNodeTypes.BLOCK) negativeArg = genBlock(negative, context);
|
1302
|
+
else negativeArg = ["() => ", ...genIf(negative, context, true)];
|
1303
|
+
if (!isNested) push(NEWLINE, `const n${oper.id} = `);
|
1304
|
+
push(...genCall(helper("createIf"), conditionExpr, positiveArg, negativeArg, once && "true"));
|
1305
|
+
return frag;
|
1306
|
+
}
|
1307
|
+
|
1308
|
+
//#endregion
|
1309
|
+
//#region src/generators/templateRef.ts
|
1310
|
+
const setTemplateRefIdent = `_setTemplateRef`;
|
1311
|
+
function genSetTemplateRef(oper, context) {
|
1312
|
+
return [
|
1313
|
+
NEWLINE,
|
1314
|
+
oper.effect && `r${oper.element} = `,
|
1315
|
+
...genCall(setTemplateRefIdent, `n${oper.element}`, genExpression(oper.value, context), oper.effect ? `r${oper.element}` : oper.refFor ? "void 0" : void 0, oper.refFor && "true")
|
1316
|
+
];
|
1317
|
+
}
|
1318
|
+
function genDeclareOldRef(oper) {
|
1319
|
+
return [NEWLINE, `let r${oper.id}`];
|
1320
|
+
}
|
1321
|
+
|
1322
|
+
//#endregion
|
1323
|
+
//#region src/generators/text.ts
|
1324
|
+
function genSetText(oper, context) {
|
1325
|
+
const { helper } = context;
|
1326
|
+
const { element, values, generated } = oper;
|
1327
|
+
const texts = combineValues(values, context, true);
|
1328
|
+
return [NEWLINE, ...genCall(helper("setText"), `${generated ? "x" : "n"}${element}`, texts)];
|
1329
|
+
}
|
1330
|
+
function genGetTextChild(oper, context) {
|
1331
|
+
return [NEWLINE, `const x${oper.parent} = ${context.helper("child")}(n${oper.parent})`];
|
1332
|
+
}
|
1333
|
+
function genSetNodes(oper, context) {
|
1334
|
+
const { helper } = context;
|
1335
|
+
const { element, values, generated } = oper;
|
1336
|
+
return [NEWLINE, ...genCall(helper("setNodes"), `${generated ? "x" : "n"}${element}`, combineValues(values, context))];
|
1337
|
+
}
|
1338
|
+
function genCreateNodes(oper, context) {
|
1339
|
+
const { helper } = context;
|
1340
|
+
const { id, values } = oper;
|
1341
|
+
return [
|
1342
|
+
NEWLINE,
|
1343
|
+
`const n${id} = `,
|
1344
|
+
...genCall(helper("createNodes"), values && combineValues(values, context))
|
1345
|
+
];
|
1346
|
+
}
|
1347
|
+
function combineValues(values, context, setText) {
|
1348
|
+
return values.flatMap((value, i) => {
|
1349
|
+
let exp = genExpression(value, context);
|
1350
|
+
if (setText && getLiteralExpressionValue(value) == null) exp = genCall(context.helper("toDisplayString"), exp);
|
1351
|
+
if (i > 0) exp.unshift(setText ? " + " : ", ");
|
1352
|
+
return exp;
|
1353
|
+
});
|
1354
|
+
}
|
1355
|
+
|
1356
|
+
//#endregion
|
1357
|
+
//#region src/generators/operation.ts
|
1358
|
+
function genOperations(opers, context) {
|
1359
|
+
const [frag, push] = buildCodeFragment();
|
1360
|
+
for (const operation of opers) push(...genOperationWithInsertionState(operation, context));
|
1361
|
+
return frag;
|
1362
|
+
}
|
1363
|
+
function genOperationWithInsertionState(oper, context) {
|
1364
|
+
const [frag, push] = buildCodeFragment();
|
1365
|
+
if (isBlockOperation(oper) && oper.parent) push(...genInsertionState(oper, context));
|
1366
|
+
push(...genOperation(oper, context));
|
1367
|
+
return frag;
|
1368
|
+
}
|
1369
|
+
function genOperation(oper, context) {
|
1370
|
+
switch (oper.type) {
|
1371
|
+
case IRNodeTypes.SET_PROP: return genSetProp(oper, context);
|
1372
|
+
case IRNodeTypes.SET_DYNAMIC_PROPS: return genDynamicProps(oper, context);
|
1373
|
+
case IRNodeTypes.SET_TEXT: return genSetText(oper, context);
|
1374
|
+
case IRNodeTypes.SET_EVENT: return genSetEvent(oper, context);
|
1375
|
+
case IRNodeTypes.SET_DYNAMIC_EVENTS: return genSetDynamicEvents(oper, context);
|
1376
|
+
case IRNodeTypes.SET_HTML: return genSetHtml(oper, context);
|
1377
|
+
case IRNodeTypes.SET_TEMPLATE_REF: return genSetTemplateRef(oper, context);
|
1378
|
+
case IRNodeTypes.INSERT_NODE: return genInsertNode(oper, context);
|
1379
|
+
case IRNodeTypes.PREPEND_NODE: return genPrependNode(oper, context);
|
1380
|
+
case IRNodeTypes.IF: return genIf(oper, context);
|
1381
|
+
case IRNodeTypes.FOR: return genFor(oper, context);
|
1382
|
+
case IRNodeTypes.CREATE_COMPONENT_NODE: return genCreateComponent(oper, context);
|
1383
|
+
case IRNodeTypes.DECLARE_OLD_REF: return genDeclareOldRef(oper);
|
1384
|
+
case IRNodeTypes.SLOT_OUTLET_NODE: return [];
|
1385
|
+
case IRNodeTypes.DIRECTIVE: return genBuiltinDirective(oper, context);
|
1386
|
+
case IRNodeTypes.GET_TEXT_CHILD: return genGetTextChild(oper, context);
|
1387
|
+
case IRNodeTypes.SET_NODES: return genSetNodes(oper, context);
|
1388
|
+
case IRNodeTypes.CREATE_NODES: return genCreateNodes(oper, context);
|
1389
|
+
default: {
|
1390
|
+
const exhaustiveCheck = oper;
|
1391
|
+
throw new Error(`Unhandled operation type in genOperation: ${exhaustiveCheck}`);
|
1392
|
+
}
|
1393
|
+
}
|
1394
|
+
}
|
1395
|
+
function genEffects(effects, context, genExtraFrag) {
|
1396
|
+
const { helper } = context;
|
1397
|
+
const [frag, push, unshift] = buildCodeFragment();
|
1398
|
+
let operationsCount = 0;
|
1399
|
+
for (const [i, effect] of effects.entries()) {
|
1400
|
+
operationsCount += effect.operations.length;
|
1401
|
+
const frags = genEffect(effect, context);
|
1402
|
+
i > 0 && push(NEWLINE);
|
1403
|
+
if (frag.at(-1) === ")" && frags[0] === "(") push(";");
|
1404
|
+
push(...frags);
|
1405
|
+
}
|
1406
|
+
const newLineCount = frag.filter((frag$1) => frag$1 === NEWLINE).length;
|
1407
|
+
if (newLineCount > 1 || operationsCount > 1) {
|
1408
|
+
unshift(`{`, INDENT_START, NEWLINE);
|
1409
|
+
push(INDENT_END, NEWLINE, "}");
|
1410
|
+
}
|
1411
|
+
if (effects.length) {
|
1412
|
+
unshift(NEWLINE, `${helper("renderEffect")}(() => `);
|
1413
|
+
push(`)`);
|
1414
|
+
}
|
1415
|
+
if (genExtraFrag) push(...context.withId(genExtraFrag, {}));
|
1416
|
+
return frag;
|
1417
|
+
}
|
1418
|
+
function genEffect({ operations }, context) {
|
1419
|
+
const [frag, push] = buildCodeFragment();
|
1420
|
+
const operationsExps = genOperations(operations, context);
|
1421
|
+
const newlineCount = operationsExps.filter((frag$1) => frag$1 === NEWLINE).length;
|
1422
|
+
if (newlineCount > 1) push(...operationsExps);
|
1423
|
+
else push(...operationsExps.filter((frag$1) => frag$1 !== NEWLINE));
|
1424
|
+
return frag;
|
1425
|
+
}
|
1426
|
+
function genInsertionState(operation, context) {
|
1427
|
+
return [NEWLINE, ...genCall(context.helper("setInsertionState"), `n${operation.parent}`, operation.anchor == null ? void 0 : operation.anchor === -1 ? `0` : `n${operation.anchor}`)];
|
1428
|
+
}
|
1429
|
+
|
1430
|
+
//#endregion
|
1431
|
+
//#region src/generators/template.ts
|
1432
|
+
function genTemplates(templates, rootIndex, { helper }) {
|
1433
|
+
return templates.map((template, i) => template.startsWith("_template") ? template : `${helper("template")}(${JSON.stringify(template)}${i === rootIndex ? ", true" : ""})`);
|
1434
|
+
}
|
1435
|
+
function genSelf(dynamic, context) {
|
1436
|
+
const [frag, push] = buildCodeFragment();
|
1437
|
+
const { id, template, operation } = dynamic;
|
1438
|
+
if (id !== void 0 && template !== void 0) {
|
1439
|
+
push(NEWLINE, `const n${id} = t${template}()`);
|
1440
|
+
push(...genDirectivesForElement(id, context));
|
1441
|
+
}
|
1442
|
+
if (operation) push(...genOperationWithInsertionState(operation, context));
|
1443
|
+
return frag;
|
1444
|
+
}
|
1445
|
+
function genChildren(dynamic, context, pushBlock, from = `n${dynamic.id}`) {
|
1446
|
+
const { helper } = context;
|
1447
|
+
const [frag, push] = buildCodeFragment();
|
1448
|
+
const { children } = dynamic;
|
1449
|
+
let offset = 0;
|
1450
|
+
let prev;
|
1451
|
+
const childrenToGen = [];
|
1452
|
+
for (const [index, child] of children.entries()) {
|
1453
|
+
if (child.flags & DynamicFlag.NON_TEMPLATE) offset--;
|
1454
|
+
const id = child.flags & DynamicFlag.REFERENCED ? child.flags & DynamicFlag.INSERT ? child.anchor : child.id : void 0;
|
1455
|
+
if (id === void 0 && !child.hasDynamicChild) {
|
1456
|
+
push(...genSelf(child, context));
|
1457
|
+
continue;
|
1458
|
+
}
|
1459
|
+
const elementIndex = Number(index) + offset;
|
1460
|
+
const variable = id === void 0 ? `p${context.block.tempId++}` : `n${id}`;
|
1461
|
+
pushBlock(NEWLINE, `const ${variable} = `);
|
1462
|
+
if (prev) if (elementIndex - prev[1] === 1) pushBlock(...genCall(helper("next"), prev[0]));
|
1463
|
+
else pushBlock(...genCall(helper("nthChild"), from, String(elementIndex)));
|
1464
|
+
else if (elementIndex === 0) pushBlock(...genCall(helper("child"), from));
|
1465
|
+
else {
|
1466
|
+
let init = genCall(helper("child"), from);
|
1467
|
+
if (elementIndex === 1) init = genCall(helper("next"), init);
|
1468
|
+
else if (elementIndex > 1) init = genCall(helper("nthChild"), from, String(elementIndex));
|
1469
|
+
pushBlock(...init);
|
1470
|
+
}
|
1471
|
+
if (id === child.anchor) push(...genSelf(child, context));
|
1472
|
+
if (id !== void 0) push(...genDirectivesForElement(id, context));
|
1473
|
+
prev = [variable, elementIndex];
|
1474
|
+
childrenToGen.push([child, variable]);
|
1475
|
+
}
|
1476
|
+
if (childrenToGen.length) for (const [child, from$1] of childrenToGen) push(...genChildren(child, context, pushBlock, from$1));
|
1477
|
+
return frag;
|
1478
|
+
}
|
1479
|
+
|
1480
|
+
//#endregion
|
1481
|
+
//#region src/generators/block.ts
|
1482
|
+
function genBlock(oper, context, args = [], root) {
|
1483
|
+
return [
|
1484
|
+
"(",
|
1485
|
+
...args,
|
1486
|
+
") => {",
|
1487
|
+
INDENT_START,
|
1488
|
+
...genBlockContent(oper, context, root),
|
1489
|
+
INDENT_END,
|
1490
|
+
NEWLINE,
|
1491
|
+
"}"
|
1492
|
+
];
|
1493
|
+
}
|
1494
|
+
function genBlockContent(block, context, root, genEffectsExtraFrag) {
|
1495
|
+
const [frag, push] = buildCodeFragment();
|
1496
|
+
const { dynamic, effect, operation, returns } = block;
|
1497
|
+
const resetBlock = context.enterBlock(block);
|
1498
|
+
if (root) {
|
1499
|
+
for (let name of context.ir.component) {
|
1500
|
+
const id = toValidAssetId(name, "component");
|
1501
|
+
const maybeSelfReference = name.endsWith("__self");
|
1502
|
+
if (maybeSelfReference) name = name.slice(0, -6);
|
1503
|
+
push(NEWLINE, `const ${id} = `, ...genCall(context.helper("resolveComponent"), JSON.stringify(name), maybeSelfReference ? "true" : void 0));
|
1504
|
+
}
|
1505
|
+
genResolveAssets("directive", "resolveDirective");
|
1506
|
+
}
|
1507
|
+
for (const child of dynamic.children) push(...genSelf(child, context));
|
1508
|
+
for (const child of dynamic.children) push(...genChildren(child, context, push, `n${child.id}`));
|
1509
|
+
push(...genOperations(operation, context));
|
1510
|
+
push(...genEffects(effect, context, genEffectsExtraFrag));
|
1511
|
+
push(NEWLINE, `return `);
|
1512
|
+
const returnNodes = returns.map((n) => `n${n}`);
|
1513
|
+
const returnsCode = returnNodes.length > 1 ? genMulti(DELIMITERS_ARRAY, ...returnNodes) : [returnNodes[0] || "null"];
|
1514
|
+
push(...returnsCode);
|
1515
|
+
resetBlock();
|
1516
|
+
return frag;
|
1517
|
+
function genResolveAssets(kind, helper) {
|
1518
|
+
for (const name of context.ir[kind]) push(NEWLINE, `const ${toValidAssetId(name, kind)} = `, ...genCall(context.helper(helper), JSON.stringify(name)));
|
1519
|
+
}
|
1520
|
+
}
|
1521
|
+
|
1522
|
+
//#endregion
|
1523
|
+
//#region src/generate.ts
|
1524
|
+
var CodegenContext = class {
|
1525
|
+
options;
|
1526
|
+
helpers = new Set([]);
|
1527
|
+
helper = (name) => {
|
1528
|
+
this.helpers.add(name);
|
1529
|
+
return `_${name}`;
|
1530
|
+
};
|
1531
|
+
delegates = /* @__PURE__ */ new Set();
|
1532
|
+
identifiers = Object.create(null);
|
1533
|
+
seenInlineHandlerNames = Object.create(null);
|
1534
|
+
block;
|
1535
|
+
withId(fn, map) {
|
1536
|
+
const { identifiers } = this;
|
1537
|
+
const ids = Object.keys(map);
|
1538
|
+
for (const id of ids) {
|
1539
|
+
identifiers[id] ||= [];
|
1540
|
+
identifiers[id].unshift(map[id] || id);
|
1541
|
+
}
|
1542
|
+
const ret = fn();
|
1543
|
+
ids.forEach((id) => remove(identifiers[id], map[id] || id));
|
1544
|
+
return ret;
|
1545
|
+
}
|
1546
|
+
enterBlock(block) {
|
1547
|
+
const parent = this.block;
|
1548
|
+
this.block = block;
|
1549
|
+
return () => this.block = parent;
|
1550
|
+
}
|
1551
|
+
scopeLevel = 0;
|
1552
|
+
enterScope() {
|
1553
|
+
return [this.scopeLevel++, () => this.scopeLevel--];
|
1554
|
+
}
|
1555
|
+
constructor(ir, options) {
|
1556
|
+
this.ir = ir;
|
1557
|
+
const defaultOptions$1 = {
|
1558
|
+
mode: "module",
|
1559
|
+
sourceMap: false,
|
1560
|
+
filename: `template.vue.html`,
|
1561
|
+
scopeId: null,
|
1562
|
+
runtimeGlobalName: `Vue`,
|
1563
|
+
runtimeModuleName: `vue`,
|
1564
|
+
ssrRuntimeModuleName: "vue/server-renderer",
|
1565
|
+
ssr: false,
|
1566
|
+
isTS: false,
|
1567
|
+
inSSR: false,
|
1568
|
+
templates: [],
|
1569
|
+
expressionPlugins: []
|
1570
|
+
};
|
1571
|
+
this.options = extend(defaultOptions$1, options);
|
1572
|
+
this.block = ir.block;
|
1573
|
+
}
|
1574
|
+
};
|
1575
|
+
function generate(ir, options = {}) {
|
1576
|
+
const [frag, push] = buildCodeFragment();
|
1577
|
+
const context = new CodegenContext(ir, options);
|
1578
|
+
const { helpers: helpers$1 } = context;
|
1579
|
+
push(INDENT_START);
|
1580
|
+
if (ir.hasTemplateRef) push(NEWLINE, `const ${setTemplateRefIdent} = ${context.helper("createTemplateRefSetter")}()`);
|
1581
|
+
push(...genBlockContent(ir.block, context, true));
|
1582
|
+
push(INDENT_END, NEWLINE);
|
1583
|
+
if (context.delegates.size) context.helper("delegateEvents");
|
1584
|
+
const templates = genTemplates(ir.templates, ir.rootTemplateIndex, context);
|
1585
|
+
const [code, map] = codeFragmentToString(frag, context);
|
1586
|
+
return {
|
1587
|
+
code,
|
1588
|
+
ast: ir,
|
1589
|
+
map: map && map.toJSON(),
|
1590
|
+
helpers: helpers$1,
|
1591
|
+
templates,
|
1592
|
+
delegates: context.delegates
|
1593
|
+
};
|
287
1594
|
}
|
288
|
-
const EMPTY_EXPRESSION = createSimpleExpression("", true);
|
289
|
-
const isFragmentNode = (node) => node.type === IRNodeTypes.ROOT || node.type === "JSXFragment" || node.type === "JSXElement" && !!isTemplate(node);
|
290
1595
|
|
291
1596
|
//#endregion
|
292
1597
|
//#region src/transform.ts
|
293
1598
|
const defaultOptions = {
|
294
1599
|
filename: "",
|
295
|
-
prefixIdentifiers: false,
|
296
1600
|
hoistStatic: false,
|
297
1601
|
hmr: false,
|
298
1602
|
cacheHandlers: false,
|
299
1603
|
nodeTransforms: [],
|
300
1604
|
directiveTransforms: {},
|
1605
|
+
templates: [],
|
301
1606
|
transformHoist: null,
|
302
1607
|
isBuiltInComponent: NOOP,
|
303
1608
|
isCustomElement: NOOP,
|
@@ -307,8 +1612,6 @@ const defaultOptions = {
|
|
307
1612
|
ssr: false,
|
308
1613
|
inSSR: false,
|
309
1614
|
ssrCssVars: ``,
|
310
|
-
bindingMetadata: EMPTY_OBJ,
|
311
|
-
inline: false,
|
312
1615
|
isTS: false,
|
313
1616
|
onError: defaultOnError,
|
314
1617
|
onWarn: defaultOnWarn
|
@@ -364,10 +1667,10 @@ var TransformContext = class TransformContext {
|
|
364
1667
|
return this.dynamic.id = this.increaseId();
|
365
1668
|
}
|
366
1669
|
pushTemplate(content) {
|
367
|
-
const existing = this.ir.
|
1670
|
+
const existing = this.ir.templates.indexOf(content);
|
368
1671
|
if (existing !== -1) return existing;
|
369
|
-
this.ir.
|
370
|
-
return this.ir.
|
1672
|
+
this.ir.templates.push(content);
|
1673
|
+
return this.ir.templates.length - 1;
|
371
1674
|
}
|
372
1675
|
registerTemplate() {
|
373
1676
|
if (!this.template) return -1;
|
@@ -402,7 +1705,7 @@ function transform(node, options = {}) {
|
|
402
1705
|
type: IRNodeTypes.ROOT,
|
403
1706
|
node,
|
404
1707
|
source: node.source,
|
405
|
-
|
1708
|
+
templates: options.templates || [],
|
406
1709
|
component: /* @__PURE__ */ new Set(),
|
407
1710
|
directive: /* @__PURE__ */ new Set(),
|
408
1711
|
block: newBlock(node),
|
@@ -587,7 +1890,7 @@ function transformNativeElement(tag, propsResult, singleRoot, context, getEffect
|
|
587
1890
|
}
|
588
1891
|
template += `>${context.childrenTemplate.join("")}`;
|
589
1892
|
if (!isVoidTag(tag)) template += `</${tag}>`;
|
590
|
-
if (singleRoot) context.ir.rootTemplateIndex = context.ir.
|
1893
|
+
if (singleRoot) context.ir.rootTemplateIndex = context.ir.templates.length;
|
591
1894
|
if (context.parent && context.parent.node.type === "JSXElement" && context.parent.node.openingElement.name.type === "JSXIdentifier" && !isValidHTMLNesting(context.parent.node.openingElement.name.name, tag)) {
|
592
1895
|
context.reference();
|
593
1896
|
context.dynamic.template = context.pushTemplate(template);
|
@@ -979,7 +2282,7 @@ function processIf(node, attribute, context) {
|
|
979
2282
|
id,
|
980
2283
|
condition: dir.exp,
|
981
2284
|
positive: branch,
|
982
|
-
once: context.inVOnce || isConstantNode(attribute.value,
|
2285
|
+
once: context.inVOnce || isConstantNode(attribute.value, {})
|
983
2286
|
};
|
984
2287
|
};
|
985
2288
|
} else {
|
@@ -1096,9 +2399,9 @@ function hasDynamicKeyVBind(node) {
|
|
1096
2399
|
const delegatedEvents = /* @__PURE__ */ makeMap("beforeinput,click,dblclick,contextmenu,focusin,focusout,input,keydown,keyup,mousedown,mousemove,mouseout,mouseover,mouseup,pointerdown,pointermove,pointerout,pointerover,pointerup,touchend,touchmove,touchstart");
|
1097
2400
|
const transformVOn = (dir, node, context) => {
|
1098
2401
|
const { name, loc, value } = dir;
|
1099
|
-
if (name
|
2402
|
+
if (!name) return;
|
1100
2403
|
const isComponent = isJSXComponent(node);
|
1101
|
-
const [nameString, ...modifiers] = name.name.replace(/^on([A-Z])/, (_, $1) => $1.toLowerCase()).split("_");
|
2404
|
+
const [nameString, ...modifiers] = context.ir.source.slice(name.start, name.end).replace(/^on([A-Z])/, (_, $1) => $1.toLowerCase()).split("_");
|
1102
2405
|
if (!value && !modifiers.length) context.options.onError(createCompilerError(ErrorCodes.X_V_ON_NO_EXPRESSION, resolveLocation(loc, context)));
|
1103
2406
|
let arg = resolveSimpleExpression(nameString, true, dir.name.loc);
|
1104
2407
|
const exp = resolveExpression(dir.value, context);
|
@@ -1296,13 +2599,10 @@ function createSlotBlock(slotNode, dir, context) {
|
|
1296
2599
|
//#region src/transforms/vSlots.ts
|
1297
2600
|
const transformVSlots = (dir, node, context) => {
|
1298
2601
|
if (!isJSXComponent(node)) return;
|
1299
|
-
if (dir.value?.type === "JSXExpressionContainer") {
|
1300
|
-
|
1301
|
-
|
1302
|
-
|
1303
|
-
}];
|
1304
|
-
if (node.children.length) context.options.onError(createCompilerError(ErrorCodes.X_V_SLOT_MIXED_SLOT_USAGE, resolveLocation(node.children[0].loc, context)));
|
1305
|
-
}
|
2602
|
+
if (dir.value?.type === "JSXExpressionContainer") context.slots = [{
|
2603
|
+
slotType: IRSlotType.EXPRESSION,
|
2604
|
+
slots: resolveExpression(dir.value.expression, context)
|
2605
|
+
}];
|
1306
2606
|
};
|
1307
2607
|
|
1308
2608
|
//#endregion
|
@@ -1339,11 +2639,7 @@ const transformVText = (dir, node, context) => {
|
|
1339
2639
|
//#endregion
|
1340
2640
|
//#region src/compile.ts
|
1341
2641
|
function compile(source, options = {}) {
|
1342
|
-
const resolvedOptions = extend({}, options, {
|
1343
|
-
inline: true,
|
1344
|
-
prefixIdentifiers: false,
|
1345
|
-
expressionPlugins: options.expressionPlugins || ["jsx"]
|
1346
|
-
});
|
2642
|
+
const resolvedOptions = extend({}, options, { expressionPlugins: options.expressionPlugins || ["jsx"] });
|
1347
2643
|
if (!resolvedOptions.source && isString(source)) resolvedOptions.source = source;
|
1348
2644
|
if (resolvedOptions.isTS) {
|
1349
2645
|
const { expressionPlugins } = resolvedOptions;
|
@@ -1364,10 +2660,7 @@ function compile(source, options = {}) {
|
|
1364
2660
|
nodeTransforms: [...nodeTransforms, ...resolvedOptions.nodeTransforms || []],
|
1365
2661
|
directiveTransforms: extend({}, directiveTransforms, resolvedOptions.directiveTransforms || {})
|
1366
2662
|
}));
|
1367
|
-
return generate(ir,
|
1368
|
-
...resolvedOptions,
|
1369
|
-
customGenOperation
|
1370
|
-
});
|
2663
|
+
return generate(ir, resolvedOptions);
|
1371
2664
|
}
|
1372
2665
|
function getBaseTransformPreset() {
|
1373
2666
|
return [[
|
@@ -1391,4 +2684,4 @@ function getBaseTransformPreset() {
|
|
1391
2684
|
}
|
1392
2685
|
|
1393
2686
|
//#endregion
|
1394
|
-
export { DynamicFlag, IRDynamicPropsKind, IRNodeTypes, IRSlotType, TransformContext, compile, createStructuralDirectiveTransform, generate, isBlockOperation, transform, transformChildren, transformElement, transformNode, transformTemplateRef, transformText, transformVBind, transformVFor, transformVHtml, transformVIf, transformVModel, transformVOn, transformVOnce, transformVShow, transformVSlot, transformVSlots, transformVText };
|
2687
|
+
export { CodegenContext, DynamicFlag, IRDynamicPropsKind, IRNodeTypes, IRSlotType, TransformContext, compile, createStructuralDirectiveTransform, generate, isBlockOperation, transform, transformChildren, transformElement, transformNode, transformTemplateRef, transformText, transformVBind, transformVFor, transformVHtml, transformVIf, transformVModel, transformVOn, transformVOnce, transformVShow, transformVSlot, transformVSlots, transformVText };
|