diff --git a/Tests/LibWeb/Text/expected/ShadowDOM/replace-declarative-shadow-root-with-style-sheet.txt b/Tests/LibWeb/Text/expected/ShadowDOM/replace-declarative-shadow-root-with-style-sheet.txt
new file mode 100644
index 0000000000..39701378c5
--- /dev/null
+++ b/Tests/LibWeb/Text/expected/ShadowDOM/replace-declarative-shadow-root-with-style-sheet.txt
@@ -0,0 +1 @@
+ PASS (didn't crash)
diff --git a/Tests/LibWeb/Text/input/ShadowDOM/replace-declarative-shadow-root-with-style-sheet.html b/Tests/LibWeb/Text/input/ShadowDOM/replace-declarative-shadow-root-with-style-sheet.html
new file mode 100644
index 0000000000..e9e64053ab
--- /dev/null
+++ b/Tests/LibWeb/Text/input/ShadowDOM/replace-declarative-shadow-root-with-style-sheet.html
@@ -0,0 +1,9 @@
+
+
+
diff --git a/Userland/Libraries/LibWeb/DOM/StyleElementUtils.cpp b/Userland/Libraries/LibWeb/DOM/StyleElementUtils.cpp
index fea12d0583..ba251894bd 100644
--- a/Userland/Libraries/LibWeb/DOM/StyleElementUtils.cpp
+++ b/Userland/Libraries/LibWeb/DOM/StyleElementUtils.cpp
@@ -13,15 +13,6 @@
namespace Web::DOM {
-static CSS::StyleSheetList& relevant_style_sheet_list_for_node(DOM::Node& node)
-{
- auto& root_node = node.root();
- if (is(root_node))
- return static_cast(root_node).style_sheets();
-
- return node.document().style_sheets();
-}
-
// The user agent must run the "update a style block" algorithm whenever one of the following conditions occur:
// FIXME: The element is popped off the stack of open elements of an HTML parser or XML parser.
//
@@ -32,7 +23,7 @@ static CSS::StyleSheetList& relevant_style_sheet_list_for_node(DOM::Node& node)
// The element is not on the stack of open elements of an HTML parser or XML parser, and it becomes connected or disconnected.
//
// https://html.spec.whatwg.org/multipage/semantics.html#update-a-style-block
-void StyleElementUtils::update_a_style_block(DOM::Element& style_element, JS::GCPtr old_parent_if_removed_from)
+void StyleElementUtils::update_a_style_block(DOM::Element& style_element)
{
// OPTIMIZATION: Skip parsing CSS if we're in the middle of parsing a HTML fragment.
// The style block will be parsed upon insertion into a proper document.
@@ -43,13 +34,8 @@ void StyleElementUtils::update_a_style_block(DOM::Element& style_element, JS::GC
// 2. If element has an associated CSS style sheet, remove the CSS style sheet in question.
if (m_associated_css_style_sheet) {
- // NOTE: If we're here in response to a node being removed from the tree, we need to remove the stylesheet from the style scope
- // of the old parent, not the style scope of the node itself, since it's too late to find it that way!
- if (old_parent_if_removed_from) {
- relevant_style_sheet_list_for_node(*old_parent_if_removed_from).remove_a_css_style_sheet(*m_associated_css_style_sheet);
- } else {
- style_element.document_or_shadow_root_style_sheets().remove_a_css_style_sheet(*m_associated_css_style_sheet);
- }
+ m_style_sheet_list->remove_a_css_style_sheet(*m_associated_css_style_sheet);
+ m_style_sheet_list = nullptr;
// FIXME: This should probably be handled by StyleSheet::set_owner_node().
m_associated_css_style_sheet = nullptr;
@@ -76,7 +62,8 @@ void StyleElementUtils::update_a_style_block(DOM::Element& style_element, JS::GC
m_associated_css_style_sheet = sheet;
// 6. Create a CSS style sheet with the following properties...
- style_element.document_or_shadow_root_style_sheets().create_a_css_style_sheet(
+ m_style_sheet_list = style_element.document_or_shadow_root_style_sheets();
+ m_style_sheet_list->create_a_css_style_sheet(
"text/css"_string,
&style_element,
style_element.attribute(HTML::AttributeNames::media).value_or({}),
@@ -91,4 +78,10 @@ void StyleElementUtils::update_a_style_block(DOM::Element& style_element, JS::GC
*sheet);
}
+void StyleElementUtils::visit_edges(JS::Cell::Visitor& visitor)
+{
+ visitor.visit(m_associated_css_style_sheet);
+ visitor.visit(m_style_sheet_list);
+}
+
}
diff --git a/Userland/Libraries/LibWeb/DOM/StyleElementUtils.h b/Userland/Libraries/LibWeb/DOM/StyleElementUtils.h
index f592dab7d8..d7e2fa1acd 100644
--- a/Userland/Libraries/LibWeb/DOM/StyleElementUtils.h
+++ b/Userland/Libraries/LibWeb/DOM/StyleElementUtils.h
@@ -14,19 +14,21 @@ namespace Web::DOM {
class StyleElementUtils {
public:
- void update_a_style_block(DOM::Element& style_element, JS::GCPtr old_parent_if_removed_from = nullptr);
+ void update_a_style_block(DOM::Element& style_element);
CSS::CSSStyleSheet* sheet() { return m_associated_css_style_sheet; }
CSS::CSSStyleSheet const* sheet() const { return m_associated_css_style_sheet; }
- void visit_edges(JS::Cell::Visitor& visitor)
- {
- visitor.visit(m_associated_css_style_sheet);
- }
+ [[nodiscard]] JS::GCPtr style_sheet_list() { return m_style_sheet_list; }
+ [[nodiscard]] JS::GCPtr style_sheet_list() const { return m_style_sheet_list; }
+
+ void visit_edges(JS::Cell::Visitor&);
private:
// https://www.w3.org/TR/cssom/#associated-css-style-sheet
JS::GCPtr m_associated_css_style_sheet;
+
+ JS::GCPtr m_style_sheet_list;
};
}
diff --git a/Userland/Libraries/LibWeb/HTML/HTMLStyleElement.cpp b/Userland/Libraries/LibWeb/HTML/HTMLStyleElement.cpp
index 693c7f7a46..84a1273159 100644
--- a/Userland/Libraries/LibWeb/HTML/HTMLStyleElement.cpp
+++ b/Userland/Libraries/LibWeb/HTML/HTMLStyleElement.cpp
@@ -46,7 +46,7 @@ void HTMLStyleElement::inserted()
void HTMLStyleElement::removed_from(Node* old_parent)
{
- m_style_element_utils.update_a_style_block(*this, old_parent);
+ m_style_element_utils.update_a_style_block(*this);
Base::removed_from(old_parent);
}
diff --git a/Userland/Libraries/LibWeb/SVG/SVGStyleElement.cpp b/Userland/Libraries/LibWeb/SVG/SVGStyleElement.cpp
index 6904e56658..7e41c25b3b 100644
--- a/Userland/Libraries/LibWeb/SVG/SVGStyleElement.cpp
+++ b/Userland/Libraries/LibWeb/SVG/SVGStyleElement.cpp
@@ -44,7 +44,7 @@ void SVGStyleElement::inserted()
void SVGStyleElement::removed_from(Node* old_parent)
{
- m_style_element_utils.update_a_style_block(*this, old_parent);
+ m_style_element_utils.update_a_style_block(*this);
Base::removed_from(old_parent);
}