Guard all appendChild calls against spread values
The previous fix only guarded domAppend/domInsertAfter, but many platform JS functions (asyncRenderChildren, asyncRenderElement, asyncRenderMap, render, sxRenderWithEnv) call appendChild directly. Add _spread guards to all direct appendChild sites. For async element rendering, merge spread attrs onto parent (class/style join, others overwrite) matching the sync adapter behavior. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -14,7 +14,7 @@
|
|||||||
// =========================================================================
|
// =========================================================================
|
||||||
|
|
||||||
var NIL = Object.freeze({ _nil: true, toString: function() { return "nil"; } });
|
var NIL = Object.freeze({ _nil: true, toString: function() { return "nil"; } });
|
||||||
var SX_VERSION = "2026-03-13T03:34:17Z";
|
var SX_VERSION = "2026-03-13T03:40:30Z";
|
||||||
|
|
||||||
function isNil(x) { return x === NIL || x === null || x === undefined; }
|
function isNil(x) { return x === NIL || x === null || x === undefined; }
|
||||||
function isSxTruthy(x) { return x !== false && !isNil(x); }
|
function isSxTruthy(x) { return x !== false && !isNil(x); }
|
||||||
@@ -5526,7 +5526,7 @@ return (isSxTruthy((_batchDepth == 0)) ? (function() {
|
|||||||
var frag = document.createDocumentFragment();
|
var frag = document.createDocumentFragment();
|
||||||
for (var i = 0; i < exprs.length; i++) {
|
for (var i = 0; i < exprs.length; i++) {
|
||||||
var node = renderToDom(exprs[i], env, null);
|
var node = renderToDom(exprs[i], env, null);
|
||||||
if (node) frag.appendChild(node);
|
if (node && !node._spread) frag.appendChild(node);
|
||||||
}
|
}
|
||||||
return frag;
|
return frag;
|
||||||
}
|
}
|
||||||
@@ -6004,7 +6004,7 @@ return (isSxTruthy((_batchDepth == 0)) ? (function() {
|
|||||||
else ph.parentNode.removeChild(ph);
|
else ph.parentNode.removeChild(ph);
|
||||||
}));
|
}));
|
||||||
})(placeholder);
|
})(placeholder);
|
||||||
} else if (result) {
|
} else if (result && !result._spread) {
|
||||||
frag.appendChild(result);
|
frag.appendChild(result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -6058,7 +6058,23 @@ return (isSxTruthy((_batchDepth == 0)) ? (function() {
|
|||||||
}));
|
}));
|
||||||
})(placeholder);
|
})(placeholder);
|
||||||
} else if (child) {
|
} else if (child) {
|
||||||
el.appendChild(child);
|
if (child._spread) {
|
||||||
|
// Spread: merge attrs onto parent element
|
||||||
|
var sa = child.attrs || {};
|
||||||
|
for (var sk in sa) {
|
||||||
|
if (sk === "class") {
|
||||||
|
var ec = el.getAttribute("class") || "";
|
||||||
|
el.setAttribute("class", ec ? ec + " " + sa[sk] : sa[sk]);
|
||||||
|
} else if (sk === "style") {
|
||||||
|
var es = el.getAttribute("style") || "";
|
||||||
|
el.setAttribute("style", es ? es + ";" + sa[sk] : sa[sk]);
|
||||||
|
} else {
|
||||||
|
el.setAttribute(sk, String(sa[sk]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
el.appendChild(child);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -6225,7 +6241,7 @@ return (isSxTruthy((_batchDepth == 0)) ? (function() {
|
|||||||
var ph = document.createComment("async");
|
var ph = document.createComment("async");
|
||||||
frag.appendChild(ph);
|
frag.appendChild(ph);
|
||||||
(function(p) { pending.push(result.then(function(n) { if (n) p.parentNode.replaceChild(n, p); else p.parentNode.removeChild(p); })); })(ph);
|
(function(p) { pending.push(result.then(function(n) { if (n) p.parentNode.replaceChild(n, p); else p.parentNode.removeChild(p); })); })(ph);
|
||||||
} else if (result) {
|
} else if (result && !result._spread) {
|
||||||
frag.appendChild(result);
|
frag.appendChild(result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -6265,7 +6281,7 @@ return (isSxTruthy((_batchDepth == 0)) ? (function() {
|
|||||||
var ph = document.createComment("async");
|
var ph = document.createComment("async");
|
||||||
frag.appendChild(ph);
|
frag.appendChild(ph);
|
||||||
(function(p) { pending.push(result.then(function(n) { if (n) p.parentNode.replaceChild(n, p); else p.parentNode.removeChild(p); })); })(ph);
|
(function(p) { pending.push(result.then(function(n) { if (n) p.parentNode.replaceChild(n, p); else p.parentNode.removeChild(p); })); })(ph);
|
||||||
} else if (result) {
|
} else if (result && !result._spread) {
|
||||||
frag.appendChild(result);
|
frag.appendChild(result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -6441,7 +6457,7 @@ return (isSxTruthy((_batchDepth == 0)) ? (function() {
|
|||||||
}
|
}
|
||||||
var exprs = parse(source);
|
var exprs = parse(source);
|
||||||
var frag = document.createDocumentFragment();
|
var frag = document.createDocumentFragment();
|
||||||
for (var i = 0; i < exprs.length; i++) frag.appendChild(renderToDom(exprs[i], merge(componentEnv), null));
|
for (var i = 0; i < exprs.length; i++) { var _r = renderToDom(exprs[i], merge(componentEnv), null); if (_r && !_r._spread) frag.appendChild(_r); }
|
||||||
return frag;
|
return frag;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -366,7 +366,7 @@ ASYNC_IO_JS = '''
|
|||||||
else ph.parentNode.removeChild(ph);
|
else ph.parentNode.removeChild(ph);
|
||||||
}));
|
}));
|
||||||
})(placeholder);
|
})(placeholder);
|
||||||
} else if (result) {
|
} else if (result && !result._spread) {
|
||||||
frag.appendChild(result);
|
frag.appendChild(result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -420,7 +420,23 @@ ASYNC_IO_JS = '''
|
|||||||
}));
|
}));
|
||||||
})(placeholder);
|
})(placeholder);
|
||||||
} else if (child) {
|
} else if (child) {
|
||||||
el.appendChild(child);
|
if (child._spread) {
|
||||||
|
// Spread: merge attrs onto parent element
|
||||||
|
var sa = child.attrs || {};
|
||||||
|
for (var sk in sa) {
|
||||||
|
if (sk === "class") {
|
||||||
|
var ec = el.getAttribute("class") || "";
|
||||||
|
el.setAttribute("class", ec ? ec + " " + sa[sk] : sa[sk]);
|
||||||
|
} else if (sk === "style") {
|
||||||
|
var es = el.getAttribute("style") || "";
|
||||||
|
el.setAttribute("style", es ? es + ";" + sa[sk] : sa[sk]);
|
||||||
|
} else {
|
||||||
|
el.setAttribute(sk, String(sa[sk]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
el.appendChild(child);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -587,7 +603,7 @@ ASYNC_IO_JS = '''
|
|||||||
var ph = document.createComment("async");
|
var ph = document.createComment("async");
|
||||||
frag.appendChild(ph);
|
frag.appendChild(ph);
|
||||||
(function(p) { pending.push(result.then(function(n) { if (n) p.parentNode.replaceChild(n, p); else p.parentNode.removeChild(p); })); })(ph);
|
(function(p) { pending.push(result.then(function(n) { if (n) p.parentNode.replaceChild(n, p); else p.parentNode.removeChild(p); })); })(ph);
|
||||||
} else if (result) {
|
} else if (result && !result._spread) {
|
||||||
frag.appendChild(result);
|
frag.appendChild(result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -627,7 +643,7 @@ ASYNC_IO_JS = '''
|
|||||||
var ph = document.createComment("async");
|
var ph = document.createComment("async");
|
||||||
frag.appendChild(ph);
|
frag.appendChild(ph);
|
||||||
(function(p) { pending.push(result.then(function(n) { if (n) p.parentNode.replaceChild(n, p); else p.parentNode.removeChild(p); })); })(ph);
|
(function(p) { pending.push(result.then(function(n) { if (n) p.parentNode.replaceChild(n, p); else p.parentNode.removeChild(p); })); })(ph);
|
||||||
} else if (result) {
|
} else if (result && !result._spread) {
|
||||||
frag.appendChild(result);
|
frag.appendChild(result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2783,7 +2799,7 @@ PLATFORM_BOOT_JS = """
|
|||||||
var frag = document.createDocumentFragment();
|
var frag = document.createDocumentFragment();
|
||||||
for (var i = 0; i < exprs.length; i++) {
|
for (var i = 0; i < exprs.length; i++) {
|
||||||
var node = renderToDom(exprs[i], env, null);
|
var node = renderToDom(exprs[i], env, null);
|
||||||
if (node) frag.appendChild(node);
|
if (node && !node._spread) frag.appendChild(node);
|
||||||
}
|
}
|
||||||
return frag;
|
return frag;
|
||||||
}
|
}
|
||||||
@@ -3079,7 +3095,7 @@ def public_api_js(has_html, has_sx, has_dom, has_engine, has_orch, has_boot, has
|
|||||||
}
|
}
|
||||||
var exprs = parse(source);
|
var exprs = parse(source);
|
||||||
var frag = document.createDocumentFragment();
|
var frag = document.createDocumentFragment();
|
||||||
for (var i = 0; i < exprs.length; i++) frag.appendChild(renderToDom(exprs[i], merge(componentEnv), null));
|
for (var i = 0; i < exprs.length; i++) { var _r = renderToDom(exprs[i], merge(componentEnv), null); if (_r && !_r._spread) frag.appendChild(_r); }
|
||||||
return frag;
|
return frag;
|
||||||
}''')
|
}''')
|
||||||
elif has_dom:
|
elif has_dom:
|
||||||
@@ -3087,7 +3103,7 @@ def public_api_js(has_html, has_sx, has_dom, has_engine, has_orch, has_boot, has
|
|||||||
function render(source) {
|
function render(source) {
|
||||||
var exprs = parse(source);
|
var exprs = parse(source);
|
||||||
var frag = document.createDocumentFragment();
|
var frag = document.createDocumentFragment();
|
||||||
for (var i = 0; i < exprs.length; i++) frag.appendChild(renderToDom(exprs[i], merge(componentEnv), null));
|
for (var i = 0; i < exprs.length; i++) { var _r = renderToDom(exprs[i], merge(componentEnv), null); if (_r && !_r._spread) frag.appendChild(_r); }
|
||||||
return frag;
|
return frag;
|
||||||
}''')
|
}''')
|
||||||
elif has_html:
|
elif has_html:
|
||||||
|
|||||||
Reference in New Issue
Block a user