Pārlūkot izejas kodu

LibWeb: Add CSSMediaRule

This is the class corresponding to a `@media` rule. It contains a list
of media queries and a list of child css rules.
Sam Atkins 3 gadi atpakaļ
vecāks
revīzija
3e74c194f9

+ 1 - 0
Userland/Libraries/LibWeb/CMakeLists.txt

@@ -17,6 +17,7 @@ set(SOURCES
     CSS/CSSConditionRule.cpp
     CSS/CSSGroupingRule.cpp
     CSS/CSSImportRule.cpp
+    CSS/CSSMediaRule.cpp
     CSS/CSSRule.cpp
     CSS/CSSRuleList.cpp
     CSS/CSSStyleDeclaration.cpp

+ 31 - 0
Userland/Libraries/LibWeb/CSS/CSSMediaRule.cpp

@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2021, Sam Atkins <atkinssj@serenityos.org>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#include <LibWeb/CSS/CSSMediaRule.h>
+
+namespace Web::CSS {
+
+CSSMediaRule::CSSMediaRule(NonnullRefPtr<MediaList>&& media, NonnullRefPtrVector<CSSRule>&& rules)
+    : CSSConditionRule(move(rules))
+    , m_media(move(media))
+{
+}
+
+CSSMediaRule::~CSSMediaRule()
+{
+}
+
+String CSSMediaRule::condition_text() const
+{
+    return m_media->media_text();
+}
+
+void CSSMediaRule::set_condition_text(String text)
+{
+    m_media->set_media_text(text);
+}
+
+}

+ 45 - 0
Userland/Libraries/LibWeb/CSS/CSSMediaRule.h

@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2021, Sam Atkins <atkinssj@serenityos.org>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#pragma once
+
+#include <LibWeb/CSS/CSSConditionRule.h>
+#include <LibWeb/CSS/MediaList.h>
+#include <LibWeb/Forward.h>
+
+namespace Web::CSS {
+
+// https://www.w3.org/TR/css-conditional-3/#the-cssmediarule-interface
+class CSSMediaRule final : public CSSConditionRule {
+    AK_MAKE_NONCOPYABLE(CSSMediaRule);
+    AK_MAKE_NONMOVABLE(CSSMediaRule);
+
+public:
+    static NonnullRefPtr<CSSMediaRule> create(NonnullRefPtr<MediaList>&& media_queries, NonnullRefPtrVector<CSSRule>&& rules)
+    {
+        return adopt_ref(*new CSSMediaRule(move(media_queries), move(rules)));
+    }
+
+    ~CSSMediaRule();
+
+    virtual StringView class_name() const override { return "CSSMediaRule"; };
+    virtual Type type() const override { return Type::Media; };
+
+    virtual String condition_text() const override;
+    virtual void set_condition_text(String) override;
+
+    NonnullRefPtr<MediaList> const& media() const { return m_media; }
+
+private:
+    explicit CSSMediaRule(NonnullRefPtr<MediaList>&&, NonnullRefPtrVector<CSSRule>&&);
+
+    NonnullRefPtr<MediaList> m_media;
+};
+
+template<>
+inline bool CSSRule::fast_is<CSSMediaRule>() const { return type() == CSSRule::Type::Media; }
+
+}

+ 31 - 6
Userland/Libraries/LibWeb/Dump.cpp

@@ -9,6 +9,7 @@
 #include <AK/StringBuilder.h>
 #include <AK/Utf8View.h>
 #include <LibWeb/CSS/CSSImportRule.h>
+#include <LibWeb/CSS/CSSMediaRule.h>
 #include <LibWeb/CSS/CSSRule.h>
 #include <LibWeb/CSS/CSSStyleRule.h>
 #include <LibWeb/CSS/CSSStyleSheet.h>
@@ -28,6 +29,12 @@
 
 namespace Web {
 
+static void indent(StringBuilder& builder, int levels)
+{
+    for (int i = 0; i < levels; i++)
+        builder.append("  ");
+}
+
 void dump_tree(DOM::Node const& node)
 {
     StringBuilder builder;
@@ -478,33 +485,51 @@ void dump_rule(CSS::CSSRule const& rule)
     dbgln("{}", builder.string_view());
 }
 
-void dump_rule(StringBuilder& builder, CSS::CSSRule const& rule)
+void dump_rule(StringBuilder& builder, CSS::CSSRule const& rule, int indent_levels)
 {
+    indent(builder, indent_levels);
     builder.appendff("{}:\n", rule.class_name());
+
     switch (rule.type()) {
     case CSS::CSSRule::Type::Style:
-        dump_style_rule(builder, verify_cast<CSS::CSSStyleRule const>(rule));
+        dump_style_rule(builder, verify_cast<CSS::CSSStyleRule const>(rule), indent_levels);
         break;
     case CSS::CSSRule::Type::Import:
-        dump_import_rule(builder, verify_cast<CSS::CSSImportRule const>(rule));
+        dump_import_rule(builder, verify_cast<CSS::CSSImportRule const>(rule), indent_levels);
+        break;
+    case CSS::CSSRule::Type::Media:
+        dump_media_rule(builder, verify_cast<CSS::CSSMediaRule const>(rule), indent_levels);
         break;
-    default:
+    case CSS::CSSRule::Type::__Count:
         VERIFY_NOT_REACHED();
     }
 }
 
-void dump_import_rule(StringBuilder& builder, CSS::CSSImportRule const& rule)
+void dump_import_rule(StringBuilder& builder, CSS::CSSImportRule const& rule, int indent_levels)
 {
+    indent(builder, indent_levels);
     builder.appendff("  Document URL: {}\n", rule.url());
 }
 
-void dump_style_rule(StringBuilder& builder, CSS::CSSStyleRule const& rule)
+void dump_media_rule(StringBuilder& builder, CSS::CSSMediaRule const& media, int indent_levels)
+{
+    indent(builder, indent_levels);
+    builder.appendff("  Media: {}\n  Rules ({}):\n", media.condition_text(), media.css_rules().length());
+
+    for (auto& rule : media.css_rules()) {
+        dump_rule(builder, rule, indent_levels + 1);
+    }
+}
+
+void dump_style_rule(StringBuilder& builder, CSS::CSSStyleRule const& rule, int indent_levels)
 {
     for (auto& selector : rule.selectors()) {
         dump_selector(builder, selector);
     }
+    indent(builder, indent_levels);
     builder.append("  Declarations:\n");
     for (auto& property : verify_cast<CSS::PropertyOwningCSSStyleDeclaration>(rule.declaration()).properties()) {
+        indent(builder, indent_levels);
         builder.appendff("    {}: '{}'", CSS::string_from_property_id(property.property_id), property.value->to_string());
         if (property.important)
             builder.append(" \033[31;1m!important\033[0m");

+ 4 - 3
Userland/Libraries/LibWeb/Dump.h

@@ -18,10 +18,11 @@ void dump_tree(StringBuilder&, Layout::Node const&, bool show_box_model = false,
 void dump_tree(Layout::Node const&, bool show_box_model = false, bool show_specified_style = false);
 void dump_sheet(StringBuilder&, CSS::StyleSheet const&);
 void dump_sheet(CSS::StyleSheet const&);
-void dump_rule(StringBuilder&, CSS::CSSRule const&);
+void dump_rule(StringBuilder&, CSS::CSSRule const&, int indent_levels = 0);
 void dump_rule(CSS::CSSRule const&);
-void dump_style_rule(StringBuilder&, CSS::CSSStyleRule const&);
-void dump_import_rule(StringBuilder&, CSS::CSSImportRule const&);
+void dump_style_rule(StringBuilder&, CSS::CSSStyleRule const&, int indent_levels = 0);
+void dump_import_rule(StringBuilder&, CSS::CSSImportRule const&, int indent_levels = 0);
+void dump_media_rule(StringBuilder&, CSS::CSSMediaRule const&, int indent_levels = 0);
 void dump_selector(StringBuilder&, CSS::Selector const&);
 void dump_selector(CSS::Selector const&);
 

+ 2 - 1
Userland/Libraries/LibWeb/Forward.h

@@ -19,8 +19,9 @@ class Crypto;
 
 namespace Web::CSS {
 class CalculatedStyleValue;
-class CSSRule;
 class CSSImportRule;
+class CSSMediaRule;
+class CSSRule;
 class CSSStyleDeclaration;
 class CSSStyleRule;
 class CSSStyleSheet;