@fluixi/compiler 1.0.0-alpha.93 → 1.0.0-alpha.95
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/LICENSE +1 -1
- package/dist/analyze/intrinsics.cjs +13 -1
- package/dist/analyze/intrinsics.d.cts +14 -0
- package/dist/analyze/intrinsics.d.ts +14 -0
- package/dist/analyze/intrinsics.d.ts.map +1 -1
- package/dist/analyze/intrinsics.js +17 -0
- package/dist/analyze/intrinsics.mjs +13 -1
- package/dist/analyze/static-graph.cjs +1 -1
- package/dist/analyze/static-graph.mjs +1 -1
- package/dist/{babel-RJHJQVEM.mjs → babel-V33QLJBF.mjs} +4 -4
- package/dist/{chunk-56QSOVVL.mjs → chunk-62F2LLBM.mjs} +1 -1
- package/dist/{chunk-R7PPFBCL.mjs → chunk-7GNSGUHK.mjs} +4 -83
- package/dist/{chunk-U7HCFLZ2.mjs → chunk-B64LVPTU.mjs} +356 -24
- package/dist/{chunk-OD53TMER.mjs → chunk-C3AK5PBV.mjs} +13 -1
- package/dist/{chunk-TJIH7TLX.mjs → chunk-GLFUPZ27.mjs} +1 -1
- package/dist/chunk-HUABRVWB.mjs +92 -0
- package/dist/chunk-XCWP7WJG.mjs +584 -0
- package/dist/codegen/backends/imperative.cjs +1 -1
- package/dist/codegen/backends/imperative.d.ts.map +1 -1
- package/dist/codegen/backends/imperative.js +2 -1
- package/dist/codegen/backends/imperative.mjs +1 -1
- package/dist/frontend/babel/build-ir-lit.cjs +352 -22
- package/dist/frontend/babel/build-ir-lit.mjs +352 -22
- package/dist/frontend/babel/build-ir.cjs +352 -22
- package/dist/frontend/babel/build-ir.mjs +352 -22
- package/dist/frontend/babel/index.cjs +353 -23
- package/dist/frontend/babel/index.mjs +353 -23
- package/dist/frontend/babel/lower-template.cjs +352 -22
- package/dist/frontend/babel/lower-template.mjs +352 -22
- package/dist/frontend/babel/plugin.cjs +352 -22
- package/dist/frontend/babel/plugin.mjs +352 -22
- package/dist/index.cjs +321 -22
- package/dist/index.mjs +333 -22
- package/dist/integrations.cjs +1240 -56
- package/dist/integrations.d.ts.map +1 -1
- package/dist/integrations.js +62 -9
- package/dist/integrations.mjs +257 -26
- package/dist/lower/compile-template.cjs +315 -21
- package/dist/lower/compile-template.d.cts +13 -0
- package/dist/lower/compile-template.d.ts +13 -0
- package/dist/lower/compile-template.d.ts.map +1 -1
- package/dist/lower/compile-template.js +3 -0
- package/dist/lower/compile-template.mjs +327 -21
- package/dist/lower/entities.cjs +288 -0
- package/dist/lower/entities.d.cts +1 -0
- package/dist/lower/entities.d.ts +2 -0
- package/dist/lower/entities.d.ts.map +1 -0
- package/dist/lower/entities.js +54 -0
- package/dist/lower/entities.mjs +267 -0
- package/dist/lower/jsx.cjs +104 -47
- package/dist/lower/jsx.d.cts +8 -0
- package/dist/lower/jsx.d.ts +8 -0
- package/dist/lower/jsx.d.ts.map +1 -1
- package/dist/lower/jsx.js +92 -2
- package/dist/lower/jsx.mjs +104 -47
- package/dist/lower/template.cjs +293 -20
- package/dist/lower/template.d.ts.map +1 -1
- package/dist/lower/template.js +35 -19
- package/dist/lower/template.mjs +293 -20
- package/dist/resolve/builtins.cjs +1 -1
- package/dist/resolve/builtins.mjs +1 -1
- package/dist/resolve/component-globals.cjs +6 -1
- package/dist/resolve/component-globals.js +2 -2
- package/dist/resolve/component-globals.mjs +6 -1
- package/dist/resolve/write-globals.cjs +6 -1
- package/dist/resolve/write-globals.mjs +6 -1
- package/dist/{server-fns-ZFRDIQ2X.mjs → server-fns-N3SDJXA7.mjs} +5 -4
- package/dist/{server-functions-CTDXX67X.mjs → server-functions-LVS66Q4R.mjs} +3 -3
- package/dist/transform/index.cjs +973 -33
- package/dist/transform/index.mjs +991 -47
- package/dist/transform/props.mjs +19 -14
- package/dist/transform/server-fns.mjs +19 -14
- package/dist/transform/styles.cjs +606 -0
- package/dist/transform/styles.d.cts +237 -0
- package/dist/transform/styles.d.ts +238 -0
- package/dist/transform/styles.d.ts.map +1 -0
- package/dist/transform/styles.js +743 -0
- package/dist/transform/styles.mjs +671 -0
- package/dist/transform/templates.cjs +972 -32
- package/dist/transform/templates.d.cts +13 -0
- package/dist/transform/templates.d.ts +13 -0
- package/dist/transform/templates.d.ts.map +1 -1
- package/dist/transform/templates.js +49 -12
- package/dist/transform/templates.mjs +990 -46
- package/dist/{transform-QWWQDCXE.mjs → transform-P4AETYV4.mjs} +49 -16
- package/dist/tsconfig.lib.tsbuildinfo +1 -1
- package/dist/vite-styles.cjs +223 -0
- package/dist/vite-styles.d.cts +68 -0
- package/dist/vite-styles.d.ts +69 -0
- package/dist/vite-styles.d.ts.map +1 -0
- package/dist/vite-styles.js +241 -0
- package/dist/vite-styles.mjs +214 -0
- package/package.json +5 -4
package/dist/transform/index.mjs
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
/*! @fluixi/compiler v1.0.0-alpha.
|
|
1
|
+
/*! @fluixi/compiler v1.0.0-alpha.95 | (c) 2026 Ibrahima Touré and Fluixi contributors | MIT */
|
|
2
2
|
|
|
3
3
|
// src/transform/templates.ts
|
|
4
4
|
import { parse as parse2 } from "@babel/parser";
|
|
5
5
|
|
|
6
|
-
// ../../node_modules/.pnpm/@jridgewell+sourcemap-codec@1.
|
|
6
|
+
// ../../node_modules/.pnpm/@jridgewell+sourcemap-codec@1.6.0/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.mjs
|
|
7
7
|
var comma = ",".charCodeAt(0);
|
|
8
8
|
var semicolon = ";".charCodeAt(0);
|
|
9
9
|
var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
@@ -14,16 +14,16 @@ for (let i = 0; i < chars.length; i++) {
|
|
|
14
14
|
intToChar[i] = c;
|
|
15
15
|
charToInt[c] = i;
|
|
16
16
|
}
|
|
17
|
-
function encodeInteger(builder, num
|
|
18
|
-
let delta = num - relative;
|
|
19
|
-
delta = delta < 0 ? -delta << 1 | 1 : delta << 1;
|
|
17
|
+
function encodeInteger(builder, num) {
|
|
20
18
|
do {
|
|
21
|
-
let clamped =
|
|
22
|
-
|
|
23
|
-
if (
|
|
19
|
+
let clamped = num & 31;
|
|
20
|
+
num >>>= 5;
|
|
21
|
+
if (num > 0) clamped |= 32;
|
|
24
22
|
builder.write(intToChar[clamped]);
|
|
25
|
-
} while (
|
|
26
|
-
|
|
23
|
+
} while (num > 0);
|
|
24
|
+
}
|
|
25
|
+
function encodeSign(num) {
|
|
26
|
+
return num < 0 ? -num << 1 | 1 : num << 1;
|
|
27
27
|
}
|
|
28
28
|
var bufLength = 1024 * 16;
|
|
29
29
|
var td = typeof TextDecoder !== "undefined" ? /* @__PURE__ */ new TextDecoder() : typeof Buffer !== "undefined" ? {
|
|
@@ -73,13 +73,18 @@ function encode(decoded) {
|
|
|
73
73
|
for (let j = 0; j < line.length; j++) {
|
|
74
74
|
const segment = line[j];
|
|
75
75
|
if (j > 0) writer.write(comma);
|
|
76
|
-
|
|
76
|
+
encodeInteger(writer, encodeSign(segment[0] - genColumn));
|
|
77
|
+
genColumn = segment[0];
|
|
77
78
|
if (segment.length === 1) continue;
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
79
|
+
encodeInteger(writer, encodeSign(segment[1] - sourcesIndex));
|
|
80
|
+
encodeInteger(writer, encodeSign(segment[2] - sourceLine));
|
|
81
|
+
encodeInteger(writer, encodeSign(segment[3] - sourceColumn));
|
|
82
|
+
sourcesIndex = segment[1];
|
|
83
|
+
sourceLine = segment[2];
|
|
84
|
+
sourceColumn = segment[3];
|
|
81
85
|
if (segment.length === 4) continue;
|
|
82
|
-
|
|
86
|
+
encodeInteger(writer, encodeSign(segment[4] - namesIndex));
|
|
87
|
+
namesIndex = segment[4];
|
|
83
88
|
}
|
|
84
89
|
}
|
|
85
90
|
return writer.flush();
|
|
@@ -1076,6 +1081,579 @@ var MagicString = class _MagicString {
|
|
|
1076
1081
|
}
|
|
1077
1082
|
};
|
|
1078
1083
|
|
|
1084
|
+
// src/transform/styles.ts
|
|
1085
|
+
var SCOPE_ATTR = "data-fx-s";
|
|
1086
|
+
var FUNCTIONS = /* @__PURE__ */ new Set(["FunctionDeclaration", "FunctionExpression", "ArrowFunctionExpression", "ObjectMethod", "ClassMethod"]);
|
|
1087
|
+
function collectStyles(program, sourceName, options, tags = { html: /* @__PURE__ */ new Map([["html", "html"]]) }, module) {
|
|
1088
|
+
const plan = {
|
|
1089
|
+
scopes: [],
|
|
1090
|
+
templateOwners: /* @__PURE__ */ new Map(),
|
|
1091
|
+
drop: /* @__PURE__ */ new Set(),
|
|
1092
|
+
styles: [],
|
|
1093
|
+
diagnostics: [],
|
|
1094
|
+
edits: [],
|
|
1095
|
+
literals: [],
|
|
1096
|
+
references: [],
|
|
1097
|
+
shadowClasses: /* @__PURE__ */ new Map()
|
|
1098
|
+
};
|
|
1099
|
+
if (!options) return plan;
|
|
1100
|
+
const literalsOf = findLiterals(program, options.cssModules ?? ["@fluixi/core", "@fluixi/dom"], plan, tags.css ?? []);
|
|
1101
|
+
plan.names = literalsOf;
|
|
1102
|
+
const classOf = /* @__PURE__ */ new Map();
|
|
1103
|
+
const shadowOf = (owner) => {
|
|
1104
|
+
const cls = classOf.get(owner);
|
|
1105
|
+
return cls ? plan.shadowClasses.get(cls) : void 0;
|
|
1106
|
+
};
|
|
1107
|
+
const resolved = /* @__PURE__ */ new Map();
|
|
1108
|
+
const piecesToNodes = (quasis, expressions, at, stack) => {
|
|
1109
|
+
const out = [];
|
|
1110
|
+
for (let i = 0; i < quasis.length; i++) {
|
|
1111
|
+
const text = quasis[i].value.cooked ?? quasis[i].value.raw;
|
|
1112
|
+
if (text.trim()) {
|
|
1113
|
+
try {
|
|
1114
|
+
const start = quasis[i].loc?.start;
|
|
1115
|
+
out.push(...options.process(text, sourceName).map((n2) => start ? shiftLoc(n2, sourceName, start) : n2));
|
|
1116
|
+
} catch (error) {
|
|
1117
|
+
plan.diagnostics.push({ ...at, message: `CSS could not be processed: ${error.message}` });
|
|
1118
|
+
return null;
|
|
1119
|
+
}
|
|
1120
|
+
}
|
|
1121
|
+
const expr = expressions[i];
|
|
1122
|
+
if (!expr) continue;
|
|
1123
|
+
const value = expr.type === "Identifier" ? resolveLiteral(expr.name, at, stack) : void 0;
|
|
1124
|
+
if (value === void 0) {
|
|
1125
|
+
plan.diagnostics.push({
|
|
1126
|
+
...at,
|
|
1127
|
+
message: "Only css`` values can be interpolated into styles, and only by name: ${base}. Dynamic values go through custom properties (style:--x={...} and var(--x))."
|
|
1128
|
+
});
|
|
1129
|
+
return null;
|
|
1130
|
+
}
|
|
1131
|
+
if (value === null) return null;
|
|
1132
|
+
out.push(...value);
|
|
1133
|
+
}
|
|
1134
|
+
return out;
|
|
1135
|
+
};
|
|
1136
|
+
function resolveLiteral(name, at, stack) {
|
|
1137
|
+
const imported = literalsOf.imports.get(name);
|
|
1138
|
+
if (imported) {
|
|
1139
|
+
const nodes = options?.imported?.get(`${imported.source}#${imported.name}`);
|
|
1140
|
+
if (nodes) return nodes.map((n2) => keepLocIn(n2, options?.importedModules));
|
|
1141
|
+
plan.references.push({ name: imported.name, source: imported.source, ...at });
|
|
1142
|
+
plan.diagnostics.push({
|
|
1143
|
+
...at,
|
|
1144
|
+
message: options?.imported ? `${name} from ${imported.source} is not a css\`\` value the build could find.` : `${name} comes from ${imported.source}: style values from another module are resolved by the build.`
|
|
1145
|
+
});
|
|
1146
|
+
return null;
|
|
1147
|
+
}
|
|
1148
|
+
const literal = literalsOf.literals.get(name);
|
|
1149
|
+
if (!literal) return void 0;
|
|
1150
|
+
if (stack.includes(name)) {
|
|
1151
|
+
plan.diagnostics.push({ ...at, message: `css\`\` values include each other: ${[...stack, name].join(" → ")}.` });
|
|
1152
|
+
return null;
|
|
1153
|
+
}
|
|
1154
|
+
if (!resolved.has(name)) {
|
|
1155
|
+
resolved.set(name, piecesToNodes(literal.quasi.quasis, literal.quasi.expressions, at, [...stack, name]));
|
|
1156
|
+
}
|
|
1157
|
+
return resolved.get(name);
|
|
1158
|
+
}
|
|
1159
|
+
for (const [name, literal] of literalsOf.literals) {
|
|
1160
|
+
const at = { line: literal.loc?.start.line ?? 0, column: literal.loc?.start.column ?? 0 };
|
|
1161
|
+
const nodes = resolveLiteral(name, at, []);
|
|
1162
|
+
const id = hash(`${sourceName}:css:${name}`);
|
|
1163
|
+
plan.edits.push({ start: literal.start, end: literal.end, code: `({ $fxStyle: ${JSON.stringify(id)} })` });
|
|
1164
|
+
if (nodes) plan.literals.push({ id, name, css: printStyle(nodes, options.minify), nodes });
|
|
1165
|
+
}
|
|
1166
|
+
const scopeOf = /* @__PURE__ */ new Map();
|
|
1167
|
+
const names = /* @__PURE__ */ new Map();
|
|
1168
|
+
const named = /* @__PURE__ */ new Map();
|
|
1169
|
+
const visit = (node, owners) => {
|
|
1170
|
+
if (!node || typeof node !== "object") return;
|
|
1171
|
+
if (node.type === "VariableDeclarator" && node.id.type === "Identifier" && node.init && FUNCTIONS.has(node.init.type)) {
|
|
1172
|
+
named.set(node.init, node.id.name);
|
|
1173
|
+
}
|
|
1174
|
+
if ((node.type === "ClassDeclaration" || node.type === "ClassExpression") && node.id) {
|
|
1175
|
+
for (const member of node.body.body) if (member.type === "ClassMethod") named.set(member, node.id.name);
|
|
1176
|
+
}
|
|
1177
|
+
if (node.type === "ClassDeclaration" || node.type === "ClassExpression") {
|
|
1178
|
+
for (const member of node.body.body) if (member.type === "ClassMethod") classOf.set(member, node);
|
|
1179
|
+
const shadow = staticMember(node, "shadow");
|
|
1180
|
+
if (shadow?.value && !(shadow.value.type === "BooleanLiteral" && shadow.value.value === false)) {
|
|
1181
|
+
plan.shadowClasses.set(node, { node, styles: staticMember(node, "styles"), indexes: [] });
|
|
1182
|
+
}
|
|
1183
|
+
}
|
|
1184
|
+
if (node.type === "TaggedTemplateExpression" && node.tag.type === "Identifier" && tags.html.get(node.tag.name) === "html") {
|
|
1185
|
+
const text = node.quasi.quasis.map((q) => q.value.raw).join("");
|
|
1186
|
+
if (/<style[\s>]/.test(text)) {
|
|
1187
|
+
const at = { line: node.loc?.start.line ?? 0, column: node.loc?.start.column ?? 0 };
|
|
1188
|
+
const owner = owners[0];
|
|
1189
|
+
if (!owner) plan.diagnostics.push({ ...at, message: "<style> has to be written inside a component." });
|
|
1190
|
+
else {
|
|
1191
|
+
const id = idFor(owner);
|
|
1192
|
+
const shadow = shadowOf(owner);
|
|
1193
|
+
plan.templateOwners.set(node.start, { id, component: functionName(owner, named) });
|
|
1194
|
+
for (const block of templateBlocks(node.quasi)) compileBlock(block, block.scoped, owner, at);
|
|
1195
|
+
}
|
|
1196
|
+
}
|
|
1197
|
+
}
|
|
1198
|
+
const inner = FUNCTIONS.has(node.type) ? [...owners, node] : owners;
|
|
1199
|
+
if (node.type === "JSXElement" && isStyle(node)) {
|
|
1200
|
+
handle(node, owners);
|
|
1201
|
+
return;
|
|
1202
|
+
}
|
|
1203
|
+
for (const key of Object.keys(node)) {
|
|
1204
|
+
if (key === "loc" || key === "leadingComments" || key === "trailingComments" || key === "innerComments") continue;
|
|
1205
|
+
const value = node[key];
|
|
1206
|
+
if (Array.isArray(value)) for (const v of value) visit(v, inner);
|
|
1207
|
+
else if (value && typeof value === "object" && "type" in value) visit(value, inner);
|
|
1208
|
+
}
|
|
1209
|
+
};
|
|
1210
|
+
const handle = (node, owners) => {
|
|
1211
|
+
const at = { line: node.loc?.start.line ?? 0, column: node.loc?.start.column ?? 0 };
|
|
1212
|
+
const pieces = blockPieces(node);
|
|
1213
|
+
if (pieces === null) {
|
|
1214
|
+
plan.diagnostics.push({
|
|
1215
|
+
...at,
|
|
1216
|
+
message: "<style> needs its CSS as one template literal, <style>{`...`}</style>: JSX reads a bare `{` as an expression."
|
|
1217
|
+
});
|
|
1218
|
+
return;
|
|
1219
|
+
}
|
|
1220
|
+
const owner = owners[0];
|
|
1221
|
+
if (!owner) {
|
|
1222
|
+
plan.diagnostics.push({ ...at, message: "<style> has to be written inside a component." });
|
|
1223
|
+
return;
|
|
1224
|
+
}
|
|
1225
|
+
compileBlock(pieces, isScoped(node), owner, at);
|
|
1226
|
+
plan.drop.add(node.start);
|
|
1227
|
+
};
|
|
1228
|
+
const compileBlock = (pieces, scoped, owner, at) => {
|
|
1229
|
+
const component = functionName(owner, named);
|
|
1230
|
+
const id = idFor(owner);
|
|
1231
|
+
const processed = piecesToNodes(pieces.quasis, pieces.expressions, at, []);
|
|
1232
|
+
if (!processed) return;
|
|
1233
|
+
let nodes = processed;
|
|
1234
|
+
const shadow = shadowOf(owner);
|
|
1235
|
+
if (scoped && !shadow) {
|
|
1236
|
+
if (!plan.scopes.some((s) => s.value === id)) plan.scopes.push({ start: owner.start, end: owner.end, value: id });
|
|
1237
|
+
nodes = scopeNodes(nodes, id, (message) => plan.diagnostics.push({ ...at, message }));
|
|
1238
|
+
}
|
|
1239
|
+
const printed = module ? printStyleWithMap(nodes, options.minify, sourceName, module, options.importedModules) : { css: printStyle(nodes, options.minify) };
|
|
1240
|
+
plan.styles.push({ id, scoped: scoped && !shadow, component, ...printed, ...shadow ? { shadow: true } : {}, ...at });
|
|
1241
|
+
if (shadow) shadow.indexes.push(plan.styles.length - 1);
|
|
1242
|
+
};
|
|
1243
|
+
function idFor(owner) {
|
|
1244
|
+
let id = scopeOf.get(owner);
|
|
1245
|
+
if (!id) {
|
|
1246
|
+
const component = functionName(owner, named);
|
|
1247
|
+
const seen = names.get(component) ?? 0;
|
|
1248
|
+
names.set(component, seen + 1);
|
|
1249
|
+
id = hash(`${sourceName}:${component}${seen ? ":" + seen : ""}`);
|
|
1250
|
+
scopeOf.set(owner, id);
|
|
1251
|
+
}
|
|
1252
|
+
return id;
|
|
1253
|
+
}
|
|
1254
|
+
visit(program, []);
|
|
1255
|
+
return plan;
|
|
1256
|
+
}
|
|
1257
|
+
function applyTemplateStyles(ir, t) {
|
|
1258
|
+
const walk8 = (node) => {
|
|
1259
|
+
const children = node.children;
|
|
1260
|
+
if (children) {
|
|
1261
|
+
for (let i = children.length - 1; i >= 0; i--) {
|
|
1262
|
+
const child = children[i];
|
|
1263
|
+
if (child.kind === "element" && child.tag === "style" && t.owner) children.splice(i, 1);
|
|
1264
|
+
else walk8(child);
|
|
1265
|
+
}
|
|
1266
|
+
}
|
|
1267
|
+
if (t.scope && node.kind === "element" && node.tag !== "style" && node.props && !node.props.some((p) => p.name === SCOPE_ATTR)) {
|
|
1268
|
+
node.props.unshift({ name: SCOPE_ATTR, kind: "attr", literal: t.scope });
|
|
1269
|
+
}
|
|
1270
|
+
};
|
|
1271
|
+
walk8(ir);
|
|
1272
|
+
}
|
|
1273
|
+
function staticMember(cls, name) {
|
|
1274
|
+
return cls.body.body.find(
|
|
1275
|
+
(m) => m.type === "ClassProperty" && m.static && (m.key.type === "Identifier" && m.key.name === name || m.key.type === "StringLiteral" && m.key.value === name)
|
|
1276
|
+
);
|
|
1277
|
+
}
|
|
1278
|
+
var styleIds = {
|
|
1279
|
+
block: (owner, index) => `${owner}.fx-${index}.css`,
|
|
1280
|
+
inline: (owner, index) => `${owner}.fx-${index}.css?inline`,
|
|
1281
|
+
literal: (owner, name) => `${owner}.fx-literal-${name}.css?inline`
|
|
1282
|
+
};
|
|
1283
|
+
function finishShadowStyles(plan, code, moduleId) {
|
|
1284
|
+
const edits = [];
|
|
1285
|
+
const imports = [];
|
|
1286
|
+
let next = 0;
|
|
1287
|
+
const importOf = (specifier) => {
|
|
1288
|
+
const local = `__fxShadow${next++}`;
|
|
1289
|
+
imports.push(`import ${local} from ${JSON.stringify(specifier)};
|
|
1290
|
+
`);
|
|
1291
|
+
return local;
|
|
1292
|
+
};
|
|
1293
|
+
for (const shadow of plan.shadowClasses.values()) {
|
|
1294
|
+
const blocks = shadow.indexes.map((i) => importOf(styleIds.inline(moduleId, i)));
|
|
1295
|
+
let value;
|
|
1296
|
+
const prop = shadow.styles;
|
|
1297
|
+
if (prop?.value) {
|
|
1298
|
+
const start = prop.value.start;
|
|
1299
|
+
let text = code.slice(start, prop.value.end);
|
|
1300
|
+
const replacements = [];
|
|
1301
|
+
walkIdentifiers(prop.value, (id) => {
|
|
1302
|
+
const local = plan.names?.literals.has(id.name) ? importOf(styleIds.literal(moduleId, id.name)) : plan.names?.imports.has(id.name) && !/\.css(\?|$)/.test(plan.names.imports.get(id.name).source) ? importOf(styleIds.literal(plan.names.imports.get(id.name).source, plan.names.imports.get(id.name).name)) : void 0;
|
|
1303
|
+
if (local) replacements.push({ at: id.start - start, length: id.name.length, with: local });
|
|
1304
|
+
});
|
|
1305
|
+
for (const r of replacements.sort((a, b) => b.at - a.at)) text = text.slice(0, r.at) + r.with + text.slice(r.at + r.length);
|
|
1306
|
+
value = text;
|
|
1307
|
+
}
|
|
1308
|
+
if (!blocks.length && value === void 0) continue;
|
|
1309
|
+
if (prop?.value) {
|
|
1310
|
+
const merged = blocks.length ? `[${value}, ${blocks.join(", ")}]` : value;
|
|
1311
|
+
edits.push({ start: prop.value.start, end: prop.value.end, code: merged });
|
|
1312
|
+
} else if (blocks.length) {
|
|
1313
|
+
const open = shadow.node.body.start + 1;
|
|
1314
|
+
edits.push({ start: open, end: open, code: ` static styles = [${blocks.join(", ")}];` });
|
|
1315
|
+
}
|
|
1316
|
+
}
|
|
1317
|
+
if (imports.length) edits.push({ start: 0, end: 0, code: imports.join("") });
|
|
1318
|
+
return edits;
|
|
1319
|
+
}
|
|
1320
|
+
function walkIdentifiers(node, visit) {
|
|
1321
|
+
if (!node || typeof node !== "object") return;
|
|
1322
|
+
if (node.type === "Identifier") return visit(node);
|
|
1323
|
+
if (node.type === "MemberExpression") return walkIdentifiers(node.object, visit);
|
|
1324
|
+
if (node.type === "ObjectProperty") return walkIdentifiers(node.value, visit);
|
|
1325
|
+
for (const key of Object.keys(node)) {
|
|
1326
|
+
if (key === "loc") continue;
|
|
1327
|
+
const value = node[key];
|
|
1328
|
+
if (Array.isArray(value)) for (const v of value) walkIdentifiers(v, visit);
|
|
1329
|
+
else if (value && typeof value === "object" && "type" in value) walkIdentifiers(value, visit);
|
|
1330
|
+
}
|
|
1331
|
+
}
|
|
1332
|
+
function isStyle(node) {
|
|
1333
|
+
const name = node.openingElement.name;
|
|
1334
|
+
return name.type === "JSXIdentifier" && name.name === "style";
|
|
1335
|
+
}
|
|
1336
|
+
function isScoped(node) {
|
|
1337
|
+
return node.openingElement.attributes.some((a) => a.type === "JSXAttribute" && a.name.type === "JSXIdentifier" && a.name.name === "scoped");
|
|
1338
|
+
}
|
|
1339
|
+
function templateBlocks(quasi) {
|
|
1340
|
+
const blocks = [];
|
|
1341
|
+
let open = null;
|
|
1342
|
+
quasi.quasis.forEach((q, i) => {
|
|
1343
|
+
const raw = q.value.raw;
|
|
1344
|
+
let from = 0;
|
|
1345
|
+
while (from <= raw.length) {
|
|
1346
|
+
if (!open) {
|
|
1347
|
+
const tag = /<style\b([^>]*)>/g;
|
|
1348
|
+
tag.lastIndex = from;
|
|
1349
|
+
const m = tag.exec(raw);
|
|
1350
|
+
if (!m) break;
|
|
1351
|
+
open = { quasis: [], expressions: [], scoped: /\bscoped\b/.test(m[1]) };
|
|
1352
|
+
from = m.index + m[0].length;
|
|
1353
|
+
}
|
|
1354
|
+
const close = raw.indexOf("</style", from);
|
|
1355
|
+
open.quasis.push(slicePiece(q, raw, from, close === -1 ? raw.length : close));
|
|
1356
|
+
if (close === -1) break;
|
|
1357
|
+
blocks.push(open);
|
|
1358
|
+
open = null;
|
|
1359
|
+
from = close;
|
|
1360
|
+
}
|
|
1361
|
+
const expr = quasi.expressions[i];
|
|
1362
|
+
if (open && expr) open.expressions.push(expr);
|
|
1363
|
+
});
|
|
1364
|
+
return blocks;
|
|
1365
|
+
}
|
|
1366
|
+
function slicePiece(q, raw, from, to) {
|
|
1367
|
+
const text = raw.slice(from, to);
|
|
1368
|
+
const start = q.loc?.start;
|
|
1369
|
+
if (!start) return { type: "TemplateElement", value: { raw: text, cooked: text } };
|
|
1370
|
+
const before = raw.slice(0, from).split("\n");
|
|
1371
|
+
const line = start.line + before.length - 1;
|
|
1372
|
+
const column = before.length > 1 ? before[before.length - 1].length : start.column + from;
|
|
1373
|
+
return { type: "TemplateElement", value: { raw: text, cooked: text }, loc: { start: { line, column } } };
|
|
1374
|
+
}
|
|
1375
|
+
function blockPieces(node) {
|
|
1376
|
+
const meaningful = node.children.filter((c) => !(c.type === "JSXText" && !c.value.trim()));
|
|
1377
|
+
if (meaningful.length === 0) return { quasis: [], expressions: [] };
|
|
1378
|
+
if (meaningful.length !== 1) return null;
|
|
1379
|
+
const only = meaningful[0];
|
|
1380
|
+
if (only.type !== "JSXExpressionContainer") return null;
|
|
1381
|
+
const expr = only.expression;
|
|
1382
|
+
if (expr.type === "StringLiteral") return { quasis: [{ type: "TemplateElement", value: { raw: expr.value, cooked: expr.value } }], expressions: [] };
|
|
1383
|
+
if (expr.type === "TemplateLiteral") return { quasis: expr.quasis, expressions: expr.expressions };
|
|
1384
|
+
return null;
|
|
1385
|
+
}
|
|
1386
|
+
function findLiterals(program, modules, plan, intrinsic) {
|
|
1387
|
+
const literals = /* @__PURE__ */ new Map();
|
|
1388
|
+
const imports = /* @__PURE__ */ new Map();
|
|
1389
|
+
const tags = new Set(intrinsic);
|
|
1390
|
+
for (const statement of program.body ?? []) {
|
|
1391
|
+
if (statement.type !== "ImportDeclaration") continue;
|
|
1392
|
+
const source = statement.source.value;
|
|
1393
|
+
const specifiers = statement.specifiers;
|
|
1394
|
+
for (const sp of specifiers) {
|
|
1395
|
+
if (sp.type === "ImportSpecifier") imports.set(sp.local.name, { source, name: sp.imported.name ?? sp.imported.value });
|
|
1396
|
+
}
|
|
1397
|
+
if (!modules.includes(source)) continue;
|
|
1398
|
+
const css = specifiers.find((sp) => sp.type === "ImportSpecifier" && (sp.imported.name ?? sp.imported.value) === "css");
|
|
1399
|
+
if (!css) continue;
|
|
1400
|
+
const local = css.local.name;
|
|
1401
|
+
tags.add(local);
|
|
1402
|
+
imports.delete(local);
|
|
1403
|
+
plan.edits.push({ start: statement.start, end: statement.end, code: importWithout(statement, css) });
|
|
1404
|
+
}
|
|
1405
|
+
if (tags.size === 0) return { literals, imports };
|
|
1406
|
+
const visit = (node) => {
|
|
1407
|
+
if (!node || typeof node !== "object") return;
|
|
1408
|
+
if (node.type === "VariableDeclarator" && node.id.type === "Identifier" && node.init?.type === "TaggedTemplateExpression" && node.init.tag.type === "Identifier" && tags.has(node.init.tag.name)) {
|
|
1409
|
+
literals.set(node.id.name, node.init);
|
|
1410
|
+
}
|
|
1411
|
+
for (const key of Object.keys(node)) {
|
|
1412
|
+
if (key === "loc") continue;
|
|
1413
|
+
const value = node[key];
|
|
1414
|
+
if (Array.isArray(value)) for (const v of value) visit(v);
|
|
1415
|
+
else if (value && typeof value === "object" && "type" in value) visit(value);
|
|
1416
|
+
}
|
|
1417
|
+
};
|
|
1418
|
+
visit(program);
|
|
1419
|
+
return { literals, imports };
|
|
1420
|
+
}
|
|
1421
|
+
function importWithout(statement, removed) {
|
|
1422
|
+
const rest = statement.specifiers.filter((sp) => sp !== removed);
|
|
1423
|
+
const source = JSON.stringify(statement.source.value);
|
|
1424
|
+
if (rest.length === 0) return "";
|
|
1425
|
+
const def = rest.find((sp) => sp.type === "ImportDefaultSpecifier");
|
|
1426
|
+
const ns = rest.find((sp) => sp.type === "ImportNamespaceSpecifier");
|
|
1427
|
+
const named = rest.filter((sp) => sp.type === "ImportSpecifier").map((sp) => {
|
|
1428
|
+
const imported = sp.imported.name ?? JSON.stringify(sp.imported.value);
|
|
1429
|
+
return imported === sp.local.name ? imported : `${imported} as ${sp.local.name}`;
|
|
1430
|
+
});
|
|
1431
|
+
const parts = [def?.local.name, ns ? `* as ${ns.local.name}` : void 0, named.length ? `{ ${named.join(", ")} }` : void 0].filter(Boolean);
|
|
1432
|
+
return `import ${parts.join(", ")} from ${source};`;
|
|
1433
|
+
}
|
|
1434
|
+
function functionName(fn, named) {
|
|
1435
|
+
if ((fn.type === "FunctionDeclaration" || fn.type === "FunctionExpression") && fn.id) return fn.id.name;
|
|
1436
|
+
return named.get(fn) ?? "anonymous";
|
|
1437
|
+
}
|
|
1438
|
+
function hash(text) {
|
|
1439
|
+
let h = 2166136261;
|
|
1440
|
+
for (let i = 0; i < text.length; i++) {
|
|
1441
|
+
h ^= text.charCodeAt(i);
|
|
1442
|
+
h = Math.imul(h, 16777619);
|
|
1443
|
+
}
|
|
1444
|
+
return (h >>> 0).toString(36);
|
|
1445
|
+
}
|
|
1446
|
+
var OPAQUE = /(^|-)keyframes$|^font-face$|^property$|^counter-style$|^page$|^font-feature-values$/;
|
|
1447
|
+
function scopeNodes(nodes, id, warn = () => {
|
|
1448
|
+
}) {
|
|
1449
|
+
return nodes.map((node) => {
|
|
1450
|
+
if (node.kind === "rule") return { ...node, selector: scopeSelector(node.selector, id, warn) };
|
|
1451
|
+
if (node.kind === "at-rule" && !OPAQUE.test(node.name)) return { ...node, nodes: scopeNodes(node.nodes, id, warn) };
|
|
1452
|
+
return node;
|
|
1453
|
+
});
|
|
1454
|
+
}
|
|
1455
|
+
function scopeSelector(selector, id, warn = () => {
|
|
1456
|
+
}) {
|
|
1457
|
+
return splitTop(selector, ",").map((complex) => scopeComplex(complex.trim(), `[${SCOPE_ATTR}="${id}"]`, warn)).join(", ");
|
|
1458
|
+
}
|
|
1459
|
+
function scopeComplex(selector, attr, warn) {
|
|
1460
|
+
if (/:host\b|::slotted\(/.test(selector)) {
|
|
1461
|
+
warn(`\`${selector}\` only means something in a shadow root; in a light-DOM component it is left as written.`);
|
|
1462
|
+
return selector;
|
|
1463
|
+
}
|
|
1464
|
+
const parts = compounds(selector);
|
|
1465
|
+
const deep = parts.findIndex((p) => p.text.startsWith(":deep("));
|
|
1466
|
+
if (deep !== -1) {
|
|
1467
|
+
const inner = unwrap(parts[deep].text, ":deep(");
|
|
1468
|
+
const before = parts.slice(0, deep);
|
|
1469
|
+
if (before.length === 0) return `${attr} ${inner}`;
|
|
1470
|
+
const scopedBefore = scopeAt(before, before.length - 1, attr);
|
|
1471
|
+
return `${join(scopedBefore)} ${inner}`;
|
|
1472
|
+
}
|
|
1473
|
+
let target = -1;
|
|
1474
|
+
for (let i = parts.length - 1; i >= 0; i--) {
|
|
1475
|
+
if (!parts[i].text.startsWith(":global(")) {
|
|
1476
|
+
target = i;
|
|
1477
|
+
break;
|
|
1478
|
+
}
|
|
1479
|
+
}
|
|
1480
|
+
const out = target === -1 ? parts : scopeAt(parts, target, attr);
|
|
1481
|
+
return join(out.map((p) => p.text.startsWith(":global(") ? { ...p, text: unwrap(p.text, ":global(") } : p));
|
|
1482
|
+
}
|
|
1483
|
+
function scopeAt(parts, index, attr) {
|
|
1484
|
+
return parts.map((p, i) => i === index ? { ...p, text: insertAttr(p.text, attr) } : p);
|
|
1485
|
+
}
|
|
1486
|
+
function insertAttr(compound, attr) {
|
|
1487
|
+
let depth = 0;
|
|
1488
|
+
let quote = "";
|
|
1489
|
+
for (let i = 0; i < compound.length; i++) {
|
|
1490
|
+
const c = compound[i];
|
|
1491
|
+
if (quote) {
|
|
1492
|
+
if (c === "\\") i++;
|
|
1493
|
+
else if (c === quote) quote = "";
|
|
1494
|
+
continue;
|
|
1495
|
+
}
|
|
1496
|
+
if (c === "\\") {
|
|
1497
|
+
i++;
|
|
1498
|
+
continue;
|
|
1499
|
+
}
|
|
1500
|
+
if (c === '"' || c === "'") quote = c;
|
|
1501
|
+
else if (c === "(" || c === "[") depth++;
|
|
1502
|
+
else if (c === ")" || c === "]") depth--;
|
|
1503
|
+
else if (c === ":" && depth === 0 && i > 0) return compound.slice(0, i) + attr + compound.slice(i);
|
|
1504
|
+
}
|
|
1505
|
+
return compound + attr;
|
|
1506
|
+
}
|
|
1507
|
+
function compounds(selector) {
|
|
1508
|
+
const out = [];
|
|
1509
|
+
let depth = 0;
|
|
1510
|
+
let quote = "";
|
|
1511
|
+
let current = "";
|
|
1512
|
+
let combinator = "";
|
|
1513
|
+
const push = () => {
|
|
1514
|
+
if (current.trim()) out.push({ combinator: out.length ? combinator || " " : "", text: current.trim() });
|
|
1515
|
+
current = "";
|
|
1516
|
+
combinator = "";
|
|
1517
|
+
};
|
|
1518
|
+
for (let i = 0; i < selector.length; i++) {
|
|
1519
|
+
const c = selector[i];
|
|
1520
|
+
if (quote) {
|
|
1521
|
+
current += c;
|
|
1522
|
+
if (c === "\\") current += selector[++i] ?? "";
|
|
1523
|
+
else if (c === quote) quote = "";
|
|
1524
|
+
continue;
|
|
1525
|
+
}
|
|
1526
|
+
if (c === "\\") {
|
|
1527
|
+
current += c + (selector[++i] ?? "");
|
|
1528
|
+
continue;
|
|
1529
|
+
}
|
|
1530
|
+
if (c === '"' || c === "'") quote = c;
|
|
1531
|
+
if (c === "(" || c === "[") depth++;
|
|
1532
|
+
if (c === ")" || c === "]") depth--;
|
|
1533
|
+
if (depth === 0 && (c === ">" || c === "+" || c === "~")) {
|
|
1534
|
+
push();
|
|
1535
|
+
combinator = c;
|
|
1536
|
+
continue;
|
|
1537
|
+
}
|
|
1538
|
+
if (depth === 0 && /\s/.test(c)) {
|
|
1539
|
+
if (current.trim()) {
|
|
1540
|
+
const keep = combinator;
|
|
1541
|
+
push();
|
|
1542
|
+
combinator = keep;
|
|
1543
|
+
}
|
|
1544
|
+
continue;
|
|
1545
|
+
}
|
|
1546
|
+
current += c;
|
|
1547
|
+
}
|
|
1548
|
+
push();
|
|
1549
|
+
return out;
|
|
1550
|
+
}
|
|
1551
|
+
function join(parts) {
|
|
1552
|
+
return parts.map((p, i) => i === 0 ? p.text : p.combinator === " " ? ` ${p.text}` : ` ${p.combinator} ${p.text}`).join("");
|
|
1553
|
+
}
|
|
1554
|
+
function unwrap(text, prefix) {
|
|
1555
|
+
return text.slice(prefix.length, text.lastIndexOf(")")).trim() + text.slice(text.lastIndexOf(")") + 1);
|
|
1556
|
+
}
|
|
1557
|
+
function splitTop(selector, separator) {
|
|
1558
|
+
const parts = [];
|
|
1559
|
+
let depth = 0;
|
|
1560
|
+
let quote = "";
|
|
1561
|
+
let start = 0;
|
|
1562
|
+
for (let i = 0; i < selector.length; i++) {
|
|
1563
|
+
const c = selector[i];
|
|
1564
|
+
if (quote) {
|
|
1565
|
+
if (c === "\\") i++;
|
|
1566
|
+
else if (c === quote) quote = "";
|
|
1567
|
+
} else if (c === '"' || c === "'") quote = c;
|
|
1568
|
+
else if (c === "\\") i++;
|
|
1569
|
+
else if (c === "(" || c === "[") depth++;
|
|
1570
|
+
else if (c === ")" || c === "]") depth--;
|
|
1571
|
+
else if (c === separator && depth === 0) {
|
|
1572
|
+
parts.push(selector.slice(start, i));
|
|
1573
|
+
start = i + 1;
|
|
1574
|
+
}
|
|
1575
|
+
}
|
|
1576
|
+
parts.push(selector.slice(start));
|
|
1577
|
+
return parts.filter((p) => p.trim());
|
|
1578
|
+
}
|
|
1579
|
+
function shiftLoc(node, source, start) {
|
|
1580
|
+
const loc = node.loc && node.loc.source === source ? { source, line: start.line + node.loc.line - 1, column: node.loc.line === 1 ? start.column + node.loc.column : node.loc.column } : node.loc;
|
|
1581
|
+
if (node.kind === "rule" || node.kind === "at-rule") return { ...node, loc, nodes: node.nodes.map((n2) => shiftLoc(n2, source, start)) };
|
|
1582
|
+
return { ...node, loc };
|
|
1583
|
+
}
|
|
1584
|
+
function keepLocIn(node, modules) {
|
|
1585
|
+
const keep = node.loc !== void 0 && modules?.has(node.loc.source) === true;
|
|
1586
|
+
const { loc, ...rest } = node;
|
|
1587
|
+
const kept = keep ? { ...rest, loc } : rest;
|
|
1588
|
+
if (kept.kind === "rule" || kept.kind === "at-rule") return { ...kept, nodes: kept.nodes.map((n2) => keepLocIn(n2, modules)) };
|
|
1589
|
+
return kept;
|
|
1590
|
+
}
|
|
1591
|
+
function printStyleWithMap(nodes, minify, sourceName, module, others) {
|
|
1592
|
+
const sources = [module];
|
|
1593
|
+
const index = /* @__PURE__ */ new Map([[sourceName, 0]]);
|
|
1594
|
+
const sourceOf = (name) => {
|
|
1595
|
+
if (index.has(name)) return index.get(name);
|
|
1596
|
+
const other = others?.get(name);
|
|
1597
|
+
if (!other) return void 0;
|
|
1598
|
+
index.set(name, sources.push(other) - 1);
|
|
1599
|
+
return index.get(name);
|
|
1600
|
+
};
|
|
1601
|
+
const lines = [[]];
|
|
1602
|
+
let css = "";
|
|
1603
|
+
let column = 0;
|
|
1604
|
+
const emit = (text) => {
|
|
1605
|
+
for (const ch of text) {
|
|
1606
|
+
css += ch;
|
|
1607
|
+
if (ch === "\n") {
|
|
1608
|
+
lines.push([]);
|
|
1609
|
+
column = 0;
|
|
1610
|
+
} else column++;
|
|
1611
|
+
}
|
|
1612
|
+
};
|
|
1613
|
+
const mark = (loc) => {
|
|
1614
|
+
const at = loc ? sourceOf(loc.source) : void 0;
|
|
1615
|
+
if (loc && at !== void 0) lines[lines.length - 1].push([column, at, loc.line - 1, loc.column]);
|
|
1616
|
+
};
|
|
1617
|
+
const write = (node, depth) => {
|
|
1618
|
+
const pad = minify ? "" : " ".repeat(depth);
|
|
1619
|
+
const nl = minify ? "" : "\n";
|
|
1620
|
+
const sp = minify ? "" : " ";
|
|
1621
|
+
emit(pad);
|
|
1622
|
+
mark(node.loc);
|
|
1623
|
+
if (node.kind === "declaration") {
|
|
1624
|
+
emit(`${node.property}:${sp}${node.value}${node.important ? `${sp}!important` : ""};${nl}`);
|
|
1625
|
+
} else if (node.kind === "raw") {
|
|
1626
|
+
emit(`${node.text}${nl}`);
|
|
1627
|
+
} else {
|
|
1628
|
+
emit(`${node.kind === "rule" ? node.selector : `@${node.name}${node.params ? " " + node.params : ""}`}${sp}{${nl}`);
|
|
1629
|
+
for (const child of node.nodes) write(child, depth + 1);
|
|
1630
|
+
emit(`${pad}}${nl}`);
|
|
1631
|
+
}
|
|
1632
|
+
};
|
|
1633
|
+
for (const node of nodes) write(node, 0);
|
|
1634
|
+
return { css, map: { version: 3, sources: sources.map((s) => s.id), sourcesContent: sources.map((s) => s.code), names: [], mappings: encode(lines) } };
|
|
1635
|
+
}
|
|
1636
|
+
function printStyle(nodes, minify = false) {
|
|
1637
|
+
const out = [];
|
|
1638
|
+
const write = (node, depth) => {
|
|
1639
|
+
const pad = minify ? "" : " ".repeat(depth);
|
|
1640
|
+
const nl = minify ? "" : "\n";
|
|
1641
|
+
const sp = minify ? "" : " ";
|
|
1642
|
+
if (node.kind === "declaration") {
|
|
1643
|
+
out.push(`${pad}${node.property}:${sp}${node.value}${node.important ? `${sp}!important` : ""};${nl}`);
|
|
1644
|
+
} else if (node.kind === "raw") {
|
|
1645
|
+
out.push(`${pad}${node.text}${nl}`);
|
|
1646
|
+
} else {
|
|
1647
|
+
const header = node.kind === "rule" ? node.selector : `@${node.name}${node.params ? " " + node.params : ""}`;
|
|
1648
|
+
out.push(`${pad}${header}${sp}{${nl}`);
|
|
1649
|
+
for (const child of node.nodes) write(child, depth + 1);
|
|
1650
|
+
out.push(`${pad}}${nl}`);
|
|
1651
|
+
}
|
|
1652
|
+
};
|
|
1653
|
+
for (const node of nodes) write(node, 0);
|
|
1654
|
+
return out.join("");
|
|
1655
|
+
}
|
|
1656
|
+
|
|
1079
1657
|
// src/optimize/analyze-static.ts
|
|
1080
1658
|
function propReason(prop) {
|
|
1081
1659
|
switch (prop.kind) {
|
|
@@ -1573,6 +2151,16 @@ var PRIMITIVE_MODULES = [
|
|
|
1573
2151
|
"@fluixi/reactive/cached-resource",
|
|
1574
2152
|
"@fluixi/core"
|
|
1575
2153
|
];
|
|
2154
|
+
var TAG_INTRINSICS = {
|
|
2155
|
+
$html: { export: "html", module: "@fluixi/core" },
|
|
2156
|
+
$svg: { export: "svg", module: "@fluixi/core" },
|
|
2157
|
+
$css: { export: "css", module: "@fluixi/core" }
|
|
2158
|
+
};
|
|
2159
|
+
function tagIntrinsics(bound) {
|
|
2160
|
+
const tags = /* @__PURE__ */ new Map();
|
|
2161
|
+
for (const [name, tag] of Object.entries(TAG_INTRINSICS)) if (!bound.has(name)) tags.set(name, tag.export);
|
|
2162
|
+
return tags;
|
|
2163
|
+
}
|
|
1576
2164
|
var INTRINSIC_CALL = new RegExp(`\\$(?:${Object.keys(INTRINSICS).map((n2) => n2.slice(1)).join("|")})\\s*\\(`);
|
|
1577
2165
|
function mayHaveIntrinsic(code) {
|
|
1578
2166
|
return INTRINSIC_CALL.test(code);
|
|
@@ -2076,7 +2664,7 @@ function emitComponent(name, props, children, used, templates, at) {
|
|
|
2076
2664
|
}
|
|
2077
2665
|
let obj = `{ ${bodies.map(([name2, body]) => `get ${propKey(name2)}() { return ${body}; }`).join(", ")} }`;
|
|
2078
2666
|
if (bodies.some(([, body]) => /\bthis\b/.test(body))) {
|
|
2079
|
-
const thunks = bodies.map(([name2, body]) => `${JSON.stringify(name2)}: () => ${body}`);
|
|
2667
|
+
const thunks = bodies.map(([name2, body]) => `${JSON.stringify(name2)}: () => (${body})`);
|
|
2080
2668
|
const getters = bodies.map(([name2]) => `get ${propKey(name2)}() { return _$t[${JSON.stringify(name2)}](); }`);
|
|
2081
2669
|
obj = `((_$t) => ({ ${getters.join(", ")} }))({ ${thunks.join(", ")} })`;
|
|
2082
2670
|
}
|
|
@@ -2277,6 +2865,271 @@ function cleanTemplateText(value) {
|
|
|
2277
2865
|
return out;
|
|
2278
2866
|
}
|
|
2279
2867
|
|
|
2868
|
+
// src/lower/entities.ts
|
|
2869
|
+
var NAMED = {
|
|
2870
|
+
quot: 34,
|
|
2871
|
+
amp: 38,
|
|
2872
|
+
apos: 39,
|
|
2873
|
+
lt: 60,
|
|
2874
|
+
gt: 62,
|
|
2875
|
+
nbsp: 160,
|
|
2876
|
+
iexcl: 161,
|
|
2877
|
+
cent: 162,
|
|
2878
|
+
pound: 163,
|
|
2879
|
+
curren: 164,
|
|
2880
|
+
yen: 165,
|
|
2881
|
+
brvbar: 166,
|
|
2882
|
+
sect: 167,
|
|
2883
|
+
uml: 168,
|
|
2884
|
+
copy: 169,
|
|
2885
|
+
ordf: 170,
|
|
2886
|
+
laquo: 171,
|
|
2887
|
+
not: 172,
|
|
2888
|
+
shy: 173,
|
|
2889
|
+
reg: 174,
|
|
2890
|
+
macr: 175,
|
|
2891
|
+
deg: 176,
|
|
2892
|
+
plusmn: 177,
|
|
2893
|
+
sup2: 178,
|
|
2894
|
+
sup3: 179,
|
|
2895
|
+
acute: 180,
|
|
2896
|
+
micro: 181,
|
|
2897
|
+
para: 182,
|
|
2898
|
+
middot: 183,
|
|
2899
|
+
cedil: 184,
|
|
2900
|
+
sup1: 185,
|
|
2901
|
+
ordm: 186,
|
|
2902
|
+
raquo: 187,
|
|
2903
|
+
frac14: 188,
|
|
2904
|
+
frac12: 189,
|
|
2905
|
+
frac34: 190,
|
|
2906
|
+
iquest: 191,
|
|
2907
|
+
Agrave: 192,
|
|
2908
|
+
Aacute: 193,
|
|
2909
|
+
Acirc: 194,
|
|
2910
|
+
Atilde: 195,
|
|
2911
|
+
Auml: 196,
|
|
2912
|
+
Aring: 197,
|
|
2913
|
+
AElig: 198,
|
|
2914
|
+
Ccedil: 199,
|
|
2915
|
+
Egrave: 200,
|
|
2916
|
+
Eacute: 201,
|
|
2917
|
+
Ecirc: 202,
|
|
2918
|
+
Euml: 203,
|
|
2919
|
+
Igrave: 204,
|
|
2920
|
+
Iacute: 205,
|
|
2921
|
+
Icirc: 206,
|
|
2922
|
+
Iuml: 207,
|
|
2923
|
+
ETH: 208,
|
|
2924
|
+
Ntilde: 209,
|
|
2925
|
+
Ograve: 210,
|
|
2926
|
+
Oacute: 211,
|
|
2927
|
+
Ocirc: 212,
|
|
2928
|
+
Otilde: 213,
|
|
2929
|
+
Ouml: 214,
|
|
2930
|
+
times: 215,
|
|
2931
|
+
Oslash: 216,
|
|
2932
|
+
Ugrave: 217,
|
|
2933
|
+
Uacute: 218,
|
|
2934
|
+
Ucirc: 219,
|
|
2935
|
+
Uuml: 220,
|
|
2936
|
+
Yacute: 221,
|
|
2937
|
+
THORN: 222,
|
|
2938
|
+
szlig: 223,
|
|
2939
|
+
agrave: 224,
|
|
2940
|
+
aacute: 225,
|
|
2941
|
+
acirc: 226,
|
|
2942
|
+
atilde: 227,
|
|
2943
|
+
auml: 228,
|
|
2944
|
+
aring: 229,
|
|
2945
|
+
aelig: 230,
|
|
2946
|
+
ccedil: 231,
|
|
2947
|
+
egrave: 232,
|
|
2948
|
+
eacute: 233,
|
|
2949
|
+
ecirc: 234,
|
|
2950
|
+
euml: 235,
|
|
2951
|
+
igrave: 236,
|
|
2952
|
+
iacute: 237,
|
|
2953
|
+
icirc: 238,
|
|
2954
|
+
iuml: 239,
|
|
2955
|
+
eth: 240,
|
|
2956
|
+
ntilde: 241,
|
|
2957
|
+
ograve: 242,
|
|
2958
|
+
oacute: 243,
|
|
2959
|
+
ocirc: 244,
|
|
2960
|
+
otilde: 245,
|
|
2961
|
+
ouml: 246,
|
|
2962
|
+
divide: 247,
|
|
2963
|
+
oslash: 248,
|
|
2964
|
+
ugrave: 249,
|
|
2965
|
+
uacute: 250,
|
|
2966
|
+
ucirc: 251,
|
|
2967
|
+
uuml: 252,
|
|
2968
|
+
yacute: 253,
|
|
2969
|
+
thorn: 254,
|
|
2970
|
+
yuml: 255,
|
|
2971
|
+
OElig: 338,
|
|
2972
|
+
oelig: 339,
|
|
2973
|
+
Scaron: 352,
|
|
2974
|
+
scaron: 353,
|
|
2975
|
+
Yuml: 376,
|
|
2976
|
+
fnof: 402,
|
|
2977
|
+
circ: 710,
|
|
2978
|
+
tilde: 732,
|
|
2979
|
+
Alpha: 913,
|
|
2980
|
+
Beta: 914,
|
|
2981
|
+
Gamma: 915,
|
|
2982
|
+
Delta: 916,
|
|
2983
|
+
Epsilon: 917,
|
|
2984
|
+
Zeta: 918,
|
|
2985
|
+
Eta: 919,
|
|
2986
|
+
Theta: 920,
|
|
2987
|
+
Iota: 921,
|
|
2988
|
+
Kappa: 922,
|
|
2989
|
+
Lambda: 923,
|
|
2990
|
+
Mu: 924,
|
|
2991
|
+
Nu: 925,
|
|
2992
|
+
Xi: 926,
|
|
2993
|
+
Omicron: 927,
|
|
2994
|
+
Pi: 928,
|
|
2995
|
+
Rho: 929,
|
|
2996
|
+
Sigma: 931,
|
|
2997
|
+
Tau: 932,
|
|
2998
|
+
Upsilon: 933,
|
|
2999
|
+
Phi: 934,
|
|
3000
|
+
Chi: 935,
|
|
3001
|
+
Psi: 936,
|
|
3002
|
+
Omega: 937,
|
|
3003
|
+
alpha: 945,
|
|
3004
|
+
beta: 946,
|
|
3005
|
+
gamma: 947,
|
|
3006
|
+
delta: 948,
|
|
3007
|
+
epsilon: 949,
|
|
3008
|
+
zeta: 950,
|
|
3009
|
+
eta: 951,
|
|
3010
|
+
theta: 952,
|
|
3011
|
+
iota: 953,
|
|
3012
|
+
kappa: 954,
|
|
3013
|
+
lambda: 955,
|
|
3014
|
+
mu: 956,
|
|
3015
|
+
nu: 957,
|
|
3016
|
+
xi: 958,
|
|
3017
|
+
omicron: 959,
|
|
3018
|
+
pi: 960,
|
|
3019
|
+
rho: 961,
|
|
3020
|
+
sigmaf: 962,
|
|
3021
|
+
sigma: 963,
|
|
3022
|
+
tau: 964,
|
|
3023
|
+
upsilon: 965,
|
|
3024
|
+
phi: 966,
|
|
3025
|
+
chi: 967,
|
|
3026
|
+
psi: 968,
|
|
3027
|
+
omega: 969,
|
|
3028
|
+
thetasym: 977,
|
|
3029
|
+
upsih: 978,
|
|
3030
|
+
piv: 982,
|
|
3031
|
+
ensp: 8194,
|
|
3032
|
+
emsp: 8195,
|
|
3033
|
+
thinsp: 8201,
|
|
3034
|
+
zwnj: 8204,
|
|
3035
|
+
zwj: 8205,
|
|
3036
|
+
lrm: 8206,
|
|
3037
|
+
rlm: 8207,
|
|
3038
|
+
ndash: 8211,
|
|
3039
|
+
mdash: 8212,
|
|
3040
|
+
lsquo: 8216,
|
|
3041
|
+
rsquo: 8217,
|
|
3042
|
+
sbquo: 8218,
|
|
3043
|
+
ldquo: 8220,
|
|
3044
|
+
rdquo: 8221,
|
|
3045
|
+
bdquo: 8222,
|
|
3046
|
+
dagger: 8224,
|
|
3047
|
+
Dagger: 8225,
|
|
3048
|
+
bull: 8226,
|
|
3049
|
+
hellip: 8230,
|
|
3050
|
+
permil: 8240,
|
|
3051
|
+
prime: 8242,
|
|
3052
|
+
Prime: 8243,
|
|
3053
|
+
lsaquo: 8249,
|
|
3054
|
+
rsaquo: 8250,
|
|
3055
|
+
oline: 8254,
|
|
3056
|
+
frasl: 8260,
|
|
3057
|
+
euro: 8364,
|
|
3058
|
+
image: 8465,
|
|
3059
|
+
weierp: 8472,
|
|
3060
|
+
real: 8476,
|
|
3061
|
+
trade: 8482,
|
|
3062
|
+
alefsym: 8501,
|
|
3063
|
+
larr: 8592,
|
|
3064
|
+
uarr: 8593,
|
|
3065
|
+
rarr: 8594,
|
|
3066
|
+
darr: 8595,
|
|
3067
|
+
harr: 8596,
|
|
3068
|
+
crarr: 8629,
|
|
3069
|
+
lArr: 8656,
|
|
3070
|
+
uArr: 8657,
|
|
3071
|
+
rArr: 8658,
|
|
3072
|
+
dArr: 8659,
|
|
3073
|
+
hArr: 8660,
|
|
3074
|
+
forall: 8704,
|
|
3075
|
+
part: 8706,
|
|
3076
|
+
exist: 8707,
|
|
3077
|
+
empty: 8709,
|
|
3078
|
+
nabla: 8711,
|
|
3079
|
+
isin: 8712,
|
|
3080
|
+
notin: 8713,
|
|
3081
|
+
ni: 8715,
|
|
3082
|
+
prod: 8719,
|
|
3083
|
+
sum: 8721,
|
|
3084
|
+
minus: 8722,
|
|
3085
|
+
lowast: 8727,
|
|
3086
|
+
radic: 8730,
|
|
3087
|
+
prop: 8733,
|
|
3088
|
+
infin: 8734,
|
|
3089
|
+
ang: 8736,
|
|
3090
|
+
and: 8743,
|
|
3091
|
+
or: 8744,
|
|
3092
|
+
cap: 8745,
|
|
3093
|
+
cup: 8746,
|
|
3094
|
+
int: 8747,
|
|
3095
|
+
there4: 8756,
|
|
3096
|
+
sim: 8764,
|
|
3097
|
+
cong: 8773,
|
|
3098
|
+
asymp: 8776,
|
|
3099
|
+
ne: 8800,
|
|
3100
|
+
equiv: 8801,
|
|
3101
|
+
le: 8804,
|
|
3102
|
+
ge: 8805,
|
|
3103
|
+
sub: 8834,
|
|
3104
|
+
sup: 8835,
|
|
3105
|
+
nsub: 8836,
|
|
3106
|
+
sube: 8838,
|
|
3107
|
+
supe: 8839,
|
|
3108
|
+
oplus: 8853,
|
|
3109
|
+
otimes: 8855,
|
|
3110
|
+
perp: 8869,
|
|
3111
|
+
sdot: 8901,
|
|
3112
|
+
lceil: 8968,
|
|
3113
|
+
rceil: 8969,
|
|
3114
|
+
lfloor: 8970,
|
|
3115
|
+
rfloor: 8971,
|
|
3116
|
+
lang: 9001,
|
|
3117
|
+
rang: 9002,
|
|
3118
|
+
loz: 9674,
|
|
3119
|
+
spades: 9824,
|
|
3120
|
+
clubs: 9827,
|
|
3121
|
+
hearts: 9829,
|
|
3122
|
+
diams: 9830
|
|
3123
|
+
};
|
|
3124
|
+
var REFERENCE = /&(?:#[xX]([0-9a-fA-F]{1,6})|#([0-9]{1,7})|([a-zA-Z][a-zA-Z0-9]{1,31}));/g;
|
|
3125
|
+
function decodeEntities(value) {
|
|
3126
|
+
if (!value.includes("&")) return value;
|
|
3127
|
+
return value.replace(REFERENCE, (match, hex, dec, name) => {
|
|
3128
|
+
const code = hex ? parseInt(hex, 16) : dec ? parseInt(dec, 10) : Object.prototype.hasOwnProperty.call(NAMED, name) ? NAMED[name] : void 0;
|
|
3129
|
+
return code !== void 0 && code <= 1114111 ? String.fromCodePoint(code) : match;
|
|
3130
|
+
});
|
|
3131
|
+
}
|
|
3132
|
+
|
|
2280
3133
|
// src/lower/template.ts
|
|
2281
3134
|
var DELEGATED = /* @__PURE__ */ new Set([
|
|
2282
3135
|
"click",
|
|
@@ -2363,7 +3216,7 @@ var Lowerer = class {
|
|
|
2363
3216
|
switch (node.kind) {
|
|
2364
3217
|
case "Text": {
|
|
2365
3218
|
if (node.raw) return { kind: "text", value: node.value };
|
|
2366
|
-
const cleaned = cleanTemplateText(node.value);
|
|
3219
|
+
const cleaned = decodeEntities(cleanTemplateText(node.value));
|
|
2367
3220
|
return cleaned ? { kind: "text", value: cleaned } : null;
|
|
2368
3221
|
}
|
|
2369
3222
|
case "Comment":
|
|
@@ -2399,7 +3252,7 @@ var Lowerer = class {
|
|
|
2399
3252
|
kind: "element",
|
|
2400
3253
|
tag: el.tag,
|
|
2401
3254
|
svg: el.namespace === "svg",
|
|
2402
|
-
props: this.lowerAttributes(el.attributes),
|
|
3255
|
+
props: this.lowerAttributes(el.attributes, true),
|
|
2403
3256
|
children,
|
|
2404
3257
|
static: false,
|
|
2405
3258
|
...at ? { at } : {}
|
|
@@ -2512,13 +3365,22 @@ var Lowerer = class {
|
|
|
2512
3365
|
return clone.kind === "Element" ? this.lowerElement(clone) : this.lowerComponent(clone);
|
|
2513
3366
|
}
|
|
2514
3367
|
// --- attributes ---------------------------------------------------------
|
|
2515
|
-
|
|
3368
|
+
/**
|
|
3369
|
+
* `element`: a DOM element, where each class:/style: value that moves is its own accessor.
|
|
3370
|
+
* A component gets the object as before, rebuilt whole when any value moves.
|
|
3371
|
+
*/
|
|
3372
|
+
lowerAttributes(attrs, element = false) {
|
|
3373
|
+
let anyReactive = false;
|
|
3374
|
+
const entry = (name, h) => {
|
|
3375
|
+
anyReactive ||= h.reactive;
|
|
3376
|
+
if (!element || !h.reactive) return `${JSON.stringify(name)}: ${h.code}`;
|
|
3377
|
+
const accessor = `() => ${paren(h.code, "arrowBody")}`;
|
|
3378
|
+
return `${JSON.stringify(name)}: ${h.at ? markHole(accessor, h.at.line, h.at.column) : accessor}`;
|
|
3379
|
+
};
|
|
2516
3380
|
const props = [];
|
|
2517
3381
|
const classEntries = [];
|
|
2518
|
-
let classReactive = false;
|
|
2519
3382
|
let classAt;
|
|
2520
3383
|
const styleEntries = [];
|
|
2521
|
-
let styleReactive = false;
|
|
2522
3384
|
let styleAt;
|
|
2523
3385
|
const usePairs = [];
|
|
2524
3386
|
for (const a of attrs) {
|
|
@@ -2558,15 +3420,13 @@ var Lowerer = class {
|
|
|
2558
3420
|
break;
|
|
2559
3421
|
case "ClassDirective": {
|
|
2560
3422
|
const h = this.hole(a.hole);
|
|
2561
|
-
classEntries.push(
|
|
2562
|
-
classReactive = classReactive || h.reactive;
|
|
3423
|
+
classEntries.push(entry(a.name, h));
|
|
2563
3424
|
classAt ??= h.at;
|
|
2564
3425
|
break;
|
|
2565
3426
|
}
|
|
2566
3427
|
case "StyleDirective": {
|
|
2567
3428
|
const h = this.hole(a.hole);
|
|
2568
|
-
styleEntries.push(
|
|
2569
|
-
styleReactive = styleReactive || h.reactive;
|
|
3429
|
+
styleEntries.push(entry(a.name, h));
|
|
2570
3430
|
styleAt ??= h.at;
|
|
2571
3431
|
break;
|
|
2572
3432
|
}
|
|
@@ -2586,18 +3446,19 @@ var Lowerer = class {
|
|
|
2586
3446
|
name: "classList",
|
|
2587
3447
|
kind: "attr",
|
|
2588
3448
|
expr: `{ ${classEntries.join(", ")} }`,
|
|
2589
|
-
reactive:
|
|
3449
|
+
reactive: !element && anyReactive,
|
|
2590
3450
|
...classAt ? { at: classAt } : {}
|
|
2591
3451
|
});
|
|
2592
3452
|
}
|
|
2593
3453
|
if (styleEntries.length > 0) {
|
|
2594
|
-
|
|
2595
|
-
|
|
2596
|
-
|
|
2597
|
-
|
|
2598
|
-
|
|
2599
|
-
|
|
2600
|
-
|
|
3454
|
+
const entries = `{ ${styleEntries.join(", ")} }`;
|
|
3455
|
+
const base = props.findIndex((p) => p.name === "style");
|
|
3456
|
+
if (base === -1) props.push({ name: "style", kind: "attr", expr: entries, reactive: !element && anyReactive, ...styleAt ? { at: styleAt } : {} });
|
|
3457
|
+
else {
|
|
3458
|
+
const prop = props[base];
|
|
3459
|
+
const value = prop.expr === void 0 ? JSON.stringify(prop.literal) : prop.reactive ? `() => ${paren(prop.expr, "arrowBody")}` : prop.expr;
|
|
3460
|
+
props[base] = { name: "style", kind: "attr", expr: `[${value}, ${entries}]`, reactive: false, ...prop.at ? { at: prop.at } : {} };
|
|
3461
|
+
}
|
|
2601
3462
|
}
|
|
2602
3463
|
if (usePairs.length > 0) {
|
|
2603
3464
|
props.push({ name: "use", kind: "attr", expr: `[${usePairs.join(", ")}]` });
|
|
@@ -2686,7 +3547,7 @@ var Lowerer = class {
|
|
|
2686
3547
|
return base;
|
|
2687
3548
|
}
|
|
2688
3549
|
if (v.kind === "static") {
|
|
2689
|
-
base.literal = v.value;
|
|
3550
|
+
base.literal = decodeEntities(v.value);
|
|
2690
3551
|
return base;
|
|
2691
3552
|
}
|
|
2692
3553
|
if (v.kind === "hole") {
|
|
@@ -2699,7 +3560,7 @@ var Lowerer = class {
|
|
|
2699
3560
|
let reactive = false;
|
|
2700
3561
|
let at;
|
|
2701
3562
|
const body = v.parts.map((p) => {
|
|
2702
|
-
if ("text" in p) return escapeTemplate(p.text);
|
|
3563
|
+
if ("text" in p) return escapeTemplate(decodeEntities(p.text));
|
|
2703
3564
|
const h = this.hole(p.hole);
|
|
2704
3565
|
reactive = reactive || h.reactive;
|
|
2705
3566
|
at ??= h.at;
|
|
@@ -2724,6 +3585,7 @@ function compilePieces(pieces, holes, options = {}) {
|
|
|
2724
3585
|
...options.sourceFile ? { sourceFile: options.sourceFile } : {},
|
|
2725
3586
|
...options.positionAt ? { positionAt: options.positionAt } : {}
|
|
2726
3587
|
});
|
|
3588
|
+
if (options.templateStyles) applyTemplateStyles(ir, options.templateStyles);
|
|
2727
3589
|
analyzeStatic(ir);
|
|
2728
3590
|
resolveComponentSources(ir, {
|
|
2729
3591
|
resolver: createComponentResolver(options.resolve ?? []),
|
|
@@ -2922,9 +3784,12 @@ function attrExprCode(attr, ctx) {
|
|
|
2922
3784
|
}
|
|
2923
3785
|
return null;
|
|
2924
3786
|
}
|
|
2925
|
-
function buildProps(attrs, ctx) {
|
|
3787
|
+
function buildProps(attrs, ctx, element = false) {
|
|
2926
3788
|
const props = [];
|
|
2927
3789
|
const usePairs = [];
|
|
3790
|
+
const classEntries = [];
|
|
3791
|
+
const styleEntries = [];
|
|
3792
|
+
let styleAt;
|
|
2928
3793
|
for (const a of attrs) {
|
|
2929
3794
|
if (a.type === "JSXSpreadAttribute") {
|
|
2930
3795
|
props.push({ name: "", kind: "spread", expr: ctx.code(a.argument) });
|
|
@@ -2940,6 +3805,27 @@ function buildProps(attrs, ctx) {
|
|
|
2940
3805
|
usePairs.push(opts != null ? `[${dir}, () => ${paren(opts, "arrowBody")}]` : `[${dir}]`);
|
|
2941
3806
|
continue;
|
|
2942
3807
|
}
|
|
3808
|
+
if (element && (ns === "class" || ns === "style")) {
|
|
3809
|
+
const key = JSON.stringify(a.name.name.name);
|
|
3810
|
+
const v = a.value;
|
|
3811
|
+
let value;
|
|
3812
|
+
if (v == null) value = "true";
|
|
3813
|
+
else if (isString(v)) value = JSON.stringify(literalOf(v));
|
|
3814
|
+
else if (v.type === "JSXExpressionContainer" && v.expression?.type !== "JSXEmptyExpression") {
|
|
3815
|
+
value = keyValue(v.expression, ctx);
|
|
3816
|
+
if (ns === "style") styleAt ??= posOf(v.expression, ctx);
|
|
3817
|
+
} else continue;
|
|
3818
|
+
(ns === "class" ? classEntries : styleEntries).push(`${key}: ${value}`);
|
|
3819
|
+
continue;
|
|
3820
|
+
}
|
|
3821
|
+
if (element && a.name.type === "JSXIdentifier" && a.name.name === "style" && a.value?.type === "JSXExpressionContainer") {
|
|
3822
|
+
const entries = objectEntries(a.value.expression, ctx);
|
|
3823
|
+
if (entries) {
|
|
3824
|
+
styleEntries.unshift(...entries);
|
|
3825
|
+
styleAt = posOf(a.value.expression, ctx);
|
|
3826
|
+
continue;
|
|
3827
|
+
}
|
|
3828
|
+
}
|
|
2943
3829
|
if (ns === "oncapture") {
|
|
2944
3830
|
const evt = a.name.name.name.toLowerCase();
|
|
2945
3831
|
const h = attrExprCode(a, ctx) ?? "undefined";
|
|
@@ -2948,9 +3834,37 @@ function buildProps(attrs, ctx) {
|
|
|
2948
3834
|
}
|
|
2949
3835
|
props.push(buildAttr(a, ctx));
|
|
2950
3836
|
}
|
|
3837
|
+
if (classEntries.length > 0) props.push({ name: "classList", kind: "attr", expr: `{ ${classEntries.join(", ")} }`, reactive: false });
|
|
3838
|
+
if (styleEntries.length > 0) {
|
|
3839
|
+
const entries = `{ ${styleEntries.join(", ")} }`;
|
|
3840
|
+
const base = props.findIndex((p) => p.name === "style" && p.kind === "attr");
|
|
3841
|
+
if (base === -1) props.push({ name: "style", kind: "attr", expr: entries, reactive: false, ...styleAt ? { at: styleAt } : {} });
|
|
3842
|
+
else {
|
|
3843
|
+
const prop = props[base];
|
|
3844
|
+
const value = prop.literal !== void 0 ? JSON.stringify(prop.literal) : prop.reactive ? `() => ${paren(prop.expr, "arrowBody")}` : prop.expr;
|
|
3845
|
+
props[base] = { name: "style", kind: "attr", expr: `[${value}, ${entries}]`, reactive: false, ...prop.at ? { at: prop.at } : {} };
|
|
3846
|
+
}
|
|
3847
|
+
}
|
|
2951
3848
|
if (usePairs.length > 0) props.push({ name: "use", kind: "attr", expr: `[${usePairs.join(", ")}]` });
|
|
2952
3849
|
return props;
|
|
2953
3850
|
}
|
|
3851
|
+
function keyValue(expr, ctx) {
|
|
3852
|
+
const code = ctx.code(expr);
|
|
3853
|
+
if (!isReactive(expr)) return code;
|
|
3854
|
+
const accessor = `() => ${paren(code, "arrowBody")}`;
|
|
3855
|
+
const at = posOf(expr, ctx);
|
|
3856
|
+
return at ? markHole(accessor, at.line, at.column) : accessor;
|
|
3857
|
+
}
|
|
3858
|
+
function objectEntries(expr, ctx) {
|
|
3859
|
+
if (expr?.type !== "ObjectExpression") return null;
|
|
3860
|
+
const entries = [];
|
|
3861
|
+
for (const p of expr.properties) {
|
|
3862
|
+
if (p.type !== "ObjectProperty") return null;
|
|
3863
|
+
const key = p.computed ? `[${ctx.code(p.key)}]` : p.key.type === "Identifier" ? JSON.stringify(p.key.name) : JSON.stringify(String(p.key.value));
|
|
3864
|
+
entries.push(`${key}: ${keyValue(p.value, ctx)}`);
|
|
3865
|
+
}
|
|
3866
|
+
return entries;
|
|
3867
|
+
}
|
|
2954
3868
|
function buildChildren(children, ctx) {
|
|
2955
3869
|
const out = [];
|
|
2956
3870
|
for (let i = 0; i < children.length; i++) {
|
|
@@ -2978,6 +3892,7 @@ function buildChildren(children, ctx) {
|
|
|
2978
3892
|
});
|
|
2979
3893
|
}
|
|
2980
3894
|
} else if (child.type === "JSXElement" || child.type === "JSXFragment") {
|
|
3895
|
+
if (ctx.dropStyles?.has(child.start)) continue;
|
|
2981
3896
|
out.push(buildNode(child, ctx));
|
|
2982
3897
|
} else if (child.type === "JSXSpreadChild") {
|
|
2983
3898
|
out.push({ kind: "expr", code: ctx.code(child.expression), reactive: false });
|
|
@@ -3047,13 +3962,17 @@ function buildElement(node, ctx, handled) {
|
|
|
3047
3962
|
const children = each ? [each] : buildChildren(node.children, ctx);
|
|
3048
3963
|
if (tag === CONTAINER2) return children.length === 1 ? children[0] : { kind: "fragment", children };
|
|
3049
3964
|
const at = ctx.sourceFile && node.loc?.start ? { file: ctx.sourceFile, line: node.loc.start.line, column: node.loc.start.column } : void 0;
|
|
3050
|
-
|
|
3965
|
+
const props = buildProps(attributes, ctx, true);
|
|
3966
|
+
const scope = ctx.scopes?.find((s) => node.start >= s.start && node.end <= s.end);
|
|
3967
|
+
if (scope) props.unshift({ name: "data-fx-s", kind: "attr", literal: scope.value });
|
|
3968
|
+
return { kind: "element", tag, svg: SVG_TAGS.has(tag), props, children, static: false, ...at ? { at } : {} };
|
|
3051
3969
|
}
|
|
3052
3970
|
function buildNode(node, ctx) {
|
|
3053
3971
|
if (node.type === "JSXFragment") {
|
|
3054
3972
|
return { kind: "fragment", children: buildChildren(node.children, ctx) };
|
|
3055
3973
|
}
|
|
3056
3974
|
if (directive(node, "if")) return buildIf(node, null, ctx);
|
|
3975
|
+
if (ctx.dropStyles?.has(node.start)) return { kind: "fragment", children: [] };
|
|
3057
3976
|
const { tag, component } = tagInfo(node.openingElement.name, ctx);
|
|
3058
3977
|
if (!component) return buildElement(node, ctx, []);
|
|
3059
3978
|
const props = buildProps(node.openingElement.attributes, ctx);
|
|
@@ -3581,8 +4500,8 @@ function isJsxRoot(node, parent, key) {
|
|
|
3581
4500
|
if (!isJsx(node)) return false;
|
|
3582
4501
|
return !(parent && isJsx(parent) && key === "children");
|
|
3583
4502
|
}
|
|
3584
|
-
function isTemplateTag(node,
|
|
3585
|
-
return node.type === "TaggedTemplateExpression" && node.tag?.type === "Identifier" && (node.tag.name
|
|
4503
|
+
function isTemplateTag(node, tags) {
|
|
4504
|
+
return node.type === "TaggedTemplateExpression" && node.tag?.type === "Identifier" && tags.has(node.tag.name);
|
|
3586
4505
|
}
|
|
3587
4506
|
function outermost(list) {
|
|
3588
4507
|
return list.filter(
|
|
@@ -3730,22 +4649,28 @@ function transformTemplates(code, id, options = {}) {
|
|
|
3730
4649
|
const wantsIntrinsics = options.intrinsics !== false && mayHaveIntrinsic(code);
|
|
3731
4650
|
const wantsSources = options.sourceLocations === true && mayHaveSourceMarks(code);
|
|
3732
4651
|
const sourceName = relativeToRoot(id, options.sourceRoot);
|
|
3733
|
-
|
|
4652
|
+
const wantsStyles = options.styles !== void 0 && (code.includes("<style") || code.includes("css`"));
|
|
4653
|
+
if (!mayHaveTemplate && !(wantsJsx && code.includes("<")) && !wantsIntrinsics && !wantsSources && !wantsStyles) return null;
|
|
3734
4654
|
const ast = parse2(code, {
|
|
3735
4655
|
sourceType: "module",
|
|
3736
4656
|
plugins: ["jsx", "typescript"],
|
|
3737
4657
|
errorRecovery: true
|
|
3738
4658
|
});
|
|
4659
|
+
const intrinsicTags = options.intrinsics === false ? /* @__PURE__ */ new Map() : tagIntrinsics(moduleBindings(ast.program));
|
|
4660
|
+
const templateTags = /* @__PURE__ */ new Map([[litTag, "html"], ["svg", "svg"]]);
|
|
4661
|
+
for (const [name, tag] of intrinsicTags) if (tag !== "css") templateTags.set(name, tag);
|
|
4662
|
+
const cssTags = [...intrinsicTags].filter(([, tag]) => tag === "css").map(([name]) => name);
|
|
3739
4663
|
const found = [];
|
|
3740
4664
|
walk7(ast.program, (n2, parent, key) => {
|
|
3741
|
-
if (wantsLit && isTemplateTag(n2,
|
|
4665
|
+
if (wantsLit && isTemplateTag(n2, templateTags)) found.push(n2);
|
|
3742
4666
|
else if (wantsJsx && isJsxRoot(n2, parent, key)) found.push(n2);
|
|
3743
4667
|
});
|
|
3744
4668
|
const props = options.propsDestructure === false ? { edits: [], diagnostics: [], used: /* @__PURE__ */ new Set() } : collectPropsEdits(ast.program, code, { runtimeModule: options.runtimeModule });
|
|
3745
4669
|
const intrinsics = options.intrinsics === false ? { edits: [], diagnostics: [], imports: /* @__PURE__ */ new Map() } : collectIntrinsicEdits(ast.program);
|
|
3746
4670
|
if (intrinsics.edits.length) avoidBindingClashes(ast.program, intrinsics, moduleBindings(ast.program));
|
|
3747
4671
|
const sources = options.sourceLocations === true ? collectSourceEdits(ast.program, sourceName) : { edits: [], marked: 0 };
|
|
3748
|
-
const
|
|
4672
|
+
const styles = wantsStyles ? collectStyles(ast.program, sourceName, options.styles, { html: templateTags, css: cssTags }, { id, code }) : void 0;
|
|
4673
|
+
const silent = found.length === 0 && props.edits.length === 0 && sources.edits.length === 0 && intrinsics.edits.length === 0 && intrinsics.diagnostics.length === 0 && props.diagnostics.length === 0 && !styles?.edits.length && !styles?.diagnostics.length;
|
|
3749
4674
|
if (silent) return null;
|
|
3750
4675
|
found.sort((a, b) => b.start - a.start || a.end - b.end);
|
|
3751
4676
|
const used = new Set(props.used);
|
|
@@ -3759,20 +4684,32 @@ function transformTemplates(code, id, options = {}) {
|
|
|
3759
4684
|
declared: declaredNames(ast.program)
|
|
3760
4685
|
};
|
|
3761
4686
|
const hoisted = /* @__PURE__ */ new Map();
|
|
3762
|
-
const edits = [...props.edits, ...intrinsics.edits, ...sources.edits];
|
|
4687
|
+
const edits = [...props.edits, ...intrinsics.edits, ...sources.edits, ...styles?.edits ?? []];
|
|
3763
4688
|
for (const node of found) {
|
|
3764
4689
|
const nested = found.some(
|
|
3765
4690
|
(o) => o !== node && o.start <= node.start && o.end >= node.end && o.end - o.start > node.end - node.start
|
|
3766
4691
|
);
|
|
3767
4692
|
if (isJsx(node)) {
|
|
3768
|
-
edits.push({ start: node.start, end: node.end, code: compileJsx(code, node, edits, nested, used, needs, hoisted, options, sourceName) });
|
|
4693
|
+
edits.push({ start: node.start, end: node.end, code: compileJsx(code, node, edits, nested, used, needs, hoisted, options, sourceName, styles) });
|
|
3769
4694
|
continue;
|
|
3770
4695
|
}
|
|
3771
4696
|
const holes = node.quasi.expressions.map(
|
|
3772
4697
|
(e) => bindHole(code, e, edits, options.sourceLocations === true)
|
|
3773
4698
|
);
|
|
4699
|
+
const scope = styles?.scopes.find((s) => node.start >= s.start && node.end <= s.end)?.value;
|
|
4700
|
+
const owner = styles?.templateOwners.get(node.start);
|
|
4701
|
+
const templateStyles = options.styles && styles && (scope || owner) ? {
|
|
4702
|
+
options: options.styles,
|
|
4703
|
+
...scope ? { scope } : {},
|
|
4704
|
+
...owner ? { owner } : {},
|
|
4705
|
+
line: node.loc?.start.line ?? 0,
|
|
4706
|
+
column: node.loc?.start.column ?? 0,
|
|
4707
|
+
styles: styles.styles,
|
|
4708
|
+
diagnostics: styles.diagnostics
|
|
4709
|
+
} : void 0;
|
|
3774
4710
|
const result = compilePieces(toPieces(node), holes, {
|
|
3775
4711
|
...options,
|
|
4712
|
+
...templateStyles ? { templateStyles } : {},
|
|
3776
4713
|
hoistTemplates: true,
|
|
3777
4714
|
// A tag inside a template gets the same mark a JSX tag does. Without one, the nodes it
|
|
3778
4715
|
// makes are the only ones in the module carrying no mark, and they take whichever was
|
|
@@ -3781,12 +4718,13 @@ function transformTemplates(code, id, options = {}) {
|
|
|
3781
4718
|
// Same defaults as the plugin, so moving a build over is not a rendering change.
|
|
3782
4719
|
templateClone: options.templateClone ?? true,
|
|
3783
4720
|
partialTemplates: nested ? false : options.partialTemplates ?? true,
|
|
3784
|
-
svg: node.tag.name === "svg"
|
|
4721
|
+
svg: templateTags.get(node.tag.name) === "svg"
|
|
3785
4722
|
});
|
|
3786
4723
|
for (const symbol of result.imports) used.add(symbol);
|
|
3787
4724
|
collectNeeds(result.ir, needs);
|
|
3788
4725
|
edits.push({ start: node.start, end: node.end, code: adoptTemplates(result.code, result.templates, hoisted) });
|
|
3789
4726
|
}
|
|
4727
|
+
if (styles && options.styles) edits.push(...finishShadowStyles(styles, code, id));
|
|
3790
4728
|
const out = new MagicString(code);
|
|
3791
4729
|
for (const e of outermost(edits)) {
|
|
3792
4730
|
if (e.start === e.end) out.appendLeft(e.start, e.code);
|
|
@@ -3844,13 +4782,19 @@ function transformTemplates(code, id, options = {}) {
|
|
|
3844
4782
|
...loadDiagnostics.length ? { loadDiagnostics } : {},
|
|
3845
4783
|
...unresolvedDiagnostics.length ? { unresolvedDiagnostics } : {},
|
|
3846
4784
|
...props.diagnostics.length ? { propsDiagnostics: props.diagnostics } : {},
|
|
3847
|
-
...intrinsics.diagnostics.length ? { intrinsicDiagnostics: intrinsics.diagnostics } : {}
|
|
4785
|
+
...intrinsics.diagnostics.length ? { intrinsicDiagnostics: intrinsics.diagnostics } : {},
|
|
4786
|
+
...styles?.styles.length ? { styles: styles.styles } : {},
|
|
4787
|
+
...styles?.diagnostics.length ? { styleDiagnostics: styles.diagnostics } : {},
|
|
4788
|
+
...styles?.literals.length ? { styleLiterals: styles.literals } : {},
|
|
4789
|
+
...styles?.references.length ? { styleReferences: styles.references } : {}
|
|
3848
4790
|
};
|
|
3849
4791
|
}
|
|
3850
|
-
function compileJsx(code, node, edits, nested, used, needs, hoisted, options, sourceFile) {
|
|
4792
|
+
function compileJsx(code, node, edits, nested, used, needs, hoisted, options, sourceFile, styles) {
|
|
3851
4793
|
const ir = buildJsxIR(node, {
|
|
3852
4794
|
code: (n2) => slice(code, n2.start, n2.end, edits),
|
|
3853
4795
|
used,
|
|
4796
|
+
...styles?.scopes.length ? { scopes: styles.scopes } : {},
|
|
4797
|
+
...styles?.drop.size ? { dropStyles: styles.drop } : {},
|
|
3854
4798
|
...options.sourceLocations === true && sourceFile ? { sourceFile } : {}
|
|
3855
4799
|
});
|
|
3856
4800
|
analyzeStatic(ir);
|