diff --git a/Userland/Libraries/LibWeb/CSS/StyleComputer.cpp b/Userland/Libraries/LibWeb/CSS/StyleComputer.cpp index 61e51e45a98fb5..b2dafd7d9aa3e5 100644 --- a/Userland/Libraries/LibWeb/CSS/StyleComputer.cpp +++ b/Userland/Libraries/LibWeb/CSS/StyleComputer.cpp @@ -1,7 +1,7 @@ /* * Copyright (c) 2018-2023, Andreas Kling * Copyright (c) 2021, the SerenityOS developers. - * Copyright (c) 2021-2023, Sam Atkins + * Copyright (c) 2021-2024, Sam Atkins * Copyright (c) 2024, Matthew Olsson * * SPDX-License-Identifier: BSD-2-Clause @@ -260,6 +260,24 @@ static CSSStyleSheet& svg_stylesheet(DOM::Document const& document) return *sheet; } +Optional StyleComputer::user_agent_style_sheet_source(StringView name) +{ + extern String default_stylesheet_source; + extern String quirks_mode_stylesheet_source; + extern String mathml_stylesheet_source; + extern String svg_stylesheet_source; + + if (name == "CSS/Default.css"sv) + return default_stylesheet_source; + if (name == "CSS/QuirksMode.css"sv) + return quirks_mode_stylesheet_source; + if (name == "MathML/Default.css"sv) + return mathml_stylesheet_source; + if (name == "SVG/Default.css"sv) + return svg_stylesheet_source; + return {}; +} + template void StyleComputer::for_each_stylesheet(CascadeOrigin cascade_origin, Callback callback) const { diff --git a/Userland/Libraries/LibWeb/CSS/StyleComputer.h b/Userland/Libraries/LibWeb/CSS/StyleComputer.h index 9ac1c8fda9aed3..408098caca8e81 100644 --- a/Userland/Libraries/LibWeb/CSS/StyleComputer.h +++ b/Userland/Libraries/LibWeb/CSS/StyleComputer.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2018-2024, Andreas Kling - * Copyright (c) 2021-2023, Sam Atkins + * Copyright (c) 2021-2024, Sam Atkins * * SPDX-License-Identifier: BSD-2-Clause */ @@ -117,6 +117,8 @@ class StyleComputer { static void set_property_expanding_shorthands(StyleProperties&, PropertyID, CSSStyleValue const&, CSS::CSSStyleDeclaration const*, StyleProperties const& style_for_revert, StyleProperties const& style_for_revert_layer, Important = Important::No); static NonnullRefPtr get_inherit_value(JS::Realm& initial_value_context_realm, CSS::PropertyID, DOM::Element const*, Optional = {}); + static Optional user_agent_style_sheet_source(StringView name); + explicit StyleComputer(DOM::Document&); ~StyleComputer(); diff --git a/Userland/Libraries/LibWeb/DOM/Document.cpp b/Userland/Libraries/LibWeb/DOM/Document.cpp index d884b2267051cb..d81d271dc77d08 100644 --- a/Userland/Libraries/LibWeb/DOM/Document.cpp +++ b/Userland/Libraries/LibWeb/DOM/Document.cpp @@ -2,7 +2,7 @@ * Copyright (c) 2018-2024, Andreas Kling * Copyright (c) 2021-2023, Linus Groh * Copyright (c) 2021-2023, Luke Wilde - * Copyright (c) 2021-2023, Sam Atkins + * Copyright (c) 2021-2024, Sam Atkins * Copyright (c) 2024, Matthew Olsson * * SPDX-License-Identifier: BSD-2-Clause @@ -26,10 +26,12 @@ #include #include #include +#include #include #include #include #include +#include #include #include #include @@ -84,6 +86,7 @@ #include #include #include +#include #include #include #include @@ -119,8 +122,8 @@ #include #include #include +#include #include -#include #include #include #include @@ -5168,6 +5171,75 @@ void Document::for_each_active_css_style_sheet(Function find_style_sheet_with_url(String const& url, CSS::CSSStyleSheet& style_sheet) +{ + if (style_sheet.location() == url) + return style_sheet; + + for (auto& import_rule : style_sheet.import_rules()) { + if (import_rule->loaded_style_sheet()) { + if (auto match = find_style_sheet_with_url(url, *import_rule->loaded_style_sheet()); match.has_value()) + return match; + } + } + + return {}; +} + +Optional Document::get_style_sheet_source(CSS::StyleSheetIdentifier const& identifier) const +{ + switch (identifier.type) { + case CSS::StyleSheetIdentifier::Type::StyleElement: + if (identifier.dom_element_unique_id.has_value()) { + if (auto* node = Node::from_unique_id(*identifier.dom_element_unique_id)) { + if (node->is_html_style_element()) { + if (auto* sheet = verify_cast(*node).sheet()) + return sheet->source_text({}); + } + if (node->is_svg_style_element()) { + if (auto* sheet = verify_cast(*node).sheet()) + return sheet->source_text({}); + } + } + } + return {}; + case CSS::StyleSheetIdentifier::Type::LinkElement: + case CSS::StyleSheetIdentifier::Type::ImportRule: { + if (!identifier.url.has_value()) { + dbgln("Attempting to get link or imported style-sheet with no url; giving up"); + return {}; + } + + if (m_style_sheets) { + for (auto& style_sheet : m_style_sheets->sheets()) { + if (auto match = find_style_sheet_with_url(identifier.url.value(), style_sheet); match.has_value()) + return match->source_text({}); + } + } + + if (m_adopted_style_sheets) { + Optional result; + m_adopted_style_sheets->for_each([&](auto& style_sheet) { + if (result.has_value()) + return; + + if (auto match = find_style_sheet_with_url(identifier.url.value(), style_sheet); match.has_value()) + result = match->source_text({}); + }); + return result; + } + + return {}; + } + case CSS::StyleSheetIdentifier::Type::UserAgent: + return CSS::StyleComputer::user_agent_style_sheet_source(identifier.url.value()); + case CSS::StyleSheetIdentifier::Type::UserStyle: + return page().user_style(); + } + + return {}; +} + void Document::register_shadow_root(Badge, DOM::ShadowRoot& shadow_root) { m_shadow_roots.append(shadow_root); diff --git a/Userland/Libraries/LibWeb/DOM/Document.h b/Userland/Libraries/LibWeb/DOM/Document.h index c230322c478301..11006f18336b8b 100644 --- a/Userland/Libraries/LibWeb/DOM/Document.h +++ b/Userland/Libraries/LibWeb/DOM/Document.h @@ -164,6 +164,8 @@ class Document CSS::StyleSheetList* style_sheets_for_bindings() { return &style_sheets(); } + Optional get_style_sheet_source(CSS::StyleSheetIdentifier const&) const; + virtual FlyString node_name() const override { return "#document"_fly_string; } void set_hovered_node(Node*);