@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/integrations.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
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
|
"use strict";
|
|
3
3
|
var __create = Object.create;
|
|
4
4
|
var __defProp = Object.defineProperty;
|
|
@@ -136,6 +136,11 @@ var init_builtins = __esm({
|
|
|
136
136
|
});
|
|
137
137
|
|
|
138
138
|
// src/analyze/intrinsics.ts
|
|
139
|
+
function tagIntrinsics(bound) {
|
|
140
|
+
const tags = /* @__PURE__ */ new Map();
|
|
141
|
+
for (const [name, tag] of Object.entries(TAG_INTRINSICS)) if (!bound.has(name)) tags.set(name, tag.export);
|
|
142
|
+
return tags;
|
|
143
|
+
}
|
|
139
144
|
function mayHaveIntrinsic(code) {
|
|
140
145
|
return INTRINSIC_CALL.test(code);
|
|
141
146
|
}
|
|
@@ -145,7 +150,7 @@ function isIntrinsicName(name) {
|
|
|
145
150
|
function isPrimitiveModule(source) {
|
|
146
151
|
return PRIMITIVE_MODULES.includes(source);
|
|
147
152
|
}
|
|
148
|
-
var REACTIVE_MODULE, INTRINSICS, RUNTIME_PRIMITIVES, PRIMITIVE_MODULES, INTRINSIC_CALL;
|
|
153
|
+
var REACTIVE_MODULE, INTRINSICS, RUNTIME_PRIMITIVES, PRIMITIVE_MODULES, TAG_INTRINSICS, INTRINSIC_CALL;
|
|
149
154
|
var init_intrinsics = __esm({
|
|
150
155
|
"src/analyze/intrinsics.ts"() {
|
|
151
156
|
"use strict";
|
|
@@ -208,10 +213,595 @@ var init_intrinsics = __esm({
|
|
|
208
213
|
"@fluixi/reactive/cached-resource",
|
|
209
214
|
"@fluixi/core"
|
|
210
215
|
];
|
|
216
|
+
TAG_INTRINSICS = {
|
|
217
|
+
$html: { export: "html", module: "@fluixi/core" },
|
|
218
|
+
$svg: { export: "svg", module: "@fluixi/core" },
|
|
219
|
+
$css: { export: "css", module: "@fluixi/core" }
|
|
220
|
+
};
|
|
211
221
|
INTRINSIC_CALL = new RegExp(`\\$(?:${Object.keys(INTRINSICS).map((n) => n.slice(1)).join("|")})\\s*\\(`);
|
|
212
222
|
}
|
|
213
223
|
});
|
|
214
224
|
|
|
225
|
+
// src/transform/styles.ts
|
|
226
|
+
function collectStyles(program, sourceName, options, tags = { html: /* @__PURE__ */ new Map([["html", "html"]]) }, module2) {
|
|
227
|
+
const plan = {
|
|
228
|
+
scopes: [],
|
|
229
|
+
templateOwners: /* @__PURE__ */ new Map(),
|
|
230
|
+
drop: /* @__PURE__ */ new Set(),
|
|
231
|
+
styles: [],
|
|
232
|
+
diagnostics: [],
|
|
233
|
+
edits: [],
|
|
234
|
+
literals: [],
|
|
235
|
+
references: [],
|
|
236
|
+
shadowClasses: /* @__PURE__ */ new Map()
|
|
237
|
+
};
|
|
238
|
+
if (!options) return plan;
|
|
239
|
+
const literalsOf = findLiterals(program, options.cssModules ?? ["@fluixi/core", "@fluixi/dom"], plan, tags.css ?? []);
|
|
240
|
+
plan.names = literalsOf;
|
|
241
|
+
const classOf = /* @__PURE__ */ new Map();
|
|
242
|
+
const shadowOf = (owner) => {
|
|
243
|
+
const cls = classOf.get(owner);
|
|
244
|
+
return cls ? plan.shadowClasses.get(cls) : void 0;
|
|
245
|
+
};
|
|
246
|
+
const resolved = /* @__PURE__ */ new Map();
|
|
247
|
+
const piecesToNodes = (quasis, expressions, at, stack) => {
|
|
248
|
+
const out = [];
|
|
249
|
+
for (let i = 0; i < quasis.length; i++) {
|
|
250
|
+
const text = quasis[i].value.cooked ?? quasis[i].value.raw;
|
|
251
|
+
if (text.trim()) {
|
|
252
|
+
try {
|
|
253
|
+
const start = quasis[i].loc?.start;
|
|
254
|
+
out.push(...options.process(text, sourceName).map((n) => start ? shiftLoc(n, sourceName, start) : n));
|
|
255
|
+
} catch (error) {
|
|
256
|
+
plan.diagnostics.push({ ...at, message: `CSS could not be processed: ${error.message}` });
|
|
257
|
+
return null;
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
const expr = expressions[i];
|
|
261
|
+
if (!expr) continue;
|
|
262
|
+
const value = expr.type === "Identifier" ? resolveLiteral(expr.name, at, stack) : void 0;
|
|
263
|
+
if (value === void 0) {
|
|
264
|
+
plan.diagnostics.push({
|
|
265
|
+
...at,
|
|
266
|
+
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))."
|
|
267
|
+
});
|
|
268
|
+
return null;
|
|
269
|
+
}
|
|
270
|
+
if (value === null) return null;
|
|
271
|
+
out.push(...value);
|
|
272
|
+
}
|
|
273
|
+
return out;
|
|
274
|
+
};
|
|
275
|
+
function resolveLiteral(name, at, stack) {
|
|
276
|
+
const imported = literalsOf.imports.get(name);
|
|
277
|
+
if (imported) {
|
|
278
|
+
const nodes = options?.imported?.get(`${imported.source}#${imported.name}`);
|
|
279
|
+
if (nodes) return nodes.map((n) => keepLocIn(n, options?.importedModules));
|
|
280
|
+
plan.references.push({ name: imported.name, source: imported.source, ...at });
|
|
281
|
+
plan.diagnostics.push({
|
|
282
|
+
...at,
|
|
283
|
+
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.`
|
|
284
|
+
});
|
|
285
|
+
return null;
|
|
286
|
+
}
|
|
287
|
+
const literal = literalsOf.literals.get(name);
|
|
288
|
+
if (!literal) return void 0;
|
|
289
|
+
if (stack.includes(name)) {
|
|
290
|
+
plan.diagnostics.push({ ...at, message: `css\`\` values include each other: ${[...stack, name].join(" → ")}.` });
|
|
291
|
+
return null;
|
|
292
|
+
}
|
|
293
|
+
if (!resolved.has(name)) {
|
|
294
|
+
resolved.set(name, piecesToNodes(literal.quasi.quasis, literal.quasi.expressions, at, [...stack, name]));
|
|
295
|
+
}
|
|
296
|
+
return resolved.get(name);
|
|
297
|
+
}
|
|
298
|
+
for (const [name, literal] of literalsOf.literals) {
|
|
299
|
+
const at = { line: literal.loc?.start.line ?? 0, column: literal.loc?.start.column ?? 0 };
|
|
300
|
+
const nodes = resolveLiteral(name, at, []);
|
|
301
|
+
const id = hash(`${sourceName}:css:${name}`);
|
|
302
|
+
plan.edits.push({ start: literal.start, end: literal.end, code: `({ $fxStyle: ${JSON.stringify(id)} })` });
|
|
303
|
+
if (nodes) plan.literals.push({ id, name, css: printStyle(nodes, options.minify), nodes });
|
|
304
|
+
}
|
|
305
|
+
const scopeOf = /* @__PURE__ */ new Map();
|
|
306
|
+
const names = /* @__PURE__ */ new Map();
|
|
307
|
+
const named = /* @__PURE__ */ new Map();
|
|
308
|
+
const visit = (node, owners) => {
|
|
309
|
+
if (!node || typeof node !== "object") return;
|
|
310
|
+
if (node.type === "VariableDeclarator" && node.id.type === "Identifier" && node.init && FUNCTIONS.has(node.init.type)) {
|
|
311
|
+
named.set(node.init, node.id.name);
|
|
312
|
+
}
|
|
313
|
+
if ((node.type === "ClassDeclaration" || node.type === "ClassExpression") && node.id) {
|
|
314
|
+
for (const member of node.body.body) if (member.type === "ClassMethod") named.set(member, node.id.name);
|
|
315
|
+
}
|
|
316
|
+
if (node.type === "ClassDeclaration" || node.type === "ClassExpression") {
|
|
317
|
+
for (const member of node.body.body) if (member.type === "ClassMethod") classOf.set(member, node);
|
|
318
|
+
const shadow = staticMember(node, "shadow");
|
|
319
|
+
if (shadow?.value && !(shadow.value.type === "BooleanLiteral" && shadow.value.value === false)) {
|
|
320
|
+
plan.shadowClasses.set(node, { node, styles: staticMember(node, "styles"), indexes: [] });
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
if (node.type === "TaggedTemplateExpression" && node.tag.type === "Identifier" && tags.html.get(node.tag.name) === "html") {
|
|
324
|
+
const text = node.quasi.quasis.map((q) => q.value.raw).join("");
|
|
325
|
+
if (/<style[\s>]/.test(text)) {
|
|
326
|
+
const at = { line: node.loc?.start.line ?? 0, column: node.loc?.start.column ?? 0 };
|
|
327
|
+
const owner = owners[0];
|
|
328
|
+
if (!owner) plan.diagnostics.push({ ...at, message: "<style> has to be written inside a component." });
|
|
329
|
+
else {
|
|
330
|
+
const id = idFor(owner);
|
|
331
|
+
const shadow = shadowOf(owner);
|
|
332
|
+
plan.templateOwners.set(node.start, { id, component: functionName(owner, named) });
|
|
333
|
+
for (const block of templateBlocks(node.quasi)) compileBlock(block, block.scoped, owner, at);
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
const inner = FUNCTIONS.has(node.type) ? [...owners, node] : owners;
|
|
338
|
+
if (node.type === "JSXElement" && isStyle(node)) {
|
|
339
|
+
handle(node, owners);
|
|
340
|
+
return;
|
|
341
|
+
}
|
|
342
|
+
for (const key of Object.keys(node)) {
|
|
343
|
+
if (key === "loc" || key === "leadingComments" || key === "trailingComments" || key === "innerComments") continue;
|
|
344
|
+
const value = node[key];
|
|
345
|
+
if (Array.isArray(value)) for (const v of value) visit(v, inner);
|
|
346
|
+
else if (value && typeof value === "object" && "type" in value) visit(value, inner);
|
|
347
|
+
}
|
|
348
|
+
};
|
|
349
|
+
const handle = (node, owners) => {
|
|
350
|
+
const at = { line: node.loc?.start.line ?? 0, column: node.loc?.start.column ?? 0 };
|
|
351
|
+
const pieces = blockPieces(node);
|
|
352
|
+
if (pieces === null) {
|
|
353
|
+
plan.diagnostics.push({
|
|
354
|
+
...at,
|
|
355
|
+
message: "<style> needs its CSS as one template literal, <style>{`...`}</style>: JSX reads a bare `{` as an expression."
|
|
356
|
+
});
|
|
357
|
+
return;
|
|
358
|
+
}
|
|
359
|
+
const owner = owners[0];
|
|
360
|
+
if (!owner) {
|
|
361
|
+
plan.diagnostics.push({ ...at, message: "<style> has to be written inside a component." });
|
|
362
|
+
return;
|
|
363
|
+
}
|
|
364
|
+
compileBlock(pieces, isScoped(node), owner, at);
|
|
365
|
+
plan.drop.add(node.start);
|
|
366
|
+
};
|
|
367
|
+
const compileBlock = (pieces, scoped, owner, at) => {
|
|
368
|
+
const component = functionName(owner, named);
|
|
369
|
+
const id = idFor(owner);
|
|
370
|
+
const processed = piecesToNodes(pieces.quasis, pieces.expressions, at, []);
|
|
371
|
+
if (!processed) return;
|
|
372
|
+
let nodes = processed;
|
|
373
|
+
const shadow = shadowOf(owner);
|
|
374
|
+
if (scoped && !shadow) {
|
|
375
|
+
if (!plan.scopes.some((s) => s.value === id)) plan.scopes.push({ start: owner.start, end: owner.end, value: id });
|
|
376
|
+
nodes = scopeNodes(nodes, id, (message) => plan.diagnostics.push({ ...at, message }));
|
|
377
|
+
}
|
|
378
|
+
const printed = module2 ? printStyleWithMap(nodes, options.minify, sourceName, module2, options.importedModules) : { css: printStyle(nodes, options.minify) };
|
|
379
|
+
plan.styles.push({ id, scoped: scoped && !shadow, component, ...printed, ...shadow ? { shadow: true } : {}, ...at });
|
|
380
|
+
if (shadow) shadow.indexes.push(plan.styles.length - 1);
|
|
381
|
+
};
|
|
382
|
+
function idFor(owner) {
|
|
383
|
+
let id = scopeOf.get(owner);
|
|
384
|
+
if (!id) {
|
|
385
|
+
const component = functionName(owner, named);
|
|
386
|
+
const seen = names.get(component) ?? 0;
|
|
387
|
+
names.set(component, seen + 1);
|
|
388
|
+
id = hash(`${sourceName}:${component}${seen ? ":" + seen : ""}`);
|
|
389
|
+
scopeOf.set(owner, id);
|
|
390
|
+
}
|
|
391
|
+
return id;
|
|
392
|
+
}
|
|
393
|
+
visit(program, []);
|
|
394
|
+
return plan;
|
|
395
|
+
}
|
|
396
|
+
function applyTemplateStyles(ir, t4) {
|
|
397
|
+
const walk8 = (node) => {
|
|
398
|
+
const children = node.children;
|
|
399
|
+
if (children) {
|
|
400
|
+
for (let i = children.length - 1; i >= 0; i--) {
|
|
401
|
+
const child = children[i];
|
|
402
|
+
if (child.kind === "element" && child.tag === "style" && t4.owner) children.splice(i, 1);
|
|
403
|
+
else walk8(child);
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
if (t4.scope && node.kind === "element" && node.tag !== "style" && node.props && !node.props.some((p) => p.name === SCOPE_ATTR)) {
|
|
407
|
+
node.props.unshift({ name: SCOPE_ATTR, kind: "attr", literal: t4.scope });
|
|
408
|
+
}
|
|
409
|
+
};
|
|
410
|
+
walk8(ir);
|
|
411
|
+
}
|
|
412
|
+
function staticMember(cls, name) {
|
|
413
|
+
return cls.body.body.find(
|
|
414
|
+
(m) => m.type === "ClassProperty" && m.static && (m.key.type === "Identifier" && m.key.name === name || m.key.type === "StringLiteral" && m.key.value === name)
|
|
415
|
+
);
|
|
416
|
+
}
|
|
417
|
+
function finishShadowStyles(plan, code, moduleId) {
|
|
418
|
+
const edits = [];
|
|
419
|
+
const imports = [];
|
|
420
|
+
let next = 0;
|
|
421
|
+
const importOf = (specifier) => {
|
|
422
|
+
const local = `__fxShadow${next++}`;
|
|
423
|
+
imports.push(`import ${local} from ${JSON.stringify(specifier)};
|
|
424
|
+
`);
|
|
425
|
+
return local;
|
|
426
|
+
};
|
|
427
|
+
for (const shadow of plan.shadowClasses.values()) {
|
|
428
|
+
const blocks = shadow.indexes.map((i) => importOf(styleIds.inline(moduleId, i)));
|
|
429
|
+
let value;
|
|
430
|
+
const prop = shadow.styles;
|
|
431
|
+
if (prop?.value) {
|
|
432
|
+
const start = prop.value.start;
|
|
433
|
+
let text = code.slice(start, prop.value.end);
|
|
434
|
+
const replacements = [];
|
|
435
|
+
walkIdentifiers(prop.value, (id) => {
|
|
436
|
+
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;
|
|
437
|
+
if (local) replacements.push({ at: id.start - start, length: id.name.length, with: local });
|
|
438
|
+
});
|
|
439
|
+
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);
|
|
440
|
+
value = text;
|
|
441
|
+
}
|
|
442
|
+
if (!blocks.length && value === void 0) continue;
|
|
443
|
+
if (prop?.value) {
|
|
444
|
+
const merged = blocks.length ? `[${value}, ${blocks.join(", ")}]` : value;
|
|
445
|
+
edits.push({ start: prop.value.start, end: prop.value.end, code: merged });
|
|
446
|
+
} else if (blocks.length) {
|
|
447
|
+
const open = shadow.node.body.start + 1;
|
|
448
|
+
edits.push({ start: open, end: open, code: ` static styles = [${blocks.join(", ")}];` });
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
if (imports.length) edits.push({ start: 0, end: 0, code: imports.join("") });
|
|
452
|
+
return edits;
|
|
453
|
+
}
|
|
454
|
+
function walkIdentifiers(node, visit) {
|
|
455
|
+
if (!node || typeof node !== "object") return;
|
|
456
|
+
if (node.type === "Identifier") return visit(node);
|
|
457
|
+
if (node.type === "MemberExpression") return walkIdentifiers(node.object, visit);
|
|
458
|
+
if (node.type === "ObjectProperty") return walkIdentifiers(node.value, visit);
|
|
459
|
+
for (const key of Object.keys(node)) {
|
|
460
|
+
if (key === "loc") continue;
|
|
461
|
+
const value = node[key];
|
|
462
|
+
if (Array.isArray(value)) for (const v of value) walkIdentifiers(v, visit);
|
|
463
|
+
else if (value && typeof value === "object" && "type" in value) walkIdentifiers(value, visit);
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
function isStyle(node) {
|
|
467
|
+
const name = node.openingElement.name;
|
|
468
|
+
return name.type === "JSXIdentifier" && name.name === "style";
|
|
469
|
+
}
|
|
470
|
+
function isScoped(node) {
|
|
471
|
+
return node.openingElement.attributes.some((a) => a.type === "JSXAttribute" && a.name.type === "JSXIdentifier" && a.name.name === "scoped");
|
|
472
|
+
}
|
|
473
|
+
function templateBlocks(quasi) {
|
|
474
|
+
const blocks = [];
|
|
475
|
+
let open = null;
|
|
476
|
+
quasi.quasis.forEach((q, i) => {
|
|
477
|
+
const raw = q.value.raw;
|
|
478
|
+
let from = 0;
|
|
479
|
+
while (from <= raw.length) {
|
|
480
|
+
if (!open) {
|
|
481
|
+
const tag = /<style\b([^>]*)>/g;
|
|
482
|
+
tag.lastIndex = from;
|
|
483
|
+
const m = tag.exec(raw);
|
|
484
|
+
if (!m) break;
|
|
485
|
+
open = { quasis: [], expressions: [], scoped: /\bscoped\b/.test(m[1]) };
|
|
486
|
+
from = m.index + m[0].length;
|
|
487
|
+
}
|
|
488
|
+
const close = raw.indexOf("</style", from);
|
|
489
|
+
open.quasis.push(slicePiece(q, raw, from, close === -1 ? raw.length : close));
|
|
490
|
+
if (close === -1) break;
|
|
491
|
+
blocks.push(open);
|
|
492
|
+
open = null;
|
|
493
|
+
from = close;
|
|
494
|
+
}
|
|
495
|
+
const expr = quasi.expressions[i];
|
|
496
|
+
if (open && expr) open.expressions.push(expr);
|
|
497
|
+
});
|
|
498
|
+
return blocks;
|
|
499
|
+
}
|
|
500
|
+
function slicePiece(q, raw, from, to) {
|
|
501
|
+
const text = raw.slice(from, to);
|
|
502
|
+
const start = q.loc?.start;
|
|
503
|
+
if (!start) return { type: "TemplateElement", value: { raw: text, cooked: text } };
|
|
504
|
+
const before = raw.slice(0, from).split("\n");
|
|
505
|
+
const line = start.line + before.length - 1;
|
|
506
|
+
const column = before.length > 1 ? before[before.length - 1].length : start.column + from;
|
|
507
|
+
return { type: "TemplateElement", value: { raw: text, cooked: text }, loc: { start: { line, column } } };
|
|
508
|
+
}
|
|
509
|
+
function blockPieces(node) {
|
|
510
|
+
const meaningful = node.children.filter((c) => !(c.type === "JSXText" && !c.value.trim()));
|
|
511
|
+
if (meaningful.length === 0) return { quasis: [], expressions: [] };
|
|
512
|
+
if (meaningful.length !== 1) return null;
|
|
513
|
+
const only = meaningful[0];
|
|
514
|
+
if (only.type !== "JSXExpressionContainer") return null;
|
|
515
|
+
const expr = only.expression;
|
|
516
|
+
if (expr.type === "StringLiteral") return { quasis: [{ type: "TemplateElement", value: { raw: expr.value, cooked: expr.value } }], expressions: [] };
|
|
517
|
+
if (expr.type === "TemplateLiteral") return { quasis: expr.quasis, expressions: expr.expressions };
|
|
518
|
+
return null;
|
|
519
|
+
}
|
|
520
|
+
function findLiterals(program, modules, plan, intrinsic) {
|
|
521
|
+
const literals = /* @__PURE__ */ new Map();
|
|
522
|
+
const imports = /* @__PURE__ */ new Map();
|
|
523
|
+
const tags = new Set(intrinsic);
|
|
524
|
+
for (const statement of program.body ?? []) {
|
|
525
|
+
if (statement.type !== "ImportDeclaration") continue;
|
|
526
|
+
const source = statement.source.value;
|
|
527
|
+
const specifiers = statement.specifiers;
|
|
528
|
+
for (const sp of specifiers) {
|
|
529
|
+
if (sp.type === "ImportSpecifier") imports.set(sp.local.name, { source, name: sp.imported.name ?? sp.imported.value });
|
|
530
|
+
}
|
|
531
|
+
if (!modules.includes(source)) continue;
|
|
532
|
+
const css = specifiers.find((sp) => sp.type === "ImportSpecifier" && (sp.imported.name ?? sp.imported.value) === "css");
|
|
533
|
+
if (!css) continue;
|
|
534
|
+
const local = css.local.name;
|
|
535
|
+
tags.add(local);
|
|
536
|
+
imports.delete(local);
|
|
537
|
+
plan.edits.push({ start: statement.start, end: statement.end, code: importWithout(statement, css) });
|
|
538
|
+
}
|
|
539
|
+
if (tags.size === 0) return { literals, imports };
|
|
540
|
+
const visit = (node) => {
|
|
541
|
+
if (!node || typeof node !== "object") return;
|
|
542
|
+
if (node.type === "VariableDeclarator" && node.id.type === "Identifier" && node.init?.type === "TaggedTemplateExpression" && node.init.tag.type === "Identifier" && tags.has(node.init.tag.name)) {
|
|
543
|
+
literals.set(node.id.name, node.init);
|
|
544
|
+
}
|
|
545
|
+
for (const key of Object.keys(node)) {
|
|
546
|
+
if (key === "loc") continue;
|
|
547
|
+
const value = node[key];
|
|
548
|
+
if (Array.isArray(value)) for (const v of value) visit(v);
|
|
549
|
+
else if (value && typeof value === "object" && "type" in value) visit(value);
|
|
550
|
+
}
|
|
551
|
+
};
|
|
552
|
+
visit(program);
|
|
553
|
+
return { literals, imports };
|
|
554
|
+
}
|
|
555
|
+
function importWithout(statement, removed) {
|
|
556
|
+
const rest = statement.specifiers.filter((sp) => sp !== removed);
|
|
557
|
+
const source = JSON.stringify(statement.source.value);
|
|
558
|
+
if (rest.length === 0) return "";
|
|
559
|
+
const def = rest.find((sp) => sp.type === "ImportDefaultSpecifier");
|
|
560
|
+
const ns = rest.find((sp) => sp.type === "ImportNamespaceSpecifier");
|
|
561
|
+
const named = rest.filter((sp) => sp.type === "ImportSpecifier").map((sp) => {
|
|
562
|
+
const imported = sp.imported.name ?? JSON.stringify(sp.imported.value);
|
|
563
|
+
return imported === sp.local.name ? imported : `${imported} as ${sp.local.name}`;
|
|
564
|
+
});
|
|
565
|
+
const parts = [def?.local.name, ns ? `* as ${ns.local.name}` : void 0, named.length ? `{ ${named.join(", ")} }` : void 0].filter(Boolean);
|
|
566
|
+
return `import ${parts.join(", ")} from ${source};`;
|
|
567
|
+
}
|
|
568
|
+
function functionName(fn, named) {
|
|
569
|
+
if ((fn.type === "FunctionDeclaration" || fn.type === "FunctionExpression") && fn.id) return fn.id.name;
|
|
570
|
+
return named.get(fn) ?? "anonymous";
|
|
571
|
+
}
|
|
572
|
+
function hash(text) {
|
|
573
|
+
let h = 2166136261;
|
|
574
|
+
for (let i = 0; i < text.length; i++) {
|
|
575
|
+
h ^= text.charCodeAt(i);
|
|
576
|
+
h = Math.imul(h, 16777619);
|
|
577
|
+
}
|
|
578
|
+
return (h >>> 0).toString(36);
|
|
579
|
+
}
|
|
580
|
+
function scopeNodes(nodes, id, warn = () => {
|
|
581
|
+
}) {
|
|
582
|
+
return nodes.map((node) => {
|
|
583
|
+
if (node.kind === "rule") return { ...node, selector: scopeSelector(node.selector, id, warn) };
|
|
584
|
+
if (node.kind === "at-rule" && !OPAQUE.test(node.name)) return { ...node, nodes: scopeNodes(node.nodes, id, warn) };
|
|
585
|
+
return node;
|
|
586
|
+
});
|
|
587
|
+
}
|
|
588
|
+
function scopeSelector(selector, id, warn = () => {
|
|
589
|
+
}) {
|
|
590
|
+
return splitTop(selector, ",").map((complex) => scopeComplex(complex.trim(), `[${SCOPE_ATTR}="${id}"]`, warn)).join(", ");
|
|
591
|
+
}
|
|
592
|
+
function scopeComplex(selector, attr, warn) {
|
|
593
|
+
if (/:host\b|::slotted\(/.test(selector)) {
|
|
594
|
+
warn(`\`${selector}\` only means something in a shadow root; in a light-DOM component it is left as written.`);
|
|
595
|
+
return selector;
|
|
596
|
+
}
|
|
597
|
+
const parts = compounds(selector);
|
|
598
|
+
const deep = parts.findIndex((p) => p.text.startsWith(":deep("));
|
|
599
|
+
if (deep !== -1) {
|
|
600
|
+
const inner = unwrap(parts[deep].text, ":deep(");
|
|
601
|
+
const before = parts.slice(0, deep);
|
|
602
|
+
if (before.length === 0) return `${attr} ${inner}`;
|
|
603
|
+
const scopedBefore = scopeAt(before, before.length - 1, attr);
|
|
604
|
+
return `${join(scopedBefore)} ${inner}`;
|
|
605
|
+
}
|
|
606
|
+
let target = -1;
|
|
607
|
+
for (let i = parts.length - 1; i >= 0; i--) {
|
|
608
|
+
if (!parts[i].text.startsWith(":global(")) {
|
|
609
|
+
target = i;
|
|
610
|
+
break;
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
const out = target === -1 ? parts : scopeAt(parts, target, attr);
|
|
614
|
+
return join(out.map((p) => p.text.startsWith(":global(") ? { ...p, text: unwrap(p.text, ":global(") } : p));
|
|
615
|
+
}
|
|
616
|
+
function scopeAt(parts, index, attr) {
|
|
617
|
+
return parts.map((p, i) => i === index ? { ...p, text: insertAttr(p.text, attr) } : p);
|
|
618
|
+
}
|
|
619
|
+
function insertAttr(compound, attr) {
|
|
620
|
+
let depth = 0;
|
|
621
|
+
let quote = "";
|
|
622
|
+
for (let i = 0; i < compound.length; i++) {
|
|
623
|
+
const c = compound[i];
|
|
624
|
+
if (quote) {
|
|
625
|
+
if (c === "\\") i++;
|
|
626
|
+
else if (c === quote) quote = "";
|
|
627
|
+
continue;
|
|
628
|
+
}
|
|
629
|
+
if (c === "\\") {
|
|
630
|
+
i++;
|
|
631
|
+
continue;
|
|
632
|
+
}
|
|
633
|
+
if (c === '"' || c === "'") quote = c;
|
|
634
|
+
else if (c === "(" || c === "[") depth++;
|
|
635
|
+
else if (c === ")" || c === "]") depth--;
|
|
636
|
+
else if (c === ":" && depth === 0 && i > 0) return compound.slice(0, i) + attr + compound.slice(i);
|
|
637
|
+
}
|
|
638
|
+
return compound + attr;
|
|
639
|
+
}
|
|
640
|
+
function compounds(selector) {
|
|
641
|
+
const out = [];
|
|
642
|
+
let depth = 0;
|
|
643
|
+
let quote = "";
|
|
644
|
+
let current = "";
|
|
645
|
+
let combinator = "";
|
|
646
|
+
const push = () => {
|
|
647
|
+
if (current.trim()) out.push({ combinator: out.length ? combinator || " " : "", text: current.trim() });
|
|
648
|
+
current = "";
|
|
649
|
+
combinator = "";
|
|
650
|
+
};
|
|
651
|
+
for (let i = 0; i < selector.length; i++) {
|
|
652
|
+
const c = selector[i];
|
|
653
|
+
if (quote) {
|
|
654
|
+
current += c;
|
|
655
|
+
if (c === "\\") current += selector[++i] ?? "";
|
|
656
|
+
else if (c === quote) quote = "";
|
|
657
|
+
continue;
|
|
658
|
+
}
|
|
659
|
+
if (c === "\\") {
|
|
660
|
+
current += c + (selector[++i] ?? "");
|
|
661
|
+
continue;
|
|
662
|
+
}
|
|
663
|
+
if (c === '"' || c === "'") quote = c;
|
|
664
|
+
if (c === "(" || c === "[") depth++;
|
|
665
|
+
if (c === ")" || c === "]") depth--;
|
|
666
|
+
if (depth === 0 && (c === ">" || c === "+" || c === "~")) {
|
|
667
|
+
push();
|
|
668
|
+
combinator = c;
|
|
669
|
+
continue;
|
|
670
|
+
}
|
|
671
|
+
if (depth === 0 && /\s/.test(c)) {
|
|
672
|
+
if (current.trim()) {
|
|
673
|
+
const keep = combinator;
|
|
674
|
+
push();
|
|
675
|
+
combinator = keep;
|
|
676
|
+
}
|
|
677
|
+
continue;
|
|
678
|
+
}
|
|
679
|
+
current += c;
|
|
680
|
+
}
|
|
681
|
+
push();
|
|
682
|
+
return out;
|
|
683
|
+
}
|
|
684
|
+
function join(parts) {
|
|
685
|
+
return parts.map((p, i) => i === 0 ? p.text : p.combinator === " " ? ` ${p.text}` : ` ${p.combinator} ${p.text}`).join("");
|
|
686
|
+
}
|
|
687
|
+
function unwrap(text, prefix) {
|
|
688
|
+
return text.slice(prefix.length, text.lastIndexOf(")")).trim() + text.slice(text.lastIndexOf(")") + 1);
|
|
689
|
+
}
|
|
690
|
+
function splitTop(selector, separator) {
|
|
691
|
+
const parts = [];
|
|
692
|
+
let depth = 0;
|
|
693
|
+
let quote = "";
|
|
694
|
+
let start = 0;
|
|
695
|
+
for (let i = 0; i < selector.length; i++) {
|
|
696
|
+
const c = selector[i];
|
|
697
|
+
if (quote) {
|
|
698
|
+
if (c === "\\") i++;
|
|
699
|
+
else if (c === quote) quote = "";
|
|
700
|
+
} else if (c === '"' || c === "'") quote = c;
|
|
701
|
+
else if (c === "\\") i++;
|
|
702
|
+
else if (c === "(" || c === "[") depth++;
|
|
703
|
+
else if (c === ")" || c === "]") depth--;
|
|
704
|
+
else if (c === separator && depth === 0) {
|
|
705
|
+
parts.push(selector.slice(start, i));
|
|
706
|
+
start = i + 1;
|
|
707
|
+
}
|
|
708
|
+
}
|
|
709
|
+
parts.push(selector.slice(start));
|
|
710
|
+
return parts.filter((p) => p.trim());
|
|
711
|
+
}
|
|
712
|
+
function shiftLoc(node, source, start) {
|
|
713
|
+
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;
|
|
714
|
+
if (node.kind === "rule" || node.kind === "at-rule") return { ...node, loc, nodes: node.nodes.map((n) => shiftLoc(n, source, start)) };
|
|
715
|
+
return { ...node, loc };
|
|
716
|
+
}
|
|
717
|
+
function keepLocIn(node, modules) {
|
|
718
|
+
const keep = node.loc !== void 0 && modules?.has(node.loc.source) === true;
|
|
719
|
+
const { loc, ...rest } = node;
|
|
720
|
+
const kept = keep ? { ...rest, loc } : rest;
|
|
721
|
+
if (kept.kind === "rule" || kept.kind === "at-rule") return { ...kept, nodes: kept.nodes.map((n) => keepLocIn(n, modules)) };
|
|
722
|
+
return kept;
|
|
723
|
+
}
|
|
724
|
+
function printStyleWithMap(nodes, minify, sourceName, module2, others) {
|
|
725
|
+
const sources = [module2];
|
|
726
|
+
const index = /* @__PURE__ */ new Map([[sourceName, 0]]);
|
|
727
|
+
const sourceOf = (name) => {
|
|
728
|
+
if (index.has(name)) return index.get(name);
|
|
729
|
+
const other = others?.get(name);
|
|
730
|
+
if (!other) return void 0;
|
|
731
|
+
index.set(name, sources.push(other) - 1);
|
|
732
|
+
return index.get(name);
|
|
733
|
+
};
|
|
734
|
+
const lines = [[]];
|
|
735
|
+
let css = "";
|
|
736
|
+
let column = 0;
|
|
737
|
+
const emit = (text) => {
|
|
738
|
+
for (const ch of text) {
|
|
739
|
+
css += ch;
|
|
740
|
+
if (ch === "\n") {
|
|
741
|
+
lines.push([]);
|
|
742
|
+
column = 0;
|
|
743
|
+
} else column++;
|
|
744
|
+
}
|
|
745
|
+
};
|
|
746
|
+
const mark = (loc) => {
|
|
747
|
+
const at = loc ? sourceOf(loc.source) : void 0;
|
|
748
|
+
if (loc && at !== void 0) lines[lines.length - 1].push([column, at, loc.line - 1, loc.column]);
|
|
749
|
+
};
|
|
750
|
+
const write = (node, depth) => {
|
|
751
|
+
const pad = minify ? "" : " ".repeat(depth);
|
|
752
|
+
const nl = minify ? "" : "\n";
|
|
753
|
+
const sp = minify ? "" : " ";
|
|
754
|
+
emit(pad);
|
|
755
|
+
mark(node.loc);
|
|
756
|
+
if (node.kind === "declaration") {
|
|
757
|
+
emit(`${node.property}:${sp}${node.value}${node.important ? `${sp}!important` : ""};${nl}`);
|
|
758
|
+
} else if (node.kind === "raw") {
|
|
759
|
+
emit(`${node.text}${nl}`);
|
|
760
|
+
} else {
|
|
761
|
+
emit(`${node.kind === "rule" ? node.selector : `@${node.name}${node.params ? " " + node.params : ""}`}${sp}{${nl}`);
|
|
762
|
+
for (const child of node.nodes) write(child, depth + 1);
|
|
763
|
+
emit(`${pad}}${nl}`);
|
|
764
|
+
}
|
|
765
|
+
};
|
|
766
|
+
for (const node of nodes) write(node, 0);
|
|
767
|
+
return { css, map: { version: 3, sources: sources.map((s) => s.id), sourcesContent: sources.map((s) => s.code), names: [], mappings: (0, import_sourcemap_codec.encode)(lines) } };
|
|
768
|
+
}
|
|
769
|
+
function printStyle(nodes, minify = false) {
|
|
770
|
+
const out = [];
|
|
771
|
+
const write = (node, depth) => {
|
|
772
|
+
const pad = minify ? "" : " ".repeat(depth);
|
|
773
|
+
const nl = minify ? "" : "\n";
|
|
774
|
+
const sp = minify ? "" : " ";
|
|
775
|
+
if (node.kind === "declaration") {
|
|
776
|
+
out.push(`${pad}${node.property}:${sp}${node.value}${node.important ? `${sp}!important` : ""};${nl}`);
|
|
777
|
+
} else if (node.kind === "raw") {
|
|
778
|
+
out.push(`${pad}${node.text}${nl}`);
|
|
779
|
+
} else {
|
|
780
|
+
const header = node.kind === "rule" ? node.selector : `@${node.name}${node.params ? " " + node.params : ""}`;
|
|
781
|
+
out.push(`${pad}${header}${sp}{${nl}`);
|
|
782
|
+
for (const child of node.nodes) write(child, depth + 1);
|
|
783
|
+
out.push(`${pad}}${nl}`);
|
|
784
|
+
}
|
|
785
|
+
};
|
|
786
|
+
for (const node of nodes) write(node, 0);
|
|
787
|
+
return out.join("");
|
|
788
|
+
}
|
|
789
|
+
var import_sourcemap_codec, SCOPE_ATTR, FUNCTIONS, styleIds, OPAQUE;
|
|
790
|
+
var init_styles = __esm({
|
|
791
|
+
"src/transform/styles.ts"() {
|
|
792
|
+
"use strict";
|
|
793
|
+
import_sourcemap_codec = require("@jridgewell/sourcemap-codec");
|
|
794
|
+
SCOPE_ATTR = "data-fx-s";
|
|
795
|
+
FUNCTIONS = /* @__PURE__ */ new Set(["FunctionDeclaration", "FunctionExpression", "ArrowFunctionExpression", "ObjectMethod", "ClassMethod"]);
|
|
796
|
+
styleIds = {
|
|
797
|
+
block: (owner, index) => `${owner}.fx-${index}.css`,
|
|
798
|
+
inline: (owner, index) => `${owner}.fx-${index}.css?inline`,
|
|
799
|
+
literal: (owner, name) => `${owner}.fx-literal-${name}.css?inline`
|
|
800
|
+
};
|
|
801
|
+
OPAQUE = /(^|-)keyframes$|^font-face$|^property$|^counter-style$|^page$|^font-feature-values$/;
|
|
802
|
+
}
|
|
803
|
+
});
|
|
804
|
+
|
|
215
805
|
// src/resolve/load-directive.ts
|
|
216
806
|
function isLoadDirective(name) {
|
|
217
807
|
return name.startsWith("load:");
|
|
@@ -1079,7 +1669,7 @@ function emitComponent(name, props, children, used, templates, at) {
|
|
|
1079
1669
|
}
|
|
1080
1670
|
let obj = `{ ${bodies.map(([name2, body]) => `get ${propKey(name2)}() { return ${body}; }`).join(", ")} }`;
|
|
1081
1671
|
if (bodies.some(([, body]) => /\bthis\b/.test(body))) {
|
|
1082
|
-
const thunks = bodies.map(([name2, body]) => `${JSON.stringify(name2)}: () => ${body}`);
|
|
1672
|
+
const thunks = bodies.map(([name2, body]) => `${JSON.stringify(name2)}: () => (${body})`);
|
|
1083
1673
|
const getters = bodies.map(([name2]) => `get ${propKey(name2)}() { return _$t[${JSON.stringify(name2)}](); }`);
|
|
1084
1674
|
obj = `((_$t) => ({ ${getters.join(", ")} }))({ ${thunks.join(", ")} })`;
|
|
1085
1675
|
}
|
|
@@ -1244,6 +1834,277 @@ var init_text = __esm({
|
|
|
1244
1834
|
}
|
|
1245
1835
|
});
|
|
1246
1836
|
|
|
1837
|
+
// src/lower/entities.ts
|
|
1838
|
+
function decodeEntities(value) {
|
|
1839
|
+
if (!value.includes("&")) return value;
|
|
1840
|
+
return value.replace(REFERENCE, (match, hex, dec, name) => {
|
|
1841
|
+
const code = hex ? parseInt(hex, 16) : dec ? parseInt(dec, 10) : Object.prototype.hasOwnProperty.call(NAMED, name) ? NAMED[name] : void 0;
|
|
1842
|
+
return code !== void 0 && code <= 1114111 ? String.fromCodePoint(code) : match;
|
|
1843
|
+
});
|
|
1844
|
+
}
|
|
1845
|
+
var NAMED, REFERENCE;
|
|
1846
|
+
var init_entities = __esm({
|
|
1847
|
+
"src/lower/entities.ts"() {
|
|
1848
|
+
"use strict";
|
|
1849
|
+
NAMED = {
|
|
1850
|
+
quot: 34,
|
|
1851
|
+
amp: 38,
|
|
1852
|
+
apos: 39,
|
|
1853
|
+
lt: 60,
|
|
1854
|
+
gt: 62,
|
|
1855
|
+
nbsp: 160,
|
|
1856
|
+
iexcl: 161,
|
|
1857
|
+
cent: 162,
|
|
1858
|
+
pound: 163,
|
|
1859
|
+
curren: 164,
|
|
1860
|
+
yen: 165,
|
|
1861
|
+
brvbar: 166,
|
|
1862
|
+
sect: 167,
|
|
1863
|
+
uml: 168,
|
|
1864
|
+
copy: 169,
|
|
1865
|
+
ordf: 170,
|
|
1866
|
+
laquo: 171,
|
|
1867
|
+
not: 172,
|
|
1868
|
+
shy: 173,
|
|
1869
|
+
reg: 174,
|
|
1870
|
+
macr: 175,
|
|
1871
|
+
deg: 176,
|
|
1872
|
+
plusmn: 177,
|
|
1873
|
+
sup2: 178,
|
|
1874
|
+
sup3: 179,
|
|
1875
|
+
acute: 180,
|
|
1876
|
+
micro: 181,
|
|
1877
|
+
para: 182,
|
|
1878
|
+
middot: 183,
|
|
1879
|
+
cedil: 184,
|
|
1880
|
+
sup1: 185,
|
|
1881
|
+
ordm: 186,
|
|
1882
|
+
raquo: 187,
|
|
1883
|
+
frac14: 188,
|
|
1884
|
+
frac12: 189,
|
|
1885
|
+
frac34: 190,
|
|
1886
|
+
iquest: 191,
|
|
1887
|
+
Agrave: 192,
|
|
1888
|
+
Aacute: 193,
|
|
1889
|
+
Acirc: 194,
|
|
1890
|
+
Atilde: 195,
|
|
1891
|
+
Auml: 196,
|
|
1892
|
+
Aring: 197,
|
|
1893
|
+
AElig: 198,
|
|
1894
|
+
Ccedil: 199,
|
|
1895
|
+
Egrave: 200,
|
|
1896
|
+
Eacute: 201,
|
|
1897
|
+
Ecirc: 202,
|
|
1898
|
+
Euml: 203,
|
|
1899
|
+
Igrave: 204,
|
|
1900
|
+
Iacute: 205,
|
|
1901
|
+
Icirc: 206,
|
|
1902
|
+
Iuml: 207,
|
|
1903
|
+
ETH: 208,
|
|
1904
|
+
Ntilde: 209,
|
|
1905
|
+
Ograve: 210,
|
|
1906
|
+
Oacute: 211,
|
|
1907
|
+
Ocirc: 212,
|
|
1908
|
+
Otilde: 213,
|
|
1909
|
+
Ouml: 214,
|
|
1910
|
+
times: 215,
|
|
1911
|
+
Oslash: 216,
|
|
1912
|
+
Ugrave: 217,
|
|
1913
|
+
Uacute: 218,
|
|
1914
|
+
Ucirc: 219,
|
|
1915
|
+
Uuml: 220,
|
|
1916
|
+
Yacute: 221,
|
|
1917
|
+
THORN: 222,
|
|
1918
|
+
szlig: 223,
|
|
1919
|
+
agrave: 224,
|
|
1920
|
+
aacute: 225,
|
|
1921
|
+
acirc: 226,
|
|
1922
|
+
atilde: 227,
|
|
1923
|
+
auml: 228,
|
|
1924
|
+
aring: 229,
|
|
1925
|
+
aelig: 230,
|
|
1926
|
+
ccedil: 231,
|
|
1927
|
+
egrave: 232,
|
|
1928
|
+
eacute: 233,
|
|
1929
|
+
ecirc: 234,
|
|
1930
|
+
euml: 235,
|
|
1931
|
+
igrave: 236,
|
|
1932
|
+
iacute: 237,
|
|
1933
|
+
icirc: 238,
|
|
1934
|
+
iuml: 239,
|
|
1935
|
+
eth: 240,
|
|
1936
|
+
ntilde: 241,
|
|
1937
|
+
ograve: 242,
|
|
1938
|
+
oacute: 243,
|
|
1939
|
+
ocirc: 244,
|
|
1940
|
+
otilde: 245,
|
|
1941
|
+
ouml: 246,
|
|
1942
|
+
divide: 247,
|
|
1943
|
+
oslash: 248,
|
|
1944
|
+
ugrave: 249,
|
|
1945
|
+
uacute: 250,
|
|
1946
|
+
ucirc: 251,
|
|
1947
|
+
uuml: 252,
|
|
1948
|
+
yacute: 253,
|
|
1949
|
+
thorn: 254,
|
|
1950
|
+
yuml: 255,
|
|
1951
|
+
OElig: 338,
|
|
1952
|
+
oelig: 339,
|
|
1953
|
+
Scaron: 352,
|
|
1954
|
+
scaron: 353,
|
|
1955
|
+
Yuml: 376,
|
|
1956
|
+
fnof: 402,
|
|
1957
|
+
circ: 710,
|
|
1958
|
+
tilde: 732,
|
|
1959
|
+
Alpha: 913,
|
|
1960
|
+
Beta: 914,
|
|
1961
|
+
Gamma: 915,
|
|
1962
|
+
Delta: 916,
|
|
1963
|
+
Epsilon: 917,
|
|
1964
|
+
Zeta: 918,
|
|
1965
|
+
Eta: 919,
|
|
1966
|
+
Theta: 920,
|
|
1967
|
+
Iota: 921,
|
|
1968
|
+
Kappa: 922,
|
|
1969
|
+
Lambda: 923,
|
|
1970
|
+
Mu: 924,
|
|
1971
|
+
Nu: 925,
|
|
1972
|
+
Xi: 926,
|
|
1973
|
+
Omicron: 927,
|
|
1974
|
+
Pi: 928,
|
|
1975
|
+
Rho: 929,
|
|
1976
|
+
Sigma: 931,
|
|
1977
|
+
Tau: 932,
|
|
1978
|
+
Upsilon: 933,
|
|
1979
|
+
Phi: 934,
|
|
1980
|
+
Chi: 935,
|
|
1981
|
+
Psi: 936,
|
|
1982
|
+
Omega: 937,
|
|
1983
|
+
alpha: 945,
|
|
1984
|
+
beta: 946,
|
|
1985
|
+
gamma: 947,
|
|
1986
|
+
delta: 948,
|
|
1987
|
+
epsilon: 949,
|
|
1988
|
+
zeta: 950,
|
|
1989
|
+
eta: 951,
|
|
1990
|
+
theta: 952,
|
|
1991
|
+
iota: 953,
|
|
1992
|
+
kappa: 954,
|
|
1993
|
+
lambda: 955,
|
|
1994
|
+
mu: 956,
|
|
1995
|
+
nu: 957,
|
|
1996
|
+
xi: 958,
|
|
1997
|
+
omicron: 959,
|
|
1998
|
+
pi: 960,
|
|
1999
|
+
rho: 961,
|
|
2000
|
+
sigmaf: 962,
|
|
2001
|
+
sigma: 963,
|
|
2002
|
+
tau: 964,
|
|
2003
|
+
upsilon: 965,
|
|
2004
|
+
phi: 966,
|
|
2005
|
+
chi: 967,
|
|
2006
|
+
psi: 968,
|
|
2007
|
+
omega: 969,
|
|
2008
|
+
thetasym: 977,
|
|
2009
|
+
upsih: 978,
|
|
2010
|
+
piv: 982,
|
|
2011
|
+
ensp: 8194,
|
|
2012
|
+
emsp: 8195,
|
|
2013
|
+
thinsp: 8201,
|
|
2014
|
+
zwnj: 8204,
|
|
2015
|
+
zwj: 8205,
|
|
2016
|
+
lrm: 8206,
|
|
2017
|
+
rlm: 8207,
|
|
2018
|
+
ndash: 8211,
|
|
2019
|
+
mdash: 8212,
|
|
2020
|
+
lsquo: 8216,
|
|
2021
|
+
rsquo: 8217,
|
|
2022
|
+
sbquo: 8218,
|
|
2023
|
+
ldquo: 8220,
|
|
2024
|
+
rdquo: 8221,
|
|
2025
|
+
bdquo: 8222,
|
|
2026
|
+
dagger: 8224,
|
|
2027
|
+
Dagger: 8225,
|
|
2028
|
+
bull: 8226,
|
|
2029
|
+
hellip: 8230,
|
|
2030
|
+
permil: 8240,
|
|
2031
|
+
prime: 8242,
|
|
2032
|
+
Prime: 8243,
|
|
2033
|
+
lsaquo: 8249,
|
|
2034
|
+
rsaquo: 8250,
|
|
2035
|
+
oline: 8254,
|
|
2036
|
+
frasl: 8260,
|
|
2037
|
+
euro: 8364,
|
|
2038
|
+
image: 8465,
|
|
2039
|
+
weierp: 8472,
|
|
2040
|
+
real: 8476,
|
|
2041
|
+
trade: 8482,
|
|
2042
|
+
alefsym: 8501,
|
|
2043
|
+
larr: 8592,
|
|
2044
|
+
uarr: 8593,
|
|
2045
|
+
rarr: 8594,
|
|
2046
|
+
darr: 8595,
|
|
2047
|
+
harr: 8596,
|
|
2048
|
+
crarr: 8629,
|
|
2049
|
+
lArr: 8656,
|
|
2050
|
+
uArr: 8657,
|
|
2051
|
+
rArr: 8658,
|
|
2052
|
+
dArr: 8659,
|
|
2053
|
+
hArr: 8660,
|
|
2054
|
+
forall: 8704,
|
|
2055
|
+
part: 8706,
|
|
2056
|
+
exist: 8707,
|
|
2057
|
+
empty: 8709,
|
|
2058
|
+
nabla: 8711,
|
|
2059
|
+
isin: 8712,
|
|
2060
|
+
notin: 8713,
|
|
2061
|
+
ni: 8715,
|
|
2062
|
+
prod: 8719,
|
|
2063
|
+
sum: 8721,
|
|
2064
|
+
minus: 8722,
|
|
2065
|
+
lowast: 8727,
|
|
2066
|
+
radic: 8730,
|
|
2067
|
+
prop: 8733,
|
|
2068
|
+
infin: 8734,
|
|
2069
|
+
ang: 8736,
|
|
2070
|
+
and: 8743,
|
|
2071
|
+
or: 8744,
|
|
2072
|
+
cap: 8745,
|
|
2073
|
+
cup: 8746,
|
|
2074
|
+
int: 8747,
|
|
2075
|
+
there4: 8756,
|
|
2076
|
+
sim: 8764,
|
|
2077
|
+
cong: 8773,
|
|
2078
|
+
asymp: 8776,
|
|
2079
|
+
ne: 8800,
|
|
2080
|
+
equiv: 8801,
|
|
2081
|
+
le: 8804,
|
|
2082
|
+
ge: 8805,
|
|
2083
|
+
sub: 8834,
|
|
2084
|
+
sup: 8835,
|
|
2085
|
+
nsub: 8836,
|
|
2086
|
+
sube: 8838,
|
|
2087
|
+
supe: 8839,
|
|
2088
|
+
oplus: 8853,
|
|
2089
|
+
otimes: 8855,
|
|
2090
|
+
perp: 8869,
|
|
2091
|
+
sdot: 8901,
|
|
2092
|
+
lceil: 8968,
|
|
2093
|
+
rceil: 8969,
|
|
2094
|
+
lfloor: 8970,
|
|
2095
|
+
rfloor: 8971,
|
|
2096
|
+
lang: 9001,
|
|
2097
|
+
rang: 9002,
|
|
2098
|
+
loz: 9674,
|
|
2099
|
+
spades: 9824,
|
|
2100
|
+
clubs: 9827,
|
|
2101
|
+
hearts: 9829,
|
|
2102
|
+
diams: 9830
|
|
2103
|
+
};
|
|
2104
|
+
REFERENCE = /&(?:#[xX]([0-9a-fA-F]{1,6})|#([0-9]{1,7})|([a-zA-Z][a-zA-Z0-9]{1,31}));/g;
|
|
2105
|
+
}
|
|
2106
|
+
});
|
|
2107
|
+
|
|
1247
2108
|
// src/lower/template.ts
|
|
1248
2109
|
function escapeTemplate(s) {
|
|
1249
2110
|
return s.replace(/\\/g, "\\\\").replace(/`/g, "\\`").replace(/\$\{/g, "\\${");
|
|
@@ -1263,7 +2124,9 @@ var init_template = __esm({
|
|
|
1263
2124
|
init_load_directive();
|
|
1264
2125
|
init_imperative();
|
|
1265
2126
|
init_text();
|
|
2127
|
+
init_entities();
|
|
1266
2128
|
init_paren();
|
|
2129
|
+
init_source_locations();
|
|
1267
2130
|
DELEGATED = /* @__PURE__ */ new Set([
|
|
1268
2131
|
"click",
|
|
1269
2132
|
"dblclick",
|
|
@@ -1343,7 +2206,7 @@ var init_template = __esm({
|
|
|
1343
2206
|
switch (node.kind) {
|
|
1344
2207
|
case "Text": {
|
|
1345
2208
|
if (node.raw) return { kind: "text", value: node.value };
|
|
1346
|
-
const cleaned = cleanTemplateText(node.value);
|
|
2209
|
+
const cleaned = decodeEntities(cleanTemplateText(node.value));
|
|
1347
2210
|
return cleaned ? { kind: "text", value: cleaned } : null;
|
|
1348
2211
|
}
|
|
1349
2212
|
case "Comment":
|
|
@@ -1379,7 +2242,7 @@ var init_template = __esm({
|
|
|
1379
2242
|
kind: "element",
|
|
1380
2243
|
tag: el.tag,
|
|
1381
2244
|
svg: el.namespace === "svg",
|
|
1382
|
-
props: this.lowerAttributes(el.attributes),
|
|
2245
|
+
props: this.lowerAttributes(el.attributes, true),
|
|
1383
2246
|
children,
|
|
1384
2247
|
static: false,
|
|
1385
2248
|
...at ? { at } : {}
|
|
@@ -1492,13 +2355,22 @@ var init_template = __esm({
|
|
|
1492
2355
|
return clone.kind === "Element" ? this.lowerElement(clone) : this.lowerComponent(clone);
|
|
1493
2356
|
}
|
|
1494
2357
|
// --- attributes ---------------------------------------------------------
|
|
1495
|
-
|
|
2358
|
+
/**
|
|
2359
|
+
* `element`: a DOM element, where each class:/style: value that moves is its own accessor.
|
|
2360
|
+
* A component gets the object as before, rebuilt whole when any value moves.
|
|
2361
|
+
*/
|
|
2362
|
+
lowerAttributes(attrs, element = false) {
|
|
2363
|
+
let anyReactive = false;
|
|
2364
|
+
const entry = (name, h) => {
|
|
2365
|
+
anyReactive ||= h.reactive;
|
|
2366
|
+
if (!element || !h.reactive) return `${JSON.stringify(name)}: ${h.code}`;
|
|
2367
|
+
const accessor = `() => ${paren(h.code, "arrowBody")}`;
|
|
2368
|
+
return `${JSON.stringify(name)}: ${h.at ? markHole(accessor, h.at.line, h.at.column) : accessor}`;
|
|
2369
|
+
};
|
|
1496
2370
|
const props = [];
|
|
1497
2371
|
const classEntries = [];
|
|
1498
|
-
let classReactive = false;
|
|
1499
2372
|
let classAt;
|
|
1500
2373
|
const styleEntries = [];
|
|
1501
|
-
let styleReactive = false;
|
|
1502
2374
|
let styleAt;
|
|
1503
2375
|
const usePairs = [];
|
|
1504
2376
|
for (const a of attrs) {
|
|
@@ -1538,15 +2410,13 @@ var init_template = __esm({
|
|
|
1538
2410
|
break;
|
|
1539
2411
|
case "ClassDirective": {
|
|
1540
2412
|
const h = this.hole(a.hole);
|
|
1541
|
-
classEntries.push(
|
|
1542
|
-
classReactive = classReactive || h.reactive;
|
|
2413
|
+
classEntries.push(entry(a.name, h));
|
|
1543
2414
|
classAt ??= h.at;
|
|
1544
2415
|
break;
|
|
1545
2416
|
}
|
|
1546
2417
|
case "StyleDirective": {
|
|
1547
2418
|
const h = this.hole(a.hole);
|
|
1548
|
-
styleEntries.push(
|
|
1549
|
-
styleReactive = styleReactive || h.reactive;
|
|
2419
|
+
styleEntries.push(entry(a.name, h));
|
|
1550
2420
|
styleAt ??= h.at;
|
|
1551
2421
|
break;
|
|
1552
2422
|
}
|
|
@@ -1566,18 +2436,19 @@ var init_template = __esm({
|
|
|
1566
2436
|
name: "classList",
|
|
1567
2437
|
kind: "attr",
|
|
1568
2438
|
expr: `{ ${classEntries.join(", ")} }`,
|
|
1569
|
-
reactive:
|
|
2439
|
+
reactive: !element && anyReactive,
|
|
1570
2440
|
...classAt ? { at: classAt } : {}
|
|
1571
2441
|
});
|
|
1572
2442
|
}
|
|
1573
2443
|
if (styleEntries.length > 0) {
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
2444
|
+
const entries = `{ ${styleEntries.join(", ")} }`;
|
|
2445
|
+
const base = props.findIndex((p) => p.name === "style");
|
|
2446
|
+
if (base === -1) props.push({ name: "style", kind: "attr", expr: entries, reactive: !element && anyReactive, ...styleAt ? { at: styleAt } : {} });
|
|
2447
|
+
else {
|
|
2448
|
+
const prop = props[base];
|
|
2449
|
+
const value = prop.expr === void 0 ? JSON.stringify(prop.literal) : prop.reactive ? `() => ${paren(prop.expr, "arrowBody")}` : prop.expr;
|
|
2450
|
+
props[base] = { name: "style", kind: "attr", expr: `[${value}, ${entries}]`, reactive: false, ...prop.at ? { at: prop.at } : {} };
|
|
2451
|
+
}
|
|
1581
2452
|
}
|
|
1582
2453
|
if (usePairs.length > 0) {
|
|
1583
2454
|
props.push({ name: "use", kind: "attr", expr: `[${usePairs.join(", ")}]` });
|
|
@@ -1666,7 +2537,7 @@ var init_template = __esm({
|
|
|
1666
2537
|
return base;
|
|
1667
2538
|
}
|
|
1668
2539
|
if (v.kind === "static") {
|
|
1669
|
-
base.literal = v.value;
|
|
2540
|
+
base.literal = decodeEntities(v.value);
|
|
1670
2541
|
return base;
|
|
1671
2542
|
}
|
|
1672
2543
|
if (v.kind === "hole") {
|
|
@@ -1679,7 +2550,7 @@ var init_template = __esm({
|
|
|
1679
2550
|
let reactive = false;
|
|
1680
2551
|
let at;
|
|
1681
2552
|
const body = v.parts.map((p) => {
|
|
1682
|
-
if ("text" in p) return escapeTemplate(p.text);
|
|
2553
|
+
if ("text" in p) return escapeTemplate(decodeEntities(p.text));
|
|
1683
2554
|
const h = this.hole(p.hole);
|
|
1684
2555
|
reactive = reactive || h.reactive;
|
|
1685
2556
|
at ??= h.at;
|
|
@@ -1990,9 +2861,12 @@ function attrExprCode(attr, ctx) {
|
|
|
1990
2861
|
}
|
|
1991
2862
|
return null;
|
|
1992
2863
|
}
|
|
1993
|
-
function buildProps(attrs, ctx) {
|
|
2864
|
+
function buildProps(attrs, ctx, element = false) {
|
|
1994
2865
|
const props = [];
|
|
1995
2866
|
const usePairs = [];
|
|
2867
|
+
const classEntries = [];
|
|
2868
|
+
const styleEntries = [];
|
|
2869
|
+
let styleAt;
|
|
1996
2870
|
for (const a of attrs) {
|
|
1997
2871
|
if (a.type === "JSXSpreadAttribute") {
|
|
1998
2872
|
props.push({ name: "", kind: "spread", expr: ctx.code(a.argument) });
|
|
@@ -2008,6 +2882,27 @@ function buildProps(attrs, ctx) {
|
|
|
2008
2882
|
usePairs.push(opts != null ? `[${dir}, () => ${paren(opts, "arrowBody")}]` : `[${dir}]`);
|
|
2009
2883
|
continue;
|
|
2010
2884
|
}
|
|
2885
|
+
if (element && (ns === "class" || ns === "style")) {
|
|
2886
|
+
const key = JSON.stringify(a.name.name.name);
|
|
2887
|
+
const v = a.value;
|
|
2888
|
+
let value;
|
|
2889
|
+
if (v == null) value = "true";
|
|
2890
|
+
else if (isString(v)) value = JSON.stringify(literalOf(v));
|
|
2891
|
+
else if (v.type === "JSXExpressionContainer" && v.expression?.type !== "JSXEmptyExpression") {
|
|
2892
|
+
value = keyValue(v.expression, ctx);
|
|
2893
|
+
if (ns === "style") styleAt ??= posOf(v.expression, ctx);
|
|
2894
|
+
} else continue;
|
|
2895
|
+
(ns === "class" ? classEntries : styleEntries).push(`${key}: ${value}`);
|
|
2896
|
+
continue;
|
|
2897
|
+
}
|
|
2898
|
+
if (element && a.name.type === "JSXIdentifier" && a.name.name === "style" && a.value?.type === "JSXExpressionContainer") {
|
|
2899
|
+
const entries = objectEntries(a.value.expression, ctx);
|
|
2900
|
+
if (entries) {
|
|
2901
|
+
styleEntries.unshift(...entries);
|
|
2902
|
+
styleAt = posOf(a.value.expression, ctx);
|
|
2903
|
+
continue;
|
|
2904
|
+
}
|
|
2905
|
+
}
|
|
2011
2906
|
if (ns === "oncapture") {
|
|
2012
2907
|
const evt = a.name.name.name.toLowerCase();
|
|
2013
2908
|
const h = attrExprCode(a, ctx) ?? "undefined";
|
|
@@ -2016,9 +2911,37 @@ function buildProps(attrs, ctx) {
|
|
|
2016
2911
|
}
|
|
2017
2912
|
props.push(buildAttr(a, ctx));
|
|
2018
2913
|
}
|
|
2914
|
+
if (classEntries.length > 0) props.push({ name: "classList", kind: "attr", expr: `{ ${classEntries.join(", ")} }`, reactive: false });
|
|
2915
|
+
if (styleEntries.length > 0) {
|
|
2916
|
+
const entries = `{ ${styleEntries.join(", ")} }`;
|
|
2917
|
+
const base = props.findIndex((p) => p.name === "style" && p.kind === "attr");
|
|
2918
|
+
if (base === -1) props.push({ name: "style", kind: "attr", expr: entries, reactive: false, ...styleAt ? { at: styleAt } : {} });
|
|
2919
|
+
else {
|
|
2920
|
+
const prop = props[base];
|
|
2921
|
+
const value = prop.literal !== void 0 ? JSON.stringify(prop.literal) : prop.reactive ? `() => ${paren(prop.expr, "arrowBody")}` : prop.expr;
|
|
2922
|
+
props[base] = { name: "style", kind: "attr", expr: `[${value}, ${entries}]`, reactive: false, ...prop.at ? { at: prop.at } : {} };
|
|
2923
|
+
}
|
|
2924
|
+
}
|
|
2019
2925
|
if (usePairs.length > 0) props.push({ name: "use", kind: "attr", expr: `[${usePairs.join(", ")}]` });
|
|
2020
2926
|
return props;
|
|
2021
2927
|
}
|
|
2928
|
+
function keyValue(expr, ctx) {
|
|
2929
|
+
const code = ctx.code(expr);
|
|
2930
|
+
if (!isReactive(expr)) return code;
|
|
2931
|
+
const accessor = `() => ${paren(code, "arrowBody")}`;
|
|
2932
|
+
const at = posOf(expr, ctx);
|
|
2933
|
+
return at ? markHole(accessor, at.line, at.column) : accessor;
|
|
2934
|
+
}
|
|
2935
|
+
function objectEntries(expr, ctx) {
|
|
2936
|
+
if (expr?.type !== "ObjectExpression") return null;
|
|
2937
|
+
const entries = [];
|
|
2938
|
+
for (const p of expr.properties) {
|
|
2939
|
+
if (p.type !== "ObjectProperty") return null;
|
|
2940
|
+
const key = p.computed ? `[${ctx.code(p.key)}]` : p.key.type === "Identifier" ? JSON.stringify(p.key.name) : JSON.stringify(String(p.key.value));
|
|
2941
|
+
entries.push(`${key}: ${keyValue(p.value, ctx)}`);
|
|
2942
|
+
}
|
|
2943
|
+
return entries;
|
|
2944
|
+
}
|
|
2022
2945
|
function buildChildren(children, ctx) {
|
|
2023
2946
|
const out = [];
|
|
2024
2947
|
for (let i = 0; i < children.length; i++) {
|
|
@@ -2046,6 +2969,7 @@ function buildChildren(children, ctx) {
|
|
|
2046
2969
|
});
|
|
2047
2970
|
}
|
|
2048
2971
|
} else if (child.type === "JSXElement" || child.type === "JSXFragment") {
|
|
2972
|
+
if (ctx.dropStyles?.has(child.start)) continue;
|
|
2049
2973
|
out.push(buildNode(child, ctx));
|
|
2050
2974
|
} else if (child.type === "JSXSpreadChild") {
|
|
2051
2975
|
out.push({ kind: "expr", code: ctx.code(child.expression), reactive: false });
|
|
@@ -2115,13 +3039,17 @@ function buildElement(node, ctx, handled) {
|
|
|
2115
3039
|
const children = each ? [each] : buildChildren(node.children, ctx);
|
|
2116
3040
|
if (tag === CONTAINER2) return children.length === 1 ? children[0] : { kind: "fragment", children };
|
|
2117
3041
|
const at = ctx.sourceFile && node.loc?.start ? { file: ctx.sourceFile, line: node.loc.start.line, column: node.loc.start.column } : void 0;
|
|
2118
|
-
|
|
3042
|
+
const props = buildProps(attributes, ctx, true);
|
|
3043
|
+
const scope = ctx.scopes?.find((s) => node.start >= s.start && node.end <= s.end);
|
|
3044
|
+
if (scope) props.unshift({ name: "data-fx-s", kind: "attr", literal: scope.value });
|
|
3045
|
+
return { kind: "element", tag, svg: SVG_TAGS.has(tag), props, children, static: false, ...at ? { at } : {} };
|
|
2119
3046
|
}
|
|
2120
3047
|
function buildNode(node, ctx) {
|
|
2121
3048
|
if (node.type === "JSXFragment") {
|
|
2122
3049
|
return { kind: "fragment", children: buildChildren(node.children, ctx) };
|
|
2123
3050
|
}
|
|
2124
3051
|
if (directive(node, "if")) return buildIf(node, null, ctx);
|
|
3052
|
+
if (ctx.dropStyles?.has(node.start)) return { kind: "fragment", children: [] };
|
|
2125
3053
|
const { tag, component } = tagInfo(node.openingElement.name, ctx);
|
|
2126
3054
|
if (!component) return buildElement(node, ctx, []);
|
|
2127
3055
|
const props = buildProps(node.openingElement.attributes, ctx);
|
|
@@ -2145,6 +3073,7 @@ var init_jsx = __esm({
|
|
|
2145
3073
|
init_analyze_static();
|
|
2146
3074
|
init_text();
|
|
2147
3075
|
init_paren();
|
|
3076
|
+
init_source_locations();
|
|
2148
3077
|
init_imperative();
|
|
2149
3078
|
SVG_TAGS = /* @__PURE__ */ new Set([
|
|
2150
3079
|
"svg",
|
|
@@ -2801,6 +3730,7 @@ function compilePieces(pieces, holes, options = {}) {
|
|
|
2801
3730
|
...options.sourceFile ? { sourceFile: options.sourceFile } : {},
|
|
2802
3731
|
...options.positionAt ? { positionAt: options.positionAt } : {}
|
|
2803
3732
|
});
|
|
3733
|
+
if (options.templateStyles) applyTemplateStyles(ir, options.templateStyles);
|
|
2804
3734
|
analyzeStatic(ir);
|
|
2805
3735
|
resolveComponentSources(ir, {
|
|
2806
3736
|
resolver: createComponentResolver(options.resolve ?? []),
|
|
@@ -2823,6 +3753,7 @@ function compilePieces(pieces, holes, options = {}) {
|
|
|
2823
3753
|
var init_compile_template = __esm({
|
|
2824
3754
|
"src/lower/compile-template.ts"() {
|
|
2825
3755
|
"use strict";
|
|
3756
|
+
init_styles();
|
|
2826
3757
|
init_analyze_static();
|
|
2827
3758
|
init_collapse_strategies();
|
|
2828
3759
|
init_imperative();
|
|
@@ -3355,8 +4286,8 @@ function isJsxRoot(node, parent, key) {
|
|
|
3355
4286
|
if (!isJsx(node)) return false;
|
|
3356
4287
|
return !(parent && isJsx(parent) && key === "children");
|
|
3357
4288
|
}
|
|
3358
|
-
function isTemplateTag(node,
|
|
3359
|
-
return node.type === "TaggedTemplateExpression" && node.tag?.type === "Identifier" && (node.tag.name
|
|
4289
|
+
function isTemplateTag(node, tags) {
|
|
4290
|
+
return node.type === "TaggedTemplateExpression" && node.tag?.type === "Identifier" && tags.has(node.tag.name);
|
|
3360
4291
|
}
|
|
3361
4292
|
function outermost(list) {
|
|
3362
4293
|
return list.filter(
|
|
@@ -3504,22 +4435,28 @@ function transformTemplates(code, id, options = {}) {
|
|
|
3504
4435
|
const wantsIntrinsics = options.intrinsics !== false && mayHaveIntrinsic(code);
|
|
3505
4436
|
const wantsSources = options.sourceLocations === true && mayHaveSourceMarks(code);
|
|
3506
4437
|
const sourceName = relativeToRoot(id, options.sourceRoot);
|
|
3507
|
-
|
|
4438
|
+
const wantsStyles = options.styles !== void 0 && (code.includes("<style") || code.includes("css`"));
|
|
4439
|
+
if (!mayHaveTemplate && !(wantsJsx && code.includes("<")) && !wantsIntrinsics && !wantsSources && !wantsStyles) return null;
|
|
3508
4440
|
const ast = (0, import_parser2.parse)(code, {
|
|
3509
4441
|
sourceType: "module",
|
|
3510
4442
|
plugins: ["jsx", "typescript"],
|
|
3511
4443
|
errorRecovery: true
|
|
3512
4444
|
});
|
|
4445
|
+
const intrinsicTags = options.intrinsics === false ? /* @__PURE__ */ new Map() : tagIntrinsics(moduleBindings(ast.program));
|
|
4446
|
+
const templateTags = /* @__PURE__ */ new Map([[litTag, "html"], ["svg", "svg"]]);
|
|
4447
|
+
for (const [name, tag] of intrinsicTags) if (tag !== "css") templateTags.set(name, tag);
|
|
4448
|
+
const cssTags = [...intrinsicTags].filter(([, tag]) => tag === "css").map(([name]) => name);
|
|
3513
4449
|
const found = [];
|
|
3514
4450
|
walk7(ast.program, (n, parent, key) => {
|
|
3515
|
-
if (wantsLit && isTemplateTag(n,
|
|
4451
|
+
if (wantsLit && isTemplateTag(n, templateTags)) found.push(n);
|
|
3516
4452
|
else if (wantsJsx && isJsxRoot(n, parent, key)) found.push(n);
|
|
3517
4453
|
});
|
|
3518
4454
|
const props = options.propsDestructure === false ? { edits: [], diagnostics: [], used: /* @__PURE__ */ new Set() } : collectPropsEdits(ast.program, code, { runtimeModule: options.runtimeModule });
|
|
3519
4455
|
const intrinsics = options.intrinsics === false ? { edits: [], diagnostics: [], imports: /* @__PURE__ */ new Map() } : collectIntrinsicEdits(ast.program);
|
|
3520
4456
|
if (intrinsics.edits.length) avoidBindingClashes(ast.program, intrinsics, moduleBindings(ast.program));
|
|
3521
4457
|
const sources = options.sourceLocations === true ? collectSourceEdits(ast.program, sourceName) : { edits: [], marked: 0 };
|
|
3522
|
-
const
|
|
4458
|
+
const styles = wantsStyles ? collectStyles(ast.program, sourceName, options.styles, { html: templateTags, css: cssTags }, { id, code }) : void 0;
|
|
4459
|
+
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;
|
|
3523
4460
|
if (silent) return null;
|
|
3524
4461
|
found.sort((a, b) => b.start - a.start || a.end - b.end);
|
|
3525
4462
|
const used = new Set(props.used);
|
|
@@ -3533,20 +4470,32 @@ function transformTemplates(code, id, options = {}) {
|
|
|
3533
4470
|
declared: declaredNames(ast.program)
|
|
3534
4471
|
};
|
|
3535
4472
|
const hoisted = /* @__PURE__ */ new Map();
|
|
3536
|
-
const edits = [...props.edits, ...intrinsics.edits, ...sources.edits];
|
|
4473
|
+
const edits = [...props.edits, ...intrinsics.edits, ...sources.edits, ...styles?.edits ?? []];
|
|
3537
4474
|
for (const node of found) {
|
|
3538
4475
|
const nested = found.some(
|
|
3539
4476
|
(o) => o !== node && o.start <= node.start && o.end >= node.end && o.end - o.start > node.end - node.start
|
|
3540
4477
|
);
|
|
3541
4478
|
if (isJsx(node)) {
|
|
3542
|
-
edits.push({ start: node.start, end: node.end, code: compileJsx(code, node, edits, nested, used, needs, hoisted, options, sourceName) });
|
|
4479
|
+
edits.push({ start: node.start, end: node.end, code: compileJsx(code, node, edits, nested, used, needs, hoisted, options, sourceName, styles) });
|
|
3543
4480
|
continue;
|
|
3544
4481
|
}
|
|
3545
4482
|
const holes = node.quasi.expressions.map(
|
|
3546
4483
|
(e) => bindHole2(code, e, edits, options.sourceLocations === true)
|
|
3547
4484
|
);
|
|
4485
|
+
const scope = styles?.scopes.find((s) => node.start >= s.start && node.end <= s.end)?.value;
|
|
4486
|
+
const owner = styles?.templateOwners.get(node.start);
|
|
4487
|
+
const templateStyles = options.styles && styles && (scope || owner) ? {
|
|
4488
|
+
options: options.styles,
|
|
4489
|
+
...scope ? { scope } : {},
|
|
4490
|
+
...owner ? { owner } : {},
|
|
4491
|
+
line: node.loc?.start.line ?? 0,
|
|
4492
|
+
column: node.loc?.start.column ?? 0,
|
|
4493
|
+
styles: styles.styles,
|
|
4494
|
+
diagnostics: styles.diagnostics
|
|
4495
|
+
} : void 0;
|
|
3548
4496
|
const result = compilePieces(toPieces(node), holes, {
|
|
3549
4497
|
...options,
|
|
4498
|
+
...templateStyles ? { templateStyles } : {},
|
|
3550
4499
|
hoistTemplates: true,
|
|
3551
4500
|
// A tag inside a template gets the same mark a JSX tag does. Without one, the nodes it
|
|
3552
4501
|
// makes are the only ones in the module carrying no mark, and they take whichever was
|
|
@@ -3555,12 +4504,13 @@ function transformTemplates(code, id, options = {}) {
|
|
|
3555
4504
|
// Same defaults as the plugin, so moving a build over is not a rendering change.
|
|
3556
4505
|
templateClone: options.templateClone ?? true,
|
|
3557
4506
|
partialTemplates: nested ? false : options.partialTemplates ?? true,
|
|
3558
|
-
svg: node.tag.name === "svg"
|
|
4507
|
+
svg: templateTags.get(node.tag.name) === "svg"
|
|
3559
4508
|
});
|
|
3560
4509
|
for (const symbol of result.imports) used.add(symbol);
|
|
3561
4510
|
collectNeeds(result.ir, needs);
|
|
3562
4511
|
edits.push({ start: node.start, end: node.end, code: adoptTemplates2(result.code, result.templates, hoisted) });
|
|
3563
4512
|
}
|
|
4513
|
+
if (styles && options.styles) edits.push(...finishShadowStyles(styles, code, id));
|
|
3564
4514
|
const out = new import_magic_string2.default(code);
|
|
3565
4515
|
for (const e of outermost(edits)) {
|
|
3566
4516
|
if (e.start === e.end) out.appendLeft(e.start, e.code);
|
|
@@ -3618,13 +4568,19 @@ function transformTemplates(code, id, options = {}) {
|
|
|
3618
4568
|
...loadDiagnostics.length ? { loadDiagnostics } : {},
|
|
3619
4569
|
...unresolvedDiagnostics.length ? { unresolvedDiagnostics } : {},
|
|
3620
4570
|
...props.diagnostics.length ? { propsDiagnostics: props.diagnostics } : {},
|
|
3621
|
-
...intrinsics.diagnostics.length ? { intrinsicDiagnostics: intrinsics.diagnostics } : {}
|
|
4571
|
+
...intrinsics.diagnostics.length ? { intrinsicDiagnostics: intrinsics.diagnostics } : {},
|
|
4572
|
+
...styles?.styles.length ? { styles: styles.styles } : {},
|
|
4573
|
+
...styles?.diagnostics.length ? { styleDiagnostics: styles.diagnostics } : {},
|
|
4574
|
+
...styles?.literals.length ? { styleLiterals: styles.literals } : {},
|
|
4575
|
+
...styles?.references.length ? { styleReferences: styles.references } : {}
|
|
3622
4576
|
};
|
|
3623
4577
|
}
|
|
3624
|
-
function compileJsx(code, node, edits, nested, used, needs, hoisted, options, sourceFile) {
|
|
4578
|
+
function compileJsx(code, node, edits, nested, used, needs, hoisted, options, sourceFile, styles) {
|
|
3625
4579
|
const ir = buildJsxIR(node, {
|
|
3626
4580
|
code: (n) => slice(code, n.start, n.end, edits),
|
|
3627
4581
|
used,
|
|
4582
|
+
...styles?.scopes.length ? { scopes: styles.scopes } : {},
|
|
4583
|
+
...styles?.drop.size ? { dropStyles: styles.drop } : {},
|
|
3628
4584
|
...options.sourceLocations === true && sourceFile ? { sourceFile } : {}
|
|
3629
4585
|
});
|
|
3630
4586
|
analyzeStatic(ir);
|
|
@@ -3710,6 +4666,7 @@ var init_templates = __esm({
|
|
|
3710
4666
|
init_props();
|
|
3711
4667
|
init_intrinsics2();
|
|
3712
4668
|
init_source_locations();
|
|
4669
|
+
init_styles();
|
|
3713
4670
|
init_intrinsics();
|
|
3714
4671
|
init_reactive_bindings();
|
|
3715
4672
|
init_builtins();
|
|
@@ -3752,14 +4709,14 @@ var init_transform = __esm({
|
|
|
3752
4709
|
});
|
|
3753
4710
|
|
|
3754
4711
|
// src/transform/server-fn-id.ts
|
|
3755
|
-
function
|
|
4712
|
+
function hash2(s) {
|
|
3756
4713
|
let h = 5381;
|
|
3757
4714
|
for (let i = 0; i < s.length; i++) h = h * 33 ^ s.charCodeAt(i);
|
|
3758
4715
|
return (h >>> 0).toString(16);
|
|
3759
4716
|
}
|
|
3760
4717
|
function serverFnId(filename, root, index) {
|
|
3761
4718
|
const rel = (filename || "unknown").replace(root ? root + "/" : "", "");
|
|
3762
|
-
return `${
|
|
4719
|
+
return `${hash2(rel)}:${index}`;
|
|
3763
4720
|
}
|
|
3764
4721
|
var init_server_fn_id = __esm({
|
|
3765
4722
|
"src/transform/server-fn-id.ts"() {
|
|
@@ -4015,7 +4972,7 @@ function componentGlobals(rules, options = {}) {
|
|
|
4015
4972
|
resolved.set(name, target);
|
|
4016
4973
|
}
|
|
4017
4974
|
}
|
|
4018
|
-
const usableIntrinsics = intrinsics ? Object.entries(INTRINSICS).filter(([, i]) => {
|
|
4975
|
+
const usableIntrinsics = intrinsics ? Object.entries({ ...INTRINSICS, ...TAG_INTRINSICS }).filter(([, i]) => {
|
|
4019
4976
|
const pkg = packageOf(i.module);
|
|
4020
4977
|
return !available || !pkg || available.has(pkg);
|
|
4021
4978
|
}) : [];
|
|
@@ -4078,11 +5035,11 @@ function coveredByInclude(root, target) {
|
|
|
4078
5035
|
}
|
|
4079
5036
|
if (config.extends !== void 0) return void 0;
|
|
4080
5037
|
if (!Array.isArray(config.include)) return true;
|
|
4081
|
-
const
|
|
5038
|
+
const relative3 = relativePosix(root, target);
|
|
4082
5039
|
return config.include.some((entry) => {
|
|
4083
5040
|
if (typeof entry !== "string") return false;
|
|
4084
5041
|
const pattern = entry.replace(/[.+^${}()|[\]\\]/g, "\\$&").replace(/\*\*\//g, "(?:.*/)?").replace(/\*/g, "[^/]*");
|
|
4085
|
-
return new RegExp(`^${pattern}(?:/.*)?$`).test(
|
|
5042
|
+
return new RegExp(`^${pattern}(?:/.*)?$`).test(relative3);
|
|
4086
5043
|
});
|
|
4087
5044
|
}
|
|
4088
5045
|
function relativePosix(from, to) {
|
|
@@ -4168,13 +5125,203 @@ function writeComponentGlobals(options, root) {
|
|
|
4168
5125
|
}
|
|
4169
5126
|
function warnIfUnreachable(root, target) {
|
|
4170
5127
|
if (coveredByInclude(root, target) !== false) return void 0;
|
|
4171
|
-
const
|
|
4172
|
-
return `[fluixi] ${
|
|
5128
|
+
const relative3 = relativePosix(root, target);
|
|
5129
|
+
return `[fluixi] ${relative3} is not covered by "include" in tsconfig.json, so TypeScript will ignore it and every resolved component stays "Cannot find name". Add "${relative3}" to "include".`;
|
|
4173
5130
|
}
|
|
4174
5131
|
|
|
4175
|
-
// src/
|
|
5132
|
+
// src/vite-styles.ts
|
|
4176
5133
|
var import_node_fs2 = require("node:fs");
|
|
4177
5134
|
var import_node_path2 = require("node:path");
|
|
5135
|
+
init_styles();
|
|
5136
|
+
var STYLE_ID = /\.fx-(\d+)\.css(?:\?inline)?$/;
|
|
5137
|
+
var LITERAL_ID = /\.fx-literal-([\w$]+)\.css\?inline$/;
|
|
5138
|
+
var SUFFIX = /\.fx-(?:\d+|literal-[\w$]+)\.css(?:\?inline)?$/;
|
|
5139
|
+
var styleId = styleIds.block;
|
|
5140
|
+
function firstLoc(nodes) {
|
|
5141
|
+
for (const node of nodes) {
|
|
5142
|
+
if (node.loc) return node.loc.source;
|
|
5143
|
+
if ((node.kind === "rule" || node.kind === "at-rule") && node.nodes.length) {
|
|
5144
|
+
const inner = firstLoc(node.nodes);
|
|
5145
|
+
if (inner) return inner;
|
|
5146
|
+
}
|
|
5147
|
+
}
|
|
5148
|
+
return void 0;
|
|
5149
|
+
}
|
|
5150
|
+
var ownerOf = (id) => id.slice(0, id.search(SUFFIX));
|
|
5151
|
+
var loader = (name) => `const href = new URL(${JSON.stringify(`./${name}`)}, import.meta.url).href;
|
|
5152
|
+
if (typeof document !== 'undefined' && !document.querySelector(\`link[data-fx-css="\${href}"]\`)) {
|
|
5153
|
+
const link = document.createElement('link');
|
|
5154
|
+
link.rel = 'stylesheet';
|
|
5155
|
+
link.href = href;
|
|
5156
|
+
link.dataset.fxCss = href;
|
|
5157
|
+
document.head.appendChild(link);
|
|
5158
|
+
}
|
|
5159
|
+
`;
|
|
5160
|
+
function createComponentStyles(compile) {
|
|
5161
|
+
let api;
|
|
5162
|
+
let server;
|
|
5163
|
+
let root = process.cwd();
|
|
5164
|
+
let library;
|
|
5165
|
+
const emitted = /* @__PURE__ */ new Map();
|
|
5166
|
+
const fileOf = (id) => (0, import_node_fs2.existsSync)(id) ? id : (0, import_node_path2.join)(root, id);
|
|
5167
|
+
const cache = /* @__PURE__ */ new Map();
|
|
5168
|
+
const resolveReference = async (ref, importer, ctx, seen, modules) => {
|
|
5169
|
+
const resolved = await ctx.resolve?.(ref.source, importer);
|
|
5170
|
+
if (!resolved) return null;
|
|
5171
|
+
const file = resolved.id.split("?")[0];
|
|
5172
|
+
if (seen.has(file)) return null;
|
|
5173
|
+
let code;
|
|
5174
|
+
try {
|
|
5175
|
+
code = (0, import_node_fs2.readFileSync)(fileOf(file), "utf8");
|
|
5176
|
+
} catch {
|
|
5177
|
+
return null;
|
|
5178
|
+
}
|
|
5179
|
+
const styles = api.styles(file);
|
|
5180
|
+
let result = compile(code, file, styles);
|
|
5181
|
+
if (result?.styleReferences?.length) {
|
|
5182
|
+
const imported = await resolveAll(result.styleReferences, file, ctx, /* @__PURE__ */ new Set([...seen, file]), modules);
|
|
5183
|
+
result = compile(code, file, { ...styles, imported, importedModules: modules });
|
|
5184
|
+
}
|
|
5185
|
+
const literal = result?.styleLiterals?.find((l) => l.name === ref.name);
|
|
5186
|
+
if (!literal) return null;
|
|
5187
|
+
const nodes = literal.nodes ?? styles.process(literal.css, file);
|
|
5188
|
+
const named = firstLoc(nodes);
|
|
5189
|
+
if (named) modules.set(named, { id: file, code });
|
|
5190
|
+
return nodes;
|
|
5191
|
+
};
|
|
5192
|
+
const resolveAll = async (refs, importer, ctx, seen, modules) => {
|
|
5193
|
+
const imported = /* @__PURE__ */ new Map();
|
|
5194
|
+
for (const ref of refs) {
|
|
5195
|
+
const nodes = await resolveReference(ref, importer, ctx, seen, modules);
|
|
5196
|
+
if (nodes) imported.set(`${ref.source}#${ref.name}`, nodes);
|
|
5197
|
+
}
|
|
5198
|
+
return imported;
|
|
5199
|
+
};
|
|
5200
|
+
const run = async (code, id, ctx) => {
|
|
5201
|
+
const file = fileOf(id);
|
|
5202
|
+
const styles = api.styles(file);
|
|
5203
|
+
let result = compile(code, file, styles);
|
|
5204
|
+
if (result?.styleReferences?.length) {
|
|
5205
|
+
const modules = /* @__PURE__ */ new Map();
|
|
5206
|
+
const imported = await resolveAll(result.styleReferences, id, ctx, /* @__PURE__ */ new Set([file]), modules);
|
|
5207
|
+
result = compile(code, file, { ...styles, imported, importedModules: modules });
|
|
5208
|
+
}
|
|
5209
|
+
const css = (result?.styles ?? []).map((s) => s.css);
|
|
5210
|
+
const maps = (result?.styles ?? []).map((s) => s.map ?? null);
|
|
5211
|
+
const literals = new Map((result?.styleLiterals ?? []).map((l) => [l.name, l.css]));
|
|
5212
|
+
const before = cache.get(file);
|
|
5213
|
+
cache.set(file, { source: code, css, maps, literals });
|
|
5214
|
+
if (server && before) {
|
|
5215
|
+
for (let i = 0; i < css.length; i++) {
|
|
5216
|
+
if (before.css[i] === css[i]) continue;
|
|
5217
|
+
const mod = server.moduleGraph.getModuleById(styleId(file, i));
|
|
5218
|
+
if (mod) void server.reloadModule(mod);
|
|
5219
|
+
}
|
|
5220
|
+
}
|
|
5221
|
+
const page = (result?.styles ?? []).flatMap((s, i) => s.shadow ? [] : [i]);
|
|
5222
|
+
if (!result || page.length === 0) return result;
|
|
5223
|
+
if (library) {
|
|
5224
|
+
const name = `${(0, import_node_path2.basename)(file, (0, import_node_path2.extname)(file))}.css`;
|
|
5225
|
+
if ((0, import_node_fs2.existsSync)((0, import_node_path2.join)((0, import_node_path2.dirname)(file), name))) {
|
|
5226
|
+
throw new Error(`[fluixi] ${file} has <style> blocks, and ${name} next to it would be overwritten by their CSS. Rename one of them.`);
|
|
5227
|
+
}
|
|
5228
|
+
const out = (0, import_node_path2.join)((0, import_node_path2.relative)(library, (0, import_node_path2.dirname)(file)), name);
|
|
5229
|
+
emitted.set(out, page.map((i) => css[i]).join("\n"));
|
|
5230
|
+
emitted.set(`${out}.js`, loader(name));
|
|
5231
|
+
return { ...result, code: `${result.code}
|
|
5232
|
+
import ${JSON.stringify(`./${name}`)};` };
|
|
5233
|
+
}
|
|
5234
|
+
const imports = page.map((i) => `
|
|
5235
|
+
import ${JSON.stringify(styleId(file, i))};`).join("");
|
|
5236
|
+
return { ...result, code: result.code + imports };
|
|
5237
|
+
};
|
|
5238
|
+
return {
|
|
5239
|
+
/** Looks for @fluixi-css/vite among the plugins; without it component styles stay off. */
|
|
5240
|
+
connect(plugins, projectRoot) {
|
|
5241
|
+
if (projectRoot) root = projectRoot;
|
|
5242
|
+
api = (plugins ?? []).map((p) => p?.api?.fluixiCss).find((a) => Boolean(a));
|
|
5243
|
+
api?.useComponentStyles();
|
|
5244
|
+
},
|
|
5245
|
+
/** Turns on library output, from the directory of a `build.lib` entry. */
|
|
5246
|
+
setLibrary(entryDir) {
|
|
5247
|
+
library = entryDir;
|
|
5248
|
+
},
|
|
5249
|
+
/** A library build's style import: left for the package's consumer to bundle. */
|
|
5250
|
+
isLibraryImport(id, importer) {
|
|
5251
|
+
if (library === void 0 || !importer || !id.startsWith("./") || !id.endsWith(".css")) return false;
|
|
5252
|
+
return emitted.has((0, import_node_path2.join)((0, import_node_path2.relative)(library, (0, import_node_path2.dirname)(fileOf(importer))), id));
|
|
5253
|
+
},
|
|
5254
|
+
/** The style files a library build writes, by path under the output directory. */
|
|
5255
|
+
libraryFiles() {
|
|
5256
|
+
return emitted;
|
|
5257
|
+
},
|
|
5258
|
+
get active() {
|
|
5259
|
+
return api !== void 0;
|
|
5260
|
+
},
|
|
5261
|
+
setServer(dev) {
|
|
5262
|
+
server = dev;
|
|
5263
|
+
},
|
|
5264
|
+
isStyle(id) {
|
|
5265
|
+
return STYLE_ID.test(id) || LITERAL_ID.test(id);
|
|
5266
|
+
},
|
|
5267
|
+
/**
|
|
5268
|
+
* A style request as the module id Vite keeps: its owner's absolute path, then the suffix.
|
|
5269
|
+
* One id per block however it was asked for (`/src/card.tsx.fx-0.css` from a page, the
|
|
5270
|
+
* absolute path from the component), or the reload after an edit misses the copy in use.
|
|
5271
|
+
* A css`` value imported from another module names that module relatively, as written.
|
|
5272
|
+
*/
|
|
5273
|
+
async resolveId(id, importer, ctx) {
|
|
5274
|
+
const at = id.search(SUFFIX);
|
|
5275
|
+
const owner = id.slice(0, at);
|
|
5276
|
+
if (!owner.startsWith(".")) return fileOf(owner) + id.slice(at);
|
|
5277
|
+
const resolved = importer ? await ctx.resolve?.(owner, importer) : null;
|
|
5278
|
+
return resolved ? resolved.id.split("?")[0] + id.slice(at) : null;
|
|
5279
|
+
},
|
|
5280
|
+
/**
|
|
5281
|
+
* The style modules of a changed file, for the update Vite sends. Their ids do not name the
|
|
5282
|
+
* file (they end in `.css`), so Vite would not find them itself.
|
|
5283
|
+
*/
|
|
5284
|
+
hotModules(file, graph) {
|
|
5285
|
+
const entry = cache.get(file);
|
|
5286
|
+
if (!entry) return [];
|
|
5287
|
+
const paths = [
|
|
5288
|
+
...entry.css.map((_, i) => styleId(file, i)),
|
|
5289
|
+
...[...entry.literals.keys()].map((name) => styleIds.literal(file, name).replace(/\?inline$/, ""))
|
|
5290
|
+
];
|
|
5291
|
+
return paths.flatMap((path) => [...graph.getModulesByFile(path) ?? []]);
|
|
5292
|
+
},
|
|
5293
|
+
compile: run,
|
|
5294
|
+
/**
|
|
5295
|
+
* A block's CSS and its map back to the module, compiling the module again when the cache
|
|
5296
|
+
* does not match the file.
|
|
5297
|
+
*/
|
|
5298
|
+
async load(id, ctx) {
|
|
5299
|
+
const match = STYLE_ID.exec(id);
|
|
5300
|
+
const literal = LITERAL_ID.exec(id);
|
|
5301
|
+
if (!match && !literal || !api) return null;
|
|
5302
|
+
const file = ownerOf(id);
|
|
5303
|
+
let source;
|
|
5304
|
+
try {
|
|
5305
|
+
source = (0, import_node_fs2.readFileSync)(fileOf(file), "utf8");
|
|
5306
|
+
} catch {
|
|
5307
|
+
return null;
|
|
5308
|
+
}
|
|
5309
|
+
if (cache.get(fileOf(file))?.source !== source) await run(source, file, ctx);
|
|
5310
|
+
const entry = cache.get(fileOf(file));
|
|
5311
|
+
if (literal) {
|
|
5312
|
+
const css = entry?.literals.get(literal[1]);
|
|
5313
|
+
if (css === void 0) throw new Error(`[fluixi] ${literal[1]} in ${file} is not a css\`\` value, so it cannot be a shadow root's styles.`);
|
|
5314
|
+
return { code: css, map: null, moduleType: "css" };
|
|
5315
|
+
}
|
|
5316
|
+
const index = Number(match[1]);
|
|
5317
|
+
return { code: entry?.css[index] ?? "", map: entry?.maps[index] ?? null, moduleType: "css" };
|
|
5318
|
+
}
|
|
5319
|
+
};
|
|
5320
|
+
}
|
|
5321
|
+
|
|
5322
|
+
// src/integrations.ts
|
|
5323
|
+
var import_node_fs3 = require("node:fs");
|
|
5324
|
+
var import_node_path3 = require("node:path");
|
|
4178
5325
|
async function createBabelPlugin(options = {}) {
|
|
4179
5326
|
let pluginModule = null;
|
|
4180
5327
|
try {
|
|
@@ -4239,27 +5386,58 @@ var RETIRED_SUBPATHS = {
|
|
|
4239
5386
|
"@fluixi/core/rx": "is gone — import signals and effects from @fluixi/reactive, or the server primitives it resolved to under node from @fluixi/core/server"
|
|
4240
5387
|
};
|
|
4241
5388
|
function createVitePlugin(options = {}) {
|
|
5389
|
+
let transformTemplates2;
|
|
5390
|
+
let projectRoot = process.cwd();
|
|
5391
|
+
const componentStyles = createComponentStyles((code, id, styles) => {
|
|
5392
|
+
return transformTemplates2(code, id, { ...transformOptions(options, id), sourceRoot: projectRoot, styles });
|
|
5393
|
+
});
|
|
4242
5394
|
return {
|
|
4243
5395
|
name: "vite-fluixi-jsx",
|
|
4244
5396
|
enforce: "pre",
|
|
4245
|
-
|
|
4246
|
-
|
|
4247
|
-
|
|
4248
|
-
|
|
4249
|
-
|
|
4250
|
-
|
|
4251
|
-
};
|
|
5397
|
+
// JSX the compiler leaves alone goes to Vite's own transform: Oxc in Vite 8 (Rolldown),
|
|
5398
|
+
// esbuild before, which Vite 8 warns about.
|
|
5399
|
+
// In dev, CSS maps are on unless the app says otherwise, so devtools show the line a
|
|
5400
|
+
// component's rule was written on. Vite leaves them off by default; a build never has them.
|
|
5401
|
+
config(user) {
|
|
5402
|
+
const importSource = options.importSource || "@fluixi/jsx";
|
|
5403
|
+
const jsx = this && this.meta?.rolldownVersion ? { oxc: { jsx: { runtime: "automatic", importSource } } } : { esbuild: { jsx: "automatic", jsxImportSource: importSource } };
|
|
5404
|
+
return user?.css?.devSourcemap === void 0 ? { ...jsx, css: { devSourcemap: true } } : jsx;
|
|
4252
5405
|
},
|
|
4253
5406
|
// Written once per build, and on dev-server start, rather than per transform: the
|
|
4254
5407
|
// set of resolvable names comes from config, so nothing a file does can change it.
|
|
4255
|
-
configResolved(config) {
|
|
5408
|
+
async configResolved(config) {
|
|
4256
5409
|
const outcome = writeComponentGlobals(options, config?.root ?? process.cwd());
|
|
4257
5410
|
if (outcome.warning) console.warn(outcome.warning);
|
|
5411
|
+
if (options.babel) return;
|
|
5412
|
+
projectRoot = config?.root ?? projectRoot;
|
|
5413
|
+
componentStyles.connect(config?.plugins, config?.root);
|
|
5414
|
+
const entry = config?.command === "build" && config.build?.lib ? config.build.lib.entry : void 0;
|
|
5415
|
+
const first = typeof entry === "string" ? entry : Array.isArray(entry) ? entry[0] : entry && typeof entry === "object" ? Object.values(entry)[0] : void 0;
|
|
5416
|
+
if (typeof first === "string") componentStyles.setLibrary((0, import_node_path3.dirname)((0, import_node_path3.resolve)(config.root ?? process.cwd(), first)));
|
|
5417
|
+
if (componentStyles.active) ({ transformTemplates: transformTemplates2 } = await Promise.resolve().then(() => (init_transform(), transform_exports)));
|
|
5418
|
+
},
|
|
5419
|
+
generateBundle() {
|
|
5420
|
+
for (const [fileName, source] of componentStyles.libraryFiles()) this.emitFile({ type: "asset", fileName, source });
|
|
5421
|
+
},
|
|
5422
|
+
// An edited component's style modules go out with its update: their ids end in `.css`, so
|
|
5423
|
+
// Vite does not connect them to the file.
|
|
5424
|
+
handleHotUpdate(ctx) {
|
|
5425
|
+
if (!componentStyles.active) return void 0;
|
|
5426
|
+
const styles = componentStyles.hotModules(ctx.file, ctx.server.moduleGraph);
|
|
5427
|
+
return styles.length ? [...ctx.modules, ...styles] : void 0;
|
|
5428
|
+
},
|
|
5429
|
+
configureServer(server) {
|
|
5430
|
+
componentStyles.setServer(server);
|
|
5431
|
+
},
|
|
5432
|
+
load(id) {
|
|
5433
|
+
return componentStyles.isStyle(id) ? componentStyles.load(id, this) : null;
|
|
4258
5434
|
},
|
|
4259
5435
|
// A subpath we retired resolves to nothing, and the bundler reports that as
|
|
4260
5436
|
// `Missing "./x" specifier`, which names neither the replacement nor the file
|
|
4261
5437
|
// that asked. Answer it here, where the rename is known.
|
|
4262
5438
|
resolveId(id, importer) {
|
|
5439
|
+
if (componentStyles.isStyle(id)) return componentStyles.resolveId(id, importer, this);
|
|
5440
|
+
if (componentStyles.isLibraryImport(id, importer)) return { id, external: true };
|
|
4263
5441
|
const moved = RETIRED_SUBPATHS[id];
|
|
4264
5442
|
if (!moved) return null;
|
|
4265
5443
|
throw new Error(
|
|
@@ -4271,6 +5449,11 @@ function createVitePlugin(options = {}) {
|
|
|
4271
5449
|
if (!/\.(jsx|tsx|ts)$/i.test(id)) {
|
|
4272
5450
|
return null;
|
|
4273
5451
|
}
|
|
5452
|
+
if (!options.babel && componentStyles.active) {
|
|
5453
|
+
const result = await componentStyles.compile(code, id, this);
|
|
5454
|
+
reportDiagnostics(result, id);
|
|
5455
|
+
return result;
|
|
5456
|
+
}
|
|
4274
5457
|
if (!options.babel) return compileModule(code, id, options);
|
|
4275
5458
|
const babelPlugin = await createBabelPlugin(options);
|
|
4276
5459
|
try {
|
|
@@ -4366,6 +5549,7 @@ function reportDiagnostics(result, id) {
|
|
|
4366
5549
|
for (const d of r?.unresolvedDiagnostics ?? []) say(d.message);
|
|
4367
5550
|
for (const d of r?.loadDiagnostics ?? []) say(d.message);
|
|
4368
5551
|
for (const d of r?.intrinsicDiagnostics ?? []) say(d.message);
|
|
5552
|
+
for (const d of r?.styleDiagnostics ?? []) say(`${d.line}:${d.column + 1} ${d.message}`);
|
|
4369
5553
|
for (const d of r?.propsDiagnostics ?? []) {
|
|
4370
5554
|
say(`\`${d.name}\` was left destructured: ${d.message}. It reads once instead of tracking.`);
|
|
4371
5555
|
}
|
|
@@ -4418,8 +5602,8 @@ function createESBuildPlugin(options = {}) {
|
|
|
4418
5602
|
name: "esbuild-fluixi-jsx",
|
|
4419
5603
|
setup(build) {
|
|
4420
5604
|
build.onLoad({ filter: /\.[jt]sx?$/ }, async (args) => {
|
|
4421
|
-
const { readFileSync:
|
|
4422
|
-
const source =
|
|
5605
|
+
const { readFileSync: readFileSync4 } = await import("node:fs");
|
|
5606
|
+
const source = readFileSync4(args.path, "utf8");
|
|
4423
5607
|
try {
|
|
4424
5608
|
const result = await compileModule(source, args.path, options);
|
|
4425
5609
|
return {
|
|
@@ -4447,17 +5631,17 @@ function hasServerDirective(source) {
|
|
|
4447
5631
|
function findServerFnModules(dir, out = []) {
|
|
4448
5632
|
let entries;
|
|
4449
5633
|
try {
|
|
4450
|
-
entries = (0,
|
|
5634
|
+
entries = (0, import_node_fs3.readdirSync)(dir, { withFileTypes: true });
|
|
4451
5635
|
} catch {
|
|
4452
5636
|
return out;
|
|
4453
5637
|
}
|
|
4454
5638
|
for (const e of entries) {
|
|
4455
5639
|
if (e.name === "node_modules" || e.name === "dist" || e.name.startsWith(".")) continue;
|
|
4456
|
-
const full = (0,
|
|
5640
|
+
const full = (0, import_node_path3.join)(dir, e.name);
|
|
4457
5641
|
if (e.isDirectory()) findServerFnModules(full, out);
|
|
4458
5642
|
else if (/\.[jt]sx?$/.test(e.name)) {
|
|
4459
5643
|
try {
|
|
4460
|
-
if (hasServerDirective((0,
|
|
5644
|
+
if (hasServerDirective((0, import_node_fs3.readFileSync)(full, "utf8"))) out.push(full);
|
|
4461
5645
|
} catch {
|
|
4462
5646
|
}
|
|
4463
5647
|
}
|
|
@@ -4477,7 +5661,7 @@ function serverFunctionsVitePlugin(options = {}) {
|
|
|
4477
5661
|
},
|
|
4478
5662
|
load(id) {
|
|
4479
5663
|
if (id !== "\0" + SERVER_FNS_VMOD) return null;
|
|
4480
|
-
const mods = findServerFnModules((0,
|
|
5664
|
+
const mods = findServerFnModules((0, import_node_path3.join)(root, "src"));
|
|
4481
5665
|
const setup = `import '@fluixi/start/server-fn-setup';
|
|
4482
5666
|
`;
|
|
4483
5667
|
const imports = mods.map((m) => `import ${JSON.stringify(m)};`).join("\n");
|