Merge pull request #1710 from lightpanda-io/custom_element_clone

Support for clone custom elements that attach them self in their cons…
This commit is contained in:
Karl Seguin
2026-03-04 15:47:39 +08:00
committed by GitHub
2 changed files with 30 additions and 2 deletions

View File

@@ -53,3 +53,22 @@
testing.expectEqual('NO-CONSTRUCTOR-ELEMENT', el.tagName);
}
</script>
<div id=clone_container></div>
<script id=clone>
{
let calls = 0;
class MyCloneElementA extends HTMLElement {
constructor() {
super();
calls += 1;
$('#clone_container').appendChild(this);
}
}
customElements.define('my-clone_element_a', MyCloneElementA);
const original = document.createElement('my-clone_element_a');
$('#clone_container').cloneNode(true);
testing.expectEqual(2, calls);
}
</script>

View File

@@ -1329,9 +1329,18 @@ pub fn clone(self: *Element, deep: bool, page: *Page) !*Node {
var child_it = self.asNode().childrenIterator();
while (child_it.next()) |child| {
const cloned_child = try child.cloneNode(true, page);
if (cloned_child._parent != null) {
// This is almost always false, the only case where a cloned
// node would already have a parent is with a custom element
// that has a constructor (which is called during cloning) which
// inserts it somewhere. In that case, whatever parent was set
// in the constructor should not be changed.
continue;
}
// We pass `true` to `child_already_connected` as a hacky optimization
// We _know_ this child isn't connected (Becasue the parent isn't connected)
// setting this to `true` skips all connection checks and just assumes t
// We _know_ this child isn't connected (Because the parent isn't connected)
// setting this to `true` skips all connection checks.
try page.appendNode(node, cloned_child, .{ .child_already_connected = true });
}
}