From 1c6133aa523fe29c25b11284d8b3353de0a03c0f Mon Sep 17 00:00:00 2001 From: Sam Atkins Date: Mon, 2 Sep 2024 16:45:25 +0100 Subject: [PATCH] LibWeb/CSS: Add CSSOM types for `@layer` rules Depending on usage, `@layer` has two forms, with two different CSSOM types. One simply lists layer names and the other defines a layer with its contained rules. --- .../Userland/Libraries/LibWeb/CSS/BUILD.gn | 2 + .../Userland/Libraries/LibWeb/idl_files.gni | 2 + .../Text/expected/all-window-properties.txt | 2 + Userland/Libraries/LibWeb/CMakeLists.txt | 2 + .../LibWeb/CSS/CSSLayerBlockRule.cpp | 81 +++++++++++++++++++ .../Libraries/LibWeb/CSS/CSSLayerBlockRule.h | 41 ++++++++++ .../LibWeb/CSS/CSSLayerBlockRule.idl | 7 ++ .../LibWeb/CSS/CSSLayerStatementRule.cpp | 58 +++++++++++++ .../LibWeb/CSS/CSSLayerStatementRule.h | 38 +++++++++ .../LibWeb/CSS/CSSLayerStatementRule.idl | 8 ++ Userland/Libraries/LibWeb/CSS/CSSRule.cpp | 36 ++++++++- Userland/Libraries/LibWeb/CSS/CSSRule.h | 6 ++ Userland/Libraries/LibWeb/CSS/CSSRuleList.cpp | 47 ++++++----- Userland/Libraries/LibWeb/Dump.cpp | 37 +++++++-- Userland/Libraries/LibWeb/Dump.h | 2 + Userland/Libraries/LibWeb/Forward.h | 2 + Userland/Libraries/LibWeb/idl_files.cmake | 2 + 17 files changed, 346 insertions(+), 27 deletions(-) create mode 100644 Userland/Libraries/LibWeb/CSS/CSSLayerBlockRule.cpp create mode 100644 Userland/Libraries/LibWeb/CSS/CSSLayerBlockRule.h create mode 100644 Userland/Libraries/LibWeb/CSS/CSSLayerBlockRule.idl create mode 100644 Userland/Libraries/LibWeb/CSS/CSSLayerStatementRule.cpp create mode 100644 Userland/Libraries/LibWeb/CSS/CSSLayerStatementRule.h create mode 100644 Userland/Libraries/LibWeb/CSS/CSSLayerStatementRule.idl diff --git a/Meta/gn/secondary/Userland/Libraries/LibWeb/CSS/BUILD.gn b/Meta/gn/secondary/Userland/Libraries/LibWeb/CSS/BUILD.gn index 32a432fdabd..b46d00d4d9e 100644 --- a/Meta/gn/secondary/Userland/Libraries/LibWeb/CSS/BUILD.gn +++ b/Meta/gn/secondary/Userland/Libraries/LibWeb/CSS/BUILD.gn @@ -17,6 +17,8 @@ source_set("CSS") { "CSSImportRule.cpp", "CSSKeyframeRule.cpp", "CSSKeyframesRule.cpp", + "CSSLayerBlockRule.cpp", + "CSSLayerStatementRule.cpp", "CSSMediaRule.cpp", "CSSNamespaceRule.cpp", "CSSNumericType.cpp", diff --git a/Meta/gn/secondary/Userland/Libraries/LibWeb/idl_files.gni b/Meta/gn/secondary/Userland/Libraries/LibWeb/idl_files.gni index 1311d66401a..c948a6b20ee 100644 --- a/Meta/gn/secondary/Userland/Libraries/LibWeb/idl_files.gni +++ b/Meta/gn/secondary/Userland/Libraries/LibWeb/idl_files.gni @@ -37,6 +37,8 @@ standard_idl_files = [ "//Userland/Libraries/LibWeb/CSS/CSSImportRule.idl", "//Userland/Libraries/LibWeb/CSS/CSSKeyframeRule.idl", "//Userland/Libraries/LibWeb/CSS/CSSKeyframesRule.idl", + "//Userland/Libraries/LibWeb/CSS/CSSLayerBlockRule.idl", + "//Userland/Libraries/LibWeb/CSS/CSSLayerStatementRule.idl", "//Userland/Libraries/LibWeb/CSS/CSSMediaRule.idl", "//Userland/Libraries/LibWeb/CSS/CSSNamespaceRule.idl", "//Userland/Libraries/LibWeb/CSS/CSSRule.idl", diff --git a/Tests/LibWeb/Text/expected/all-window-properties.txt b/Tests/LibWeb/Text/expected/all-window-properties.txt index d19780bfb28..22eac7d605d 100644 --- a/Tests/LibWeb/Text/expected/all-window-properties.txt +++ b/Tests/LibWeb/Text/expected/all-window-properties.txt @@ -37,6 +37,8 @@ CSSGroupingRule CSSImportRule CSSKeyframeRule CSSKeyframesRule +CSSLayerBlockRule +CSSLayerStatementRule CSSMediaRule CSSNamespaceRule CSSRule diff --git a/Userland/Libraries/LibWeb/CMakeLists.txt b/Userland/Libraries/LibWeb/CMakeLists.txt index 2bacaf65ea5..c38d2f065e5 100644 --- a/Userland/Libraries/LibWeb/CMakeLists.txt +++ b/Userland/Libraries/LibWeb/CMakeLists.txt @@ -44,6 +44,8 @@ set(SOURCES CSS/CSSKeyframeRule.cpp CSS/CSSKeyframesRule.cpp CSS/CSSFontFaceRule.cpp + CSS/CSSLayerBlockRule.cpp + CSS/CSSLayerStatementRule.cpp CSS/CSSMediaRule.cpp CSS/CSSNumericType.cpp CSS/CSSNamespaceRule.cpp diff --git a/Userland/Libraries/LibWeb/CSS/CSSLayerBlockRule.cpp b/Userland/Libraries/LibWeb/CSS/CSSLayerBlockRule.cpp new file mode 100644 index 00000000000..475f91da24e --- /dev/null +++ b/Userland/Libraries/LibWeb/CSS/CSSLayerBlockRule.cpp @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2024, Sam Atkins + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include "CSSLayerBlockRule.h" +#include +#include +#include + +namespace Web::CSS { + +JS_DEFINE_ALLOCATOR(CSSLayerBlockRule); + +JS::NonnullGCPtr CSSLayerBlockRule::create(JS::Realm& realm, FlyString name, CSSRuleList& rules) +{ + return realm.heap().allocate(realm, realm, move(name), rules); +} + +FlyString CSSLayerBlockRule::next_unique_anonymous_layer_name() +{ + static u64 s_anonymous_layer_id = 0; + return MUST(String::formatted("#{}", ++s_anonymous_layer_id)); +} + +CSSLayerBlockRule::CSSLayerBlockRule(JS::Realm& realm, FlyString name, CSSRuleList& rules) + : CSSGroupingRule(realm, rules) + , m_name(move(name)) +{ + if (m_name.is_empty()) { + m_name_internal = next_unique_anonymous_layer_name(); + } else { + m_name_internal = m_name; + } +} + +void CSSLayerBlockRule::initialize(JS::Realm& realm) +{ + Base::initialize(realm); + WEB_SET_PROTOTYPE_FOR_INTERFACE(CSSLayerBlockRule); +} + +String CSSLayerBlockRule::serialized() const +{ + // AD-HOC: No spec yet, so this is based on the @media serialization algorithm. + StringBuilder builder; + builder.append("@layer"sv); + if (!m_name.is_empty()) + builder.appendff(" {}", m_name); + + builder.append(" {\n"sv); + // AD-HOC: All modern browsers omit the ending newline if there are no CSS rules, so let's do the same. + if (css_rules().length() == 0) { + builder.append('}'); + return builder.to_string_without_validation(); + } + + for (size_t i = 0; i < css_rules().length(); i++) { + auto rule = css_rules().item(i); + if (i != 0) + builder.append("\n"sv); + builder.append(" "sv); + builder.append(rule->css_text()); + } + + builder.append("\n}"sv); + + return builder.to_string_without_validation(); +} + +FlyString CSSLayerBlockRule::internal_qualified_name(Badge) const +{ + // TODO: Cache this? + auto parent_name = parent_layer_internal_qualified_name(); + if (parent_name.is_empty()) + return m_name_internal; + return MUST(String::formatted("{}.{}", parent_name, m_name_internal)); +} + +} diff --git a/Userland/Libraries/LibWeb/CSS/CSSLayerBlockRule.h b/Userland/Libraries/LibWeb/CSS/CSSLayerBlockRule.h new file mode 100644 index 00000000000..0d73dca2304 --- /dev/null +++ b/Userland/Libraries/LibWeb/CSS/CSSLayerBlockRule.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2024, Sam Atkins + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include + +namespace Web::CSS { + +// https://drafts.csswg.org/css-cascade-5/#the-csslayerblockrule-interface +class CSSLayerBlockRule final : public CSSGroupingRule { + WEB_PLATFORM_OBJECT(CSSLayerBlockRule, CSSGroupingRule); + JS_DECLARE_ALLOCATOR(CSSLayerBlockRule); + +public: + [[nodiscard]] static JS::NonnullGCPtr create(JS::Realm&, FlyString name, CSSRuleList&); + + static FlyString next_unique_anonymous_layer_name(); + + virtual ~CSSLayerBlockRule() = default; + + virtual Type type() const override { return Type::LayerBlock; } + + FlyString const& name() const { return m_name; } + FlyString const& internal_name() const { return m_name_internal; } + FlyString internal_qualified_name(Badge) const; + +private: + CSSLayerBlockRule(JS::Realm&, FlyString name, CSSRuleList&); + + virtual void initialize(JS::Realm&) override; + virtual String serialized() const override; + + FlyString m_name; + FlyString m_name_internal; +}; + +} diff --git a/Userland/Libraries/LibWeb/CSS/CSSLayerBlockRule.idl b/Userland/Libraries/LibWeb/CSS/CSSLayerBlockRule.idl new file mode 100644 index 00000000000..901fe05cf46 --- /dev/null +++ b/Userland/Libraries/LibWeb/CSS/CSSLayerBlockRule.idl @@ -0,0 +1,7 @@ +#import + +// https://drafts.csswg.org/css-cascade-5/#the-csslayerblockrule-interface +[Exposed=Window] +interface CSSLayerBlockRule : CSSGroupingRule { + readonly attribute CSSOMString name; +}; \ No newline at end of file diff --git a/Userland/Libraries/LibWeb/CSS/CSSLayerStatementRule.cpp b/Userland/Libraries/LibWeb/CSS/CSSLayerStatementRule.cpp new file mode 100644 index 00000000000..82c53b268e9 --- /dev/null +++ b/Userland/Libraries/LibWeb/CSS/CSSLayerStatementRule.cpp @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2024, Sam Atkins + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include "CSSLayerStatementRule.h" +#include +#include +#include + +namespace Web::CSS { + +JS_DEFINE_ALLOCATOR(CSSLayerStatementRule); + +JS::NonnullGCPtr CSSLayerStatementRule::create(JS::Realm& realm, Vector name_list) +{ + return realm.heap().allocate(realm, realm, move(name_list)); +} + +CSSLayerStatementRule::CSSLayerStatementRule(JS::Realm& realm, Vector name_list) + : CSSRule(realm) + , m_name_list(move(name_list)) +{ +} + +void CSSLayerStatementRule::initialize(JS::Realm& realm) +{ + Base::initialize(realm); + WEB_SET_PROTOTYPE_FOR_INTERFACE(CSSLayerStatementRule); +} + +String CSSLayerStatementRule::serialized() const +{ + // AD-HOC: No spec yet. + StringBuilder builder; + builder.append("@layer "sv); + builder.join(", "sv, m_name_list); + builder.append(';'); + return builder.to_string_without_validation(); +} + +Vector CSSLayerStatementRule::internal_qualified_name_list(Badge) const +{ + // TODO: Cache these? + Vector qualified_layer_names; + + auto qualified_parent_layer_name = parent_layer_internal_qualified_name(); + if (qualified_parent_layer_name.is_empty()) + return m_name_list; + + for (auto const& name : m_name_list) + qualified_layer_names.append(MUST(String::formatted("{}.{}", qualified_parent_layer_name, name))); + + return qualified_layer_names; +} + +} diff --git a/Userland/Libraries/LibWeb/CSS/CSSLayerStatementRule.h b/Userland/Libraries/LibWeb/CSS/CSSLayerStatementRule.h new file mode 100644 index 00000000000..82fe359d0d4 --- /dev/null +++ b/Userland/Libraries/LibWeb/CSS/CSSLayerStatementRule.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2024, Sam Atkins + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include + +namespace Web::CSS { + +// https://drafts.csswg.org/css-cascade-5/#the-csslayerstatementrule-interface +class CSSLayerStatementRule final : public CSSRule { + WEB_PLATFORM_OBJECT(CSSLayerStatementRule, CSSRule); + JS_DECLARE_ALLOCATOR(CSSLayerStatementRule); + +public: + [[nodiscard]] static JS::NonnullGCPtr create(JS::Realm&, Vector name_list); + + virtual ~CSSLayerStatementRule() = default; + + virtual Type type() const override { return Type::LayerStatement; } + + // FIXME: Should be FrozenArray + ReadonlySpan name_list() const { return m_name_list; } + Vector internal_qualified_name_list(Badge) const; + +private: + CSSLayerStatementRule(JS::Realm&, Vector name_list); + + virtual void initialize(JS::Realm&) override; + virtual String serialized() const override; + + Vector m_name_list; +}; + +} diff --git a/Userland/Libraries/LibWeb/CSS/CSSLayerStatementRule.idl b/Userland/Libraries/LibWeb/CSS/CSSLayerStatementRule.idl new file mode 100644 index 00000000000..043ccb0afaa --- /dev/null +++ b/Userland/Libraries/LibWeb/CSS/CSSLayerStatementRule.idl @@ -0,0 +1,8 @@ +#import + +// https://drafts.csswg.org/css-cascade-5/#the-csslayerstatementrule-interface +[Exposed=Window] +interface CSSLayerStatementRule : CSSRule { + // FIXME: Should be a FrozenArray + readonly attribute sequence nameList; +}; \ No newline at end of file diff --git a/Userland/Libraries/LibWeb/CSS/CSSRule.cpp b/Userland/Libraries/LibWeb/CSS/CSSRule.cpp index ff33759b5f1..707f88195cb 100644 --- a/Userland/Libraries/LibWeb/CSS/CSSRule.cpp +++ b/Userland/Libraries/LibWeb/CSS/CSSRule.cpp @@ -1,12 +1,13 @@ /* * Copyright (c) 2021, the SerenityOS developers. - * Copyright (c) 2022, Sam Atkins + * Copyright (c) 2022-2024, Sam Atkins * Copyright (c) 2022, Andreas Kling * * SPDX-License-Identifier: BSD-2-Clause */ #include +#include #include #include @@ -47,4 +48,37 @@ void CSSRule::set_parent_style_sheet(CSSStyleSheet* parent_style_sheet) m_parent_style_sheet = parent_style_sheet; } +String CSSRule::parent_layer_internal_qualified_name() const +{ + // TODO: Cache this? + Vector layer_names; + for (auto* rule = parent_rule(); rule; rule = rule->parent_rule()) { + switch (rule->type()) { + case CSSRule::Type::Import: + // TODO: Handle `layer(foo)` in import rules once we implement that. + break; + + case CSSRule::Type::LayerBlock: { + auto& layer_block = static_cast(*rule); + layer_names.append(layer_block.internal_name()); + break; + } + + // Ignore everything else + // Note that LayerStatement cannot have child rules so we still ignore it here. + case CSSRule::Type::LayerStatement: + case CSSRule::Type::Style: + case CSSRule::Type::Media: + case CSSRule::Type::FontFace: + case CSSRule::Type::Keyframes: + case CSSRule::Type::Keyframe: + case CSSRule::Type::Namespace: + case CSSRule::Type::Supports: + break; + } + } + + return MUST(String::join("."sv, layer_names.in_reverse())); +} + } diff --git a/Userland/Libraries/LibWeb/CSS/CSSRule.h b/Userland/Libraries/LibWeb/CSS/CSSRule.h index 882dd53c37d..32fab795eb0 100644 --- a/Userland/Libraries/LibWeb/CSS/CSSRule.h +++ b/Userland/Libraries/LibWeb/CSS/CSSRule.h @@ -31,6 +31,9 @@ public: Keyframe = 8, Namespace = 10, Supports = 12, + // AD-HOC: These are not included in the spec, but we need them internally. So, their numbers are arbitrary. + LayerBlock = 100, + LayerStatement = 101, }; virtual Type type() const = 0; @@ -39,6 +42,7 @@ public: void set_css_text(StringView); CSSRule* parent_rule() { return m_parent_rule.ptr(); } + CSSRule const* parent_rule() const { return m_parent_rule.ptr(); } void set_parent_rule(CSSRule*); CSSStyleSheet* parent_style_sheet() { return m_parent_style_sheet.ptr(); } @@ -54,6 +58,8 @@ protected: virtual void visit_edges(Cell::Visitor&) override; + String parent_layer_internal_qualified_name() const; + JS::GCPtr m_parent_rule; JS::GCPtr m_parent_style_sheet; }; diff --git a/Userland/Libraries/LibWeb/CSS/CSSRuleList.cpp b/Userland/Libraries/LibWeb/CSS/CSSRuleList.cpp index e259b84c086..5e5f0845f39 100644 --- a/Userland/Libraries/LibWeb/CSS/CSSRuleList.cpp +++ b/Userland/Libraries/LibWeb/CSS/CSSRuleList.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2022, Sam Atkins + * Copyright (c) 2021-2024, Sam Atkins * * SPDX-License-Identifier: BSD-2-Clause */ @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -122,25 +123,27 @@ void CSSRuleList::for_each_effective_style_rule(Functiontype()) { - case CSSRule::Type::FontFace: - break; case CSSRule::Type::Import: { auto const& import_rule = static_cast(*rule); if (import_rule.loaded_style_sheet()) import_rule.loaded_style_sheet()->for_each_effective_style_rule(callback); break; } + + case CSSRule::Type::LayerBlock: case CSSRule::Type::Media: - static_cast(*rule).for_each_effective_style_rule(callback); + case CSSRule::Type::Supports: + static_cast(*rule).for_each_effective_style_rule(callback); break; + case CSSRule::Type::Style: callback(static_cast(*rule)); break; - case CSSRule::Type::Supports: - static_cast(*rule).for_each_effective_style_rule(callback); - break; + + case CSSRule::Type::FontFace: case CSSRule::Type::Keyframe: case CSSRule::Type::Keyframes: + case CSSRule::Type::LayerStatement: case CSSRule::Type::Namespace: break; } @@ -151,28 +154,27 @@ void CSSRuleList::for_each_effective_keyframes_at_rule(Functiontype()) { - case CSSRule::Type::FontFace: - break; case CSSRule::Type::Import: { auto const& import_rule = static_cast(*rule); if (import_rule.loaded_style_sheet()) import_rule.loaded_style_sheet()->for_each_effective_keyframes_at_rule(callback); break; } + + case CSSRule::Type::LayerBlock: case CSSRule::Type::Media: - static_cast(*rule).for_each_effective_keyframes_at_rule(callback); - break; - case CSSRule::Type::Style: - break; case CSSRule::Type::Supports: - static_cast(*rule).for_each_effective_keyframes_at_rule(callback); - break; - case CSSRule::Type::Keyframe: + static_cast(*rule).for_each_effective_keyframes_at_rule(callback); break; case CSSRule::Type::Keyframes: callback(static_cast(*rule)); break; + + case CSSRule::Type::FontFace: + case CSSRule::Type::Keyframe: + case CSSRule::Type::LayerStatement: case CSSRule::Type::Namespace: + case CSSRule::Type::Style: break; } } @@ -184,14 +186,18 @@ bool CSSRuleList::evaluate_media_queries(HTML::Window const& window) for (auto& rule : m_rules) { switch (rule->type()) { - case CSSRule::Type::FontFace: - break; case CSSRule::Type::Import: { auto& import_rule = verify_cast(*rule); if (import_rule.loaded_style_sheet() && import_rule.loaded_style_sheet()->evaluate_media_queries(window)) any_media_queries_changed_match_state = true; break; } + case CSSRule::Type::LayerBlock: { + auto& layer_rule = verify_cast(*rule); + if (layer_rule.css_rules().evaluate_media_queries(window)) + any_media_queries_changed_match_state = true; + break; + } case CSSRule::Type::Media: { auto& media_rule = verify_cast(*rule); bool did_match = media_rule.condition_matches(); @@ -202,17 +208,18 @@ bool CSSRuleList::evaluate_media_queries(HTML::Window const& window) any_media_queries_changed_match_state = true; break; } - case CSSRule::Type::Style: - break; case CSSRule::Type::Supports: { auto& supports_rule = verify_cast(*rule); if (supports_rule.condition_matches() && supports_rule.css_rules().evaluate_media_queries(window)) any_media_queries_changed_match_state = true; break; } + case CSSRule::Type::FontFace: case CSSRule::Type::Keyframe: case CSSRule::Type::Keyframes: + case CSSRule::Type::LayerStatement: case CSSRule::Type::Namespace: + case CSSRule::Type::Style: break; } } diff --git a/Userland/Libraries/LibWeb/Dump.cpp b/Userland/Libraries/LibWeb/Dump.cpp index a5083917a8b..f4fe4a3234b 100644 --- a/Userland/Libraries/LibWeb/Dump.cpp +++ b/Userland/Libraries/LibWeb/Dump.cpp @@ -1,6 +1,7 @@ /* * Copyright (c) 2018-2023, Andreas Kling * Copyright (c) 2021, the SerenityOS developers. + * Copyright (c) 2021-2024, Sam Atkins * * SPDX-License-Identifier: BSD-2-Clause */ @@ -10,6 +11,8 @@ #include #include #include +#include +#include #include #include #include @@ -617,21 +620,28 @@ ErrorOr dump_rule(StringBuilder& builder, CSS::CSSRule const& rule, int in case CSS::CSSRule::Type::Import: dump_import_rule(builder, verify_cast(rule), indent_levels); break; + case CSS::CSSRule::Type::Keyframe: + case CSS::CSSRule::Type::Keyframes: + // TODO: Dump them! + break; + case CSS::CSSRule::Type::LayerBlock: + dump_layer_block_rule(builder, verify_cast(rule), indent_levels); + break; + case CSS::CSSRule::Type::LayerStatement: + dump_layer_statement_rule(builder, verify_cast(rule), indent_levels); + break; case CSS::CSSRule::Type::Media: TRY(dump_media_rule(builder, verify_cast(rule), indent_levels)); break; + case CSS::CSSRule::Type::Namespace: + TRY(dump_namespace_rule(builder, verify_cast(rule), indent_levels)); + break; case CSS::CSSRule::Type::Style: TRY(dump_style_rule(builder, verify_cast(rule), indent_levels)); break; case CSS::CSSRule::Type::Supports: TRY(dump_supports_rule(builder, verify_cast(rule), indent_levels)); break; - case CSS::CSSRule::Type::Keyframe: - case CSS::CSSRule::Type::Keyframes: - break; - case CSS::CSSRule::Type::Namespace: - TRY(dump_namespace_rule(builder, verify_cast(rule), indent_levels)); - break; } return {}; } @@ -676,6 +686,21 @@ void dump_import_rule(StringBuilder& builder, CSS::CSSImportRule const& rule, in builder.appendff(" Document URL: {}\n", rule.url()); } +void dump_layer_block_rule(StringBuilder& builder, CSS::CSSLayerBlockRule const& layer_block, int indent_levels) +{ + indent(builder, indent_levels); + builder.appendff(" Layer Block: `{}`\n Rules ({}):\n", layer_block.internal_name(), layer_block.css_rules().length()); + for (auto& rule : layer_block.css_rules()) + MUST(dump_rule(builder, rule, indent_levels + 1)); +} + +void dump_layer_statement_rule(StringBuilder& builder, CSS::CSSLayerStatementRule const& layer_statement, int indent_levels) +{ + indent(builder, indent_levels); + builder.append(" Layer Statement: "sv); + builder.join(", "sv, layer_statement.name_list()); +} + ErrorOr dump_media_rule(StringBuilder& builder, CSS::CSSMediaRule const& media, int indent_levels) { indent(builder, indent_levels); diff --git a/Userland/Libraries/LibWeb/Dump.h b/Userland/Libraries/LibWeb/Dump.h index 3bb5b8ddd73..3f9ab7d6bc5 100644 --- a/Userland/Libraries/LibWeb/Dump.h +++ b/Userland/Libraries/LibWeb/Dump.h @@ -30,6 +30,8 @@ ErrorOr dump_media_rule(StringBuilder&, CSS::CSSMediaRule const&, int inde ErrorOr dump_style_rule(StringBuilder&, CSS::CSSStyleRule const&, int indent_levels = 0); ErrorOr dump_supports_rule(StringBuilder&, CSS::CSSSupportsRule const&, int indent_levels = 0); ErrorOr dump_namespace_rule(StringBuilder&, CSS::CSSNamespaceRule const&, int indent_levels = 0); +void dump_layer_block_rule(StringBuilder&, CSS::CSSLayerBlockRule const&, int indent_levels = 0); +void dump_layer_statement_rule(StringBuilder&, CSS::CSSLayerStatementRule const&, int indent_levels = 0); void dump_selector(StringBuilder&, CSS::Selector const&); void dump_selector(CSS::Selector const&); diff --git a/Userland/Libraries/LibWeb/Forward.h b/Userland/Libraries/LibWeb/Forward.h index cbb554202e9..8dc8f191f53 100644 --- a/Userland/Libraries/LibWeb/Forward.h +++ b/Userland/Libraries/LibWeb/Forward.h @@ -113,6 +113,8 @@ class CSSImportRule; class CSSKeyframeRule; class CSSKeyframesRule; class CSSKeywordValue; +class CSSLayerBlockRule; +class CSSLayerStatementRule; class CSSMediaRule; class CSSOKLab; class CSSOKLCH; diff --git a/Userland/Libraries/LibWeb/idl_files.cmake b/Userland/Libraries/LibWeb/idl_files.cmake index 17d31fc1c83..b4ac2c8f8e5 100644 --- a/Userland/Libraries/LibWeb/idl_files.cmake +++ b/Userland/Libraries/LibWeb/idl_files.cmake @@ -20,6 +20,8 @@ libweb_js_bindings(CSS/CSSGroupingRule) libweb_js_bindings(CSS/CSSImportRule) libweb_js_bindings(CSS/CSSKeyframeRule) libweb_js_bindings(CSS/CSSKeyframesRule) +libweb_js_bindings(CSS/CSSLayerBlockRule) +libweb_js_bindings(CSS/CSSLayerStatementRule) libweb_js_bindings(CSS/CSSMediaRule) libweb_js_bindings(CSS/CSS NAMESPACE) libweb_js_bindings(CSS/CSSNamespaceRule)