mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 07:48:11 +00:00
LibWeb: Add style sheets to the shadow root if applicable
If a style element belongs to a shadow tree, its CSSStyleSheet is now added to the corresponding ShadowRoot instead of the document. Co-authored-by: Simon Wanner <simon+git@skyrising.xyz>
This commit is contained in:
parent
8ce8697a66
commit
c6e69d501f
7 changed files with 45 additions and 13 deletions
2
Tests/LibWeb/Text/expected/shadow-root-style-sheets.txt
Normal file
2
Tests/LibWeb/Text/expected/shadow-root-style-sheets.txt
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
shadow.styleSheets.length=1
|
||||||
|
document.styleSheets.length=0
|
18
Tests/LibWeb/Text/input/shadow-root-style-sheets.html
Normal file
18
Tests/LibWeb/Text/input/shadow-root-style-sheets.html
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
<script src="include.js"></script>
|
||||||
|
<my-custom-element></my-custom-element>
|
||||||
|
<script>
|
||||||
|
test(() => {
|
||||||
|
class MyCustomElement extends HTMLElement {
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
const shadow = this.attachShadow({ mode: 'open' });
|
||||||
|
const style = document.createElement('style');
|
||||||
|
shadow.appendChild(style);
|
||||||
|
println(`shadow.styleSheets.length=${shadow.styleSheets.length}`);
|
||||||
|
println(`document.styleSheets.length=${document.styleSheets.length}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
customElements.define('my-custom-element', MyCustomElement);
|
||||||
|
});
|
||||||
|
</script>
|
|
@ -2380,4 +2380,13 @@ auto Element::ensure_custom_element_reaction_queue() -> CustomElementReactionQue
|
||||||
return *m_custom_element_reaction_queue;
|
return *m_custom_element_reaction_queue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CSS::StyleSheetList& Element::document_or_shadow_root_style_sheets()
|
||||||
|
{
|
||||||
|
auto& root_node = root();
|
||||||
|
if (is<DOM::ShadowRoot>(root_node))
|
||||||
|
return static_cast<DOM::ShadowRoot&>(root_node).style_sheets();
|
||||||
|
|
||||||
|
return document().style_sheets();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -183,6 +183,8 @@ public:
|
||||||
|
|
||||||
CSS::CSSStyleDeclaration* style_for_bindings();
|
CSS::CSSStyleDeclaration* style_for_bindings();
|
||||||
|
|
||||||
|
CSS::StyleSheetList& document_or_shadow_root_style_sheets();
|
||||||
|
|
||||||
WebIDL::ExceptionOr<String> inner_html() const;
|
WebIDL::ExceptionOr<String> inner_html() const;
|
||||||
WebIDL::ExceptionOr<void> set_inner_html(StringView);
|
WebIDL::ExceptionOr<void> set_inner_html(StringView);
|
||||||
|
|
||||||
|
|
|
@ -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.
|
// 2. If element has an associated CSS style sheet, remove the CSS style sheet in question.
|
||||||
|
|
||||||
if (m_associated_css_style_sheet) {
|
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().
|
// FIXME: This should probably be handled by StyleSheet::set_owner_node().
|
||||||
m_associated_css_style_sheet = nullptr;
|
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...
|
// 6. Create a CSS style sheet with the following properties...
|
||||||
create_a_css_style_sheet(
|
create_a_css_style_sheet(
|
||||||
style_element.document(),
|
style_element.document_or_shadow_root_style_sheets(),
|
||||||
"text/css"_string,
|
"text/css"_string,
|
||||||
&style_element,
|
&style_element,
|
||||||
style_element.attribute(HTML::AttributeNames::media).value_or({}),
|
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
|
// 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.
|
// 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.
|
// 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);
|
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
|
// 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<String> 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<String> 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.
|
// 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.
|
// 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));
|
sheet.set_location(move(location));
|
||||||
|
|
||||||
// 2. Then run the add a CSS style sheet steps for the newly created CSS style sheet.
|
// 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
|
// 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.
|
// 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.
|
// 2. If the disabled flag is set, then return.
|
||||||
if (sheet.disabled())
|
if (sheet.disabled())
|
||||||
|
|
|
@ -20,9 +20,9 @@ public:
|
||||||
CSS::CSSStyleSheet const* sheet() const { return m_associated_css_style_sheet; }
|
CSS::CSSStyleSheet const* sheet() const { return m_associated_css_style_sheet; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void remove_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(DOM::Document& document, String type, DOM::Element* owner_node, String media, String title, bool alternate, bool origin_clean, Optional<String> location, CSS::CSSStyleSheet* parent_style_sheet, CSS::CSSRule* owner_rule, 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<String> 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 add_a_css_style_sheet(CSS::StyleSheetList&, CSS::CSSStyleSheet& sheet);
|
||||||
|
|
||||||
// https://www.w3.org/TR/cssom/#associated-css-style-sheet
|
// https://www.w3.org/TR/cssom/#associated-css-style-sheet
|
||||||
JS::GCPtr<CSS::CSSStyleSheet> m_associated_css_style_sheet;
|
JS::GCPtr<CSS::CSSStyleSheet> m_associated_css_style_sheet;
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
#include <LibWeb/CSS/Parser/Parser.h>
|
#include <LibWeb/CSS/Parser/Parser.h>
|
||||||
#include <LibWeb/DOM/Document.h>
|
#include <LibWeb/DOM/Document.h>
|
||||||
#include <LibWeb/DOM/Event.h>
|
#include <LibWeb/DOM/Event.h>
|
||||||
|
#include <LibWeb/DOM/ShadowRoot.h>
|
||||||
#include <LibWeb/Fetch/Fetching/Fetching.h>
|
#include <LibWeb/Fetch/Fetching/Fetching.h>
|
||||||
#include <LibWeb/Fetch/Infrastructure/FetchAlgorithms.h>
|
#include <LibWeb/Fetch/Infrastructure/FetchAlgorithms.h>
|
||||||
#include <LibWeb/Fetch/Infrastructure/HTTP/Requests.h>
|
#include <LibWeb/Fetch/Infrastructure/HTTP/Requests.h>
|
||||||
|
@ -112,7 +113,7 @@ void HTMLLinkElement::attribute_changed(FlyString const& name, Optional<String>
|
||||||
// FIXME: Handle alternate stylesheets properly
|
// FIXME: Handle alternate stylesheets properly
|
||||||
if (m_relationship & Relationship::Stylesheet && !(m_relationship & Relationship::Alternate)) {
|
if (m_relationship & Relationship::Stylesheet && !(m_relationship & Relationship::Alternate)) {
|
||||||
if (name == HTML::AttributeNames::disabled && m_loaded_style_sheet)
|
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
|
// 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:
|
// 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.
|
// 3. If el has an associated CSS style sheet, remove the CSS style sheet.
|
||||||
if (m_loaded_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;
|
m_loaded_style_sheet = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue