getRootNode composed support

This commit is contained in:
Karl Seguin
2025-12-05 18:11:45 +08:00
parent 8e16c587c8
commit 637a105e5d
2 changed files with 33 additions and 3 deletions

View File

@@ -189,3 +189,24 @@
testing.expectEqual(8, Node.COMMENT_NODE);
testing.expectEqual(11, Node.DOCUMENT_FRAGMENT_NODE);
</script>
<div id="rootNodeComposed"></div>
<script id=getRootNodeComposed>
const testContainer = $('#rootNodeComposed');
const shadowHost = document.createElement('div');
testContainer.appendChild(shadowHost);
const shadowRoot = shadowHost.attachShadow({ mode: 'open' });
const shadowChild = document.createElement('span');
shadowRoot.appendChild(shadowChild);
testing.expectEqual('ShadowRoot', shadowChild.getRootNode().__proto__.constructor.name);
testing.expectEqual('ShadowRoot', shadowChild.getRootNode({ composed: false }).__proto__.constructor.name);
testing.expectEqual('HTMLDocument', shadowChild.getRootNode({ composed: true }).__proto__.constructor.name);
testing.expectEqual('HTMLDocument', shadowHost.getRootNode().__proto__.constructor.name);
const disconnected = document.createElement('div');
const disconnectedChild = document.createElement('span');
disconnected.appendChild(disconnectedChild);
testing.expectEqual('HTMLDivElement', disconnectedChild.getRootNode().__proto__.constructor.name);
testing.expectEqual('HTMLDivElement', disconnectedChild.getRootNode({ composed: true }).__proto__.constructor.name);
</script>

View File

@@ -259,14 +259,23 @@ const GetRootNodeOpts = struct {
};
pub fn getRootNode(self: *const Node, opts_: ?GetRootNodeOpts) *const Node {
const opts = opts_ orelse GetRootNodeOpts{};
if (opts.composed) {
log.warn(.not_implemented, "Node.getRootNode", .{ .feature = "composed" });
}
var root = self;
while (root._parent) |parent| {
root = parent;
}
// If composed is true, traverse through shadow boundaries
if (opts.composed) {
while (true) {
const shadow_root = @constCast(root).is(ShadowRoot) orelse break;
root = shadow_root.getHost().asNode();
while (root._parent) |parent| {
root = parent;
}
}
}
return root;
}