@vue-jsx-vapor/compiler 2.5.0 → 2.5.2
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 +168 -57
- package/dist/index.d.cts +0 -1
- package/dist/index.d.ts +0 -1
- package/dist/index.js +170 -59
- package/package.json +3 -3
package/dist/index.cjs
CHANGED
@@ -756,21 +756,10 @@ function genCreateComponent(operation, context) {
|
|
756
756
|
const { helper } = context;
|
757
757
|
const tag = genTag();
|
758
758
|
const { root, props, slots, once } = operation;
|
759
|
+
const rawProps = genRawProps(props, context);
|
759
760
|
const rawSlots = genRawSlots(slots, context);
|
760
|
-
const [ids, handlers] = processInlineHandlers(props, context);
|
761
|
-
const rawProps = context.withId(() => genRawProps(props, context), ids);
|
762
|
-
const inlineHandlers = handlers.reduce((acc, { name, value }) => {
|
763
|
-
const handler = genEventHandler(context, value, void 0, false);
|
764
|
-
return [
|
765
|
-
...acc,
|
766
|
-
`const ${name} = `,
|
767
|
-
...handler,
|
768
|
-
NEWLINE
|
769
|
-
];
|
770
|
-
}, []);
|
771
761
|
return [
|
772
762
|
NEWLINE,
|
773
|
-
...inlineHandlers,
|
774
763
|
`const n${operation.id} = `,
|
775
764
|
...genCall(operation.dynamic && !operation.dynamic.isStatic ? helper("createDynamicComponent") : operation.asset ? helper("createComponentWithFallback") : helper("createComponent"), tag, rawProps, rawSlots, root ? "true" : false, once && "true"),
|
776
765
|
...genDirectivesForElement(operation.id, context)
|
@@ -786,33 +775,6 @@ function genCreateComponent(operation, context) {
|
|
786
775
|
else return genExpression((0, __vue_shared.extend)((0, __vue_compiler_dom.createSimpleExpression)(operation.tag, false), { ast: null }), context);
|
787
776
|
}
|
788
777
|
}
|
789
|
-
function getUniqueHandlerName(context, name) {
|
790
|
-
const { seenInlineHandlerNames } = context;
|
791
|
-
const count = seenInlineHandlerNames[name] || 0;
|
792
|
-
seenInlineHandlerNames[name] = count + 1;
|
793
|
-
return count === 0 ? name : `${name}${count}`;
|
794
|
-
}
|
795
|
-
function processInlineHandlers(props, context) {
|
796
|
-
const ids = Object.create(null);
|
797
|
-
const handlers = [];
|
798
|
-
const staticProps = props[0];
|
799
|
-
if ((0, __vue_shared.isArray)(staticProps)) for (const prop of staticProps) {
|
800
|
-
if (!prop.handler) continue;
|
801
|
-
prop.values.forEach((value, i) => {
|
802
|
-
const isMemberExp = (0, __vue_compiler_dom.isMemberExpression)(value, context.options);
|
803
|
-
if (!isMemberExp) {
|
804
|
-
const name = getUniqueHandlerName(context, `_on_${prop.key.content}`);
|
805
|
-
handlers.push({
|
806
|
-
name,
|
807
|
-
value
|
808
|
-
});
|
809
|
-
ids[name] = null;
|
810
|
-
prop.values[i] = (0, __vue_shared.extend)({ ast: null }, (0, __vue_compiler_dom.createSimpleExpression)(name));
|
811
|
-
}
|
812
|
-
});
|
813
|
-
}
|
814
|
-
return [ids, handlers];
|
815
|
-
}
|
816
778
|
function genRawProps(props, context) {
|
817
779
|
const staticProps = props[0];
|
818
780
|
if ((0, __vue_shared.isArray)(staticProps)) {
|
@@ -1068,7 +1030,33 @@ function genFor(oper, context) {
|
|
1068
1030
|
idMap[rawIndex] = `${indexVar}.value`;
|
1069
1031
|
idMap[indexVar] = null;
|
1070
1032
|
}
|
1071
|
-
const
|
1033
|
+
const { selectorPatterns, keyOnlyBindingPatterns } = matchPatterns(render, keyProp, idMap);
|
1034
|
+
const selectorDeclarations = [];
|
1035
|
+
const selectorSetup = [];
|
1036
|
+
for (const [i, { selector }] of selectorPatterns.entries()) {
|
1037
|
+
const selectorName = `_selector${id}_${i}`;
|
1038
|
+
selectorDeclarations.push(`let ${selectorName}`, NEWLINE);
|
1039
|
+
if (i === 0) selectorSetup.push(`({ createSelector }) => {`, INDENT_START);
|
1040
|
+
selectorSetup.push(NEWLINE, `${selectorName} = `, ...genCall(`createSelector`, [`() => `, ...genExpression(selector, context)]));
|
1041
|
+
if (i === selectorPatterns.length - 1) selectorSetup.push(INDENT_END, NEWLINE, "}");
|
1042
|
+
}
|
1043
|
+
const blockFn = context.withId(() => {
|
1044
|
+
const frag = [];
|
1045
|
+
frag.push("(", ...args, ") => {", INDENT_START);
|
1046
|
+
if (selectorPatterns.length || keyOnlyBindingPatterns.length) frag.push(...genBlockContent(render, context, false, () => {
|
1047
|
+
const patternFrag = [];
|
1048
|
+
for (const [i, { effect }] of selectorPatterns.entries()) {
|
1049
|
+
patternFrag.push(NEWLINE, `_selector${id}_${i}(() => {`, INDENT_START);
|
1050
|
+
for (const oper$1 of effect.operations) patternFrag.push(...genOperation(oper$1, context));
|
1051
|
+
patternFrag.push(INDENT_END, NEWLINE, `})`);
|
1052
|
+
}
|
1053
|
+
for (const { effect } of keyOnlyBindingPatterns) for (const oper$1 of effect.operations) patternFrag.push(...genOperation(oper$1, context));
|
1054
|
+
return patternFrag;
|
1055
|
+
}));
|
1056
|
+
else frag.push(...genBlockContent(render, context));
|
1057
|
+
frag.push(INDENT_END, NEWLINE, "}");
|
1058
|
+
return frag;
|
1059
|
+
}, idMap);
|
1072
1060
|
exitScope();
|
1073
1061
|
let flags = 0;
|
1074
1062
|
if (onlyChild) flags |= VaporVForFlags.FAST_REMOVE;
|
@@ -1076,8 +1064,9 @@ function genFor(oper, context) {
|
|
1076
1064
|
if (once) flags |= VaporVForFlags.ONCE;
|
1077
1065
|
return [
|
1078
1066
|
NEWLINE,
|
1067
|
+
...selectorDeclarations,
|
1079
1068
|
`const n${id} = `,
|
1080
|
-
...genCall(helper("createFor"), sourceExpr, blockFn, genCallback(keyProp), flags ? String(flags) : void 0)
|
1069
|
+
...genCall([helper("createFor"), "undefined"], sourceExpr, blockFn, genCallback(keyProp), flags ? String(flags) : void 0, selectorSetup.length ? selectorSetup : void 0)
|
1081
1070
|
];
|
1082
1071
|
function parseValueDestructure() {
|
1083
1072
|
const map = /* @__PURE__ */ new Map();
|
@@ -1151,6 +1140,131 @@ function genFor(oper, context) {
|
|
1151
1140
|
return idMap$1;
|
1152
1141
|
}
|
1153
1142
|
}
|
1143
|
+
function matchPatterns(render, keyProp, idMap) {
|
1144
|
+
const selectorPatterns = [];
|
1145
|
+
const keyOnlyBindingPatterns = [];
|
1146
|
+
render.effect = render.effect.filter((effect) => {
|
1147
|
+
if (keyProp !== void 0) {
|
1148
|
+
const selector = matchSelectorPattern(effect, keyProp.ast, idMap);
|
1149
|
+
if (selector) {
|
1150
|
+
selectorPatterns.push(selector);
|
1151
|
+
return false;
|
1152
|
+
}
|
1153
|
+
const keyOnly = matchKeyOnlyBindingPattern(effect, keyProp.ast);
|
1154
|
+
if (keyOnly) {
|
1155
|
+
keyOnlyBindingPatterns.push(keyOnly);
|
1156
|
+
return false;
|
1157
|
+
}
|
1158
|
+
}
|
1159
|
+
return true;
|
1160
|
+
});
|
1161
|
+
return {
|
1162
|
+
keyOnlyBindingPatterns,
|
1163
|
+
selectorPatterns
|
1164
|
+
};
|
1165
|
+
}
|
1166
|
+
function matchKeyOnlyBindingPattern(effect, keyAst) {
|
1167
|
+
if (effect.expressions.length === 1) {
|
1168
|
+
const ast = effect.expressions[0].ast;
|
1169
|
+
if (typeof ast === "object" && ast !== null && isKeyOnlyBinding(ast, keyAst)) return { effect };
|
1170
|
+
}
|
1171
|
+
}
|
1172
|
+
function matchSelectorPattern(effect, keyAst, idMap) {
|
1173
|
+
if (effect.expressions.length === 1) {
|
1174
|
+
const ast = effect.expressions[0].ast;
|
1175
|
+
const offset = effect.expressions[0].loc.start.offset;
|
1176
|
+
if (typeof ast === "object" && ast) {
|
1177
|
+
const matcheds = [];
|
1178
|
+
(0, ast_kit.walkAST)(ast, { enter(node) {
|
1179
|
+
if (typeof node === "object" && node && node.type === "BinaryExpression" && node.operator === "===" && node.left.type !== "PrivateName") {
|
1180
|
+
const { left, right } = node;
|
1181
|
+
for (const [a, b] of [[left, right], [right, left]]) {
|
1182
|
+
const aIsKey = isKeyOnlyBinding(a, keyAst);
|
1183
|
+
const bIsKey = isKeyOnlyBinding(b, keyAst);
|
1184
|
+
const bVars = analyzeVariableScopes(b, idMap);
|
1185
|
+
if (aIsKey && !bIsKey && !bVars.locals.length) matcheds.push([a, b]);
|
1186
|
+
}
|
1187
|
+
}
|
1188
|
+
} });
|
1189
|
+
if (matcheds.length === 1) {
|
1190
|
+
const [key, selector] = matcheds[0];
|
1191
|
+
const content$1 = effect.expressions[0].content;
|
1192
|
+
let hasExtraId = false;
|
1193
|
+
const parentStackMap = /* @__PURE__ */ new Map();
|
1194
|
+
const parentStack = [];
|
1195
|
+
(0, __vue_compiler_dom.walkIdentifiers)(ast, (id) => {
|
1196
|
+
if (id.start !== key.start && id.start !== selector.start) hasExtraId = true;
|
1197
|
+
parentStackMap.set(id, parentStack.slice());
|
1198
|
+
}, false, parentStack);
|
1199
|
+
if (!hasExtraId) {
|
1200
|
+
const name = content$1.slice(selector.start - offset, selector.end - offset);
|
1201
|
+
return {
|
1202
|
+
effect,
|
1203
|
+
selector: {
|
1204
|
+
content: name,
|
1205
|
+
ast: (0, __vue_shared.extend)({}, selector, {
|
1206
|
+
start: 1,
|
1207
|
+
end: name.length + 1
|
1208
|
+
}),
|
1209
|
+
loc: selector.loc,
|
1210
|
+
isStatic: false
|
1211
|
+
}
|
1212
|
+
};
|
1213
|
+
}
|
1214
|
+
}
|
1215
|
+
}
|
1216
|
+
const content = effect.expressions[0].content;
|
1217
|
+
if (typeof ast === "object" && ast && ast.type === "ConditionalExpression" && ast.test.type === "BinaryExpression" && ast.test.operator === "===" && ast.test.left.type !== "PrivateName" && (0, __vue_compiler_dom.isStaticNode)(ast.consequent) && (0, __vue_compiler_dom.isStaticNode)(ast.alternate)) {
|
1218
|
+
const left = ast.test.left;
|
1219
|
+
const right = ast.test.right;
|
1220
|
+
for (const [a, b] of [[left, right], [right, left]]) {
|
1221
|
+
const aIsKey = isKeyOnlyBinding(a, keyAst);
|
1222
|
+
const bIsKey = isKeyOnlyBinding(b, keyAst);
|
1223
|
+
const bVars = analyzeVariableScopes(b, idMap);
|
1224
|
+
if (aIsKey && !bIsKey && !bVars.locals.length) return {
|
1225
|
+
effect,
|
1226
|
+
selector: {
|
1227
|
+
content: content.slice(b.start - offset, b.end - offset),
|
1228
|
+
ast: b,
|
1229
|
+
loc: b.loc,
|
1230
|
+
isStatic: false
|
1231
|
+
}
|
1232
|
+
};
|
1233
|
+
}
|
1234
|
+
}
|
1235
|
+
}
|
1236
|
+
}
|
1237
|
+
function analyzeVariableScopes(ast, idMap) {
|
1238
|
+
const globals = [];
|
1239
|
+
const locals = [];
|
1240
|
+
const ids = [];
|
1241
|
+
const parentStackMap = /* @__PURE__ */ new Map();
|
1242
|
+
const parentStack = [];
|
1243
|
+
(0, __vue_compiler_dom.walkIdentifiers)(ast, (id) => {
|
1244
|
+
ids.push(id);
|
1245
|
+
parentStackMap.set(id, parentStack.slice());
|
1246
|
+
}, false, parentStack);
|
1247
|
+
for (const id of ids) {
|
1248
|
+
if ((0, __vue_shared.isGloballyAllowed)(id.name)) continue;
|
1249
|
+
if (idMap[id.name]) locals.push(id.name);
|
1250
|
+
else globals.push(id.name);
|
1251
|
+
}
|
1252
|
+
return {
|
1253
|
+
globals,
|
1254
|
+
locals
|
1255
|
+
};
|
1256
|
+
}
|
1257
|
+
function isKeyOnlyBinding(expr, keyAst) {
|
1258
|
+
let only = true;
|
1259
|
+
(0, ast_kit.walkAST)(expr, { enter(node) {
|
1260
|
+
if ((0, __babel_types.isNodesEquivalent)(node, keyAst)) {
|
1261
|
+
this.skip();
|
1262
|
+
return;
|
1263
|
+
}
|
1264
|
+
if (node.type === "Identifier") only = false;
|
1265
|
+
} });
|
1266
|
+
return only;
|
1267
|
+
}
|
1154
1268
|
|
1155
1269
|
//#endregion
|
1156
1270
|
//#region src/generators/html.ts
|
@@ -1267,7 +1381,7 @@ function genOperation(oper, context) {
|
|
1267
1381
|
}
|
1268
1382
|
}
|
1269
1383
|
}
|
1270
|
-
function genEffects(effects, context) {
|
1384
|
+
function genEffects(effects, context, genExtraFrag) {
|
1271
1385
|
const { helper } = context;
|
1272
1386
|
const [frag, push, unshift] = buildCodeFragment();
|
1273
1387
|
let operationsCount = 0;
|
@@ -1287,6 +1401,7 @@ function genEffects(effects, context) {
|
|
1287
1401
|
unshift(NEWLINE, `${helper("renderEffect")}(() => `);
|
1288
1402
|
push(`)`);
|
1289
1403
|
}
|
1404
|
+
if (genExtraFrag) push(...context.withId(genExtraFrag, {}));
|
1290
1405
|
return frag;
|
1291
1406
|
}
|
1292
1407
|
function genEffect({ operations }, context) {
|
@@ -1353,19 +1468,19 @@ function genChildren(dynamic, context, pushBlock, from = `n${dynamic.id}`) {
|
|
1353
1468
|
|
1354
1469
|
//#endregion
|
1355
1470
|
//#region src/generators/block.ts
|
1356
|
-
function genBlock(oper, context, args = [], root
|
1471
|
+
function genBlock(oper, context, args = [], root) {
|
1357
1472
|
return [
|
1358
1473
|
"(",
|
1359
1474
|
...args,
|
1360
1475
|
") => {",
|
1361
1476
|
INDENT_START,
|
1362
|
-
...genBlockContent(oper, context, root
|
1477
|
+
...genBlockContent(oper, context, root),
|
1363
1478
|
INDENT_END,
|
1364
1479
|
NEWLINE,
|
1365
1480
|
"}"
|
1366
1481
|
];
|
1367
1482
|
}
|
1368
|
-
function genBlockContent(block, context, root,
|
1483
|
+
function genBlockContent(block, context, root, genEffectsExtraFrag) {
|
1369
1484
|
const [frag, push] = buildCodeFragment();
|
1370
1485
|
const { dynamic, effect, operation, returns } = block;
|
1371
1486
|
const resetBlock = context.enterBlock(block);
|
@@ -1381,11 +1496,11 @@ function genBlockContent(block, context, root, customReturns) {
|
|
1381
1496
|
for (const child of dynamic.children) push(...genSelf(child, context));
|
1382
1497
|
for (const child of dynamic.children) push(...genChildren(child, context, push, `n${child.id}`));
|
1383
1498
|
push(...genOperations(operation, context));
|
1384
|
-
push(...genEffects(effect, context));
|
1499
|
+
push(...genEffects(effect, context, genEffectsExtraFrag));
|
1385
1500
|
push(NEWLINE, `return `);
|
1386
1501
|
const returnNodes = returns.map((n) => `n${n}`);
|
1387
1502
|
const returnsCode = returnNodes.length > 1 ? genMulti(DELIMITERS_ARRAY, ...returnNodes) : [returnNodes[0] || "null"];
|
1388
|
-
push(...
|
1503
|
+
push(...returnsCode);
|
1389
1504
|
resetBlock();
|
1390
1505
|
return frag;
|
1391
1506
|
function genResolveAssets(kind, helper) {
|
@@ -1404,7 +1519,6 @@ var CodegenContext = class {
|
|
1404
1519
|
};
|
1405
1520
|
delegates = /* @__PURE__ */ new Set();
|
1406
1521
|
identifiers = Object.create(null);
|
1407
|
-
seenInlineHandlerNames = Object.create(null);
|
1408
1522
|
block;
|
1409
1523
|
withId(fn, map) {
|
1410
1524
|
const { identifiers } = this;
|
@@ -2273,9 +2387,9 @@ function hasDynamicKeyVBind(node) {
|
|
2273
2387
|
const delegatedEvents = /* @__PURE__ */ (0, __vue_shared.makeMap)("beforeinput,click,dblclick,contextmenu,focusin,focusout,input,keydown,keyup,mousedown,mousemove,mouseout,mouseover,mouseup,pointerdown,pointermove,pointerout,pointerover,pointerup,touchend,touchmove,touchstart");
|
2274
2388
|
const transformVOn = (dir, node, context) => {
|
2275
2389
|
const { name, loc, value } = dir;
|
2276
|
-
if (name
|
2390
|
+
if (!name) return;
|
2277
2391
|
const isComponent = isJSXComponent(node);
|
2278
|
-
const [nameString, ...modifiers] = name.name.replace(/^on([A-Z])/, (_, $1) => $1.toLowerCase()).split("_");
|
2392
|
+
const [nameString, ...modifiers] = context.ir.source.slice(name.start, name.end).replace(/^on([A-Z])/, (_, $1) => $1.toLowerCase()).split("_");
|
2279
2393
|
if (!value && !modifiers.length) context.options.onError((0, __vue_compiler_dom.createCompilerError)(__vue_compiler_dom.ErrorCodes.X_V_ON_NO_EXPRESSION, resolveLocation(loc, context)));
|
2280
2394
|
let arg = resolveSimpleExpression(nameString, true, dir.name.loc);
|
2281
2395
|
const exp = resolveExpression(dir.value, context);
|
@@ -2473,13 +2587,10 @@ function createSlotBlock(slotNode, dir, context) {
|
|
2473
2587
|
//#region src/transforms/vSlots.ts
|
2474
2588
|
const transformVSlots = (dir, node, context) => {
|
2475
2589
|
if (!isJSXComponent(node)) return;
|
2476
|
-
if (dir.value?.type === "JSXExpressionContainer") {
|
2477
|
-
|
2478
|
-
|
2479
|
-
|
2480
|
-
}];
|
2481
|
-
if (node.children.length) context.options.onError((0, __vue_compiler_dom.createCompilerError)(__vue_compiler_dom.ErrorCodes.X_V_SLOT_MIXED_SLOT_USAGE, resolveLocation(node.children[0].loc, context)));
|
2482
|
-
}
|
2590
|
+
if (dir.value?.type === "JSXExpressionContainer") context.slots = [{
|
2591
|
+
slotType: IRSlotType.EXPRESSION,
|
2592
|
+
slots: resolveExpression(dir.value.expression, context)
|
2593
|
+
}];
|
2483
2594
|
};
|
2484
2595
|
|
2485
2596
|
//#endregion
|
package/dist/index.d.cts
CHANGED
@@ -353,7 +353,6 @@ declare class CodegenContext {
|
|
353
353
|
helper: (name: string) => string;
|
354
354
|
delegates: Set<string>;
|
355
355
|
identifiers: Record<string, (string | SimpleExpressionNode)[]>;
|
356
|
-
seenInlineHandlerNames: Record<string, number>;
|
357
356
|
block: BlockIRNode;
|
358
357
|
withId<T>(fn: () => T, map: Record<string, string | SimpleExpressionNode | null>): T;
|
359
358
|
enterBlock(block: BlockIRNode): () => BlockIRNode;
|
package/dist/index.d.ts
CHANGED
@@ -353,7 +353,6 @@ declare class CodegenContext {
|
|
353
353
|
helper: (name: string) => string;
|
354
354
|
delegates: Set<string>;
|
355
355
|
identifiers: Record<string, (string | SimpleExpressionNode)[]>;
|
356
|
-
seenInlineHandlerNames: Record<string, number>;
|
357
356
|
block: BlockIRNode;
|
358
357
|
withId<T>(fn: () => T, map: Record<string, string | SimpleExpressionNode | null>): T;
|
359
358
|
enterBlock(block: BlockIRNode): () => BlockIRNode;
|
package/dist/index.js
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
import { parse, parseExpression } from "@babel/parser";
|
2
2
|
import { NOOP, camelize, canSetValueDirectly, capitalize, extend, isArray, isBuiltInDirective, isGloballyAllowed, isHTMLTag, isSVGTag, isString, isVoidTag, makeMap, remove, shouldSetAsAttr, toHandlerKey } from "@vue/shared";
|
3
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 { walkIdentifiers as walkIdentifiers$1 } from "ast-kit";
|
5
|
-
import { isLiteral, jsxClosingFragment, jsxExpressionContainer, jsxFragment, jsxOpeningFragment } from "@babel/types";
|
4
|
+
import { walkAST, walkIdentifiers as walkIdentifiers$1 } from "ast-kit";
|
5
|
+
import { isLiteral, isNodesEquivalent, jsxClosingFragment, jsxExpressionContainer, jsxFragment, jsxOpeningFragment } from "@babel/types";
|
6
6
|
import { SourceMapGenerator } from "source-map-js";
|
7
7
|
|
8
8
|
//#region src/ir/component.ts
|
@@ -733,21 +733,10 @@ function genCreateComponent(operation, context) {
|
|
733
733
|
const { helper } = context;
|
734
734
|
const tag = genTag();
|
735
735
|
const { root, props, slots, once } = operation;
|
736
|
+
const rawProps = genRawProps(props, context);
|
736
737
|
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
738
|
return [
|
749
739
|
NEWLINE,
|
750
|
-
...inlineHandlers,
|
751
740
|
`const n${operation.id} = `,
|
752
741
|
...genCall(operation.dynamic && !operation.dynamic.isStatic ? helper("createDynamicComponent") : operation.asset ? helper("createComponentWithFallback") : helper("createComponent"), tag, rawProps, rawSlots, root ? "true" : false, once && "true"),
|
753
742
|
...genDirectivesForElement(operation.id, context)
|
@@ -763,33 +752,6 @@ function genCreateComponent(operation, context) {
|
|
763
752
|
else return genExpression(extend(createSimpleExpression(operation.tag, false), { ast: null }), context);
|
764
753
|
}
|
765
754
|
}
|
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}`);
|
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
755
|
function genRawProps(props, context) {
|
794
756
|
const staticProps = props[0];
|
795
757
|
if (isArray(staticProps)) {
|
@@ -1045,7 +1007,33 @@ function genFor(oper, context) {
|
|
1045
1007
|
idMap[rawIndex] = `${indexVar}.value`;
|
1046
1008
|
idMap[indexVar] = null;
|
1047
1009
|
}
|
1048
|
-
const
|
1010
|
+
const { selectorPatterns, keyOnlyBindingPatterns } = matchPatterns(render, keyProp, idMap);
|
1011
|
+
const selectorDeclarations = [];
|
1012
|
+
const selectorSetup = [];
|
1013
|
+
for (const [i, { selector }] of selectorPatterns.entries()) {
|
1014
|
+
const selectorName = `_selector${id}_${i}`;
|
1015
|
+
selectorDeclarations.push(`let ${selectorName}`, NEWLINE);
|
1016
|
+
if (i === 0) selectorSetup.push(`({ createSelector }) => {`, INDENT_START);
|
1017
|
+
selectorSetup.push(NEWLINE, `${selectorName} = `, ...genCall(`createSelector`, [`() => `, ...genExpression(selector, context)]));
|
1018
|
+
if (i === selectorPatterns.length - 1) selectorSetup.push(INDENT_END, NEWLINE, "}");
|
1019
|
+
}
|
1020
|
+
const blockFn = context.withId(() => {
|
1021
|
+
const frag = [];
|
1022
|
+
frag.push("(", ...args, ") => {", INDENT_START);
|
1023
|
+
if (selectorPatterns.length || keyOnlyBindingPatterns.length) frag.push(...genBlockContent(render, context, false, () => {
|
1024
|
+
const patternFrag = [];
|
1025
|
+
for (const [i, { effect }] of selectorPatterns.entries()) {
|
1026
|
+
patternFrag.push(NEWLINE, `_selector${id}_${i}(() => {`, INDENT_START);
|
1027
|
+
for (const oper$1 of effect.operations) patternFrag.push(...genOperation(oper$1, context));
|
1028
|
+
patternFrag.push(INDENT_END, NEWLINE, `})`);
|
1029
|
+
}
|
1030
|
+
for (const { effect } of keyOnlyBindingPatterns) for (const oper$1 of effect.operations) patternFrag.push(...genOperation(oper$1, context));
|
1031
|
+
return patternFrag;
|
1032
|
+
}));
|
1033
|
+
else frag.push(...genBlockContent(render, context));
|
1034
|
+
frag.push(INDENT_END, NEWLINE, "}");
|
1035
|
+
return frag;
|
1036
|
+
}, idMap);
|
1049
1037
|
exitScope();
|
1050
1038
|
let flags = 0;
|
1051
1039
|
if (onlyChild) flags |= VaporVForFlags.FAST_REMOVE;
|
@@ -1053,8 +1041,9 @@ function genFor(oper, context) {
|
|
1053
1041
|
if (once) flags |= VaporVForFlags.ONCE;
|
1054
1042
|
return [
|
1055
1043
|
NEWLINE,
|
1044
|
+
...selectorDeclarations,
|
1056
1045
|
`const n${id} = `,
|
1057
|
-
...genCall(helper("createFor"), sourceExpr, blockFn, genCallback(keyProp), flags ? String(flags) : void 0)
|
1046
|
+
...genCall([helper("createFor"), "undefined"], sourceExpr, blockFn, genCallback(keyProp), flags ? String(flags) : void 0, selectorSetup.length ? selectorSetup : void 0)
|
1058
1047
|
];
|
1059
1048
|
function parseValueDestructure() {
|
1060
1049
|
const map = /* @__PURE__ */ new Map();
|
@@ -1128,6 +1117,131 @@ function genFor(oper, context) {
|
|
1128
1117
|
return idMap$1;
|
1129
1118
|
}
|
1130
1119
|
}
|
1120
|
+
function matchPatterns(render, keyProp, idMap) {
|
1121
|
+
const selectorPatterns = [];
|
1122
|
+
const keyOnlyBindingPatterns = [];
|
1123
|
+
render.effect = render.effect.filter((effect) => {
|
1124
|
+
if (keyProp !== void 0) {
|
1125
|
+
const selector = matchSelectorPattern(effect, keyProp.ast, idMap);
|
1126
|
+
if (selector) {
|
1127
|
+
selectorPatterns.push(selector);
|
1128
|
+
return false;
|
1129
|
+
}
|
1130
|
+
const keyOnly = matchKeyOnlyBindingPattern(effect, keyProp.ast);
|
1131
|
+
if (keyOnly) {
|
1132
|
+
keyOnlyBindingPatterns.push(keyOnly);
|
1133
|
+
return false;
|
1134
|
+
}
|
1135
|
+
}
|
1136
|
+
return true;
|
1137
|
+
});
|
1138
|
+
return {
|
1139
|
+
keyOnlyBindingPatterns,
|
1140
|
+
selectorPatterns
|
1141
|
+
};
|
1142
|
+
}
|
1143
|
+
function matchKeyOnlyBindingPattern(effect, keyAst) {
|
1144
|
+
if (effect.expressions.length === 1) {
|
1145
|
+
const ast = effect.expressions[0].ast;
|
1146
|
+
if (typeof ast === "object" && ast !== null && isKeyOnlyBinding(ast, keyAst)) return { effect };
|
1147
|
+
}
|
1148
|
+
}
|
1149
|
+
function matchSelectorPattern(effect, keyAst, idMap) {
|
1150
|
+
if (effect.expressions.length === 1) {
|
1151
|
+
const ast = effect.expressions[0].ast;
|
1152
|
+
const offset = effect.expressions[0].loc.start.offset;
|
1153
|
+
if (typeof ast === "object" && ast) {
|
1154
|
+
const matcheds = [];
|
1155
|
+
walkAST(ast, { enter(node) {
|
1156
|
+
if (typeof node === "object" && node && node.type === "BinaryExpression" && node.operator === "===" && node.left.type !== "PrivateName") {
|
1157
|
+
const { left, right } = node;
|
1158
|
+
for (const [a, b] of [[left, right], [right, left]]) {
|
1159
|
+
const aIsKey = isKeyOnlyBinding(a, keyAst);
|
1160
|
+
const bIsKey = isKeyOnlyBinding(b, keyAst);
|
1161
|
+
const bVars = analyzeVariableScopes(b, idMap);
|
1162
|
+
if (aIsKey && !bIsKey && !bVars.locals.length) matcheds.push([a, b]);
|
1163
|
+
}
|
1164
|
+
}
|
1165
|
+
} });
|
1166
|
+
if (matcheds.length === 1) {
|
1167
|
+
const [key, selector] = matcheds[0];
|
1168
|
+
const content$1 = effect.expressions[0].content;
|
1169
|
+
let hasExtraId = false;
|
1170
|
+
const parentStackMap = /* @__PURE__ */ new Map();
|
1171
|
+
const parentStack = [];
|
1172
|
+
walkIdentifiers(ast, (id) => {
|
1173
|
+
if (id.start !== key.start && id.start !== selector.start) hasExtraId = true;
|
1174
|
+
parentStackMap.set(id, parentStack.slice());
|
1175
|
+
}, false, parentStack);
|
1176
|
+
if (!hasExtraId) {
|
1177
|
+
const name = content$1.slice(selector.start - offset, selector.end - offset);
|
1178
|
+
return {
|
1179
|
+
effect,
|
1180
|
+
selector: {
|
1181
|
+
content: name,
|
1182
|
+
ast: extend({}, selector, {
|
1183
|
+
start: 1,
|
1184
|
+
end: name.length + 1
|
1185
|
+
}),
|
1186
|
+
loc: selector.loc,
|
1187
|
+
isStatic: false
|
1188
|
+
}
|
1189
|
+
};
|
1190
|
+
}
|
1191
|
+
}
|
1192
|
+
}
|
1193
|
+
const content = effect.expressions[0].content;
|
1194
|
+
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)) {
|
1195
|
+
const left = ast.test.left;
|
1196
|
+
const right = ast.test.right;
|
1197
|
+
for (const [a, b] of [[left, right], [right, left]]) {
|
1198
|
+
const aIsKey = isKeyOnlyBinding(a, keyAst);
|
1199
|
+
const bIsKey = isKeyOnlyBinding(b, keyAst);
|
1200
|
+
const bVars = analyzeVariableScopes(b, idMap);
|
1201
|
+
if (aIsKey && !bIsKey && !bVars.locals.length) return {
|
1202
|
+
effect,
|
1203
|
+
selector: {
|
1204
|
+
content: content.slice(b.start - offset, b.end - offset),
|
1205
|
+
ast: b,
|
1206
|
+
loc: b.loc,
|
1207
|
+
isStatic: false
|
1208
|
+
}
|
1209
|
+
};
|
1210
|
+
}
|
1211
|
+
}
|
1212
|
+
}
|
1213
|
+
}
|
1214
|
+
function analyzeVariableScopes(ast, idMap) {
|
1215
|
+
const globals = [];
|
1216
|
+
const locals = [];
|
1217
|
+
const ids = [];
|
1218
|
+
const parentStackMap = /* @__PURE__ */ new Map();
|
1219
|
+
const parentStack = [];
|
1220
|
+
walkIdentifiers(ast, (id) => {
|
1221
|
+
ids.push(id);
|
1222
|
+
parentStackMap.set(id, parentStack.slice());
|
1223
|
+
}, false, parentStack);
|
1224
|
+
for (const id of ids) {
|
1225
|
+
if (isGloballyAllowed(id.name)) continue;
|
1226
|
+
if (idMap[id.name]) locals.push(id.name);
|
1227
|
+
else globals.push(id.name);
|
1228
|
+
}
|
1229
|
+
return {
|
1230
|
+
globals,
|
1231
|
+
locals
|
1232
|
+
};
|
1233
|
+
}
|
1234
|
+
function isKeyOnlyBinding(expr, keyAst) {
|
1235
|
+
let only = true;
|
1236
|
+
walkAST(expr, { enter(node) {
|
1237
|
+
if (isNodesEquivalent(node, keyAst)) {
|
1238
|
+
this.skip();
|
1239
|
+
return;
|
1240
|
+
}
|
1241
|
+
if (node.type === "Identifier") only = false;
|
1242
|
+
} });
|
1243
|
+
return only;
|
1244
|
+
}
|
1131
1245
|
|
1132
1246
|
//#endregion
|
1133
1247
|
//#region src/generators/html.ts
|
@@ -1244,7 +1358,7 @@ function genOperation(oper, context) {
|
|
1244
1358
|
}
|
1245
1359
|
}
|
1246
1360
|
}
|
1247
|
-
function genEffects(effects, context) {
|
1361
|
+
function genEffects(effects, context, genExtraFrag) {
|
1248
1362
|
const { helper } = context;
|
1249
1363
|
const [frag, push, unshift] = buildCodeFragment();
|
1250
1364
|
let operationsCount = 0;
|
@@ -1264,6 +1378,7 @@ function genEffects(effects, context) {
|
|
1264
1378
|
unshift(NEWLINE, `${helper("renderEffect")}(() => `);
|
1265
1379
|
push(`)`);
|
1266
1380
|
}
|
1381
|
+
if (genExtraFrag) push(...context.withId(genExtraFrag, {}));
|
1267
1382
|
return frag;
|
1268
1383
|
}
|
1269
1384
|
function genEffect({ operations }, context) {
|
@@ -1330,19 +1445,19 @@ function genChildren(dynamic, context, pushBlock, from = `n${dynamic.id}`) {
|
|
1330
1445
|
|
1331
1446
|
//#endregion
|
1332
1447
|
//#region src/generators/block.ts
|
1333
|
-
function genBlock(oper, context, args = [], root
|
1448
|
+
function genBlock(oper, context, args = [], root) {
|
1334
1449
|
return [
|
1335
1450
|
"(",
|
1336
1451
|
...args,
|
1337
1452
|
") => {",
|
1338
1453
|
INDENT_START,
|
1339
|
-
...genBlockContent(oper, context, root
|
1454
|
+
...genBlockContent(oper, context, root),
|
1340
1455
|
INDENT_END,
|
1341
1456
|
NEWLINE,
|
1342
1457
|
"}"
|
1343
1458
|
];
|
1344
1459
|
}
|
1345
|
-
function genBlockContent(block, context, root,
|
1460
|
+
function genBlockContent(block, context, root, genEffectsExtraFrag) {
|
1346
1461
|
const [frag, push] = buildCodeFragment();
|
1347
1462
|
const { dynamic, effect, operation, returns } = block;
|
1348
1463
|
const resetBlock = context.enterBlock(block);
|
@@ -1358,11 +1473,11 @@ function genBlockContent(block, context, root, customReturns) {
|
|
1358
1473
|
for (const child of dynamic.children) push(...genSelf(child, context));
|
1359
1474
|
for (const child of dynamic.children) push(...genChildren(child, context, push, `n${child.id}`));
|
1360
1475
|
push(...genOperations(operation, context));
|
1361
|
-
push(...genEffects(effect, context));
|
1476
|
+
push(...genEffects(effect, context, genEffectsExtraFrag));
|
1362
1477
|
push(NEWLINE, `return `);
|
1363
1478
|
const returnNodes = returns.map((n) => `n${n}`);
|
1364
1479
|
const returnsCode = returnNodes.length > 1 ? genMulti(DELIMITERS_ARRAY, ...returnNodes) : [returnNodes[0] || "null"];
|
1365
|
-
push(...
|
1480
|
+
push(...returnsCode);
|
1366
1481
|
resetBlock();
|
1367
1482
|
return frag;
|
1368
1483
|
function genResolveAssets(kind, helper) {
|
@@ -1381,7 +1496,6 @@ var CodegenContext = class {
|
|
1381
1496
|
};
|
1382
1497
|
delegates = /* @__PURE__ */ new Set();
|
1383
1498
|
identifiers = Object.create(null);
|
1384
|
-
seenInlineHandlerNames = Object.create(null);
|
1385
1499
|
block;
|
1386
1500
|
withId(fn, map) {
|
1387
1501
|
const { identifiers } = this;
|
@@ -2250,9 +2364,9 @@ function hasDynamicKeyVBind(node) {
|
|
2250
2364
|
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");
|
2251
2365
|
const transformVOn = (dir, node, context) => {
|
2252
2366
|
const { name, loc, value } = dir;
|
2253
|
-
if (name
|
2367
|
+
if (!name) return;
|
2254
2368
|
const isComponent = isJSXComponent(node);
|
2255
|
-
const [nameString, ...modifiers] = name.name.replace(/^on([A-Z])/, (_, $1) => $1.toLowerCase()).split("_");
|
2369
|
+
const [nameString, ...modifiers] = context.ir.source.slice(name.start, name.end).replace(/^on([A-Z])/, (_, $1) => $1.toLowerCase()).split("_");
|
2256
2370
|
if (!value && !modifiers.length) context.options.onError(createCompilerError(ErrorCodes.X_V_ON_NO_EXPRESSION, resolveLocation(loc, context)));
|
2257
2371
|
let arg = resolveSimpleExpression(nameString, true, dir.name.loc);
|
2258
2372
|
const exp = resolveExpression(dir.value, context);
|
@@ -2450,13 +2564,10 @@ function createSlotBlock(slotNode, dir, context) {
|
|
2450
2564
|
//#region src/transforms/vSlots.ts
|
2451
2565
|
const transformVSlots = (dir, node, context) => {
|
2452
2566
|
if (!isJSXComponent(node)) return;
|
2453
|
-
if (dir.value?.type === "JSXExpressionContainer") {
|
2454
|
-
|
2455
|
-
|
2456
|
-
|
2457
|
-
}];
|
2458
|
-
if (node.children.length) context.options.onError(createCompilerError(ErrorCodes.X_V_SLOT_MIXED_SLOT_USAGE, resolveLocation(node.children[0].loc, context)));
|
2459
|
-
}
|
2567
|
+
if (dir.value?.type === "JSXExpressionContainer") context.slots = [{
|
2568
|
+
slotType: IRSlotType.EXPRESSION,
|
2569
|
+
slots: resolveExpression(dir.value.expression, context)
|
2570
|
+
}];
|
2460
2571
|
};
|
2461
2572
|
|
2462
2573
|
//#endregion
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@vue-jsx-vapor/compiler",
|
3
|
-
"version": "2.5.
|
3
|
+
"version": "2.5.2",
|
4
4
|
"description": "Vue JSX Vapor Compiler",
|
5
5
|
"type": "module",
|
6
6
|
"keywords": [
|
@@ -36,8 +36,8 @@
|
|
36
36
|
"dependencies": {
|
37
37
|
"@babel/parser": "^7.28.0",
|
38
38
|
"@babel/types": "^7.28.0",
|
39
|
-
"@vue/compiler-dom": "https://pkg.pr.new/@vue/compiler-dom@
|
40
|
-
"@vue/shared": "https://pkg.pr.new/@vue/shared@
|
39
|
+
"@vue/compiler-dom": "https://pkg.pr.new/@vue/compiler-dom@5771104",
|
40
|
+
"@vue/shared": "https://pkg.pr.new/@vue/shared@5771104",
|
41
41
|
"ast-kit": "^2.1.1",
|
42
42
|
"source-map-js": "^1.2.1"
|
43
43
|
},
|