@fluixi/compiler 1.0.0-alpha.105 → 1.0.0-alpha.106
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/static-graph.cjs +1 -1
- package/dist/analyze/static-graph.mjs +1 -1
- package/dist/{babel-USPHNEJF.mjs → babel-HJY4RVAV.mjs} +33 -20
- package/dist/{chunk-OQYQ7UTD.mjs → chunk-4XEOMQ57.mjs} +1 -1
- package/dist/{chunk-EK4OMGTU.mjs → chunk-JUFI6IR3.mjs} +1 -1
- package/dist/{chunk-5GAYDAAC.mjs → chunk-LCQHL2VQ.mjs} +132 -10
- package/dist/{chunk-XBAQME2V.mjs → chunk-LGUZRHYN.mjs} +2 -2
- package/dist/{chunk-O6OBEV4V.mjs → chunk-TDN5MYWI.mjs} +1 -1
- package/dist/{chunk-EQIIWIEU.mjs → chunk-W7DYOMXJ.mjs} +2 -2
- package/dist/{chunk-FMIIK5UM.mjs → chunk-WHEDRMNR.mjs} +1 -1
- package/dist/codegen/backends/imperative.cjs +130 -8
- package/dist/codegen/backends/imperative.d.ts.map +1 -1
- package/dist/codegen/backends/imperative.js +62 -0
- package/dist/codegen/backends/imperative.mjs +130 -8
- package/dist/codegen/partial-template.cjs +80 -8
- package/dist/codegen/partial-template.d.cts +21 -4
- package/dist/codegen/partial-template.d.ts +21 -4
- package/dist/codegen/partial-template.d.ts.map +1 -1
- package/dist/codegen/partial-template.js +0 -0
- package/dist/codegen/partial-template.mjs +80 -8
- package/dist/codegen/serialize-static.cjs +1 -0
- package/dist/codegen/serialize-static.d.cts +8 -0
- package/dist/codegen/serialize-static.d.ts +8 -0
- package/dist/codegen/serialize-static.d.ts.map +1 -1
- package/dist/codegen/serialize-static.js +1 -1
- package/dist/codegen/serialize-static.mjs +1 -0
- package/dist/frontend/babel/build-ir-html.cjs +149 -21
- package/dist/frontend/babel/build-ir-html.d.cts +3 -1
- package/dist/frontend/babel/build-ir-html.d.ts +3 -1
- package/dist/frontend/babel/build-ir-html.d.ts.map +1 -1
- package/dist/frontend/babel/build-ir-html.mjs +149 -21
- package/dist/frontend/babel/build-ir.cjs +149 -21
- package/dist/frontend/babel/build-ir.d.cts +11 -2
- package/dist/frontend/babel/build-ir.d.ts +11 -2
- package/dist/frontend/babel/build-ir.d.ts.map +1 -1
- package/dist/frontend/babel/build-ir.js +15 -9
- package/dist/frontend/babel/build-ir.mjs +149 -21
- package/dist/frontend/babel/index.cjs +160 -25
- package/dist/frontend/babel/index.mjs +160 -25
- package/dist/frontend/babel/lower-template.cjs +149 -21
- package/dist/frontend/babel/lower-template.d.cts +2 -1
- package/dist/frontend/babel/lower-template.d.ts +2 -1
- package/dist/frontend/babel/lower-template.d.ts.map +1 -1
- package/dist/frontend/babel/lower-template.js +4 -4
- package/dist/frontend/babel/lower-template.mjs +149 -21
- package/dist/frontend/babel/plugin.cjs +158 -23
- package/dist/frontend/babel/plugin.js +9 -2
- package/dist/frontend/babel/plugin.mjs +158 -23
- package/dist/index.cjs +131 -9
- package/dist/index.mjs +131 -9
- package/dist/integrations.cjs +165 -33
- package/dist/integrations.mjs +11 -11
- package/dist/lower/compile-template.cjs +131 -9
- package/dist/lower/compile-template.mjs +131 -9
- package/dist/lower/jsx.cjs +130 -8
- package/dist/lower/jsx.mjs +130 -8
- package/dist/lower/template.cjs +130 -8
- package/dist/lower/template.mjs +130 -8
- package/dist/resolve/builtins.cjs +1 -1
- package/dist/resolve/builtins.mjs +1 -1
- package/dist/{server-fns-7Y25MR3B.mjs → server-fns-WZJK4BJE.mjs} +5 -5
- package/dist/{server-functions-43CFKXY3.mjs → server-functions-4KTFFEO3.mjs} +3 -3
- package/dist/transform/index.cjs +135 -16
- package/dist/transform/index.mjs +135 -16
- package/dist/transform/templates.cjs +134 -15
- package/dist/transform/templates.d.ts.map +1 -1
- package/dist/transform/templates.js +4 -8
- package/dist/transform/templates.mjs +134 -15
- package/dist/{transform-YUDW7K4J.mjs → transform-NO46NFQH.mjs} +11 -14
- package/dist/tsconfig.lib.tsbuildinfo +1 -1
- package/package.json +4 -4
package/dist/index.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! @fluixi/compiler v1.0.0-alpha.
|
|
1
|
+
/*! @fluixi/compiler v1.0.0-alpha.106 | (c) 2026 Ibrahima Touré and Fluixi contributors | MIT */
|
|
2
2
|
"use strict";
|
|
3
3
|
var __defProp = Object.defineProperty;
|
|
4
4
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
@@ -222,10 +222,64 @@ function isHole(node) {
|
|
|
222
222
|
function isTemplateChild(node) {
|
|
223
223
|
return node.kind === "text" || node.kind === "element" && isTemplateElement(node);
|
|
224
224
|
}
|
|
225
|
+
var PROPERTY_BINDS = /* @__PURE__ */ new Set(["indeterminate"]);
|
|
226
|
+
function disposition(prop) {
|
|
227
|
+
if (prop.kind === "spread") return null;
|
|
228
|
+
if (prop.name === "ref") return "ref";
|
|
229
|
+
if (prop.name === "use") return "use";
|
|
230
|
+
if (prop.kind === "event") return prop.event ? "event" : null;
|
|
231
|
+
if (prop.kind === "prop") return "property";
|
|
232
|
+
if (prop.kind !== "attr") return null;
|
|
233
|
+
const name = prop.name;
|
|
234
|
+
if (name.startsWith("on:")) return "nativeEvent";
|
|
235
|
+
if (name.startsWith("prop:")) return "property";
|
|
236
|
+
if (name.startsWith("attr:")) return "attr";
|
|
237
|
+
if (name.startsWith("bool:")) return "boolAttr";
|
|
238
|
+
if (name === "className" || name === "class") {
|
|
239
|
+
return isPlainLiteralAttr(prop) ? "serialize" : "class";
|
|
240
|
+
}
|
|
241
|
+
if (name === "classList") {
|
|
242
|
+
if (isPlainLiteralAttr(prop)) return "serialize";
|
|
243
|
+
return prop.reactive ? "classListDynamic" : "classList";
|
|
244
|
+
}
|
|
245
|
+
if (name === "style") {
|
|
246
|
+
if (isPlainLiteralAttr(prop)) return "serialize";
|
|
247
|
+
return prop.reactive ? "styleDynamic" : "style";
|
|
248
|
+
}
|
|
249
|
+
if (name.includes(":")) return null;
|
|
250
|
+
if (PROPERTY_ONLY.has(name)) return null;
|
|
251
|
+
if (PROPERTY_BINDS.has(name)) return "property";
|
|
252
|
+
if (prop.expr === void 0) return isPlainLiteralAttr(prop) ? "serialize" : null;
|
|
253
|
+
return "attr";
|
|
254
|
+
}
|
|
255
|
+
function effectiveProps(el) {
|
|
256
|
+
const order = [];
|
|
257
|
+
const byName = /* @__PURE__ */ new Map();
|
|
258
|
+
for (const prop of el.props) {
|
|
259
|
+
if (!byName.has(prop.name)) order.push(prop.name);
|
|
260
|
+
byName.set(prop.name, prop);
|
|
261
|
+
}
|
|
262
|
+
return order.map((name) => byName.get(name));
|
|
263
|
+
}
|
|
264
|
+
function propPlan(el) {
|
|
265
|
+
const custom = el.tag.includes("-");
|
|
266
|
+
const plan = { serialize: [], bindings: [] };
|
|
267
|
+
for (const prop of effectiveProps(el)) {
|
|
268
|
+
const kind = disposition(prop);
|
|
269
|
+
if (kind === null) return null;
|
|
270
|
+
if (kind === "serialize") {
|
|
271
|
+
plan.serialize.push(prop);
|
|
272
|
+
continue;
|
|
273
|
+
}
|
|
274
|
+
if (custom) return null;
|
|
275
|
+
plan.bindings.push({ prop, kind });
|
|
276
|
+
}
|
|
277
|
+
return plan;
|
|
278
|
+
}
|
|
225
279
|
function isTemplateElement(node) {
|
|
226
280
|
if (node.svg) return false;
|
|
227
281
|
if (isRawTextElement(node.tag)) return false;
|
|
228
|
-
if (!node
|
|
282
|
+
if (!propPlan(node)) return false;
|
|
229
283
|
return node.children.every((c) => isTemplateChild(c) || isHole(c));
|
|
230
284
|
}
|
|
231
285
|
function containsHole(node) {
|
|
@@ -233,6 +287,15 @@ function containsHole(node) {
|
|
|
233
287
|
const children = node.children;
|
|
234
288
|
return children ? children.some(containsHole) : false;
|
|
235
289
|
}
|
|
290
|
+
function containsBinding(node) {
|
|
291
|
+
if (node.kind !== "element") return false;
|
|
292
|
+
const plan = propPlan(node);
|
|
293
|
+
if (plan && plan.bindings.length > 0) return true;
|
|
294
|
+
return node.children.some(containsBinding);
|
|
295
|
+
}
|
|
296
|
+
function interesting(node) {
|
|
297
|
+
return containsHole(node) || containsBinding(node);
|
|
298
|
+
}
|
|
236
299
|
function addressable(el) {
|
|
237
300
|
for (let i = 0; i < el.children.length; i++) {
|
|
238
301
|
const child = el.children[i];
|
|
@@ -246,9 +309,10 @@ function addressable(el) {
|
|
|
246
309
|
function planPartialTemplate(root) {
|
|
247
310
|
if (!isTemplateElement(root)) return null;
|
|
248
311
|
if (!addressable(root)) return null;
|
|
249
|
-
if (!root
|
|
312
|
+
if (!interesting(root)) return null;
|
|
250
313
|
const steps = [];
|
|
251
314
|
const holes = [];
|
|
315
|
+
const bindings = [];
|
|
252
316
|
let refCount = 0;
|
|
253
317
|
const declare = (expr) => {
|
|
254
318
|
const ref = `_n$${refCount++}`;
|
|
@@ -256,11 +320,17 @@ function planPartialTemplate(root) {
|
|
|
256
320
|
return ref;
|
|
257
321
|
};
|
|
258
322
|
walk2(root, "_el$");
|
|
259
|
-
return { html: serializeWithMarkers(root), tag: root.tag, steps, holes };
|
|
323
|
+
return { html: serializeWithMarkers(root), tag: root.tag, steps, holes, bindings };
|
|
260
324
|
function walk2(el, elementRef) {
|
|
325
|
+
const plan = propPlan(el);
|
|
326
|
+
if (plan) {
|
|
327
|
+
for (const binding of plan.bindings) {
|
|
328
|
+
bindings.push({ ref: elementRef, prop: binding.prop, kind: binding.kind });
|
|
329
|
+
}
|
|
330
|
+
}
|
|
261
331
|
let last = -1;
|
|
262
332
|
el.children.forEach((child, i) => {
|
|
263
|
-
if (
|
|
333
|
+
if (interesting(child)) last = i;
|
|
264
334
|
});
|
|
265
335
|
let previous = null;
|
|
266
336
|
for (let i = 0; i <= last; i++) {
|
|
@@ -274,19 +344,21 @@ function planPartialTemplate(root) {
|
|
|
274
344
|
continue;
|
|
275
345
|
}
|
|
276
346
|
const ref = declare(expr);
|
|
277
|
-
if (child.kind === "element" &&
|
|
347
|
+
if (child.kind === "element" && interesting(child)) walk2(child, ref);
|
|
278
348
|
previous = ref;
|
|
279
349
|
}
|
|
280
350
|
}
|
|
281
351
|
}
|
|
282
352
|
function serializeWithMarkers(el) {
|
|
283
|
-
return serializeStatic(
|
|
353
|
+
return serializeStatic(templateTree(el)).split(SENTINEL).join(HOLE_START + HOLE_END);
|
|
284
354
|
}
|
|
285
|
-
function
|
|
355
|
+
function templateTree(el) {
|
|
356
|
+
const plan = propPlan(el);
|
|
286
357
|
return {
|
|
287
358
|
...el,
|
|
359
|
+
props: plan ? plan.serialize : [],
|
|
288
360
|
children: el.children.map(
|
|
289
|
-
(child) => isHole(child) ? { kind: "text", value: SENTINEL } : child.kind === "element" ?
|
|
361
|
+
(child) => isHole(child) ? { kind: "text", value: SENTINEL } : child.kind === "element" ? templateTree(child) : child
|
|
290
362
|
)
|
|
291
363
|
};
|
|
292
364
|
}
|
|
@@ -564,6 +636,55 @@ function emitComponent(name, props, children, used, templates, at) {
|
|
|
564
636
|
const mark = at ? `globalThis.${SOURCE_MARKER}?.(${JSON.stringify(at.file)},${at.line},${at.column},${JSON.stringify(name)}), ` : "";
|
|
565
637
|
return `createMemo(${paren(`${mark}() => createComponent(${name}, ${obj})`, "value")})`;
|
|
566
638
|
}
|
|
639
|
+
function bindingTarget(binding) {
|
|
640
|
+
const name = binding.prop.name;
|
|
641
|
+
if (binding.kind === "boolAttr") return name.slice("bool:".length);
|
|
642
|
+
if (name.startsWith("prop:")) return name.slice("prop:".length);
|
|
643
|
+
if (name.startsWith("attr:")) return name.slice("attr:".length);
|
|
644
|
+
return htmlAttrName(name);
|
|
645
|
+
}
|
|
646
|
+
function bindingStatement(binding, used) {
|
|
647
|
+
const { ref, prop, kind } = binding;
|
|
648
|
+
const value = propValue(prop);
|
|
649
|
+
switch (kind) {
|
|
650
|
+
case "class":
|
|
651
|
+
used.add("setClassName");
|
|
652
|
+
return `setClassName(${ref}, ${value});`;
|
|
653
|
+
case "classList":
|
|
654
|
+
used.add("setClassList");
|
|
655
|
+
return `setClassList(${ref}, ${value}, []);`;
|
|
656
|
+
case "classListDynamic":
|
|
657
|
+
used.add("setDynamicClassList");
|
|
658
|
+
return `setDynamicClassList(${ref}, ${value});`;
|
|
659
|
+
case "style":
|
|
660
|
+
used.add("setStyle");
|
|
661
|
+
return `setStyle(${ref}, ${value}, []);`;
|
|
662
|
+
case "styleDynamic":
|
|
663
|
+
used.add("setDynamicStyle");
|
|
664
|
+
return `setDynamicStyle(${ref}, ${value});`;
|
|
665
|
+
case "attr":
|
|
666
|
+
used.add("setDynamicAttribute");
|
|
667
|
+
return `setDynamicAttribute(${ref}, ${JSON.stringify(bindingTarget(binding))}, ${value});`;
|
|
668
|
+
case "property":
|
|
669
|
+
used.add("setDynamicProperty");
|
|
670
|
+
return `setDynamicProperty(${ref}, ${JSON.stringify(bindingTarget(binding))}, ${value});`;
|
|
671
|
+
case "boolAttr":
|
|
672
|
+
used.add("setDynamicBoolAttribute");
|
|
673
|
+
return `setDynamicBoolAttribute(${ref}, ${JSON.stringify(bindingTarget(binding))}, ${value});`;
|
|
674
|
+
case "event":
|
|
675
|
+
used.add("addDelegatedEventListener");
|
|
676
|
+
return `addDelegatedEventListener(${ref}, ${JSON.stringify(prop.event.name)}, ${value});`;
|
|
677
|
+
case "nativeEvent":
|
|
678
|
+
used.add("addNativeEventListener");
|
|
679
|
+
return `addNativeEventListener(${ref}, ${JSON.stringify(prop.name.slice(3))}, ${value});`;
|
|
680
|
+
case "ref":
|
|
681
|
+
used.add("handleRef");
|
|
682
|
+
return `handleRef(${value}, ${ref});`;
|
|
683
|
+
case "use":
|
|
684
|
+
used.add("applyUse");
|
|
685
|
+
return `applyUse(${ref}, ${value});`;
|
|
686
|
+
}
|
|
687
|
+
}
|
|
567
688
|
function staticAttrAssignment(el, prop) {
|
|
568
689
|
const name = htmlAttrName(prop.name);
|
|
569
690
|
const value = prop.literal;
|
|
@@ -614,6 +735,7 @@ function emitNode(node, used, templates) {
|
|
|
614
735
|
`const _el$ = templateNode(${id}, ${JSON.stringify(plan.tag)}, true${at ? `, false, ${JSON.stringify(at)}` : ""});`
|
|
615
736
|
];
|
|
616
737
|
for (const step of plan.steps) lines.push(`const ${step.ref} = ${step.expr};`);
|
|
738
|
+
for (const binding of plan.bindings) lines.push(bindingStatement(binding, used));
|
|
617
739
|
for (const hole of plan.holes) {
|
|
618
740
|
lines.push(
|
|
619
741
|
`insert(${hole.parentRef}, holeScope(${hole.startRef}, () => ${paren(emitNode(hole.node, used, templates), "arrowBody")}), ${hole.endRef}, holeContent(${hole.startRef}, ${hole.endRef}));`
|
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! @fluixi/compiler v1.0.0-alpha.
|
|
1
|
+
/*! @fluixi/compiler v1.0.0-alpha.106 | (c) 2026 Ibrahima Touré and Fluixi contributors | MIT */
|
|
2
2
|
|
|
3
3
|
// src/analyze/reactive-expr.ts
|
|
4
4
|
var STABLE_MEMBER = "children";
|
|
@@ -175,10 +175,64 @@ function isHole(node) {
|
|
|
175
175
|
function isTemplateChild(node) {
|
|
176
176
|
return node.kind === "text" || node.kind === "element" && isTemplateElement(node);
|
|
177
177
|
}
|
|
178
|
+
var PROPERTY_BINDS = /* @__PURE__ */ new Set(["indeterminate"]);
|
|
179
|
+
function disposition(prop) {
|
|
180
|
+
if (prop.kind === "spread") return null;
|
|
181
|
+
if (prop.name === "ref") return "ref";
|
|
182
|
+
if (prop.name === "use") return "use";
|
|
183
|
+
if (prop.kind === "event") return prop.event ? "event" : null;
|
|
184
|
+
if (prop.kind === "prop") return "property";
|
|
185
|
+
if (prop.kind !== "attr") return null;
|
|
186
|
+
const name = prop.name;
|
|
187
|
+
if (name.startsWith("on:")) return "nativeEvent";
|
|
188
|
+
if (name.startsWith("prop:")) return "property";
|
|
189
|
+
if (name.startsWith("attr:")) return "attr";
|
|
190
|
+
if (name.startsWith("bool:")) return "boolAttr";
|
|
191
|
+
if (name === "className" || name === "class") {
|
|
192
|
+
return isPlainLiteralAttr(prop) ? "serialize" : "class";
|
|
193
|
+
}
|
|
194
|
+
if (name === "classList") {
|
|
195
|
+
if (isPlainLiteralAttr(prop)) return "serialize";
|
|
196
|
+
return prop.reactive ? "classListDynamic" : "classList";
|
|
197
|
+
}
|
|
198
|
+
if (name === "style") {
|
|
199
|
+
if (isPlainLiteralAttr(prop)) return "serialize";
|
|
200
|
+
return prop.reactive ? "styleDynamic" : "style";
|
|
201
|
+
}
|
|
202
|
+
if (name.includes(":")) return null;
|
|
203
|
+
if (PROPERTY_ONLY.has(name)) return null;
|
|
204
|
+
if (PROPERTY_BINDS.has(name)) return "property";
|
|
205
|
+
if (prop.expr === void 0) return isPlainLiteralAttr(prop) ? "serialize" : null;
|
|
206
|
+
return "attr";
|
|
207
|
+
}
|
|
208
|
+
function effectiveProps(el) {
|
|
209
|
+
const order = [];
|
|
210
|
+
const byName = /* @__PURE__ */ new Map();
|
|
211
|
+
for (const prop of el.props) {
|
|
212
|
+
if (!byName.has(prop.name)) order.push(prop.name);
|
|
213
|
+
byName.set(prop.name, prop);
|
|
214
|
+
}
|
|
215
|
+
return order.map((name) => byName.get(name));
|
|
216
|
+
}
|
|
217
|
+
function propPlan(el) {
|
|
218
|
+
const custom = el.tag.includes("-");
|
|
219
|
+
const plan = { serialize: [], bindings: [] };
|
|
220
|
+
for (const prop of effectiveProps(el)) {
|
|
221
|
+
const kind = disposition(prop);
|
|
222
|
+
if (kind === null) return null;
|
|
223
|
+
if (kind === "serialize") {
|
|
224
|
+
plan.serialize.push(prop);
|
|
225
|
+
continue;
|
|
226
|
+
}
|
|
227
|
+
if (custom) return null;
|
|
228
|
+
plan.bindings.push({ prop, kind });
|
|
229
|
+
}
|
|
230
|
+
return plan;
|
|
231
|
+
}
|
|
178
232
|
function isTemplateElement(node) {
|
|
179
233
|
if (node.svg) return false;
|
|
180
234
|
if (isRawTextElement(node.tag)) return false;
|
|
181
|
-
if (!node
|
|
235
|
+
if (!propPlan(node)) return false;
|
|
182
236
|
return node.children.every((c) => isTemplateChild(c) || isHole(c));
|
|
183
237
|
}
|
|
184
238
|
function containsHole(node) {
|
|
@@ -186,6 +240,15 @@ function containsHole(node) {
|
|
|
186
240
|
const children = node.children;
|
|
187
241
|
return children ? children.some(containsHole) : false;
|
|
188
242
|
}
|
|
243
|
+
function containsBinding(node) {
|
|
244
|
+
if (node.kind !== "element") return false;
|
|
245
|
+
const plan = propPlan(node);
|
|
246
|
+
if (plan && plan.bindings.length > 0) return true;
|
|
247
|
+
return node.children.some(containsBinding);
|
|
248
|
+
}
|
|
249
|
+
function interesting(node) {
|
|
250
|
+
return containsHole(node) || containsBinding(node);
|
|
251
|
+
}
|
|
189
252
|
function addressable(el) {
|
|
190
253
|
for (let i = 0; i < el.children.length; i++) {
|
|
191
254
|
const child = el.children[i];
|
|
@@ -199,9 +262,10 @@ function addressable(el) {
|
|
|
199
262
|
function planPartialTemplate(root) {
|
|
200
263
|
if (!isTemplateElement(root)) return null;
|
|
201
264
|
if (!addressable(root)) return null;
|
|
202
|
-
if (!root
|
|
265
|
+
if (!interesting(root)) return null;
|
|
203
266
|
const steps = [];
|
|
204
267
|
const holes = [];
|
|
268
|
+
const bindings = [];
|
|
205
269
|
let refCount = 0;
|
|
206
270
|
const declare = (expr) => {
|
|
207
271
|
const ref = `_n$${refCount++}`;
|
|
@@ -209,11 +273,17 @@ function planPartialTemplate(root) {
|
|
|
209
273
|
return ref;
|
|
210
274
|
};
|
|
211
275
|
walk2(root, "_el$");
|
|
212
|
-
return { html: serializeWithMarkers(root), tag: root.tag, steps, holes };
|
|
276
|
+
return { html: serializeWithMarkers(root), tag: root.tag, steps, holes, bindings };
|
|
213
277
|
function walk2(el, elementRef) {
|
|
278
|
+
const plan = propPlan(el);
|
|
279
|
+
if (plan) {
|
|
280
|
+
for (const binding of plan.bindings) {
|
|
281
|
+
bindings.push({ ref: elementRef, prop: binding.prop, kind: binding.kind });
|
|
282
|
+
}
|
|
283
|
+
}
|
|
214
284
|
let last = -1;
|
|
215
285
|
el.children.forEach((child, i) => {
|
|
216
|
-
if (
|
|
286
|
+
if (interesting(child)) last = i;
|
|
217
287
|
});
|
|
218
288
|
let previous = null;
|
|
219
289
|
for (let i = 0; i <= last; i++) {
|
|
@@ -227,19 +297,21 @@ function planPartialTemplate(root) {
|
|
|
227
297
|
continue;
|
|
228
298
|
}
|
|
229
299
|
const ref = declare(expr);
|
|
230
|
-
if (child.kind === "element" &&
|
|
300
|
+
if (child.kind === "element" && interesting(child)) walk2(child, ref);
|
|
231
301
|
previous = ref;
|
|
232
302
|
}
|
|
233
303
|
}
|
|
234
304
|
}
|
|
235
305
|
function serializeWithMarkers(el) {
|
|
236
|
-
return serializeStatic(
|
|
306
|
+
return serializeStatic(templateTree(el)).split(SENTINEL).join(HOLE_START + HOLE_END);
|
|
237
307
|
}
|
|
238
|
-
function
|
|
308
|
+
function templateTree(el) {
|
|
309
|
+
const plan = propPlan(el);
|
|
239
310
|
return {
|
|
240
311
|
...el,
|
|
312
|
+
props: plan ? plan.serialize : [],
|
|
241
313
|
children: el.children.map(
|
|
242
|
-
(child) => isHole(child) ? { kind: "text", value: SENTINEL } : child.kind === "element" ?
|
|
314
|
+
(child) => isHole(child) ? { kind: "text", value: SENTINEL } : child.kind === "element" ? templateTree(child) : child
|
|
243
315
|
)
|
|
244
316
|
};
|
|
245
317
|
}
|
|
@@ -517,6 +589,55 @@ function emitComponent(name, props, children, used, templates, at) {
|
|
|
517
589
|
const mark = at ? `globalThis.${SOURCE_MARKER}?.(${JSON.stringify(at.file)},${at.line},${at.column},${JSON.stringify(name)}), ` : "";
|
|
518
590
|
return `createMemo(${paren(`${mark}() => createComponent(${name}, ${obj})`, "value")})`;
|
|
519
591
|
}
|
|
592
|
+
function bindingTarget(binding) {
|
|
593
|
+
const name = binding.prop.name;
|
|
594
|
+
if (binding.kind === "boolAttr") return name.slice("bool:".length);
|
|
595
|
+
if (name.startsWith("prop:")) return name.slice("prop:".length);
|
|
596
|
+
if (name.startsWith("attr:")) return name.slice("attr:".length);
|
|
597
|
+
return htmlAttrName(name);
|
|
598
|
+
}
|
|
599
|
+
function bindingStatement(binding, used) {
|
|
600
|
+
const { ref, prop, kind } = binding;
|
|
601
|
+
const value = propValue(prop);
|
|
602
|
+
switch (kind) {
|
|
603
|
+
case "class":
|
|
604
|
+
used.add("setClassName");
|
|
605
|
+
return `setClassName(${ref}, ${value});`;
|
|
606
|
+
case "classList":
|
|
607
|
+
used.add("setClassList");
|
|
608
|
+
return `setClassList(${ref}, ${value}, []);`;
|
|
609
|
+
case "classListDynamic":
|
|
610
|
+
used.add("setDynamicClassList");
|
|
611
|
+
return `setDynamicClassList(${ref}, ${value});`;
|
|
612
|
+
case "style":
|
|
613
|
+
used.add("setStyle");
|
|
614
|
+
return `setStyle(${ref}, ${value}, []);`;
|
|
615
|
+
case "styleDynamic":
|
|
616
|
+
used.add("setDynamicStyle");
|
|
617
|
+
return `setDynamicStyle(${ref}, ${value});`;
|
|
618
|
+
case "attr":
|
|
619
|
+
used.add("setDynamicAttribute");
|
|
620
|
+
return `setDynamicAttribute(${ref}, ${JSON.stringify(bindingTarget(binding))}, ${value});`;
|
|
621
|
+
case "property":
|
|
622
|
+
used.add("setDynamicProperty");
|
|
623
|
+
return `setDynamicProperty(${ref}, ${JSON.stringify(bindingTarget(binding))}, ${value});`;
|
|
624
|
+
case "boolAttr":
|
|
625
|
+
used.add("setDynamicBoolAttribute");
|
|
626
|
+
return `setDynamicBoolAttribute(${ref}, ${JSON.stringify(bindingTarget(binding))}, ${value});`;
|
|
627
|
+
case "event":
|
|
628
|
+
used.add("addDelegatedEventListener");
|
|
629
|
+
return `addDelegatedEventListener(${ref}, ${JSON.stringify(prop.event.name)}, ${value});`;
|
|
630
|
+
case "nativeEvent":
|
|
631
|
+
used.add("addNativeEventListener");
|
|
632
|
+
return `addNativeEventListener(${ref}, ${JSON.stringify(prop.name.slice(3))}, ${value});`;
|
|
633
|
+
case "ref":
|
|
634
|
+
used.add("handleRef");
|
|
635
|
+
return `handleRef(${value}, ${ref});`;
|
|
636
|
+
case "use":
|
|
637
|
+
used.add("applyUse");
|
|
638
|
+
return `applyUse(${ref}, ${value});`;
|
|
639
|
+
}
|
|
640
|
+
}
|
|
520
641
|
function staticAttrAssignment(el, prop) {
|
|
521
642
|
const name = htmlAttrName(prop.name);
|
|
522
643
|
const value = prop.literal;
|
|
@@ -567,6 +688,7 @@ function emitNode(node, used, templates) {
|
|
|
567
688
|
`const _el$ = templateNode(${id}, ${JSON.stringify(plan.tag)}, true${at ? `, false, ${JSON.stringify(at)}` : ""});`
|
|
568
689
|
];
|
|
569
690
|
for (const step of plan.steps) lines.push(`const ${step.ref} = ${step.expr};`);
|
|
691
|
+
for (const binding of plan.bindings) lines.push(bindingStatement(binding, used));
|
|
570
692
|
for (const hole of plan.holes) {
|
|
571
693
|
lines.push(
|
|
572
694
|
`insert(${hole.parentRef}, holeScope(${hole.startRef}, () => ${paren(emitNode(hole.node, used, templates), "arrowBody")}), ${hole.endRef}, holeContent(${hole.startRef}, ${hole.endRef}));`
|