@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.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;
|
|
@@ -44,6 +44,580 @@ module.exports = __toCommonJS(index_exports);
|
|
|
44
44
|
var import_parser2 = require("@babel/parser");
|
|
45
45
|
var import_magic_string2 = __toESM(require("magic-string"), 1);
|
|
46
46
|
|
|
47
|
+
// src/transform/styles.ts
|
|
48
|
+
var import_sourcemap_codec = require("@jridgewell/sourcemap-codec");
|
|
49
|
+
var SCOPE_ATTR = "data-fx-s";
|
|
50
|
+
var FUNCTIONS = /* @__PURE__ */ new Set(["FunctionDeclaration", "FunctionExpression", "ArrowFunctionExpression", "ObjectMethod", "ClassMethod"]);
|
|
51
|
+
function collectStyles(program, sourceName, options, tags = { html: /* @__PURE__ */ new Map([["html", "html"]]) }, module2) {
|
|
52
|
+
const plan = {
|
|
53
|
+
scopes: [],
|
|
54
|
+
templateOwners: /* @__PURE__ */ new Map(),
|
|
55
|
+
drop: /* @__PURE__ */ new Set(),
|
|
56
|
+
styles: [],
|
|
57
|
+
diagnostics: [],
|
|
58
|
+
edits: [],
|
|
59
|
+
literals: [],
|
|
60
|
+
references: [],
|
|
61
|
+
shadowClasses: /* @__PURE__ */ new Map()
|
|
62
|
+
};
|
|
63
|
+
if (!options) return plan;
|
|
64
|
+
const literalsOf = findLiterals(program, options.cssModules ?? ["@fluixi/core", "@fluixi/dom"], plan, tags.css ?? []);
|
|
65
|
+
plan.names = literalsOf;
|
|
66
|
+
const classOf = /* @__PURE__ */ new Map();
|
|
67
|
+
const shadowOf = (owner) => {
|
|
68
|
+
const cls = classOf.get(owner);
|
|
69
|
+
return cls ? plan.shadowClasses.get(cls) : void 0;
|
|
70
|
+
};
|
|
71
|
+
const resolved = /* @__PURE__ */ new Map();
|
|
72
|
+
const piecesToNodes = (quasis, expressions, at, stack) => {
|
|
73
|
+
const out = [];
|
|
74
|
+
for (let i = 0; i < quasis.length; i++) {
|
|
75
|
+
const text = quasis[i].value.cooked ?? quasis[i].value.raw;
|
|
76
|
+
if (text.trim()) {
|
|
77
|
+
try {
|
|
78
|
+
const start = quasis[i].loc?.start;
|
|
79
|
+
out.push(...options.process(text, sourceName).map((n) => start ? shiftLoc(n, sourceName, start) : n));
|
|
80
|
+
} catch (error) {
|
|
81
|
+
plan.diagnostics.push({ ...at, message: `CSS could not be processed: ${error.message}` });
|
|
82
|
+
return null;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
const expr = expressions[i];
|
|
86
|
+
if (!expr) continue;
|
|
87
|
+
const value = expr.type === "Identifier" ? resolveLiteral(expr.name, at, stack) : void 0;
|
|
88
|
+
if (value === void 0) {
|
|
89
|
+
plan.diagnostics.push({
|
|
90
|
+
...at,
|
|
91
|
+
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))."
|
|
92
|
+
});
|
|
93
|
+
return null;
|
|
94
|
+
}
|
|
95
|
+
if (value === null) return null;
|
|
96
|
+
out.push(...value);
|
|
97
|
+
}
|
|
98
|
+
return out;
|
|
99
|
+
};
|
|
100
|
+
function resolveLiteral(name, at, stack) {
|
|
101
|
+
const imported = literalsOf.imports.get(name);
|
|
102
|
+
if (imported) {
|
|
103
|
+
const nodes = options?.imported?.get(`${imported.source}#${imported.name}`);
|
|
104
|
+
if (nodes) return nodes.map((n) => keepLocIn(n, options?.importedModules));
|
|
105
|
+
plan.references.push({ name: imported.name, source: imported.source, ...at });
|
|
106
|
+
plan.diagnostics.push({
|
|
107
|
+
...at,
|
|
108
|
+
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.`
|
|
109
|
+
});
|
|
110
|
+
return null;
|
|
111
|
+
}
|
|
112
|
+
const literal = literalsOf.literals.get(name);
|
|
113
|
+
if (!literal) return void 0;
|
|
114
|
+
if (stack.includes(name)) {
|
|
115
|
+
plan.diagnostics.push({ ...at, message: `css\`\` values include each other: ${[...stack, name].join(" → ")}.` });
|
|
116
|
+
return null;
|
|
117
|
+
}
|
|
118
|
+
if (!resolved.has(name)) {
|
|
119
|
+
resolved.set(name, piecesToNodes(literal.quasi.quasis, literal.quasi.expressions, at, [...stack, name]));
|
|
120
|
+
}
|
|
121
|
+
return resolved.get(name);
|
|
122
|
+
}
|
|
123
|
+
for (const [name, literal] of literalsOf.literals) {
|
|
124
|
+
const at = { line: literal.loc?.start.line ?? 0, column: literal.loc?.start.column ?? 0 };
|
|
125
|
+
const nodes = resolveLiteral(name, at, []);
|
|
126
|
+
const id = hash(`${sourceName}:css:${name}`);
|
|
127
|
+
plan.edits.push({ start: literal.start, end: literal.end, code: `({ $fxStyle: ${JSON.stringify(id)} })` });
|
|
128
|
+
if (nodes) plan.literals.push({ id, name, css: printStyle(nodes, options.minify), nodes });
|
|
129
|
+
}
|
|
130
|
+
const scopeOf = /* @__PURE__ */ new Map();
|
|
131
|
+
const names = /* @__PURE__ */ new Map();
|
|
132
|
+
const named = /* @__PURE__ */ new Map();
|
|
133
|
+
const visit = (node, owners) => {
|
|
134
|
+
if (!node || typeof node !== "object") return;
|
|
135
|
+
if (node.type === "VariableDeclarator" && node.id.type === "Identifier" && node.init && FUNCTIONS.has(node.init.type)) {
|
|
136
|
+
named.set(node.init, node.id.name);
|
|
137
|
+
}
|
|
138
|
+
if ((node.type === "ClassDeclaration" || node.type === "ClassExpression") && node.id) {
|
|
139
|
+
for (const member of node.body.body) if (member.type === "ClassMethod") named.set(member, node.id.name);
|
|
140
|
+
}
|
|
141
|
+
if (node.type === "ClassDeclaration" || node.type === "ClassExpression") {
|
|
142
|
+
for (const member of node.body.body) if (member.type === "ClassMethod") classOf.set(member, node);
|
|
143
|
+
const shadow = staticMember(node, "shadow");
|
|
144
|
+
if (shadow?.value && !(shadow.value.type === "BooleanLiteral" && shadow.value.value === false)) {
|
|
145
|
+
plan.shadowClasses.set(node, { node, styles: staticMember(node, "styles"), indexes: [] });
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
if (node.type === "TaggedTemplateExpression" && node.tag.type === "Identifier" && tags.html.get(node.tag.name) === "html") {
|
|
149
|
+
const text = node.quasi.quasis.map((q) => q.value.raw).join("");
|
|
150
|
+
if (/<style[\s>]/.test(text)) {
|
|
151
|
+
const at = { line: node.loc?.start.line ?? 0, column: node.loc?.start.column ?? 0 };
|
|
152
|
+
const owner = owners[0];
|
|
153
|
+
if (!owner) plan.diagnostics.push({ ...at, message: "<style> has to be written inside a component." });
|
|
154
|
+
else {
|
|
155
|
+
const id = idFor(owner);
|
|
156
|
+
const shadow = shadowOf(owner);
|
|
157
|
+
plan.templateOwners.set(node.start, { id, component: functionName(owner, named) });
|
|
158
|
+
for (const block of templateBlocks(node.quasi)) compileBlock(block, block.scoped, owner, at);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
const inner = FUNCTIONS.has(node.type) ? [...owners, node] : owners;
|
|
163
|
+
if (node.type === "JSXElement" && isStyle(node)) {
|
|
164
|
+
handle(node, owners);
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
for (const key of Object.keys(node)) {
|
|
168
|
+
if (key === "loc" || key === "leadingComments" || key === "trailingComments" || key === "innerComments") continue;
|
|
169
|
+
const value = node[key];
|
|
170
|
+
if (Array.isArray(value)) for (const v of value) visit(v, inner);
|
|
171
|
+
else if (value && typeof value === "object" && "type" in value) visit(value, inner);
|
|
172
|
+
}
|
|
173
|
+
};
|
|
174
|
+
const handle = (node, owners) => {
|
|
175
|
+
const at = { line: node.loc?.start.line ?? 0, column: node.loc?.start.column ?? 0 };
|
|
176
|
+
const pieces = blockPieces(node);
|
|
177
|
+
if (pieces === null) {
|
|
178
|
+
plan.diagnostics.push({
|
|
179
|
+
...at,
|
|
180
|
+
message: "<style> needs its CSS as one template literal, <style>{`...`}</style>: JSX reads a bare `{` as an expression."
|
|
181
|
+
});
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
const owner = owners[0];
|
|
185
|
+
if (!owner) {
|
|
186
|
+
plan.diagnostics.push({ ...at, message: "<style> has to be written inside a component." });
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
compileBlock(pieces, isScoped(node), owner, at);
|
|
190
|
+
plan.drop.add(node.start);
|
|
191
|
+
};
|
|
192
|
+
const compileBlock = (pieces, scoped, owner, at) => {
|
|
193
|
+
const component = functionName(owner, named);
|
|
194
|
+
const id = idFor(owner);
|
|
195
|
+
const processed = piecesToNodes(pieces.quasis, pieces.expressions, at, []);
|
|
196
|
+
if (!processed) return;
|
|
197
|
+
let nodes = processed;
|
|
198
|
+
const shadow = shadowOf(owner);
|
|
199
|
+
if (scoped && !shadow) {
|
|
200
|
+
if (!plan.scopes.some((s) => s.value === id)) plan.scopes.push({ start: owner.start, end: owner.end, value: id });
|
|
201
|
+
nodes = scopeNodes(nodes, id, (message) => plan.diagnostics.push({ ...at, message }));
|
|
202
|
+
}
|
|
203
|
+
const printed = module2 ? printStyleWithMap(nodes, options.minify, sourceName, module2, options.importedModules) : { css: printStyle(nodes, options.minify) };
|
|
204
|
+
plan.styles.push({ id, scoped: scoped && !shadow, component, ...printed, ...shadow ? { shadow: true } : {}, ...at });
|
|
205
|
+
if (shadow) shadow.indexes.push(plan.styles.length - 1);
|
|
206
|
+
};
|
|
207
|
+
function idFor(owner) {
|
|
208
|
+
let id = scopeOf.get(owner);
|
|
209
|
+
if (!id) {
|
|
210
|
+
const component = functionName(owner, named);
|
|
211
|
+
const seen = names.get(component) ?? 0;
|
|
212
|
+
names.set(component, seen + 1);
|
|
213
|
+
id = hash(`${sourceName}:${component}${seen ? ":" + seen : ""}`);
|
|
214
|
+
scopeOf.set(owner, id);
|
|
215
|
+
}
|
|
216
|
+
return id;
|
|
217
|
+
}
|
|
218
|
+
visit(program, []);
|
|
219
|
+
return plan;
|
|
220
|
+
}
|
|
221
|
+
function applyTemplateStyles(ir, t) {
|
|
222
|
+
const walk8 = (node) => {
|
|
223
|
+
const children = node.children;
|
|
224
|
+
if (children) {
|
|
225
|
+
for (let i = children.length - 1; i >= 0; i--) {
|
|
226
|
+
const child = children[i];
|
|
227
|
+
if (child.kind === "element" && child.tag === "style" && t.owner) children.splice(i, 1);
|
|
228
|
+
else walk8(child);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
if (t.scope && node.kind === "element" && node.tag !== "style" && node.props && !node.props.some((p) => p.name === SCOPE_ATTR)) {
|
|
232
|
+
node.props.unshift({ name: SCOPE_ATTR, kind: "attr", literal: t.scope });
|
|
233
|
+
}
|
|
234
|
+
};
|
|
235
|
+
walk8(ir);
|
|
236
|
+
}
|
|
237
|
+
function staticMember(cls, name) {
|
|
238
|
+
return cls.body.body.find(
|
|
239
|
+
(m) => m.type === "ClassProperty" && m.static && (m.key.type === "Identifier" && m.key.name === name || m.key.type === "StringLiteral" && m.key.value === name)
|
|
240
|
+
);
|
|
241
|
+
}
|
|
242
|
+
var styleIds = {
|
|
243
|
+
block: (owner, index) => `${owner}.fx-${index}.css`,
|
|
244
|
+
inline: (owner, index) => `${owner}.fx-${index}.css?inline`,
|
|
245
|
+
literal: (owner, name) => `${owner}.fx-literal-${name}.css?inline`
|
|
246
|
+
};
|
|
247
|
+
function finishShadowStyles(plan, code, moduleId) {
|
|
248
|
+
const edits = [];
|
|
249
|
+
const imports = [];
|
|
250
|
+
let next = 0;
|
|
251
|
+
const importOf = (specifier) => {
|
|
252
|
+
const local = `__fxShadow${next++}`;
|
|
253
|
+
imports.push(`import ${local} from ${JSON.stringify(specifier)};
|
|
254
|
+
`);
|
|
255
|
+
return local;
|
|
256
|
+
};
|
|
257
|
+
for (const shadow of plan.shadowClasses.values()) {
|
|
258
|
+
const blocks = shadow.indexes.map((i) => importOf(styleIds.inline(moduleId, i)));
|
|
259
|
+
let value;
|
|
260
|
+
const prop = shadow.styles;
|
|
261
|
+
if (prop?.value) {
|
|
262
|
+
const start = prop.value.start;
|
|
263
|
+
let text = code.slice(start, prop.value.end);
|
|
264
|
+
const replacements = [];
|
|
265
|
+
walkIdentifiers(prop.value, (id) => {
|
|
266
|
+
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;
|
|
267
|
+
if (local) replacements.push({ at: id.start - start, length: id.name.length, with: local });
|
|
268
|
+
});
|
|
269
|
+
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);
|
|
270
|
+
value = text;
|
|
271
|
+
}
|
|
272
|
+
if (!blocks.length && value === void 0) continue;
|
|
273
|
+
if (prop?.value) {
|
|
274
|
+
const merged = blocks.length ? `[${value}, ${blocks.join(", ")}]` : value;
|
|
275
|
+
edits.push({ start: prop.value.start, end: prop.value.end, code: merged });
|
|
276
|
+
} else if (blocks.length) {
|
|
277
|
+
const open = shadow.node.body.start + 1;
|
|
278
|
+
edits.push({ start: open, end: open, code: ` static styles = [${blocks.join(", ")}];` });
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
if (imports.length) edits.push({ start: 0, end: 0, code: imports.join("") });
|
|
282
|
+
return edits;
|
|
283
|
+
}
|
|
284
|
+
function walkIdentifiers(node, visit) {
|
|
285
|
+
if (!node || typeof node !== "object") return;
|
|
286
|
+
if (node.type === "Identifier") return visit(node);
|
|
287
|
+
if (node.type === "MemberExpression") return walkIdentifiers(node.object, visit);
|
|
288
|
+
if (node.type === "ObjectProperty") return walkIdentifiers(node.value, visit);
|
|
289
|
+
for (const key of Object.keys(node)) {
|
|
290
|
+
if (key === "loc") continue;
|
|
291
|
+
const value = node[key];
|
|
292
|
+
if (Array.isArray(value)) for (const v of value) walkIdentifiers(v, visit);
|
|
293
|
+
else if (value && typeof value === "object" && "type" in value) walkIdentifiers(value, visit);
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
function isStyle(node) {
|
|
297
|
+
const name = node.openingElement.name;
|
|
298
|
+
return name.type === "JSXIdentifier" && name.name === "style";
|
|
299
|
+
}
|
|
300
|
+
function isScoped(node) {
|
|
301
|
+
return node.openingElement.attributes.some((a) => a.type === "JSXAttribute" && a.name.type === "JSXIdentifier" && a.name.name === "scoped");
|
|
302
|
+
}
|
|
303
|
+
function templateBlocks(quasi) {
|
|
304
|
+
const blocks = [];
|
|
305
|
+
let open = null;
|
|
306
|
+
quasi.quasis.forEach((q, i) => {
|
|
307
|
+
const raw = q.value.raw;
|
|
308
|
+
let from = 0;
|
|
309
|
+
while (from <= raw.length) {
|
|
310
|
+
if (!open) {
|
|
311
|
+
const tag = /<style\b([^>]*)>/g;
|
|
312
|
+
tag.lastIndex = from;
|
|
313
|
+
const m = tag.exec(raw);
|
|
314
|
+
if (!m) break;
|
|
315
|
+
open = { quasis: [], expressions: [], scoped: /\bscoped\b/.test(m[1]) };
|
|
316
|
+
from = m.index + m[0].length;
|
|
317
|
+
}
|
|
318
|
+
const close = raw.indexOf("</style", from);
|
|
319
|
+
open.quasis.push(slicePiece(q, raw, from, close === -1 ? raw.length : close));
|
|
320
|
+
if (close === -1) break;
|
|
321
|
+
blocks.push(open);
|
|
322
|
+
open = null;
|
|
323
|
+
from = close;
|
|
324
|
+
}
|
|
325
|
+
const expr = quasi.expressions[i];
|
|
326
|
+
if (open && expr) open.expressions.push(expr);
|
|
327
|
+
});
|
|
328
|
+
return blocks;
|
|
329
|
+
}
|
|
330
|
+
function slicePiece(q, raw, from, to) {
|
|
331
|
+
const text = raw.slice(from, to);
|
|
332
|
+
const start = q.loc?.start;
|
|
333
|
+
if (!start) return { type: "TemplateElement", value: { raw: text, cooked: text } };
|
|
334
|
+
const before = raw.slice(0, from).split("\n");
|
|
335
|
+
const line = start.line + before.length - 1;
|
|
336
|
+
const column = before.length > 1 ? before[before.length - 1].length : start.column + from;
|
|
337
|
+
return { type: "TemplateElement", value: { raw: text, cooked: text }, loc: { start: { line, column } } };
|
|
338
|
+
}
|
|
339
|
+
function blockPieces(node) {
|
|
340
|
+
const meaningful = node.children.filter((c) => !(c.type === "JSXText" && !c.value.trim()));
|
|
341
|
+
if (meaningful.length === 0) return { quasis: [], expressions: [] };
|
|
342
|
+
if (meaningful.length !== 1) return null;
|
|
343
|
+
const only = meaningful[0];
|
|
344
|
+
if (only.type !== "JSXExpressionContainer") return null;
|
|
345
|
+
const expr = only.expression;
|
|
346
|
+
if (expr.type === "StringLiteral") return { quasis: [{ type: "TemplateElement", value: { raw: expr.value, cooked: expr.value } }], expressions: [] };
|
|
347
|
+
if (expr.type === "TemplateLiteral") return { quasis: expr.quasis, expressions: expr.expressions };
|
|
348
|
+
return null;
|
|
349
|
+
}
|
|
350
|
+
function findLiterals(program, modules, plan, intrinsic) {
|
|
351
|
+
const literals = /* @__PURE__ */ new Map();
|
|
352
|
+
const imports = /* @__PURE__ */ new Map();
|
|
353
|
+
const tags = new Set(intrinsic);
|
|
354
|
+
for (const statement of program.body ?? []) {
|
|
355
|
+
if (statement.type !== "ImportDeclaration") continue;
|
|
356
|
+
const source = statement.source.value;
|
|
357
|
+
const specifiers = statement.specifiers;
|
|
358
|
+
for (const sp of specifiers) {
|
|
359
|
+
if (sp.type === "ImportSpecifier") imports.set(sp.local.name, { source, name: sp.imported.name ?? sp.imported.value });
|
|
360
|
+
}
|
|
361
|
+
if (!modules.includes(source)) continue;
|
|
362
|
+
const css = specifiers.find((sp) => sp.type === "ImportSpecifier" && (sp.imported.name ?? sp.imported.value) === "css");
|
|
363
|
+
if (!css) continue;
|
|
364
|
+
const local = css.local.name;
|
|
365
|
+
tags.add(local);
|
|
366
|
+
imports.delete(local);
|
|
367
|
+
plan.edits.push({ start: statement.start, end: statement.end, code: importWithout(statement, css) });
|
|
368
|
+
}
|
|
369
|
+
if (tags.size === 0) return { literals, imports };
|
|
370
|
+
const visit = (node) => {
|
|
371
|
+
if (!node || typeof node !== "object") return;
|
|
372
|
+
if (node.type === "VariableDeclarator" && node.id.type === "Identifier" && node.init?.type === "TaggedTemplateExpression" && node.init.tag.type === "Identifier" && tags.has(node.init.tag.name)) {
|
|
373
|
+
literals.set(node.id.name, node.init);
|
|
374
|
+
}
|
|
375
|
+
for (const key of Object.keys(node)) {
|
|
376
|
+
if (key === "loc") continue;
|
|
377
|
+
const value = node[key];
|
|
378
|
+
if (Array.isArray(value)) for (const v of value) visit(v);
|
|
379
|
+
else if (value && typeof value === "object" && "type" in value) visit(value);
|
|
380
|
+
}
|
|
381
|
+
};
|
|
382
|
+
visit(program);
|
|
383
|
+
return { literals, imports };
|
|
384
|
+
}
|
|
385
|
+
function importWithout(statement, removed) {
|
|
386
|
+
const rest = statement.specifiers.filter((sp) => sp !== removed);
|
|
387
|
+
const source = JSON.stringify(statement.source.value);
|
|
388
|
+
if (rest.length === 0) return "";
|
|
389
|
+
const def = rest.find((sp) => sp.type === "ImportDefaultSpecifier");
|
|
390
|
+
const ns = rest.find((sp) => sp.type === "ImportNamespaceSpecifier");
|
|
391
|
+
const named = rest.filter((sp) => sp.type === "ImportSpecifier").map((sp) => {
|
|
392
|
+
const imported = sp.imported.name ?? JSON.stringify(sp.imported.value);
|
|
393
|
+
return imported === sp.local.name ? imported : `${imported} as ${sp.local.name}`;
|
|
394
|
+
});
|
|
395
|
+
const parts = [def?.local.name, ns ? `* as ${ns.local.name}` : void 0, named.length ? `{ ${named.join(", ")} }` : void 0].filter(Boolean);
|
|
396
|
+
return `import ${parts.join(", ")} from ${source};`;
|
|
397
|
+
}
|
|
398
|
+
function functionName(fn, named) {
|
|
399
|
+
if ((fn.type === "FunctionDeclaration" || fn.type === "FunctionExpression") && fn.id) return fn.id.name;
|
|
400
|
+
return named.get(fn) ?? "anonymous";
|
|
401
|
+
}
|
|
402
|
+
function hash(text) {
|
|
403
|
+
let h = 2166136261;
|
|
404
|
+
for (let i = 0; i < text.length; i++) {
|
|
405
|
+
h ^= text.charCodeAt(i);
|
|
406
|
+
h = Math.imul(h, 16777619);
|
|
407
|
+
}
|
|
408
|
+
return (h >>> 0).toString(36);
|
|
409
|
+
}
|
|
410
|
+
var OPAQUE = /(^|-)keyframes$|^font-face$|^property$|^counter-style$|^page$|^font-feature-values$/;
|
|
411
|
+
function scopeNodes(nodes, id, warn = () => {
|
|
412
|
+
}) {
|
|
413
|
+
return nodes.map((node) => {
|
|
414
|
+
if (node.kind === "rule") return { ...node, selector: scopeSelector(node.selector, id, warn) };
|
|
415
|
+
if (node.kind === "at-rule" && !OPAQUE.test(node.name)) return { ...node, nodes: scopeNodes(node.nodes, id, warn) };
|
|
416
|
+
return node;
|
|
417
|
+
});
|
|
418
|
+
}
|
|
419
|
+
function scopeSelector(selector, id, warn = () => {
|
|
420
|
+
}) {
|
|
421
|
+
return splitTop(selector, ",").map((complex) => scopeComplex(complex.trim(), `[${SCOPE_ATTR}="${id}"]`, warn)).join(", ");
|
|
422
|
+
}
|
|
423
|
+
function scopeComplex(selector, attr, warn) {
|
|
424
|
+
if (/:host\b|::slotted\(/.test(selector)) {
|
|
425
|
+
warn(`\`${selector}\` only means something in a shadow root; in a light-DOM component it is left as written.`);
|
|
426
|
+
return selector;
|
|
427
|
+
}
|
|
428
|
+
const parts = compounds(selector);
|
|
429
|
+
const deep = parts.findIndex((p) => p.text.startsWith(":deep("));
|
|
430
|
+
if (deep !== -1) {
|
|
431
|
+
const inner = unwrap(parts[deep].text, ":deep(");
|
|
432
|
+
const before = parts.slice(0, deep);
|
|
433
|
+
if (before.length === 0) return `${attr} ${inner}`;
|
|
434
|
+
const scopedBefore = scopeAt(before, before.length - 1, attr);
|
|
435
|
+
return `${join(scopedBefore)} ${inner}`;
|
|
436
|
+
}
|
|
437
|
+
let target = -1;
|
|
438
|
+
for (let i = parts.length - 1; i >= 0; i--) {
|
|
439
|
+
if (!parts[i].text.startsWith(":global(")) {
|
|
440
|
+
target = i;
|
|
441
|
+
break;
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
const out = target === -1 ? parts : scopeAt(parts, target, attr);
|
|
445
|
+
return join(out.map((p) => p.text.startsWith(":global(") ? { ...p, text: unwrap(p.text, ":global(") } : p));
|
|
446
|
+
}
|
|
447
|
+
function scopeAt(parts, index, attr) {
|
|
448
|
+
return parts.map((p, i) => i === index ? { ...p, text: insertAttr(p.text, attr) } : p);
|
|
449
|
+
}
|
|
450
|
+
function insertAttr(compound, attr) {
|
|
451
|
+
let depth = 0;
|
|
452
|
+
let quote = "";
|
|
453
|
+
for (let i = 0; i < compound.length; i++) {
|
|
454
|
+
const c = compound[i];
|
|
455
|
+
if (quote) {
|
|
456
|
+
if (c === "\\") i++;
|
|
457
|
+
else if (c === quote) quote = "";
|
|
458
|
+
continue;
|
|
459
|
+
}
|
|
460
|
+
if (c === "\\") {
|
|
461
|
+
i++;
|
|
462
|
+
continue;
|
|
463
|
+
}
|
|
464
|
+
if (c === '"' || c === "'") quote = c;
|
|
465
|
+
else if (c === "(" || c === "[") depth++;
|
|
466
|
+
else if (c === ")" || c === "]") depth--;
|
|
467
|
+
else if (c === ":" && depth === 0 && i > 0) return compound.slice(0, i) + attr + compound.slice(i);
|
|
468
|
+
}
|
|
469
|
+
return compound + attr;
|
|
470
|
+
}
|
|
471
|
+
function compounds(selector) {
|
|
472
|
+
const out = [];
|
|
473
|
+
let depth = 0;
|
|
474
|
+
let quote = "";
|
|
475
|
+
let current = "";
|
|
476
|
+
let combinator = "";
|
|
477
|
+
const push = () => {
|
|
478
|
+
if (current.trim()) out.push({ combinator: out.length ? combinator || " " : "", text: current.trim() });
|
|
479
|
+
current = "";
|
|
480
|
+
combinator = "";
|
|
481
|
+
};
|
|
482
|
+
for (let i = 0; i < selector.length; i++) {
|
|
483
|
+
const c = selector[i];
|
|
484
|
+
if (quote) {
|
|
485
|
+
current += c;
|
|
486
|
+
if (c === "\\") current += selector[++i] ?? "";
|
|
487
|
+
else if (c === quote) quote = "";
|
|
488
|
+
continue;
|
|
489
|
+
}
|
|
490
|
+
if (c === "\\") {
|
|
491
|
+
current += c + (selector[++i] ?? "");
|
|
492
|
+
continue;
|
|
493
|
+
}
|
|
494
|
+
if (c === '"' || c === "'") quote = c;
|
|
495
|
+
if (c === "(" || c === "[") depth++;
|
|
496
|
+
if (c === ")" || c === "]") depth--;
|
|
497
|
+
if (depth === 0 && (c === ">" || c === "+" || c === "~")) {
|
|
498
|
+
push();
|
|
499
|
+
combinator = c;
|
|
500
|
+
continue;
|
|
501
|
+
}
|
|
502
|
+
if (depth === 0 && /\s/.test(c)) {
|
|
503
|
+
if (current.trim()) {
|
|
504
|
+
const keep = combinator;
|
|
505
|
+
push();
|
|
506
|
+
combinator = keep;
|
|
507
|
+
}
|
|
508
|
+
continue;
|
|
509
|
+
}
|
|
510
|
+
current += c;
|
|
511
|
+
}
|
|
512
|
+
push();
|
|
513
|
+
return out;
|
|
514
|
+
}
|
|
515
|
+
function join(parts) {
|
|
516
|
+
return parts.map((p, i) => i === 0 ? p.text : p.combinator === " " ? ` ${p.text}` : ` ${p.combinator} ${p.text}`).join("");
|
|
517
|
+
}
|
|
518
|
+
function unwrap(text, prefix) {
|
|
519
|
+
return text.slice(prefix.length, text.lastIndexOf(")")).trim() + text.slice(text.lastIndexOf(")") + 1);
|
|
520
|
+
}
|
|
521
|
+
function splitTop(selector, separator) {
|
|
522
|
+
const parts = [];
|
|
523
|
+
let depth = 0;
|
|
524
|
+
let quote = "";
|
|
525
|
+
let start = 0;
|
|
526
|
+
for (let i = 0; i < selector.length; i++) {
|
|
527
|
+
const c = selector[i];
|
|
528
|
+
if (quote) {
|
|
529
|
+
if (c === "\\") i++;
|
|
530
|
+
else if (c === quote) quote = "";
|
|
531
|
+
} else if (c === '"' || c === "'") quote = c;
|
|
532
|
+
else if (c === "\\") i++;
|
|
533
|
+
else if (c === "(" || c === "[") depth++;
|
|
534
|
+
else if (c === ")" || c === "]") depth--;
|
|
535
|
+
else if (c === separator && depth === 0) {
|
|
536
|
+
parts.push(selector.slice(start, i));
|
|
537
|
+
start = i + 1;
|
|
538
|
+
}
|
|
539
|
+
}
|
|
540
|
+
parts.push(selector.slice(start));
|
|
541
|
+
return parts.filter((p) => p.trim());
|
|
542
|
+
}
|
|
543
|
+
function shiftLoc(node, source, start) {
|
|
544
|
+
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;
|
|
545
|
+
if (node.kind === "rule" || node.kind === "at-rule") return { ...node, loc, nodes: node.nodes.map((n) => shiftLoc(n, source, start)) };
|
|
546
|
+
return { ...node, loc };
|
|
547
|
+
}
|
|
548
|
+
function keepLocIn(node, modules) {
|
|
549
|
+
const keep = node.loc !== void 0 && modules?.has(node.loc.source) === true;
|
|
550
|
+
const { loc, ...rest } = node;
|
|
551
|
+
const kept = keep ? { ...rest, loc } : rest;
|
|
552
|
+
if (kept.kind === "rule" || kept.kind === "at-rule") return { ...kept, nodes: kept.nodes.map((n) => keepLocIn(n, modules)) };
|
|
553
|
+
return kept;
|
|
554
|
+
}
|
|
555
|
+
function printStyleWithMap(nodes, minify, sourceName, module2, others) {
|
|
556
|
+
const sources = [module2];
|
|
557
|
+
const index = /* @__PURE__ */ new Map([[sourceName, 0]]);
|
|
558
|
+
const sourceOf = (name) => {
|
|
559
|
+
if (index.has(name)) return index.get(name);
|
|
560
|
+
const other = others?.get(name);
|
|
561
|
+
if (!other) return void 0;
|
|
562
|
+
index.set(name, sources.push(other) - 1);
|
|
563
|
+
return index.get(name);
|
|
564
|
+
};
|
|
565
|
+
const lines = [[]];
|
|
566
|
+
let css = "";
|
|
567
|
+
let column = 0;
|
|
568
|
+
const emit = (text) => {
|
|
569
|
+
for (const ch of text) {
|
|
570
|
+
css += ch;
|
|
571
|
+
if (ch === "\n") {
|
|
572
|
+
lines.push([]);
|
|
573
|
+
column = 0;
|
|
574
|
+
} else column++;
|
|
575
|
+
}
|
|
576
|
+
};
|
|
577
|
+
const mark = (loc) => {
|
|
578
|
+
const at = loc ? sourceOf(loc.source) : void 0;
|
|
579
|
+
if (loc && at !== void 0) lines[lines.length - 1].push([column, at, loc.line - 1, loc.column]);
|
|
580
|
+
};
|
|
581
|
+
const write = (node, depth) => {
|
|
582
|
+
const pad = minify ? "" : " ".repeat(depth);
|
|
583
|
+
const nl = minify ? "" : "\n";
|
|
584
|
+
const sp = minify ? "" : " ";
|
|
585
|
+
emit(pad);
|
|
586
|
+
mark(node.loc);
|
|
587
|
+
if (node.kind === "declaration") {
|
|
588
|
+
emit(`${node.property}:${sp}${node.value}${node.important ? `${sp}!important` : ""};${nl}`);
|
|
589
|
+
} else if (node.kind === "raw") {
|
|
590
|
+
emit(`${node.text}${nl}`);
|
|
591
|
+
} else {
|
|
592
|
+
emit(`${node.kind === "rule" ? node.selector : `@${node.name}${node.params ? " " + node.params : ""}`}${sp}{${nl}`);
|
|
593
|
+
for (const child of node.nodes) write(child, depth + 1);
|
|
594
|
+
emit(`${pad}}${nl}`);
|
|
595
|
+
}
|
|
596
|
+
};
|
|
597
|
+
for (const node of nodes) write(node, 0);
|
|
598
|
+
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) } };
|
|
599
|
+
}
|
|
600
|
+
function printStyle(nodes, minify = false) {
|
|
601
|
+
const out = [];
|
|
602
|
+
const write = (node, depth) => {
|
|
603
|
+
const pad = minify ? "" : " ".repeat(depth);
|
|
604
|
+
const nl = minify ? "" : "\n";
|
|
605
|
+
const sp = minify ? "" : " ";
|
|
606
|
+
if (node.kind === "declaration") {
|
|
607
|
+
out.push(`${pad}${node.property}:${sp}${node.value}${node.important ? `${sp}!important` : ""};${nl}`);
|
|
608
|
+
} else if (node.kind === "raw") {
|
|
609
|
+
out.push(`${pad}${node.text}${nl}`);
|
|
610
|
+
} else {
|
|
611
|
+
const header = node.kind === "rule" ? node.selector : `@${node.name}${node.params ? " " + node.params : ""}`;
|
|
612
|
+
out.push(`${pad}${header}${sp}{${nl}`);
|
|
613
|
+
for (const child of node.nodes) write(child, depth + 1);
|
|
614
|
+
out.push(`${pad}}${nl}`);
|
|
615
|
+
}
|
|
616
|
+
};
|
|
617
|
+
for (const node of nodes) write(node, 0);
|
|
618
|
+
return out.join("");
|
|
619
|
+
}
|
|
620
|
+
|
|
47
621
|
// src/optimize/analyze-static.ts
|
|
48
622
|
function propReason(prop) {
|
|
49
623
|
switch (prop.kind) {
|
|
@@ -541,6 +1115,16 @@ var PRIMITIVE_MODULES = [
|
|
|
541
1115
|
"@fluixi/reactive/cached-resource",
|
|
542
1116
|
"@fluixi/core"
|
|
543
1117
|
];
|
|
1118
|
+
var TAG_INTRINSICS = {
|
|
1119
|
+
$html: { export: "html", module: "@fluixi/core" },
|
|
1120
|
+
$svg: { export: "svg", module: "@fluixi/core" },
|
|
1121
|
+
$css: { export: "css", module: "@fluixi/core" }
|
|
1122
|
+
};
|
|
1123
|
+
function tagIntrinsics(bound) {
|
|
1124
|
+
const tags = /* @__PURE__ */ new Map();
|
|
1125
|
+
for (const [name, tag] of Object.entries(TAG_INTRINSICS)) if (!bound.has(name)) tags.set(name, tag.export);
|
|
1126
|
+
return tags;
|
|
1127
|
+
}
|
|
544
1128
|
var INTRINSIC_CALL = new RegExp(`\\$(?:${Object.keys(INTRINSICS).map((n) => n.slice(1)).join("|")})\\s*\\(`);
|
|
545
1129
|
function mayHaveIntrinsic(code) {
|
|
546
1130
|
return INTRINSIC_CALL.test(code);
|
|
@@ -1044,7 +1628,7 @@ function emitComponent(name, props, children, used, templates, at) {
|
|
|
1044
1628
|
}
|
|
1045
1629
|
let obj = `{ ${bodies.map(([name2, body]) => `get ${propKey(name2)}() { return ${body}; }`).join(", ")} }`;
|
|
1046
1630
|
if (bodies.some(([, body]) => /\bthis\b/.test(body))) {
|
|
1047
|
-
const thunks = bodies.map(([name2, body]) => `${JSON.stringify(name2)}: () => ${body}`);
|
|
1631
|
+
const thunks = bodies.map(([name2, body]) => `${JSON.stringify(name2)}: () => (${body})`);
|
|
1048
1632
|
const getters = bodies.map(([name2]) => `get ${propKey(name2)}() { return _$t[${JSON.stringify(name2)}](); }`);
|
|
1049
1633
|
obj = `((_$t) => ({ ${getters.join(", ")} }))({ ${thunks.join(", ")} })`;
|
|
1050
1634
|
}
|
|
@@ -1243,6 +1827,271 @@ function cleanTemplateText(value) {
|
|
|
1243
1827
|
return out;
|
|
1244
1828
|
}
|
|
1245
1829
|
|
|
1830
|
+
// src/lower/entities.ts
|
|
1831
|
+
var NAMED = {
|
|
1832
|
+
quot: 34,
|
|
1833
|
+
amp: 38,
|
|
1834
|
+
apos: 39,
|
|
1835
|
+
lt: 60,
|
|
1836
|
+
gt: 62,
|
|
1837
|
+
nbsp: 160,
|
|
1838
|
+
iexcl: 161,
|
|
1839
|
+
cent: 162,
|
|
1840
|
+
pound: 163,
|
|
1841
|
+
curren: 164,
|
|
1842
|
+
yen: 165,
|
|
1843
|
+
brvbar: 166,
|
|
1844
|
+
sect: 167,
|
|
1845
|
+
uml: 168,
|
|
1846
|
+
copy: 169,
|
|
1847
|
+
ordf: 170,
|
|
1848
|
+
laquo: 171,
|
|
1849
|
+
not: 172,
|
|
1850
|
+
shy: 173,
|
|
1851
|
+
reg: 174,
|
|
1852
|
+
macr: 175,
|
|
1853
|
+
deg: 176,
|
|
1854
|
+
plusmn: 177,
|
|
1855
|
+
sup2: 178,
|
|
1856
|
+
sup3: 179,
|
|
1857
|
+
acute: 180,
|
|
1858
|
+
micro: 181,
|
|
1859
|
+
para: 182,
|
|
1860
|
+
middot: 183,
|
|
1861
|
+
cedil: 184,
|
|
1862
|
+
sup1: 185,
|
|
1863
|
+
ordm: 186,
|
|
1864
|
+
raquo: 187,
|
|
1865
|
+
frac14: 188,
|
|
1866
|
+
frac12: 189,
|
|
1867
|
+
frac34: 190,
|
|
1868
|
+
iquest: 191,
|
|
1869
|
+
Agrave: 192,
|
|
1870
|
+
Aacute: 193,
|
|
1871
|
+
Acirc: 194,
|
|
1872
|
+
Atilde: 195,
|
|
1873
|
+
Auml: 196,
|
|
1874
|
+
Aring: 197,
|
|
1875
|
+
AElig: 198,
|
|
1876
|
+
Ccedil: 199,
|
|
1877
|
+
Egrave: 200,
|
|
1878
|
+
Eacute: 201,
|
|
1879
|
+
Ecirc: 202,
|
|
1880
|
+
Euml: 203,
|
|
1881
|
+
Igrave: 204,
|
|
1882
|
+
Iacute: 205,
|
|
1883
|
+
Icirc: 206,
|
|
1884
|
+
Iuml: 207,
|
|
1885
|
+
ETH: 208,
|
|
1886
|
+
Ntilde: 209,
|
|
1887
|
+
Ograve: 210,
|
|
1888
|
+
Oacute: 211,
|
|
1889
|
+
Ocirc: 212,
|
|
1890
|
+
Otilde: 213,
|
|
1891
|
+
Ouml: 214,
|
|
1892
|
+
times: 215,
|
|
1893
|
+
Oslash: 216,
|
|
1894
|
+
Ugrave: 217,
|
|
1895
|
+
Uacute: 218,
|
|
1896
|
+
Ucirc: 219,
|
|
1897
|
+
Uuml: 220,
|
|
1898
|
+
Yacute: 221,
|
|
1899
|
+
THORN: 222,
|
|
1900
|
+
szlig: 223,
|
|
1901
|
+
agrave: 224,
|
|
1902
|
+
aacute: 225,
|
|
1903
|
+
acirc: 226,
|
|
1904
|
+
atilde: 227,
|
|
1905
|
+
auml: 228,
|
|
1906
|
+
aring: 229,
|
|
1907
|
+
aelig: 230,
|
|
1908
|
+
ccedil: 231,
|
|
1909
|
+
egrave: 232,
|
|
1910
|
+
eacute: 233,
|
|
1911
|
+
ecirc: 234,
|
|
1912
|
+
euml: 235,
|
|
1913
|
+
igrave: 236,
|
|
1914
|
+
iacute: 237,
|
|
1915
|
+
icirc: 238,
|
|
1916
|
+
iuml: 239,
|
|
1917
|
+
eth: 240,
|
|
1918
|
+
ntilde: 241,
|
|
1919
|
+
ograve: 242,
|
|
1920
|
+
oacute: 243,
|
|
1921
|
+
ocirc: 244,
|
|
1922
|
+
otilde: 245,
|
|
1923
|
+
ouml: 246,
|
|
1924
|
+
divide: 247,
|
|
1925
|
+
oslash: 248,
|
|
1926
|
+
ugrave: 249,
|
|
1927
|
+
uacute: 250,
|
|
1928
|
+
ucirc: 251,
|
|
1929
|
+
uuml: 252,
|
|
1930
|
+
yacute: 253,
|
|
1931
|
+
thorn: 254,
|
|
1932
|
+
yuml: 255,
|
|
1933
|
+
OElig: 338,
|
|
1934
|
+
oelig: 339,
|
|
1935
|
+
Scaron: 352,
|
|
1936
|
+
scaron: 353,
|
|
1937
|
+
Yuml: 376,
|
|
1938
|
+
fnof: 402,
|
|
1939
|
+
circ: 710,
|
|
1940
|
+
tilde: 732,
|
|
1941
|
+
Alpha: 913,
|
|
1942
|
+
Beta: 914,
|
|
1943
|
+
Gamma: 915,
|
|
1944
|
+
Delta: 916,
|
|
1945
|
+
Epsilon: 917,
|
|
1946
|
+
Zeta: 918,
|
|
1947
|
+
Eta: 919,
|
|
1948
|
+
Theta: 920,
|
|
1949
|
+
Iota: 921,
|
|
1950
|
+
Kappa: 922,
|
|
1951
|
+
Lambda: 923,
|
|
1952
|
+
Mu: 924,
|
|
1953
|
+
Nu: 925,
|
|
1954
|
+
Xi: 926,
|
|
1955
|
+
Omicron: 927,
|
|
1956
|
+
Pi: 928,
|
|
1957
|
+
Rho: 929,
|
|
1958
|
+
Sigma: 931,
|
|
1959
|
+
Tau: 932,
|
|
1960
|
+
Upsilon: 933,
|
|
1961
|
+
Phi: 934,
|
|
1962
|
+
Chi: 935,
|
|
1963
|
+
Psi: 936,
|
|
1964
|
+
Omega: 937,
|
|
1965
|
+
alpha: 945,
|
|
1966
|
+
beta: 946,
|
|
1967
|
+
gamma: 947,
|
|
1968
|
+
delta: 948,
|
|
1969
|
+
epsilon: 949,
|
|
1970
|
+
zeta: 950,
|
|
1971
|
+
eta: 951,
|
|
1972
|
+
theta: 952,
|
|
1973
|
+
iota: 953,
|
|
1974
|
+
kappa: 954,
|
|
1975
|
+
lambda: 955,
|
|
1976
|
+
mu: 956,
|
|
1977
|
+
nu: 957,
|
|
1978
|
+
xi: 958,
|
|
1979
|
+
omicron: 959,
|
|
1980
|
+
pi: 960,
|
|
1981
|
+
rho: 961,
|
|
1982
|
+
sigmaf: 962,
|
|
1983
|
+
sigma: 963,
|
|
1984
|
+
tau: 964,
|
|
1985
|
+
upsilon: 965,
|
|
1986
|
+
phi: 966,
|
|
1987
|
+
chi: 967,
|
|
1988
|
+
psi: 968,
|
|
1989
|
+
omega: 969,
|
|
1990
|
+
thetasym: 977,
|
|
1991
|
+
upsih: 978,
|
|
1992
|
+
piv: 982,
|
|
1993
|
+
ensp: 8194,
|
|
1994
|
+
emsp: 8195,
|
|
1995
|
+
thinsp: 8201,
|
|
1996
|
+
zwnj: 8204,
|
|
1997
|
+
zwj: 8205,
|
|
1998
|
+
lrm: 8206,
|
|
1999
|
+
rlm: 8207,
|
|
2000
|
+
ndash: 8211,
|
|
2001
|
+
mdash: 8212,
|
|
2002
|
+
lsquo: 8216,
|
|
2003
|
+
rsquo: 8217,
|
|
2004
|
+
sbquo: 8218,
|
|
2005
|
+
ldquo: 8220,
|
|
2006
|
+
rdquo: 8221,
|
|
2007
|
+
bdquo: 8222,
|
|
2008
|
+
dagger: 8224,
|
|
2009
|
+
Dagger: 8225,
|
|
2010
|
+
bull: 8226,
|
|
2011
|
+
hellip: 8230,
|
|
2012
|
+
permil: 8240,
|
|
2013
|
+
prime: 8242,
|
|
2014
|
+
Prime: 8243,
|
|
2015
|
+
lsaquo: 8249,
|
|
2016
|
+
rsaquo: 8250,
|
|
2017
|
+
oline: 8254,
|
|
2018
|
+
frasl: 8260,
|
|
2019
|
+
euro: 8364,
|
|
2020
|
+
image: 8465,
|
|
2021
|
+
weierp: 8472,
|
|
2022
|
+
real: 8476,
|
|
2023
|
+
trade: 8482,
|
|
2024
|
+
alefsym: 8501,
|
|
2025
|
+
larr: 8592,
|
|
2026
|
+
uarr: 8593,
|
|
2027
|
+
rarr: 8594,
|
|
2028
|
+
darr: 8595,
|
|
2029
|
+
harr: 8596,
|
|
2030
|
+
crarr: 8629,
|
|
2031
|
+
lArr: 8656,
|
|
2032
|
+
uArr: 8657,
|
|
2033
|
+
rArr: 8658,
|
|
2034
|
+
dArr: 8659,
|
|
2035
|
+
hArr: 8660,
|
|
2036
|
+
forall: 8704,
|
|
2037
|
+
part: 8706,
|
|
2038
|
+
exist: 8707,
|
|
2039
|
+
empty: 8709,
|
|
2040
|
+
nabla: 8711,
|
|
2041
|
+
isin: 8712,
|
|
2042
|
+
notin: 8713,
|
|
2043
|
+
ni: 8715,
|
|
2044
|
+
prod: 8719,
|
|
2045
|
+
sum: 8721,
|
|
2046
|
+
minus: 8722,
|
|
2047
|
+
lowast: 8727,
|
|
2048
|
+
radic: 8730,
|
|
2049
|
+
prop: 8733,
|
|
2050
|
+
infin: 8734,
|
|
2051
|
+
ang: 8736,
|
|
2052
|
+
and: 8743,
|
|
2053
|
+
or: 8744,
|
|
2054
|
+
cap: 8745,
|
|
2055
|
+
cup: 8746,
|
|
2056
|
+
int: 8747,
|
|
2057
|
+
there4: 8756,
|
|
2058
|
+
sim: 8764,
|
|
2059
|
+
cong: 8773,
|
|
2060
|
+
asymp: 8776,
|
|
2061
|
+
ne: 8800,
|
|
2062
|
+
equiv: 8801,
|
|
2063
|
+
le: 8804,
|
|
2064
|
+
ge: 8805,
|
|
2065
|
+
sub: 8834,
|
|
2066
|
+
sup: 8835,
|
|
2067
|
+
nsub: 8836,
|
|
2068
|
+
sube: 8838,
|
|
2069
|
+
supe: 8839,
|
|
2070
|
+
oplus: 8853,
|
|
2071
|
+
otimes: 8855,
|
|
2072
|
+
perp: 8869,
|
|
2073
|
+
sdot: 8901,
|
|
2074
|
+
lceil: 8968,
|
|
2075
|
+
rceil: 8969,
|
|
2076
|
+
lfloor: 8970,
|
|
2077
|
+
rfloor: 8971,
|
|
2078
|
+
lang: 9001,
|
|
2079
|
+
rang: 9002,
|
|
2080
|
+
loz: 9674,
|
|
2081
|
+
spades: 9824,
|
|
2082
|
+
clubs: 9827,
|
|
2083
|
+
hearts: 9829,
|
|
2084
|
+
diams: 9830
|
|
2085
|
+
};
|
|
2086
|
+
var REFERENCE = /&(?:#[xX]([0-9a-fA-F]{1,6})|#([0-9]{1,7})|([a-zA-Z][a-zA-Z0-9]{1,31}));/g;
|
|
2087
|
+
function decodeEntities(value) {
|
|
2088
|
+
if (!value.includes("&")) return value;
|
|
2089
|
+
return value.replace(REFERENCE, (match, hex, dec, name) => {
|
|
2090
|
+
const code = hex ? parseInt(hex, 16) : dec ? parseInt(dec, 10) : Object.prototype.hasOwnProperty.call(NAMED, name) ? NAMED[name] : void 0;
|
|
2091
|
+
return code !== void 0 && code <= 1114111 ? String.fromCodePoint(code) : match;
|
|
2092
|
+
});
|
|
2093
|
+
}
|
|
2094
|
+
|
|
1246
2095
|
// src/lower/template.ts
|
|
1247
2096
|
var DELEGATED = /* @__PURE__ */ new Set([
|
|
1248
2097
|
"click",
|
|
@@ -1329,7 +2178,7 @@ var Lowerer = class {
|
|
|
1329
2178
|
switch (node.kind) {
|
|
1330
2179
|
case "Text": {
|
|
1331
2180
|
if (node.raw) return { kind: "text", value: node.value };
|
|
1332
|
-
const cleaned = cleanTemplateText(node.value);
|
|
2181
|
+
const cleaned = decodeEntities(cleanTemplateText(node.value));
|
|
1333
2182
|
return cleaned ? { kind: "text", value: cleaned } : null;
|
|
1334
2183
|
}
|
|
1335
2184
|
case "Comment":
|
|
@@ -1365,7 +2214,7 @@ var Lowerer = class {
|
|
|
1365
2214
|
kind: "element",
|
|
1366
2215
|
tag: el.tag,
|
|
1367
2216
|
svg: el.namespace === "svg",
|
|
1368
|
-
props: this.lowerAttributes(el.attributes),
|
|
2217
|
+
props: this.lowerAttributes(el.attributes, true),
|
|
1369
2218
|
children,
|
|
1370
2219
|
static: false,
|
|
1371
2220
|
...at ? { at } : {}
|
|
@@ -1478,13 +2327,22 @@ var Lowerer = class {
|
|
|
1478
2327
|
return clone.kind === "Element" ? this.lowerElement(clone) : this.lowerComponent(clone);
|
|
1479
2328
|
}
|
|
1480
2329
|
// --- attributes ---------------------------------------------------------
|
|
1481
|
-
|
|
2330
|
+
/**
|
|
2331
|
+
* `element`: a DOM element, where each class:/style: value that moves is its own accessor.
|
|
2332
|
+
* A component gets the object as before, rebuilt whole when any value moves.
|
|
2333
|
+
*/
|
|
2334
|
+
lowerAttributes(attrs, element = false) {
|
|
2335
|
+
let anyReactive = false;
|
|
2336
|
+
const entry = (name, h) => {
|
|
2337
|
+
anyReactive ||= h.reactive;
|
|
2338
|
+
if (!element || !h.reactive) return `${JSON.stringify(name)}: ${h.code}`;
|
|
2339
|
+
const accessor = `() => ${paren(h.code, "arrowBody")}`;
|
|
2340
|
+
return `${JSON.stringify(name)}: ${h.at ? markHole(accessor, h.at.line, h.at.column) : accessor}`;
|
|
2341
|
+
};
|
|
1482
2342
|
const props = [];
|
|
1483
2343
|
const classEntries = [];
|
|
1484
|
-
let classReactive = false;
|
|
1485
2344
|
let classAt;
|
|
1486
2345
|
const styleEntries = [];
|
|
1487
|
-
let styleReactive = false;
|
|
1488
2346
|
let styleAt;
|
|
1489
2347
|
const usePairs = [];
|
|
1490
2348
|
for (const a of attrs) {
|
|
@@ -1524,15 +2382,13 @@ var Lowerer = class {
|
|
|
1524
2382
|
break;
|
|
1525
2383
|
case "ClassDirective": {
|
|
1526
2384
|
const h = this.hole(a.hole);
|
|
1527
|
-
classEntries.push(
|
|
1528
|
-
classReactive = classReactive || h.reactive;
|
|
2385
|
+
classEntries.push(entry(a.name, h));
|
|
1529
2386
|
classAt ??= h.at;
|
|
1530
2387
|
break;
|
|
1531
2388
|
}
|
|
1532
2389
|
case "StyleDirective": {
|
|
1533
2390
|
const h = this.hole(a.hole);
|
|
1534
|
-
styleEntries.push(
|
|
1535
|
-
styleReactive = styleReactive || h.reactive;
|
|
2391
|
+
styleEntries.push(entry(a.name, h));
|
|
1536
2392
|
styleAt ??= h.at;
|
|
1537
2393
|
break;
|
|
1538
2394
|
}
|
|
@@ -1552,18 +2408,19 @@ var Lowerer = class {
|
|
|
1552
2408
|
name: "classList",
|
|
1553
2409
|
kind: "attr",
|
|
1554
2410
|
expr: `{ ${classEntries.join(", ")} }`,
|
|
1555
|
-
reactive:
|
|
2411
|
+
reactive: !element && anyReactive,
|
|
1556
2412
|
...classAt ? { at: classAt } : {}
|
|
1557
2413
|
});
|
|
1558
2414
|
}
|
|
1559
2415
|
if (styleEntries.length > 0) {
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
2416
|
+
const entries = `{ ${styleEntries.join(", ")} }`;
|
|
2417
|
+
const base = props.findIndex((p) => p.name === "style");
|
|
2418
|
+
if (base === -1) props.push({ name: "style", kind: "attr", expr: entries, reactive: !element && anyReactive, ...styleAt ? { at: styleAt } : {} });
|
|
2419
|
+
else {
|
|
2420
|
+
const prop = props[base];
|
|
2421
|
+
const value = prop.expr === void 0 ? JSON.stringify(prop.literal) : prop.reactive ? `() => ${paren(prop.expr, "arrowBody")}` : prop.expr;
|
|
2422
|
+
props[base] = { name: "style", kind: "attr", expr: `[${value}, ${entries}]`, reactive: false, ...prop.at ? { at: prop.at } : {} };
|
|
2423
|
+
}
|
|
1567
2424
|
}
|
|
1568
2425
|
if (usePairs.length > 0) {
|
|
1569
2426
|
props.push({ name: "use", kind: "attr", expr: `[${usePairs.join(", ")}]` });
|
|
@@ -1652,7 +2509,7 @@ var Lowerer = class {
|
|
|
1652
2509
|
return base;
|
|
1653
2510
|
}
|
|
1654
2511
|
if (v.kind === "static") {
|
|
1655
|
-
base.literal = v.value;
|
|
2512
|
+
base.literal = decodeEntities(v.value);
|
|
1656
2513
|
return base;
|
|
1657
2514
|
}
|
|
1658
2515
|
if (v.kind === "hole") {
|
|
@@ -1665,7 +2522,7 @@ var Lowerer = class {
|
|
|
1665
2522
|
let reactive = false;
|
|
1666
2523
|
let at;
|
|
1667
2524
|
const body = v.parts.map((p) => {
|
|
1668
|
-
if ("text" in p) return escapeTemplate(p.text);
|
|
2525
|
+
if ("text" in p) return escapeTemplate(decodeEntities(p.text));
|
|
1669
2526
|
const h = this.hole(p.hole);
|
|
1670
2527
|
reactive = reactive || h.reactive;
|
|
1671
2528
|
at ??= h.at;
|
|
@@ -1690,6 +2547,7 @@ function compilePieces(pieces, holes, options = {}) {
|
|
|
1690
2547
|
...options.sourceFile ? { sourceFile: options.sourceFile } : {},
|
|
1691
2548
|
...options.positionAt ? { positionAt: options.positionAt } : {}
|
|
1692
2549
|
});
|
|
2550
|
+
if (options.templateStyles) applyTemplateStyles(ir, options.templateStyles);
|
|
1693
2551
|
analyzeStatic(ir);
|
|
1694
2552
|
resolveComponentSources(ir, {
|
|
1695
2553
|
resolver: createComponentResolver(options.resolve ?? []),
|
|
@@ -1888,9 +2746,12 @@ function attrExprCode(attr, ctx) {
|
|
|
1888
2746
|
}
|
|
1889
2747
|
return null;
|
|
1890
2748
|
}
|
|
1891
|
-
function buildProps(attrs, ctx) {
|
|
2749
|
+
function buildProps(attrs, ctx, element = false) {
|
|
1892
2750
|
const props = [];
|
|
1893
2751
|
const usePairs = [];
|
|
2752
|
+
const classEntries = [];
|
|
2753
|
+
const styleEntries = [];
|
|
2754
|
+
let styleAt;
|
|
1894
2755
|
for (const a of attrs) {
|
|
1895
2756
|
if (a.type === "JSXSpreadAttribute") {
|
|
1896
2757
|
props.push({ name: "", kind: "spread", expr: ctx.code(a.argument) });
|
|
@@ -1906,6 +2767,27 @@ function buildProps(attrs, ctx) {
|
|
|
1906
2767
|
usePairs.push(opts != null ? `[${dir}, () => ${paren(opts, "arrowBody")}]` : `[${dir}]`);
|
|
1907
2768
|
continue;
|
|
1908
2769
|
}
|
|
2770
|
+
if (element && (ns === "class" || ns === "style")) {
|
|
2771
|
+
const key = JSON.stringify(a.name.name.name);
|
|
2772
|
+
const v = a.value;
|
|
2773
|
+
let value;
|
|
2774
|
+
if (v == null) value = "true";
|
|
2775
|
+
else if (isString(v)) value = JSON.stringify(literalOf(v));
|
|
2776
|
+
else if (v.type === "JSXExpressionContainer" && v.expression?.type !== "JSXEmptyExpression") {
|
|
2777
|
+
value = keyValue(v.expression, ctx);
|
|
2778
|
+
if (ns === "style") styleAt ??= posOf(v.expression, ctx);
|
|
2779
|
+
} else continue;
|
|
2780
|
+
(ns === "class" ? classEntries : styleEntries).push(`${key}: ${value}`);
|
|
2781
|
+
continue;
|
|
2782
|
+
}
|
|
2783
|
+
if (element && a.name.type === "JSXIdentifier" && a.name.name === "style" && a.value?.type === "JSXExpressionContainer") {
|
|
2784
|
+
const entries = objectEntries(a.value.expression, ctx);
|
|
2785
|
+
if (entries) {
|
|
2786
|
+
styleEntries.unshift(...entries);
|
|
2787
|
+
styleAt = posOf(a.value.expression, ctx);
|
|
2788
|
+
continue;
|
|
2789
|
+
}
|
|
2790
|
+
}
|
|
1909
2791
|
if (ns === "oncapture") {
|
|
1910
2792
|
const evt = a.name.name.name.toLowerCase();
|
|
1911
2793
|
const h = attrExprCode(a, ctx) ?? "undefined";
|
|
@@ -1914,9 +2796,37 @@ function buildProps(attrs, ctx) {
|
|
|
1914
2796
|
}
|
|
1915
2797
|
props.push(buildAttr(a, ctx));
|
|
1916
2798
|
}
|
|
2799
|
+
if (classEntries.length > 0) props.push({ name: "classList", kind: "attr", expr: `{ ${classEntries.join(", ")} }`, reactive: false });
|
|
2800
|
+
if (styleEntries.length > 0) {
|
|
2801
|
+
const entries = `{ ${styleEntries.join(", ")} }`;
|
|
2802
|
+
const base = props.findIndex((p) => p.name === "style" && p.kind === "attr");
|
|
2803
|
+
if (base === -1) props.push({ name: "style", kind: "attr", expr: entries, reactive: false, ...styleAt ? { at: styleAt } : {} });
|
|
2804
|
+
else {
|
|
2805
|
+
const prop = props[base];
|
|
2806
|
+
const value = prop.literal !== void 0 ? JSON.stringify(prop.literal) : prop.reactive ? `() => ${paren(prop.expr, "arrowBody")}` : prop.expr;
|
|
2807
|
+
props[base] = { name: "style", kind: "attr", expr: `[${value}, ${entries}]`, reactive: false, ...prop.at ? { at: prop.at } : {} };
|
|
2808
|
+
}
|
|
2809
|
+
}
|
|
1917
2810
|
if (usePairs.length > 0) props.push({ name: "use", kind: "attr", expr: `[${usePairs.join(", ")}]` });
|
|
1918
2811
|
return props;
|
|
1919
2812
|
}
|
|
2813
|
+
function keyValue(expr, ctx) {
|
|
2814
|
+
const code = ctx.code(expr);
|
|
2815
|
+
if (!isReactive(expr)) return code;
|
|
2816
|
+
const accessor = `() => ${paren(code, "arrowBody")}`;
|
|
2817
|
+
const at = posOf(expr, ctx);
|
|
2818
|
+
return at ? markHole(accessor, at.line, at.column) : accessor;
|
|
2819
|
+
}
|
|
2820
|
+
function objectEntries(expr, ctx) {
|
|
2821
|
+
if (expr?.type !== "ObjectExpression") return null;
|
|
2822
|
+
const entries = [];
|
|
2823
|
+
for (const p of expr.properties) {
|
|
2824
|
+
if (p.type !== "ObjectProperty") return null;
|
|
2825
|
+
const key = p.computed ? `[${ctx.code(p.key)}]` : p.key.type === "Identifier" ? JSON.stringify(p.key.name) : JSON.stringify(String(p.key.value));
|
|
2826
|
+
entries.push(`${key}: ${keyValue(p.value, ctx)}`);
|
|
2827
|
+
}
|
|
2828
|
+
return entries;
|
|
2829
|
+
}
|
|
1920
2830
|
function buildChildren(children, ctx) {
|
|
1921
2831
|
const out = [];
|
|
1922
2832
|
for (let i = 0; i < children.length; i++) {
|
|
@@ -1944,6 +2854,7 @@ function buildChildren(children, ctx) {
|
|
|
1944
2854
|
});
|
|
1945
2855
|
}
|
|
1946
2856
|
} else if (child.type === "JSXElement" || child.type === "JSXFragment") {
|
|
2857
|
+
if (ctx.dropStyles?.has(child.start)) continue;
|
|
1947
2858
|
out.push(buildNode(child, ctx));
|
|
1948
2859
|
} else if (child.type === "JSXSpreadChild") {
|
|
1949
2860
|
out.push({ kind: "expr", code: ctx.code(child.expression), reactive: false });
|
|
@@ -2013,13 +2924,17 @@ function buildElement(node, ctx, handled) {
|
|
|
2013
2924
|
const children = each ? [each] : buildChildren(node.children, ctx);
|
|
2014
2925
|
if (tag === CONTAINER2) return children.length === 1 ? children[0] : { kind: "fragment", children };
|
|
2015
2926
|
const at = ctx.sourceFile && node.loc?.start ? { file: ctx.sourceFile, line: node.loc.start.line, column: node.loc.start.column } : void 0;
|
|
2016
|
-
|
|
2927
|
+
const props = buildProps(attributes, ctx, true);
|
|
2928
|
+
const scope = ctx.scopes?.find((s) => node.start >= s.start && node.end <= s.end);
|
|
2929
|
+
if (scope) props.unshift({ name: "data-fx-s", kind: "attr", literal: scope.value });
|
|
2930
|
+
return { kind: "element", tag, svg: SVG_TAGS.has(tag), props, children, static: false, ...at ? { at } : {} };
|
|
2017
2931
|
}
|
|
2018
2932
|
function buildNode(node, ctx) {
|
|
2019
2933
|
if (node.type === "JSXFragment") {
|
|
2020
2934
|
return { kind: "fragment", children: buildChildren(node.children, ctx) };
|
|
2021
2935
|
}
|
|
2022
2936
|
if (directive(node, "if")) return buildIf(node, null, ctx);
|
|
2937
|
+
if (ctx.dropStyles?.has(node.start)) return { kind: "fragment", children: [] };
|
|
2023
2938
|
const { tag, component } = tagInfo(node.openingElement.name, ctx);
|
|
2024
2939
|
if (!component) return buildElement(node, ctx, []);
|
|
2025
2940
|
const props = buildProps(node.openingElement.attributes, ctx);
|
|
@@ -2548,8 +3463,8 @@ function isJsxRoot(node, parent, key) {
|
|
|
2548
3463
|
if (!isJsx(node)) return false;
|
|
2549
3464
|
return !(parent && isJsx(parent) && key === "children");
|
|
2550
3465
|
}
|
|
2551
|
-
function isTemplateTag(node,
|
|
2552
|
-
return node.type === "TaggedTemplateExpression" && node.tag?.type === "Identifier" && (node.tag.name
|
|
3466
|
+
function isTemplateTag(node, tags) {
|
|
3467
|
+
return node.type === "TaggedTemplateExpression" && node.tag?.type === "Identifier" && tags.has(node.tag.name);
|
|
2553
3468
|
}
|
|
2554
3469
|
function outermost(list) {
|
|
2555
3470
|
return list.filter(
|
|
@@ -2697,22 +3612,28 @@ function transformTemplates(code, id, options = {}) {
|
|
|
2697
3612
|
const wantsIntrinsics = options.intrinsics !== false && mayHaveIntrinsic(code);
|
|
2698
3613
|
const wantsSources = options.sourceLocations === true && mayHaveSourceMarks(code);
|
|
2699
3614
|
const sourceName = relativeToRoot(id, options.sourceRoot);
|
|
2700
|
-
|
|
3615
|
+
const wantsStyles = options.styles !== void 0 && (code.includes("<style") || code.includes("css`"));
|
|
3616
|
+
if (!mayHaveTemplate && !(wantsJsx && code.includes("<")) && !wantsIntrinsics && !wantsSources && !wantsStyles) return null;
|
|
2701
3617
|
const ast = (0, import_parser2.parse)(code, {
|
|
2702
3618
|
sourceType: "module",
|
|
2703
3619
|
plugins: ["jsx", "typescript"],
|
|
2704
3620
|
errorRecovery: true
|
|
2705
3621
|
});
|
|
3622
|
+
const intrinsicTags = options.intrinsics === false ? /* @__PURE__ */ new Map() : tagIntrinsics(moduleBindings(ast.program));
|
|
3623
|
+
const templateTags = /* @__PURE__ */ new Map([[litTag, "html"], ["svg", "svg"]]);
|
|
3624
|
+
for (const [name, tag] of intrinsicTags) if (tag !== "css") templateTags.set(name, tag);
|
|
3625
|
+
const cssTags = [...intrinsicTags].filter(([, tag]) => tag === "css").map(([name]) => name);
|
|
2706
3626
|
const found = [];
|
|
2707
3627
|
walk7(ast.program, (n, parent, key) => {
|
|
2708
|
-
if (wantsLit && isTemplateTag(n,
|
|
3628
|
+
if (wantsLit && isTemplateTag(n, templateTags)) found.push(n);
|
|
2709
3629
|
else if (wantsJsx && isJsxRoot(n, parent, key)) found.push(n);
|
|
2710
3630
|
});
|
|
2711
3631
|
const props = options.propsDestructure === false ? { edits: [], diagnostics: [], used: /* @__PURE__ */ new Set() } : collectPropsEdits(ast.program, code, { runtimeModule: options.runtimeModule });
|
|
2712
3632
|
const intrinsics = options.intrinsics === false ? { edits: [], diagnostics: [], imports: /* @__PURE__ */ new Map() } : collectIntrinsicEdits(ast.program);
|
|
2713
3633
|
if (intrinsics.edits.length) avoidBindingClashes(ast.program, intrinsics, moduleBindings(ast.program));
|
|
2714
3634
|
const sources = options.sourceLocations === true ? collectSourceEdits(ast.program, sourceName) : { edits: [], marked: 0 };
|
|
2715
|
-
const
|
|
3635
|
+
const styles = wantsStyles ? collectStyles(ast.program, sourceName, options.styles, { html: templateTags, css: cssTags }, { id, code }) : void 0;
|
|
3636
|
+
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;
|
|
2716
3637
|
if (silent) return null;
|
|
2717
3638
|
found.sort((a, b) => b.start - a.start || a.end - b.end);
|
|
2718
3639
|
const used = new Set(props.used);
|
|
@@ -2726,20 +3647,32 @@ function transformTemplates(code, id, options = {}) {
|
|
|
2726
3647
|
declared: declaredNames(ast.program)
|
|
2727
3648
|
};
|
|
2728
3649
|
const hoisted = /* @__PURE__ */ new Map();
|
|
2729
|
-
const edits = [...props.edits, ...intrinsics.edits, ...sources.edits];
|
|
3650
|
+
const edits = [...props.edits, ...intrinsics.edits, ...sources.edits, ...styles?.edits ?? []];
|
|
2730
3651
|
for (const node of found) {
|
|
2731
3652
|
const nested = found.some(
|
|
2732
3653
|
(o) => o !== node && o.start <= node.start && o.end >= node.end && o.end - o.start > node.end - node.start
|
|
2733
3654
|
);
|
|
2734
3655
|
if (isJsx(node)) {
|
|
2735
|
-
edits.push({ start: node.start, end: node.end, code: compileJsx(code, node, edits, nested, used, needs, hoisted, options, sourceName) });
|
|
3656
|
+
edits.push({ start: node.start, end: node.end, code: compileJsx(code, node, edits, nested, used, needs, hoisted, options, sourceName, styles) });
|
|
2736
3657
|
continue;
|
|
2737
3658
|
}
|
|
2738
3659
|
const holes = node.quasi.expressions.map(
|
|
2739
3660
|
(e) => bindHole(code, e, edits, options.sourceLocations === true)
|
|
2740
3661
|
);
|
|
3662
|
+
const scope = styles?.scopes.find((s) => node.start >= s.start && node.end <= s.end)?.value;
|
|
3663
|
+
const owner = styles?.templateOwners.get(node.start);
|
|
3664
|
+
const templateStyles = options.styles && styles && (scope || owner) ? {
|
|
3665
|
+
options: options.styles,
|
|
3666
|
+
...scope ? { scope } : {},
|
|
3667
|
+
...owner ? { owner } : {},
|
|
3668
|
+
line: node.loc?.start.line ?? 0,
|
|
3669
|
+
column: node.loc?.start.column ?? 0,
|
|
3670
|
+
styles: styles.styles,
|
|
3671
|
+
diagnostics: styles.diagnostics
|
|
3672
|
+
} : void 0;
|
|
2741
3673
|
const result = compilePieces(toPieces(node), holes, {
|
|
2742
3674
|
...options,
|
|
3675
|
+
...templateStyles ? { templateStyles } : {},
|
|
2743
3676
|
hoistTemplates: true,
|
|
2744
3677
|
// A tag inside a template gets the same mark a JSX tag does. Without one, the nodes it
|
|
2745
3678
|
// makes are the only ones in the module carrying no mark, and they take whichever was
|
|
@@ -2748,12 +3681,13 @@ function transformTemplates(code, id, options = {}) {
|
|
|
2748
3681
|
// Same defaults as the plugin, so moving a build over is not a rendering change.
|
|
2749
3682
|
templateClone: options.templateClone ?? true,
|
|
2750
3683
|
partialTemplates: nested ? false : options.partialTemplates ?? true,
|
|
2751
|
-
svg: node.tag.name === "svg"
|
|
3684
|
+
svg: templateTags.get(node.tag.name) === "svg"
|
|
2752
3685
|
});
|
|
2753
3686
|
for (const symbol of result.imports) used.add(symbol);
|
|
2754
3687
|
collectNeeds(result.ir, needs);
|
|
2755
3688
|
edits.push({ start: node.start, end: node.end, code: adoptTemplates(result.code, result.templates, hoisted) });
|
|
2756
3689
|
}
|
|
3690
|
+
if (styles && options.styles) edits.push(...finishShadowStyles(styles, code, id));
|
|
2757
3691
|
const out = new import_magic_string2.default(code);
|
|
2758
3692
|
for (const e of outermost(edits)) {
|
|
2759
3693
|
if (e.start === e.end) out.appendLeft(e.start, e.code);
|
|
@@ -2811,13 +3745,19 @@ function transformTemplates(code, id, options = {}) {
|
|
|
2811
3745
|
...loadDiagnostics.length ? { loadDiagnostics } : {},
|
|
2812
3746
|
...unresolvedDiagnostics.length ? { unresolvedDiagnostics } : {},
|
|
2813
3747
|
...props.diagnostics.length ? { propsDiagnostics: props.diagnostics } : {},
|
|
2814
|
-
...intrinsics.diagnostics.length ? { intrinsicDiagnostics: intrinsics.diagnostics } : {}
|
|
3748
|
+
...intrinsics.diagnostics.length ? { intrinsicDiagnostics: intrinsics.diagnostics } : {},
|
|
3749
|
+
...styles?.styles.length ? { styles: styles.styles } : {},
|
|
3750
|
+
...styles?.diagnostics.length ? { styleDiagnostics: styles.diagnostics } : {},
|
|
3751
|
+
...styles?.literals.length ? { styleLiterals: styles.literals } : {},
|
|
3752
|
+
...styles?.references.length ? { styleReferences: styles.references } : {}
|
|
2815
3753
|
};
|
|
2816
3754
|
}
|
|
2817
|
-
function compileJsx(code, node, edits, nested, used, needs, hoisted, options, sourceFile) {
|
|
3755
|
+
function compileJsx(code, node, edits, nested, used, needs, hoisted, options, sourceFile, styles) {
|
|
2818
3756
|
const ir = buildJsxIR(node, {
|
|
2819
3757
|
code: (n) => slice(code, n.start, n.end, edits),
|
|
2820
3758
|
used,
|
|
3759
|
+
...styles?.scopes.length ? { scopes: styles.scopes } : {},
|
|
3760
|
+
...styles?.drop.size ? { dropStyles: styles.drop } : {},
|
|
2821
3761
|
...options.sourceLocations === true && sourceFile ? { sourceFile } : {}
|
|
2822
3762
|
});
|
|
2823
3763
|
analyzeStatic(ir);
|