Fix renderComponentDOM: route render-only forms through renderDOM
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 2m19s
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 2m19s
The previous fix eagerly evaluated all kwarg expressions via sxEval, which broke render-only forms (<>, raw!, HTML tags, ~components) that only exist in the render pipeline. Now detect render expressions by checking if the head symbol is an HTML/SVG tag, <>, raw!, or ~component, and route those through renderDOM while data expressions still go through sxEval for correct scope resolution. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -808,17 +808,32 @@
|
|||||||
return renderDOM(fn.body, local);
|
return renderDOM(fn.body, local);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** True when the array expr is a render-only form (HTML tag, <>, raw!, ~comp). */
|
||||||
|
function _isRenderExpr(v) {
|
||||||
|
if (!Array.isArray(v) || !v.length) return false;
|
||||||
|
var h = v[0];
|
||||||
|
if (!isSym(h)) return false;
|
||||||
|
var n = h.name;
|
||||||
|
return !!(HTML_TAGS[n] || SVG_TAGS[n] || n === "<>" || n === "raw!" || n.charAt(0) === "~");
|
||||||
|
}
|
||||||
|
|
||||||
function renderComponentDOM(comp, args, env) {
|
function renderComponentDOM(comp, args, env) {
|
||||||
var kwargs = {}, children = [];
|
var kwargs = {}, children = [];
|
||||||
var i = 0;
|
var i = 0;
|
||||||
while (i < args.length) {
|
while (i < args.length) {
|
||||||
if (isKw(args[i]) && i + 1 < args.length) {
|
if (isKw(args[i]) && i + 1 < args.length) {
|
||||||
// Evaluate kwarg values eagerly so expressions like (get t "src")
|
// Evaluate kwarg values eagerly in the caller's env so expressions
|
||||||
// resolve in the caller's env (where lambda params are bound).
|
// like (get t "src") resolve while lambda params are still bound.
|
||||||
|
// Render-only forms (HTML tags, <>, ~comp) go through renderDOM instead.
|
||||||
var v = args[i + 1];
|
var v = args[i + 1];
|
||||||
kwargs[args[i].name] = (typeof v === "string" || typeof v === "number" ||
|
if (typeof v === "string" || typeof v === "number" ||
|
||||||
typeof v === "boolean" || isNil(v))
|
typeof v === "boolean" || isNil(v)) {
|
||||||
? v : sxEval(v, env);
|
kwargs[args[i].name] = v;
|
||||||
|
} else if (_isRenderExpr(v)) {
|
||||||
|
kwargs[args[i].name] = renderDOM(v, env);
|
||||||
|
} else {
|
||||||
|
kwargs[args[i].name] = sxEval(v, env);
|
||||||
|
}
|
||||||
i += 2;
|
i += 2;
|
||||||
} else {
|
} else {
|
||||||
children.push(args[i]);
|
children.push(args[i]);
|
||||||
|
|||||||
Reference in New Issue
Block a user