fix(js): flatten DocumentFragment during node insertion

Move fragment children into the target for appendChild, insertBefore, and replaceChild while preserving their order and emptying the fragment.

Add runtime regression coverage for the DOM attachment portion of #452.
This commit is contained in:
lisa0314 committed 2026-07-21 18:17:40 +08:00
1 parent 72d66bc5c0
commit c4f545e68b
2 files changed
+122

No files matched your search

+16
View File
@@ -663,6 +663,11 @@ class Node {
get previousSibling() { return _wrap(+_dom("prev_sibling", this._nid)); }
appendChild(c) {
if (!c) return c;
if (c instanceof DocumentFragment) {
const children = Array.from(c.childNodes);
for (const child of children) this.appendChild(child);
return c;
}
_dom("append_child", this._nid, c._nid);
if (globalThis.__mutationObservers?.length) globalThis.__notifyMutation('childList', this._nid, [c._nid], []);
if (c instanceof Element && c.tagName === 'SCRIPT') {
@@ -745,6 +750,12 @@ class Node {
}
replaceChild(newChild, oldChild) {
if (!oldChild || !newChild) return oldChild;
if (newChild instanceof DocumentFragment) {
const children = Array.from(newChild.childNodes);
for (const child of children) this.insertBefore(child, oldChild);
this.removeChild(oldChild);
return oldChild;
}
_dom("insert_before", newChild._nid, oldChild._nid);
_dom("remove_child", oldChild._nid);
return oldChild;
@@ -752,6 +763,11 @@ class Node {
insertBefore(n, ref) {
if (!n) return n;
if (!ref) { this.appendChild(n); return n; }
if (n instanceof DocumentFragment) {
const children = Array.from(n.childNodes);
for (const child of children) this.insertBefore(child, ref);
return n;
}
_dom("insert_before", n._nid, ref._nid);
return n;
}