@fluixi/compiler 1.0.0-alpha.93 → 1.0.0-alpha.94
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/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-RJFQVFJW.mjs} +4 -4
- package/dist/{chunk-56QSOVVL.mjs → chunk-DP2QDWWH.mjs} +1 -1
- package/dist/{chunk-R7PPFBCL.mjs → chunk-E2RWTIYE.mjs} +21 -15
- package/dist/{chunk-OD53TMER.mjs → chunk-HCCBEJEZ.mjs} +13 -1
- package/dist/{chunk-TJIH7TLX.mjs → chunk-HIZU7WI2.mjs} +1 -1
- package/dist/{chunk-U7HCFLZ2.mjs → chunk-ZR2QHTEX.mjs} +356 -24
- 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 +1174 -49
- package/dist/integrations.d.ts.map +1 -1
- package/dist/integrations.js +44 -2
- package/dist/integrations.mjs +205 -19
- 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-JLSTKWPS.mjs} +4 -4
- package/dist/{server-functions-CTDXX67X.mjs → server-functions-BGY3RD4R.mjs} +3 -3
- package/dist/transform/index.cjs +956 -33
- package/dist/transform/index.mjs +974 -47
- package/dist/transform/props.mjs +19 -14
- package/dist/transform/server-fns.mjs +19 -14
- package/dist/transform/styles.cjs +588 -0
- package/dist/transform/styles.d.cts +211 -0
- package/dist/transform/styles.d.ts +212 -0
- package/dist/transform/styles.d.ts.map +1 -0
- package/dist/transform/styles.js +714 -0
- package/dist/transform/styles.mjs +653 -0
- package/dist/transform/templates.cjs +955 -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 +973 -46
- package/dist/{transform-QWWQDCXE.mjs → transform-GBP6Y4UI.mjs} +601 -17
- package/dist/tsconfig.lib.tsbuildinfo +1 -1
- package/dist/vite-styles.cjs +180 -0
- package/dist/vite-styles.d.cts +59 -0
- package/dist/vite-styles.d.ts +60 -0
- package/dist/vite-styles.d.ts.map +1 -0
- package/dist/vite-styles.js +198 -0
- package/dist/vite-styles.mjs +159 -0
- package/package.json +4 -3
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! @fluixi/compiler v1.0.0-alpha.
|
|
1
|
+
/*! @fluixi/compiler v1.0.0-alpha.94 | (c) 2026 Ibrahima Touré and Fluixi contributors | MIT */
|
|
2
2
|
import {
|
|
3
3
|
analyzeStatic,
|
|
4
4
|
buildJsxIR,
|
|
@@ -14,7 +14,7 @@ import {
|
|
|
14
14
|
resolveComponentSources,
|
|
15
15
|
resolveReactiveBindings,
|
|
16
16
|
shapeOf
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-ZR2QHTEX.mjs";
|
|
18
18
|
import {
|
|
19
19
|
CORE_CONTROL_FLOW,
|
|
20
20
|
DOM_CONTROL_FLOW,
|
|
@@ -22,16 +22,574 @@ import {
|
|
|
22
22
|
ROUTER_COMPONENTS,
|
|
23
23
|
createComponentResolver,
|
|
24
24
|
isIntrinsicName,
|
|
25
|
-
mayHaveIntrinsic
|
|
26
|
-
|
|
25
|
+
mayHaveIntrinsic,
|
|
26
|
+
tagIntrinsics
|
|
27
|
+
} from "./chunk-HCCBEJEZ.mjs";
|
|
27
28
|
import {
|
|
28
|
-
MagicString
|
|
29
|
-
|
|
30
|
-
|
|
29
|
+
MagicString,
|
|
30
|
+
encode
|
|
31
|
+
} from "./chunk-E2RWTIYE.mjs";
|
|
32
|
+
import "./chunk-HIZU7WI2.mjs";
|
|
31
33
|
|
|
32
34
|
// src/transform/templates.ts
|
|
33
35
|
import { parse as parse2 } from "@babel/parser";
|
|
34
36
|
|
|
37
|
+
// src/transform/styles.ts
|
|
38
|
+
var SCOPE_ATTR = "data-fx-s";
|
|
39
|
+
var FUNCTIONS = /* @__PURE__ */ new Set(["FunctionDeclaration", "FunctionExpression", "ArrowFunctionExpression", "ObjectMethod", "ClassMethod"]);
|
|
40
|
+
function collectStyles(program, sourceName, options, tags = { html: /* @__PURE__ */ new Map([["html", "html"]]) }, module) {
|
|
41
|
+
const plan = {
|
|
42
|
+
scopes: [],
|
|
43
|
+
templateOwners: /* @__PURE__ */ new Map(),
|
|
44
|
+
drop: /* @__PURE__ */ new Set(),
|
|
45
|
+
styles: [],
|
|
46
|
+
diagnostics: [],
|
|
47
|
+
edits: [],
|
|
48
|
+
literals: [],
|
|
49
|
+
references: [],
|
|
50
|
+
shadowClasses: /* @__PURE__ */ new Map()
|
|
51
|
+
};
|
|
52
|
+
if (!options) return plan;
|
|
53
|
+
const literalsOf = findLiterals(program, options.cssModules ?? ["@fluixi/core", "@fluixi/dom"], plan, tags.css ?? []);
|
|
54
|
+
plan.names = literalsOf;
|
|
55
|
+
const classOf = /* @__PURE__ */ new Map();
|
|
56
|
+
const shadowOf = (owner) => {
|
|
57
|
+
const cls = classOf.get(owner);
|
|
58
|
+
return cls ? plan.shadowClasses.get(cls) : void 0;
|
|
59
|
+
};
|
|
60
|
+
const resolved = /* @__PURE__ */ new Map();
|
|
61
|
+
const piecesToNodes = (quasis, expressions, at, stack) => {
|
|
62
|
+
const out = [];
|
|
63
|
+
for (let i = 0; i < quasis.length; i++) {
|
|
64
|
+
const text = quasis[i].value.cooked ?? quasis[i].value.raw;
|
|
65
|
+
if (text.trim()) {
|
|
66
|
+
try {
|
|
67
|
+
const start = quasis[i].loc?.start;
|
|
68
|
+
out.push(...options.process(text, sourceName).map((n) => start ? shiftLoc(n, sourceName, start) : n));
|
|
69
|
+
} catch (error) {
|
|
70
|
+
plan.diagnostics.push({ ...at, message: `CSS could not be processed: ${error.message}` });
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
const expr = expressions[i];
|
|
75
|
+
if (!expr) continue;
|
|
76
|
+
const value = expr.type === "Identifier" ? resolveLiteral(expr.name, at, stack) : void 0;
|
|
77
|
+
if (value === void 0) {
|
|
78
|
+
plan.diagnostics.push({
|
|
79
|
+
...at,
|
|
80
|
+
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))."
|
|
81
|
+
});
|
|
82
|
+
return null;
|
|
83
|
+
}
|
|
84
|
+
if (value === null) return null;
|
|
85
|
+
out.push(...value);
|
|
86
|
+
}
|
|
87
|
+
return out;
|
|
88
|
+
};
|
|
89
|
+
function resolveLiteral(name, at, stack) {
|
|
90
|
+
const imported = literalsOf.imports.get(name);
|
|
91
|
+
if (imported) {
|
|
92
|
+
const nodes = options?.imported?.get(`${imported.source}#${imported.name}`);
|
|
93
|
+
if (nodes) return nodes.map(dropLoc);
|
|
94
|
+
plan.references.push({ name: imported.name, source: imported.source, ...at });
|
|
95
|
+
plan.diagnostics.push({
|
|
96
|
+
...at,
|
|
97
|
+
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.`
|
|
98
|
+
});
|
|
99
|
+
return null;
|
|
100
|
+
}
|
|
101
|
+
const literal = literalsOf.literals.get(name);
|
|
102
|
+
if (!literal) return void 0;
|
|
103
|
+
if (stack.includes(name)) {
|
|
104
|
+
plan.diagnostics.push({ ...at, message: `css\`\` values include each other: ${[...stack, name].join(" → ")}.` });
|
|
105
|
+
return null;
|
|
106
|
+
}
|
|
107
|
+
if (!resolved.has(name)) {
|
|
108
|
+
resolved.set(name, piecesToNodes(literal.quasi.quasis, literal.quasi.expressions, at, [...stack, name]));
|
|
109
|
+
}
|
|
110
|
+
return resolved.get(name);
|
|
111
|
+
}
|
|
112
|
+
for (const [name, literal] of literalsOf.literals) {
|
|
113
|
+
const at = { line: literal.loc?.start.line ?? 0, column: literal.loc?.start.column ?? 0 };
|
|
114
|
+
const nodes = resolveLiteral(name, at, []);
|
|
115
|
+
const id = hash(`${sourceName}:css:${name}`);
|
|
116
|
+
plan.edits.push({ start: literal.start, end: literal.end, code: `({ $fxStyle: ${JSON.stringify(id)} })` });
|
|
117
|
+
if (nodes) plan.literals.push({ id, name, css: printStyle(nodes, options.minify) });
|
|
118
|
+
}
|
|
119
|
+
const scopeOf = /* @__PURE__ */ new Map();
|
|
120
|
+
const names = /* @__PURE__ */ new Map();
|
|
121
|
+
const named = /* @__PURE__ */ new Map();
|
|
122
|
+
const visit = (node, owners) => {
|
|
123
|
+
if (!node || typeof node !== "object") return;
|
|
124
|
+
if (node.type === "VariableDeclarator" && node.id.type === "Identifier" && node.init && FUNCTIONS.has(node.init.type)) {
|
|
125
|
+
named.set(node.init, node.id.name);
|
|
126
|
+
}
|
|
127
|
+
if ((node.type === "ClassDeclaration" || node.type === "ClassExpression") && node.id) {
|
|
128
|
+
for (const member of node.body.body) if (member.type === "ClassMethod") named.set(member, node.id.name);
|
|
129
|
+
}
|
|
130
|
+
if (node.type === "ClassDeclaration" || node.type === "ClassExpression") {
|
|
131
|
+
for (const member of node.body.body) if (member.type === "ClassMethod") classOf.set(member, node);
|
|
132
|
+
const shadow = staticMember(node, "shadow");
|
|
133
|
+
if (shadow?.value && !(shadow.value.type === "BooleanLiteral" && shadow.value.value === false)) {
|
|
134
|
+
plan.shadowClasses.set(node, { node, styles: staticMember(node, "styles"), indexes: [] });
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
if (node.type === "TaggedTemplateExpression" && node.tag.type === "Identifier" && tags.html.get(node.tag.name) === "html") {
|
|
138
|
+
const text = node.quasi.quasis.map((q) => q.value.raw).join("");
|
|
139
|
+
if (/<style[\s>]/.test(text)) {
|
|
140
|
+
const at = { line: node.loc?.start.line ?? 0, column: node.loc?.start.column ?? 0 };
|
|
141
|
+
const owner = owners[0];
|
|
142
|
+
if (!owner) plan.diagnostics.push({ ...at, message: "<style> has to be written inside a component." });
|
|
143
|
+
else {
|
|
144
|
+
const id = idFor(owner);
|
|
145
|
+
const shadow = shadowOf(owner);
|
|
146
|
+
plan.templateOwners.set(node.start, { id, component: functionName(owner, named) });
|
|
147
|
+
for (const block of templateBlocks(node.quasi)) compileBlock(block, block.scoped, owner, at);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
const inner = FUNCTIONS.has(node.type) ? [...owners, node] : owners;
|
|
152
|
+
if (node.type === "JSXElement" && isStyle(node)) {
|
|
153
|
+
handle(node, owners);
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
for (const key of Object.keys(node)) {
|
|
157
|
+
if (key === "loc" || key === "leadingComments" || key === "trailingComments" || key === "innerComments") continue;
|
|
158
|
+
const value = node[key];
|
|
159
|
+
if (Array.isArray(value)) for (const v of value) visit(v, inner);
|
|
160
|
+
else if (value && typeof value === "object" && "type" in value) visit(value, inner);
|
|
161
|
+
}
|
|
162
|
+
};
|
|
163
|
+
const handle = (node, owners) => {
|
|
164
|
+
const at = { line: node.loc?.start.line ?? 0, column: node.loc?.start.column ?? 0 };
|
|
165
|
+
const pieces = blockPieces(node);
|
|
166
|
+
if (pieces === null) {
|
|
167
|
+
plan.diagnostics.push({
|
|
168
|
+
...at,
|
|
169
|
+
message: "<style> needs its CSS as one template literal, <style>{`...`}</style>: JSX reads a bare `{` as an expression."
|
|
170
|
+
});
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
const owner = owners[0];
|
|
174
|
+
if (!owner) {
|
|
175
|
+
plan.diagnostics.push({ ...at, message: "<style> has to be written inside a component." });
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
compileBlock(pieces, isScoped(node), owner, at);
|
|
179
|
+
plan.drop.add(node.start);
|
|
180
|
+
};
|
|
181
|
+
const compileBlock = (pieces, scoped, owner, at) => {
|
|
182
|
+
const component = functionName(owner, named);
|
|
183
|
+
const id = idFor(owner);
|
|
184
|
+
const processed = piecesToNodes(pieces.quasis, pieces.expressions, at, []);
|
|
185
|
+
if (!processed) return;
|
|
186
|
+
let nodes = processed;
|
|
187
|
+
const shadow = shadowOf(owner);
|
|
188
|
+
if (scoped && !shadow) {
|
|
189
|
+
if (!plan.scopes.some((s) => s.value === id)) plan.scopes.push({ start: owner.start, end: owner.end, value: id });
|
|
190
|
+
nodes = scopeNodes(nodes, id, (message) => plan.diagnostics.push({ ...at, message }));
|
|
191
|
+
}
|
|
192
|
+
const printed = module ? printStyleWithMap(nodes, options.minify, sourceName, module) : { css: printStyle(nodes, options.minify) };
|
|
193
|
+
plan.styles.push({ id, scoped: scoped && !shadow, component, ...printed, ...shadow ? { shadow: true } : {}, ...at });
|
|
194
|
+
if (shadow) shadow.indexes.push(plan.styles.length - 1);
|
|
195
|
+
};
|
|
196
|
+
function idFor(owner) {
|
|
197
|
+
let id = scopeOf.get(owner);
|
|
198
|
+
if (!id) {
|
|
199
|
+
const component = functionName(owner, named);
|
|
200
|
+
const seen = names.get(component) ?? 0;
|
|
201
|
+
names.set(component, seen + 1);
|
|
202
|
+
id = hash(`${sourceName}:${component}${seen ? ":" + seen : ""}`);
|
|
203
|
+
scopeOf.set(owner, id);
|
|
204
|
+
}
|
|
205
|
+
return id;
|
|
206
|
+
}
|
|
207
|
+
visit(program, []);
|
|
208
|
+
return plan;
|
|
209
|
+
}
|
|
210
|
+
function applyTemplateStyles(ir, t) {
|
|
211
|
+
const walk5 = (node) => {
|
|
212
|
+
const children = node.children;
|
|
213
|
+
if (children) {
|
|
214
|
+
for (let i = children.length - 1; i >= 0; i--) {
|
|
215
|
+
const child = children[i];
|
|
216
|
+
if (child.kind === "element" && child.tag === "style" && t.owner) children.splice(i, 1);
|
|
217
|
+
else walk5(child);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
if (t.scope && node.kind === "element" && node.tag !== "style" && node.props && !node.props.some((p) => p.name === SCOPE_ATTR)) {
|
|
221
|
+
node.props.unshift({ name: SCOPE_ATTR, kind: "attr", literal: t.scope });
|
|
222
|
+
}
|
|
223
|
+
};
|
|
224
|
+
walk5(ir);
|
|
225
|
+
}
|
|
226
|
+
function staticMember(cls, name) {
|
|
227
|
+
return cls.body.body.find(
|
|
228
|
+
(m) => m.type === "ClassProperty" && m.static && (m.key.type === "Identifier" && m.key.name === name || m.key.type === "StringLiteral" && m.key.value === name)
|
|
229
|
+
);
|
|
230
|
+
}
|
|
231
|
+
function finishShadowStyles(plan, code, moduleId) {
|
|
232
|
+
const edits = [];
|
|
233
|
+
const imports = [];
|
|
234
|
+
let next = 0;
|
|
235
|
+
const importOf = (specifier) => {
|
|
236
|
+
const local = `__fxShadow${next++}`;
|
|
237
|
+
imports.push(`import ${local} from ${JSON.stringify(specifier)};
|
|
238
|
+
`);
|
|
239
|
+
return local;
|
|
240
|
+
};
|
|
241
|
+
for (const shadow of plan.shadowClasses.values()) {
|
|
242
|
+
const blocks = shadow.indexes.map((i) => importOf(`${moduleId}?fx-style&index=${i}&inline&lang.css`));
|
|
243
|
+
let value;
|
|
244
|
+
const prop = shadow.styles;
|
|
245
|
+
if (prop?.value) {
|
|
246
|
+
const start = prop.value.start;
|
|
247
|
+
let text = code.slice(start, prop.value.end);
|
|
248
|
+
const replacements = [];
|
|
249
|
+
walkIdentifiers(prop.value, (id) => {
|
|
250
|
+
const local = plan.names?.literals.has(id.name) ? importOf(`${moduleId}?fx-literal=${id.name}&inline&lang.css`) : plan.names?.imports.has(id.name) && !/\.css(\?|$)/.test(plan.names.imports.get(id.name).source) ? importOf(`${plan.names.imports.get(id.name).source}?fx-literal=${plan.names.imports.get(id.name).name}&inline&lang.css`) : void 0;
|
|
251
|
+
if (local) replacements.push({ at: id.start - start, length: id.name.length, with: local });
|
|
252
|
+
});
|
|
253
|
+
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);
|
|
254
|
+
value = text;
|
|
255
|
+
}
|
|
256
|
+
if (!blocks.length && value === void 0) continue;
|
|
257
|
+
if (prop?.value) {
|
|
258
|
+
const merged = blocks.length ? `[${value}, ${blocks.join(", ")}]` : value;
|
|
259
|
+
edits.push({ start: prop.value.start, end: prop.value.end, code: merged });
|
|
260
|
+
} else if (blocks.length) {
|
|
261
|
+
const open = shadow.node.body.start + 1;
|
|
262
|
+
edits.push({ start: open, end: open, code: ` static styles = [${blocks.join(", ")}];` });
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
if (imports.length) edits.push({ start: 0, end: 0, code: imports.join("") });
|
|
266
|
+
return edits;
|
|
267
|
+
}
|
|
268
|
+
function walkIdentifiers(node, visit) {
|
|
269
|
+
if (!node || typeof node !== "object") return;
|
|
270
|
+
if (node.type === "Identifier") return visit(node);
|
|
271
|
+
if (node.type === "MemberExpression") return walkIdentifiers(node.object, visit);
|
|
272
|
+
if (node.type === "ObjectProperty") return walkIdentifiers(node.value, visit);
|
|
273
|
+
for (const key of Object.keys(node)) {
|
|
274
|
+
if (key === "loc") continue;
|
|
275
|
+
const value = node[key];
|
|
276
|
+
if (Array.isArray(value)) for (const v of value) walkIdentifiers(v, visit);
|
|
277
|
+
else if (value && typeof value === "object" && "type" in value) walkIdentifiers(value, visit);
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
function isStyle(node) {
|
|
281
|
+
const name = node.openingElement.name;
|
|
282
|
+
return name.type === "JSXIdentifier" && name.name === "style";
|
|
283
|
+
}
|
|
284
|
+
function isScoped(node) {
|
|
285
|
+
return node.openingElement.attributes.some((a) => a.type === "JSXAttribute" && a.name.type === "JSXIdentifier" && a.name.name === "scoped");
|
|
286
|
+
}
|
|
287
|
+
function templateBlocks(quasi) {
|
|
288
|
+
const blocks = [];
|
|
289
|
+
let open = null;
|
|
290
|
+
quasi.quasis.forEach((q, i) => {
|
|
291
|
+
const raw = q.value.raw;
|
|
292
|
+
let from = 0;
|
|
293
|
+
while (from <= raw.length) {
|
|
294
|
+
if (!open) {
|
|
295
|
+
const tag = /<style\b([^>]*)>/g;
|
|
296
|
+
tag.lastIndex = from;
|
|
297
|
+
const m = tag.exec(raw);
|
|
298
|
+
if (!m) break;
|
|
299
|
+
open = { quasis: [], expressions: [], scoped: /\bscoped\b/.test(m[1]) };
|
|
300
|
+
from = m.index + m[0].length;
|
|
301
|
+
}
|
|
302
|
+
const close = raw.indexOf("</style", from);
|
|
303
|
+
open.quasis.push(slicePiece(q, raw, from, close === -1 ? raw.length : close));
|
|
304
|
+
if (close === -1) break;
|
|
305
|
+
blocks.push(open);
|
|
306
|
+
open = null;
|
|
307
|
+
from = close;
|
|
308
|
+
}
|
|
309
|
+
const expr = quasi.expressions[i];
|
|
310
|
+
if (open && expr) open.expressions.push(expr);
|
|
311
|
+
});
|
|
312
|
+
return blocks;
|
|
313
|
+
}
|
|
314
|
+
function slicePiece(q, raw, from, to) {
|
|
315
|
+
const text = raw.slice(from, to);
|
|
316
|
+
const start = q.loc?.start;
|
|
317
|
+
if (!start) return { type: "TemplateElement", value: { raw: text, cooked: text } };
|
|
318
|
+
const before = raw.slice(0, from).split("\n");
|
|
319
|
+
const line = start.line + before.length - 1;
|
|
320
|
+
const column = before.length > 1 ? before[before.length - 1].length : start.column + from;
|
|
321
|
+
return { type: "TemplateElement", value: { raw: text, cooked: text }, loc: { start: { line, column } } };
|
|
322
|
+
}
|
|
323
|
+
function blockPieces(node) {
|
|
324
|
+
const meaningful = node.children.filter((c) => !(c.type === "JSXText" && !c.value.trim()));
|
|
325
|
+
if (meaningful.length === 0) return { quasis: [], expressions: [] };
|
|
326
|
+
if (meaningful.length !== 1) return null;
|
|
327
|
+
const only = meaningful[0];
|
|
328
|
+
if (only.type !== "JSXExpressionContainer") return null;
|
|
329
|
+
const expr = only.expression;
|
|
330
|
+
if (expr.type === "StringLiteral") return { quasis: [{ type: "TemplateElement", value: { raw: expr.value, cooked: expr.value } }], expressions: [] };
|
|
331
|
+
if (expr.type === "TemplateLiteral") return { quasis: expr.quasis, expressions: expr.expressions };
|
|
332
|
+
return null;
|
|
333
|
+
}
|
|
334
|
+
function findLiterals(program, modules, plan, intrinsic) {
|
|
335
|
+
const literals = /* @__PURE__ */ new Map();
|
|
336
|
+
const imports = /* @__PURE__ */ new Map();
|
|
337
|
+
const tags = new Set(intrinsic);
|
|
338
|
+
for (const statement of program.body ?? []) {
|
|
339
|
+
if (statement.type !== "ImportDeclaration") continue;
|
|
340
|
+
const source = statement.source.value;
|
|
341
|
+
const specifiers = statement.specifiers;
|
|
342
|
+
for (const sp of specifiers) {
|
|
343
|
+
if (sp.type === "ImportSpecifier") imports.set(sp.local.name, { source, name: sp.imported.name ?? sp.imported.value });
|
|
344
|
+
}
|
|
345
|
+
if (!modules.includes(source)) continue;
|
|
346
|
+
const css = specifiers.find((sp) => sp.type === "ImportSpecifier" && (sp.imported.name ?? sp.imported.value) === "css");
|
|
347
|
+
if (!css) continue;
|
|
348
|
+
const local = css.local.name;
|
|
349
|
+
tags.add(local);
|
|
350
|
+
imports.delete(local);
|
|
351
|
+
plan.edits.push({ start: statement.start, end: statement.end, code: importWithout(statement, css) });
|
|
352
|
+
}
|
|
353
|
+
if (tags.size === 0) return { literals, imports };
|
|
354
|
+
const visit = (node) => {
|
|
355
|
+
if (!node || typeof node !== "object") return;
|
|
356
|
+
if (node.type === "VariableDeclarator" && node.id.type === "Identifier" && node.init?.type === "TaggedTemplateExpression" && node.init.tag.type === "Identifier" && tags.has(node.init.tag.name)) {
|
|
357
|
+
literals.set(node.id.name, node.init);
|
|
358
|
+
}
|
|
359
|
+
for (const key of Object.keys(node)) {
|
|
360
|
+
if (key === "loc") continue;
|
|
361
|
+
const value = node[key];
|
|
362
|
+
if (Array.isArray(value)) for (const v of value) visit(v);
|
|
363
|
+
else if (value && typeof value === "object" && "type" in value) visit(value);
|
|
364
|
+
}
|
|
365
|
+
};
|
|
366
|
+
visit(program);
|
|
367
|
+
return { literals, imports };
|
|
368
|
+
}
|
|
369
|
+
function importWithout(statement, removed) {
|
|
370
|
+
const rest = statement.specifiers.filter((sp) => sp !== removed);
|
|
371
|
+
const source = JSON.stringify(statement.source.value);
|
|
372
|
+
if (rest.length === 0) return "";
|
|
373
|
+
const def = rest.find((sp) => sp.type === "ImportDefaultSpecifier");
|
|
374
|
+
const ns = rest.find((sp) => sp.type === "ImportNamespaceSpecifier");
|
|
375
|
+
const named = rest.filter((sp) => sp.type === "ImportSpecifier").map((sp) => {
|
|
376
|
+
const imported = sp.imported.name ?? JSON.stringify(sp.imported.value);
|
|
377
|
+
return imported === sp.local.name ? imported : `${imported} as ${sp.local.name}`;
|
|
378
|
+
});
|
|
379
|
+
const parts = [def?.local.name, ns ? `* as ${ns.local.name}` : void 0, named.length ? `{ ${named.join(", ")} }` : void 0].filter(Boolean);
|
|
380
|
+
return `import ${parts.join(", ")} from ${source};`;
|
|
381
|
+
}
|
|
382
|
+
function functionName(fn, named) {
|
|
383
|
+
if ((fn.type === "FunctionDeclaration" || fn.type === "FunctionExpression") && fn.id) return fn.id.name;
|
|
384
|
+
return named.get(fn) ?? "anonymous";
|
|
385
|
+
}
|
|
386
|
+
function hash(text) {
|
|
387
|
+
let h = 2166136261;
|
|
388
|
+
for (let i = 0; i < text.length; i++) {
|
|
389
|
+
h ^= text.charCodeAt(i);
|
|
390
|
+
h = Math.imul(h, 16777619);
|
|
391
|
+
}
|
|
392
|
+
return (h >>> 0).toString(36);
|
|
393
|
+
}
|
|
394
|
+
var OPAQUE = /(^|-)keyframes$|^font-face$|^property$|^counter-style$|^page$|^font-feature-values$/;
|
|
395
|
+
function scopeNodes(nodes, id, warn = () => {
|
|
396
|
+
}) {
|
|
397
|
+
return nodes.map((node) => {
|
|
398
|
+
if (node.kind === "rule") return { ...node, selector: scopeSelector(node.selector, id, warn) };
|
|
399
|
+
if (node.kind === "at-rule" && !OPAQUE.test(node.name)) return { ...node, nodes: scopeNodes(node.nodes, id, warn) };
|
|
400
|
+
return node;
|
|
401
|
+
});
|
|
402
|
+
}
|
|
403
|
+
function scopeSelector(selector, id, warn = () => {
|
|
404
|
+
}) {
|
|
405
|
+
return splitTop(selector, ",").map((complex) => scopeComplex(complex.trim(), `[${SCOPE_ATTR}="${id}"]`, warn)).join(", ");
|
|
406
|
+
}
|
|
407
|
+
function scopeComplex(selector, attr, warn) {
|
|
408
|
+
if (/:host\b|::slotted\(/.test(selector)) {
|
|
409
|
+
warn(`\`${selector}\` only means something in a shadow root; in a light-DOM component it is left as written.`);
|
|
410
|
+
return selector;
|
|
411
|
+
}
|
|
412
|
+
const parts = compounds(selector);
|
|
413
|
+
const deep = parts.findIndex((p) => p.text.startsWith(":deep("));
|
|
414
|
+
if (deep !== -1) {
|
|
415
|
+
const inner = unwrap(parts[deep].text, ":deep(");
|
|
416
|
+
const before = parts.slice(0, deep);
|
|
417
|
+
if (before.length === 0) return `${attr} ${inner}`;
|
|
418
|
+
const scopedBefore = scopeAt(before, before.length - 1, attr);
|
|
419
|
+
return `${join(scopedBefore)} ${inner}`;
|
|
420
|
+
}
|
|
421
|
+
let target = -1;
|
|
422
|
+
for (let i = parts.length - 1; i >= 0; i--) {
|
|
423
|
+
if (!parts[i].text.startsWith(":global(")) {
|
|
424
|
+
target = i;
|
|
425
|
+
break;
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
const out = target === -1 ? parts : scopeAt(parts, target, attr);
|
|
429
|
+
return join(out.map((p) => p.text.startsWith(":global(") ? { ...p, text: unwrap(p.text, ":global(") } : p));
|
|
430
|
+
}
|
|
431
|
+
function scopeAt(parts, index, attr) {
|
|
432
|
+
return parts.map((p, i) => i === index ? { ...p, text: insertAttr(p.text, attr) } : p);
|
|
433
|
+
}
|
|
434
|
+
function insertAttr(compound, attr) {
|
|
435
|
+
let depth = 0;
|
|
436
|
+
let quote = "";
|
|
437
|
+
for (let i = 0; i < compound.length; i++) {
|
|
438
|
+
const c = compound[i];
|
|
439
|
+
if (quote) {
|
|
440
|
+
if (c === "\\") i++;
|
|
441
|
+
else if (c === quote) quote = "";
|
|
442
|
+
continue;
|
|
443
|
+
}
|
|
444
|
+
if (c === "\\") {
|
|
445
|
+
i++;
|
|
446
|
+
continue;
|
|
447
|
+
}
|
|
448
|
+
if (c === '"' || c === "'") quote = c;
|
|
449
|
+
else if (c === "(" || c === "[") depth++;
|
|
450
|
+
else if (c === ")" || c === "]") depth--;
|
|
451
|
+
else if (c === ":" && depth === 0 && i > 0) return compound.slice(0, i) + attr + compound.slice(i);
|
|
452
|
+
}
|
|
453
|
+
return compound + attr;
|
|
454
|
+
}
|
|
455
|
+
function compounds(selector) {
|
|
456
|
+
const out = [];
|
|
457
|
+
let depth = 0;
|
|
458
|
+
let quote = "";
|
|
459
|
+
let current = "";
|
|
460
|
+
let combinator = "";
|
|
461
|
+
const push = () => {
|
|
462
|
+
if (current.trim()) out.push({ combinator: out.length ? combinator || " " : "", text: current.trim() });
|
|
463
|
+
current = "";
|
|
464
|
+
combinator = "";
|
|
465
|
+
};
|
|
466
|
+
for (let i = 0; i < selector.length; i++) {
|
|
467
|
+
const c = selector[i];
|
|
468
|
+
if (quote) {
|
|
469
|
+
current += c;
|
|
470
|
+
if (c === "\\") current += selector[++i] ?? "";
|
|
471
|
+
else if (c === quote) quote = "";
|
|
472
|
+
continue;
|
|
473
|
+
}
|
|
474
|
+
if (c === "\\") {
|
|
475
|
+
current += c + (selector[++i] ?? "");
|
|
476
|
+
continue;
|
|
477
|
+
}
|
|
478
|
+
if (c === '"' || c === "'") quote = c;
|
|
479
|
+
if (c === "(" || c === "[") depth++;
|
|
480
|
+
if (c === ")" || c === "]") depth--;
|
|
481
|
+
if (depth === 0 && (c === ">" || c === "+" || c === "~")) {
|
|
482
|
+
push();
|
|
483
|
+
combinator = c;
|
|
484
|
+
continue;
|
|
485
|
+
}
|
|
486
|
+
if (depth === 0 && /\s/.test(c)) {
|
|
487
|
+
if (current.trim()) {
|
|
488
|
+
const keep = combinator;
|
|
489
|
+
push();
|
|
490
|
+
combinator = keep;
|
|
491
|
+
}
|
|
492
|
+
continue;
|
|
493
|
+
}
|
|
494
|
+
current += c;
|
|
495
|
+
}
|
|
496
|
+
push();
|
|
497
|
+
return out;
|
|
498
|
+
}
|
|
499
|
+
function join(parts) {
|
|
500
|
+
return parts.map((p, i) => i === 0 ? p.text : p.combinator === " " ? ` ${p.text}` : ` ${p.combinator} ${p.text}`).join("");
|
|
501
|
+
}
|
|
502
|
+
function unwrap(text, prefix) {
|
|
503
|
+
return text.slice(prefix.length, text.lastIndexOf(")")).trim() + text.slice(text.lastIndexOf(")") + 1);
|
|
504
|
+
}
|
|
505
|
+
function splitTop(selector, separator) {
|
|
506
|
+
const parts = [];
|
|
507
|
+
let depth = 0;
|
|
508
|
+
let quote = "";
|
|
509
|
+
let start = 0;
|
|
510
|
+
for (let i = 0; i < selector.length; i++) {
|
|
511
|
+
const c = selector[i];
|
|
512
|
+
if (quote) {
|
|
513
|
+
if (c === "\\") i++;
|
|
514
|
+
else if (c === quote) quote = "";
|
|
515
|
+
} else if (c === '"' || c === "'") quote = c;
|
|
516
|
+
else if (c === "\\") i++;
|
|
517
|
+
else if (c === "(" || c === "[") depth++;
|
|
518
|
+
else if (c === ")" || c === "]") depth--;
|
|
519
|
+
else if (c === separator && depth === 0) {
|
|
520
|
+
parts.push(selector.slice(start, i));
|
|
521
|
+
start = i + 1;
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
parts.push(selector.slice(start));
|
|
525
|
+
return parts.filter((p) => p.trim());
|
|
526
|
+
}
|
|
527
|
+
function shiftLoc(node, source, start) {
|
|
528
|
+
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;
|
|
529
|
+
if (node.kind === "rule" || node.kind === "at-rule") return { ...node, loc, nodes: node.nodes.map((n) => shiftLoc(n, source, start)) };
|
|
530
|
+
return { ...node, loc };
|
|
531
|
+
}
|
|
532
|
+
function dropLoc(node) {
|
|
533
|
+
const { loc: _loc, ...rest } = node;
|
|
534
|
+
if (rest.kind === "rule" || rest.kind === "at-rule") return { ...rest, nodes: rest.nodes.map(dropLoc) };
|
|
535
|
+
return rest;
|
|
536
|
+
}
|
|
537
|
+
function printStyleWithMap(nodes, minify, sourceName, module) {
|
|
538
|
+
const lines = [[]];
|
|
539
|
+
let css = "";
|
|
540
|
+
let column = 0;
|
|
541
|
+
const emit = (text) => {
|
|
542
|
+
for (const ch of text) {
|
|
543
|
+
css += ch;
|
|
544
|
+
if (ch === "\n") {
|
|
545
|
+
lines.push([]);
|
|
546
|
+
column = 0;
|
|
547
|
+
} else column++;
|
|
548
|
+
}
|
|
549
|
+
};
|
|
550
|
+
const mark = (loc) => {
|
|
551
|
+
if (loc && loc.source === sourceName) lines[lines.length - 1].push([column, 0, loc.line - 1, loc.column]);
|
|
552
|
+
};
|
|
553
|
+
const write = (node, depth) => {
|
|
554
|
+
const pad = minify ? "" : " ".repeat(depth);
|
|
555
|
+
const nl = minify ? "" : "\n";
|
|
556
|
+
const sp = minify ? "" : " ";
|
|
557
|
+
emit(pad);
|
|
558
|
+
mark(node.loc);
|
|
559
|
+
if (node.kind === "declaration") {
|
|
560
|
+
emit(`${node.property}:${sp}${node.value}${node.important ? `${sp}!important` : ""};${nl}`);
|
|
561
|
+
} else if (node.kind === "raw") {
|
|
562
|
+
emit(`${node.text}${nl}`);
|
|
563
|
+
} else {
|
|
564
|
+
emit(`${node.kind === "rule" ? node.selector : `@${node.name}${node.params ? " " + node.params : ""}`}${sp}{${nl}`);
|
|
565
|
+
for (const child of node.nodes) write(child, depth + 1);
|
|
566
|
+
emit(`${pad}}${nl}`);
|
|
567
|
+
}
|
|
568
|
+
};
|
|
569
|
+
for (const node of nodes) write(node, 0);
|
|
570
|
+
return { css, map: { version: 3, sources: [module.id], sourcesContent: [module.code], names: [], mappings: encode(lines) } };
|
|
571
|
+
}
|
|
572
|
+
function printStyle(nodes, minify = false) {
|
|
573
|
+
const out = [];
|
|
574
|
+
const write = (node, depth) => {
|
|
575
|
+
const pad = minify ? "" : " ".repeat(depth);
|
|
576
|
+
const nl = minify ? "" : "\n";
|
|
577
|
+
const sp = minify ? "" : " ";
|
|
578
|
+
if (node.kind === "declaration") {
|
|
579
|
+
out.push(`${pad}${node.property}:${sp}${node.value}${node.important ? `${sp}!important` : ""};${nl}`);
|
|
580
|
+
} else if (node.kind === "raw") {
|
|
581
|
+
out.push(`${pad}${node.text}${nl}`);
|
|
582
|
+
} else {
|
|
583
|
+
const header = node.kind === "rule" ? node.selector : `@${node.name}${node.params ? " " + node.params : ""}`;
|
|
584
|
+
out.push(`${pad}${header}${sp}{${nl}`);
|
|
585
|
+
for (const child of node.nodes) write(child, depth + 1);
|
|
586
|
+
out.push(`${pad}}${nl}`);
|
|
587
|
+
}
|
|
588
|
+
};
|
|
589
|
+
for (const node of nodes) write(node, 0);
|
|
590
|
+
return out.join("");
|
|
591
|
+
}
|
|
592
|
+
|
|
35
593
|
// src/lower/compile-template.ts
|
|
36
594
|
function compilePieces(pieces, holes, options = {}) {
|
|
37
595
|
const used = /* @__PURE__ */ new Set();
|
|
@@ -40,6 +598,7 @@ function compilePieces(pieces, holes, options = {}) {
|
|
|
40
598
|
...options.sourceFile ? { sourceFile: options.sourceFile } : {},
|
|
41
599
|
...options.positionAt ? { positionAt: options.positionAt } : {}
|
|
42
600
|
});
|
|
601
|
+
if (options.templateStyles) applyTemplateStyles(ir, options.templateStyles);
|
|
43
602
|
analyzeStatic(ir);
|
|
44
603
|
resolveComponentSources(ir, {
|
|
45
604
|
resolver: createComponentResolver(options.resolve ?? []),
|
|
@@ -573,8 +1132,8 @@ function isJsxRoot(node, parent, key) {
|
|
|
573
1132
|
if (!isJsx(node)) return false;
|
|
574
1133
|
return !(parent && isJsx(parent) && key === "children");
|
|
575
1134
|
}
|
|
576
|
-
function isTemplateTag(node,
|
|
577
|
-
return node.type === "TaggedTemplateExpression" && node.tag?.type === "Identifier" && (node.tag.name
|
|
1135
|
+
function isTemplateTag(node, tags) {
|
|
1136
|
+
return node.type === "TaggedTemplateExpression" && node.tag?.type === "Identifier" && tags.has(node.tag.name);
|
|
578
1137
|
}
|
|
579
1138
|
function outermost(list) {
|
|
580
1139
|
return list.filter(
|
|
@@ -722,22 +1281,28 @@ function transformTemplates(code, id, options = {}) {
|
|
|
722
1281
|
const wantsIntrinsics = options.intrinsics !== false && mayHaveIntrinsic(code);
|
|
723
1282
|
const wantsSources = options.sourceLocations === true && mayHaveSourceMarks(code);
|
|
724
1283
|
const sourceName = relativeToRoot(id, options.sourceRoot);
|
|
725
|
-
|
|
1284
|
+
const wantsStyles = options.styles !== void 0 && (code.includes("<style") || code.includes("css`"));
|
|
1285
|
+
if (!mayHaveTemplate && !(wantsJsx && code.includes("<")) && !wantsIntrinsics && !wantsSources && !wantsStyles) return null;
|
|
726
1286
|
const ast = parse2(code, {
|
|
727
1287
|
sourceType: "module",
|
|
728
1288
|
plugins: ["jsx", "typescript"],
|
|
729
1289
|
errorRecovery: true
|
|
730
1290
|
});
|
|
1291
|
+
const intrinsicTags = options.intrinsics === false ? /* @__PURE__ */ new Map() : tagIntrinsics(moduleBindings(ast.program));
|
|
1292
|
+
const templateTags = /* @__PURE__ */ new Map([[litTag, "html"], ["svg", "svg"]]);
|
|
1293
|
+
for (const [name, tag] of intrinsicTags) if (tag !== "css") templateTags.set(name, tag);
|
|
1294
|
+
const cssTags = [...intrinsicTags].filter(([, tag]) => tag === "css").map(([name]) => name);
|
|
731
1295
|
const found = [];
|
|
732
1296
|
walk4(ast.program, (n, parent, key) => {
|
|
733
|
-
if (wantsLit && isTemplateTag(n,
|
|
1297
|
+
if (wantsLit && isTemplateTag(n, templateTags)) found.push(n);
|
|
734
1298
|
else if (wantsJsx && isJsxRoot(n, parent, key)) found.push(n);
|
|
735
1299
|
});
|
|
736
1300
|
const props = options.propsDestructure === false ? { edits: [], diagnostics: [], used: /* @__PURE__ */ new Set() } : collectPropsEdits(ast.program, code, { runtimeModule: options.runtimeModule });
|
|
737
1301
|
const intrinsics = options.intrinsics === false ? { edits: [], diagnostics: [], imports: /* @__PURE__ */ new Map() } : collectIntrinsicEdits(ast.program);
|
|
738
1302
|
if (intrinsics.edits.length) avoidBindingClashes(ast.program, intrinsics, moduleBindings(ast.program));
|
|
739
1303
|
const sources = options.sourceLocations === true ? collectSourceEdits(ast.program, sourceName) : { edits: [], marked: 0 };
|
|
740
|
-
const
|
|
1304
|
+
const styles = wantsStyles ? collectStyles(ast.program, sourceName, options.styles, { html: templateTags, css: cssTags }, { id, code }) : void 0;
|
|
1305
|
+
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;
|
|
741
1306
|
if (silent) return null;
|
|
742
1307
|
found.sort((a, b) => b.start - a.start || a.end - b.end);
|
|
743
1308
|
const used = new Set(props.used);
|
|
@@ -751,20 +1316,32 @@ function transformTemplates(code, id, options = {}) {
|
|
|
751
1316
|
declared: declaredNames(ast.program)
|
|
752
1317
|
};
|
|
753
1318
|
const hoisted = /* @__PURE__ */ new Map();
|
|
754
|
-
const edits = [...props.edits, ...intrinsics.edits, ...sources.edits];
|
|
1319
|
+
const edits = [...props.edits, ...intrinsics.edits, ...sources.edits, ...styles?.edits ?? []];
|
|
755
1320
|
for (const node of found) {
|
|
756
1321
|
const nested = found.some(
|
|
757
1322
|
(o) => o !== node && o.start <= node.start && o.end >= node.end && o.end - o.start > node.end - node.start
|
|
758
1323
|
);
|
|
759
1324
|
if (isJsx(node)) {
|
|
760
|
-
edits.push({ start: node.start, end: node.end, code: compileJsx(code, node, edits, nested, used, needs, hoisted, options, sourceName) });
|
|
1325
|
+
edits.push({ start: node.start, end: node.end, code: compileJsx(code, node, edits, nested, used, needs, hoisted, options, sourceName, styles) });
|
|
761
1326
|
continue;
|
|
762
1327
|
}
|
|
763
1328
|
const holes = node.quasi.expressions.map(
|
|
764
1329
|
(e) => bindHole(code, e, edits, options.sourceLocations === true)
|
|
765
1330
|
);
|
|
1331
|
+
const scope = styles?.scopes.find((s) => node.start >= s.start && node.end <= s.end)?.value;
|
|
1332
|
+
const owner = styles?.templateOwners.get(node.start);
|
|
1333
|
+
const templateStyles = options.styles && styles && (scope || owner) ? {
|
|
1334
|
+
options: options.styles,
|
|
1335
|
+
...scope ? { scope } : {},
|
|
1336
|
+
...owner ? { owner } : {},
|
|
1337
|
+
line: node.loc?.start.line ?? 0,
|
|
1338
|
+
column: node.loc?.start.column ?? 0,
|
|
1339
|
+
styles: styles.styles,
|
|
1340
|
+
diagnostics: styles.diagnostics
|
|
1341
|
+
} : void 0;
|
|
766
1342
|
const result = compilePieces(toPieces(node), holes, {
|
|
767
1343
|
...options,
|
|
1344
|
+
...templateStyles ? { templateStyles } : {},
|
|
768
1345
|
hoistTemplates: true,
|
|
769
1346
|
// A tag inside a template gets the same mark a JSX tag does. Without one, the nodes it
|
|
770
1347
|
// makes are the only ones in the module carrying no mark, and they take whichever was
|
|
@@ -773,12 +1350,13 @@ function transformTemplates(code, id, options = {}) {
|
|
|
773
1350
|
// Same defaults as the plugin, so moving a build over is not a rendering change.
|
|
774
1351
|
templateClone: options.templateClone ?? true,
|
|
775
1352
|
partialTemplates: nested ? false : options.partialTemplates ?? true,
|
|
776
|
-
svg: node.tag.name === "svg"
|
|
1353
|
+
svg: templateTags.get(node.tag.name) === "svg"
|
|
777
1354
|
});
|
|
778
1355
|
for (const symbol of result.imports) used.add(symbol);
|
|
779
1356
|
collectNeeds(result.ir, needs);
|
|
780
1357
|
edits.push({ start: node.start, end: node.end, code: adoptTemplates(result.code, result.templates, hoisted) });
|
|
781
1358
|
}
|
|
1359
|
+
if (styles && options.styles) edits.push(...finishShadowStyles(styles, code, id));
|
|
782
1360
|
const out = new MagicString(code);
|
|
783
1361
|
for (const e of outermost(edits)) {
|
|
784
1362
|
if (e.start === e.end) out.appendLeft(e.start, e.code);
|
|
@@ -836,13 +1414,19 @@ function transformTemplates(code, id, options = {}) {
|
|
|
836
1414
|
...loadDiagnostics.length ? { loadDiagnostics } : {},
|
|
837
1415
|
...unresolvedDiagnostics.length ? { unresolvedDiagnostics } : {},
|
|
838
1416
|
...props.diagnostics.length ? { propsDiagnostics: props.diagnostics } : {},
|
|
839
|
-
...intrinsics.diagnostics.length ? { intrinsicDiagnostics: intrinsics.diagnostics } : {}
|
|
1417
|
+
...intrinsics.diagnostics.length ? { intrinsicDiagnostics: intrinsics.diagnostics } : {},
|
|
1418
|
+
...styles?.styles.length ? { styles: styles.styles } : {},
|
|
1419
|
+
...styles?.diagnostics.length ? { styleDiagnostics: styles.diagnostics } : {},
|
|
1420
|
+
...styles?.literals.length ? { styleLiterals: styles.literals } : {},
|
|
1421
|
+
...styles?.references.length ? { styleReferences: styles.references } : {}
|
|
840
1422
|
};
|
|
841
1423
|
}
|
|
842
|
-
function compileJsx(code, node, edits, nested, used, needs, hoisted, options, sourceFile) {
|
|
1424
|
+
function compileJsx(code, node, edits, nested, used, needs, hoisted, options, sourceFile, styles) {
|
|
843
1425
|
const ir = buildJsxIR(node, {
|
|
844
1426
|
code: (n) => slice(code, n.start, n.end, edits),
|
|
845
1427
|
used,
|
|
1428
|
+
...styles?.scopes.length ? { scopes: styles.scopes } : {},
|
|
1429
|
+
...styles?.drop.size ? { dropStyles: styles.drop } : {},
|
|
846
1430
|
...options.sourceLocations === true && sourceFile ? { sourceFile } : {}
|
|
847
1431
|
});
|
|
848
1432
|
analyzeStatic(ir);
|