diff --git a/Tests/LibWeb/Text/expected/shadow-root-style-sheets.txt b/Tests/LibWeb/Text/expected/shadow-root-style-sheets.txt
new file mode 100644
index 0000000000..a254fbf7ca
--- /dev/null
+++ b/Tests/LibWeb/Text/expected/shadow-root-style-sheets.txt
@@ -0,0 +1,2 @@
+ shadow.styleSheets.length=1
+document.styleSheets.length=0
diff --git a/Tests/LibWeb/Text/input/shadow-root-style-sheets.html b/Tests/LibWeb/Text/input/shadow-root-style-sheets.html
new file mode 100644
index 0000000000..7b1d361a24
--- /dev/null
+++ b/Tests/LibWeb/Text/input/shadow-root-style-sheets.html
@@ -0,0 +1,18 @@
+
+
+
diff --git a/Userland/Libraries/LibWeb/DOM/Element.cpp b/Userland/Libraries/LibWeb/DOM/Element.cpp
index 2199d6c80c..8f32b12102 100644
--- a/Userland/Libraries/LibWeb/DOM/Element.cpp
+++ b/Userland/Libraries/LibWeb/DOM/Element.cpp
@@ -2380,4 +2380,13 @@ auto Element::ensure_custom_element_reaction_queue() -> CustomElementReactionQue
return *m_custom_element_reaction_queue;
}
+CSS::StyleSheetList& Element::document_or_shadow_root_style_sheets()
+{
+ auto& root_node = root();
+ if (is(root_node))
+ return static_cast(root_node).style_sheets();
+
+ return document().style_sheets();
+}
+
}
diff --git a/Userland/Libraries/LibWeb/DOM/Element.h b/Userland/Libraries/LibWeb/DOM/Element.h
index 884e6c7001..904de8fe33 100644
--- a/Userland/Libraries/LibWeb/DOM/Element.h
+++ b/Userland/Libraries/LibWeb/DOM/Element.h
@@ -183,6 +183,8 @@ public:
CSS::CSSStyleDeclaration* style_for_bindings();
+ CSS::StyleSheetList& document_or_shadow_root_style_sheets();
+
WebIDL::ExceptionOr inner_html() const;
WebIDL::ExceptionOr set_inner_html(StringView);
diff --git a/Userland/Libraries/LibWeb/DOM/StyleElementUtils.cpp b/Userland/Libraries/LibWeb/DOM/StyleElementUtils.cpp
index 377d9775f3..8e24e58fcd 100644
--- a/Userland/Libraries/LibWeb/DOM/StyleElementUtils.cpp
+++ b/Userland/Libraries/LibWeb/DOM/StyleElementUtils.cpp
@@ -33,7 +33,7 @@ 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) {
- remove_a_css_style_sheet(style_element.document(), *m_associated_css_style_sheet);
+ remove_a_css_style_sheet(style_element.document_or_shadow_root_style_sheets(), *m_associated_css_style_sheet);
// FIXME: This should probably be handled by StyleSheet::set_owner_node().
m_associated_css_style_sheet = nullptr;
@@ -61,7 +61,7 @@ void StyleElementUtils::update_a_style_block(DOM::Element& style_element)
// 6. Create a CSS style sheet with the following properties...
create_a_css_style_sheet(
- style_element.document(),
+ style_element.document_or_shadow_root_style_sheets(),
"text/css"_string,
&style_element,
style_element.attribute(HTML::AttributeNames::media).value_or({}),
@@ -77,10 +77,10 @@ void StyleElementUtils::update_a_style_block(DOM::Element& style_element)
}
// https://www.w3.org/TR/cssom/#remove-a-css-style-sheet
-void StyleElementUtils::remove_a_css_style_sheet(DOM::Document& document, CSS::CSSStyleSheet& sheet)
+void StyleElementUtils::remove_a_css_style_sheet(CSS::StyleSheetList& style_sheets, CSS::CSSStyleSheet& sheet)
{
// 1. Remove the CSS style sheet from the list of document or shadow root CSS style sheets.
- document.style_sheets().remove_sheet(sheet);
+ style_sheets.remove_sheet(sheet);
// 2. Set the CSS style sheet’s parent CSS style sheet, owner node and owner CSS rule to null.
sheet.set_parent_css_style_sheet(nullptr);
@@ -89,7 +89,7 @@ void StyleElementUtils::remove_a_css_style_sheet(DOM::Document& document, CSS::C
}
// https://www.w3.org/TR/cssom/#create-a-css-style-sheet
-void StyleElementUtils::create_a_css_style_sheet(DOM::Document& document, String type, DOM::Element* owner_node, String media, String title, bool alternate, bool origin_clean, Optional location, CSS::CSSStyleSheet* parent_style_sheet, CSS::CSSRule* owner_rule, CSS::CSSStyleSheet& sheet)
+void StyleElementUtils::create_a_css_style_sheet(CSS::StyleSheetList& style_sheets, String type, DOM::Element* owner_node, String media, String title, bool alternate, bool origin_clean, Optional location, CSS::CSSStyleSheet* parent_style_sheet, CSS::CSSRule* owner_rule, CSS::CSSStyleSheet& sheet)
{
// 1. Create a new CSS style sheet object and set its properties as specified.
// FIXME: We receive `sheet` from the caller already. This is weird.
@@ -105,14 +105,14 @@ void StyleElementUtils::create_a_css_style_sheet(DOM::Document& document, String
sheet.set_location(move(location));
// 2. Then run the add a CSS style sheet steps for the newly created CSS style sheet.
- add_a_css_style_sheet(document, sheet);
+ add_a_css_style_sheet(style_sheets, sheet);
}
// https://www.w3.org/TR/cssom/#add-a-css-style-sheet
-void StyleElementUtils::add_a_css_style_sheet(DOM::Document& document, CSS::CSSStyleSheet& sheet)
+void StyleElementUtils::add_a_css_style_sheet(CSS::StyleSheetList& style_sheets, CSS::CSSStyleSheet& sheet)
{
// 1. Add the CSS style sheet to the list of document or shadow root CSS style sheets at the appropriate location. The remainder of these steps deal with the disabled flag.
- document.style_sheets().add_sheet(sheet);
+ style_sheets.add_sheet(sheet);
// 2. If the disabled flag is set, then return.
if (sheet.disabled())
diff --git a/Userland/Libraries/LibWeb/DOM/StyleElementUtils.h b/Userland/Libraries/LibWeb/DOM/StyleElementUtils.h
index c2298a657b..cfa5771934 100644
--- a/Userland/Libraries/LibWeb/DOM/StyleElementUtils.h
+++ b/Userland/Libraries/LibWeb/DOM/StyleElementUtils.h
@@ -20,9 +20,9 @@ public:
CSS::CSSStyleSheet const* sheet() const { return m_associated_css_style_sheet; }
private:
- void remove_a_css_style_sheet(DOM::Document& document, CSS::CSSStyleSheet& sheet);
- void create_a_css_style_sheet(DOM::Document& document, String type, DOM::Element* owner_node, String media, String title, bool alternate, bool origin_clean, Optional location, CSS::CSSStyleSheet* parent_style_sheet, CSS::CSSRule* owner_rule, CSS::CSSStyleSheet& sheet);
- void add_a_css_style_sheet(DOM::Document& document, CSS::CSSStyleSheet& sheet);
+ void remove_a_css_style_sheet(CSS::StyleSheetList&, CSS::CSSStyleSheet& sheet);
+ void create_a_css_style_sheet(CSS::StyleSheetList&, String type, DOM::Element* owner_node, String media, String title, bool alternate, bool origin_clean, Optional location, CSS::CSSStyleSheet* parent_style_sheet, CSS::CSSRule* owner_rule, CSS::CSSStyleSheet& sheet);
+ void add_a_css_style_sheet(CSS::StyleSheetList&, CSS::CSSStyleSheet& sheet);
// https://www.w3.org/TR/cssom/#associated-css-style-sheet
JS::GCPtr m_associated_css_style_sheet;
diff --git a/Userland/Libraries/LibWeb/HTML/HTMLLinkElement.cpp b/Userland/Libraries/LibWeb/HTML/HTMLLinkElement.cpp
index a199e2450b..5d1e03db36 100644
--- a/Userland/Libraries/LibWeb/HTML/HTMLLinkElement.cpp
+++ b/Userland/Libraries/LibWeb/HTML/HTMLLinkElement.cpp
@@ -14,6 +14,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -112,7 +113,7 @@ void HTMLLinkElement::attribute_changed(FlyString const& name, Optional
// FIXME: Handle alternate stylesheets properly
if (m_relationship & Relationship::Stylesheet && !(m_relationship & Relationship::Alternate)) {
if (name == HTML::AttributeNames::disabled && m_loaded_style_sheet)
- document().style_sheets().remove_sheet(*m_loaded_style_sheet);
+ document_or_shadow_root_style_sheets().remove_sheet(*m_loaded_style_sheet);
// https://html.spec.whatwg.org/multipage/links.html#link-type-stylesheet:fetch-and-process-the-linked-resource
// The appropriate times to fetch and process this type of link are:
@@ -311,7 +312,7 @@ void HTMLLinkElement::process_stylesheet_resource(bool success, Fetch::Infrastru
// 3. If el has an associated CSS style sheet, remove the CSS style sheet.
if (m_loaded_style_sheet) {
- document().style_sheets().remove_sheet(*m_loaded_style_sheet);
+ document_or_shadow_root_style_sheets().remove_sheet(*m_loaded_style_sheet);
m_loaded_style_sheet = nullptr;
}