LibWeb: Do not assume a shadow root has a host

After commit ff48b7333c, we remove shadow
roots from elements that are removed from the DOM. Setting a node's
shadow root to null also sets that shadow root's host to null. Thus, the
comment in Node::is_shadow_including_descendant_of that assumes the host
is always non-null is not true.

The test added here would previously crash when interacting with a node
that is a descendant of a removed shadow root.
This commit is contained in:
Timothy Flynn 2023-12-03 14:34:53 -05:00 committed by Andreas Kling
parent fd297a3248
commit 18a4455d43
Notes: sideshowbarker 2024-07-17 05:09:48 +09:00
3 changed files with 35 additions and 2 deletions

View file

@ -0,0 +1,20 @@
Viewport <#document> at (0,0) content-size 800x600 children: not-inline
BlockContainer <html> at (0,0) content-size 800x600 [BFC] children: not-inline
BlockContainer <body> at (8,8) content-size 784x17.46875 children: not-inline
BlockContainer <div#container> at (8,8) content-size 784x17.46875 children: inline
line 0 width: 43.421875, height: 17.46875, bottom: 17.46875, baseline: 13.53125
frag 0 from TextNode start: 0, length: 5, rect: [8,8 43.421875x17.46875]
"Pass!"
InlineNode <span>
TextNode <#text>
BlockContainer <(anonymous)> at (8,25.46875) content-size 784x0 children: inline
TextNode <#text>
TextNode <#text>
ViewportPaintable (Viewport<#document>) [0,0 800x600]
PaintableWithLines (BlockContainer<HTML>) [0,0 800x600]
PaintableWithLines (BlockContainer<BODY>) [8,8 784x17.46875]
PaintableWithLines (BlockContainer<DIV>#container) [8,8 784x17.46875]
InlinePaintable (InlineNode<SPAN>)
TextPaintable (TextNode<#text>)
PaintableWithLines (BlockContainer(anonymous)) [8,25.46875 784x0]

View file

@ -0,0 +1,14 @@
<div id=container>
<details open>
<summary>summary</summary>
<span id=node></span>
</details>
</div>
<script type="text/javascript">
let node = document.getElementById("node");
let container = document.getElementById("container");
container.innerHTML = "<span>Pass!</span>";
node.click();
</script>

View file

@ -1259,8 +1259,7 @@ bool Node::is_shadow_including_descendant_of(Node const& other) const
// and As roots host is a shadow-including inclusive descendant of B.
auto& shadow_root = verify_cast<ShadowRoot>(root());
// NOTE: While host is nullable because of inheriting from DocumentFragment, shadow roots always have a host.
return shadow_root.host()->is_shadow_including_inclusive_descendant_of(other);
return shadow_root.host() && shadow_root.host()->is_shadow_including_inclusive_descendant_of(other);
}
// https://dom.spec.whatwg.org/#concept-shadow-including-inclusive-descendant