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); }