LibWeb/HTML: Handle no parent element for Element::list_owner

Fixes a crash when running Speedometer 3.0 as reduced in the included
test case.
This commit is contained in:
Shannon Booth 2025-04-18 17:07:41 +12:00
parent b88fddbf47
commit 41d8b8a1ec
2 changed files with 20 additions and 1 deletions

View file

@ -3153,6 +3153,10 @@ Element const* Element::list_owner() const
// 2. Let ancestor be the element's parent.
auto const* ancestor = parent_element();
// AC-HOC: There may not be any parent element in a shadow tree.
if (!ancestor)
return nullptr;
// 3. If the element has an ol, ul, or menu ancestor, set ancestor to the closest such ancestor element.
for_each_ancestor([&ancestor](GC::Ref<Node> node) {
if (is<HTML::HTMLOListElement>(*node) || is<HTML::HTMLUListElement>(*node) || is<HTML::HTMLMenuElement>(*node)) {
@ -3163,7 +3167,6 @@ Element const* Element::list_owner() const
});
// 4. Return the closest inclusive ancestor of ancestor that produces a CSS box.
// Spec-Note: Such an element will always exist, as at the very least the document element will always produce a CSS box.
ancestor->for_each_inclusive_ancestor([&ancestor](GC::Ref<Node> node) {
if (is<Element>(*node) && node->paintable_box()) {
ancestor = static_cast<Element const*>(node.ptr());

View file

@ -0,0 +1,16 @@
<todo-item></todo-item>
<script>
const template = document.createElement("template");
template.innerHTML = `<li></li>`;
class TodoItem extends HTMLElement {
constructor() {
super();
const shadow = this.attachShadow({ mode: "open" });
const node = document.importNode(template.content, true);
shadow.appendChild(node);
}
}
customElements.define("todo-item", TodoItem);
</script>