diff --git a/Tests/LibWeb/Text/expected/ShadowDOM/remove-style-element-inside-shadow-tree.txt b/Tests/LibWeb/Text/expected/ShadowDOM/remove-style-element-inside-shadow-tree.txt
new file mode 100644
index 00000000000..b5528437c81
--- /dev/null
+++ b/Tests/LibWeb/Text/expected/ShadowDOM/remove-style-element-inside-shadow-tree.txt
@@ -0,0 +1,4 @@
+ hello [object StyleSheetList]
+Before remove, sheet count: 1
+After remove, sheet count: 0
+After setting innerText of removed sheet, we're still alive!
diff --git a/Tests/LibWeb/Text/input/ShadowDOM/remove-style-element-inside-shadow-tree.html b/Tests/LibWeb/Text/input/ShadowDOM/remove-style-element-inside-shadow-tree.html
new file mode 100644
index 00000000000..c5642083f25
--- /dev/null
+++ b/Tests/LibWeb/Text/input/ShadowDOM/remove-style-element-inside-shadow-tree.html
@@ -0,0 +1,20 @@
+
+
+
diff --git a/Userland/Libraries/LibWeb/DOM/StyleElementUtils.cpp b/Userland/Libraries/LibWeb/DOM/StyleElementUtils.cpp
index 539fa45d26c..fea12d0583b 100644
--- a/Userland/Libraries/LibWeb/DOM/StyleElementUtils.cpp
+++ b/Userland/Libraries/LibWeb/DOM/StyleElementUtils.cpp
@@ -7,11 +7,21 @@
#include
#include
#include
+#include
#include
#include
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.
//
@@ -22,7 +32,7 @@ namespace Web::DOM {
// 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)
+void StyleElementUtils::update_a_style_block(DOM::Element& style_element, JS::GCPtr old_parent_if_removed_from)
{
// 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.
@@ -33,7 +43,13 @@ void StyleElementUtils::update_a_style_block(DOM::Element& style_element)
// 2. If element has an associated CSS style sheet, remove the CSS style sheet in question.
if (m_associated_css_style_sheet) {
- style_element.document_or_shadow_root_style_sheets().remove_a_css_style_sheet(*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);
+ }
// FIXME: This should probably be handled by StyleSheet::set_owner_node().
m_associated_css_style_sheet = nullptr;
diff --git a/Userland/Libraries/LibWeb/DOM/StyleElementUtils.h b/Userland/Libraries/LibWeb/DOM/StyleElementUtils.h
index 14d3d06db57..f0879ff36c1 100644
--- a/Userland/Libraries/LibWeb/DOM/StyleElementUtils.h
+++ b/Userland/Libraries/LibWeb/DOM/StyleElementUtils.h
@@ -14,7 +14,7 @@ namespace Web::DOM {
class StyleElementUtils {
public:
- void update_a_style_block(DOM::Element& style_element);
+ void update_a_style_block(DOM::Element& style_element, JS::GCPtr old_parent_if_removed_from = nullptr);
CSS::CSSStyleSheet* sheet() { return m_associated_css_style_sheet; }
CSS::CSSStyleSheet const* sheet() const { return m_associated_css_style_sheet; }
diff --git a/Userland/Libraries/LibWeb/HTML/HTMLStyleElement.cpp b/Userland/Libraries/LibWeb/HTML/HTMLStyleElement.cpp
index c3ab7b4e060..33126fb0bb0 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);
+ m_style_element_utils.update_a_style_block(*this, old_parent);
Base::removed_from(old_parent);
}
diff --git a/Userland/Libraries/LibWeb/SVG/SVGStyleElement.cpp b/Userland/Libraries/LibWeb/SVG/SVGStyleElement.cpp
index 983e9bd7081..86ee2fd8b4c 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);
+ m_style_element_utils.update_a_style_block(*this, old_parent);
Base::removed_from(old_parent);
}