From 04d67d023945ebfc8375a67212b690619916ef2a Mon Sep 17 00:00:00 2001 From: Sviatoslav Peleshko Date: Sun, 21 Feb 2021 13:45:26 +0200 Subject: [PATCH] LibWeb: Create base class CSSRule for all CSS rules This is a foundation for handling other ("at") CSS rules. --- Userland/Libraries/LibWeb/CMakeLists.txt | 1 + Userland/Libraries/LibWeb/CSS/CSSRule.cpp | 35 ++++++++++++ Userland/Libraries/LibWeb/CSS/CSSRule.h | 53 +++++++++++++++++++ .../Libraries/LibWeb/CSS/Parser/CSSParser.cpp | 4 +- .../Libraries/LibWeb/CSS/StyleInvalidator.cpp | 1 + .../Libraries/LibWeb/CSS/StyleResolver.cpp | 6 ++- Userland/Libraries/LibWeb/CSS/StyleRule.h | 7 ++- Userland/Libraries/LibWeb/CSS/StyleSheet.cpp | 3 +- Userland/Libraries/LibWeb/CSS/StyleSheet.h | 24 ++++++--- Userland/Libraries/LibWeb/Dump.cpp | 22 ++++++-- Userland/Libraries/LibWeb/Dump.h | 6 ++- Userland/Libraries/LibWeb/Forward.h | 2 + 12 files changed, 147 insertions(+), 17 deletions(-) create mode 100644 Userland/Libraries/LibWeb/CSS/CSSRule.cpp create mode 100644 Userland/Libraries/LibWeb/CSS/CSSRule.h diff --git a/Userland/Libraries/LibWeb/CMakeLists.txt b/Userland/Libraries/LibWeb/CMakeLists.txt index 563f3f743e..61ed208ca5 100644 --- a/Userland/Libraries/LibWeb/CMakeLists.txt +++ b/Userland/Libraries/LibWeb/CMakeLists.txt @@ -9,6 +9,7 @@ set(SOURCES Bindings/ScriptExecutionContext.cpp Bindings/WindowObject.cpp Bindings/Wrappable.cpp + CSS/CSSRule.cpp CSS/DefaultStyleSheetSource.cpp CSS/Length.cpp CSS/Parser/CSSParser.cpp diff --git a/Userland/Libraries/LibWeb/CSS/CSSRule.cpp b/Userland/Libraries/LibWeb/CSS/CSSRule.cpp new file mode 100644 index 0000000000..1f4790293c --- /dev/null +++ b/Userland/Libraries/LibWeb/CSS/CSSRule.cpp @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2021, the SerenityOS developers. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include + +namespace Web::CSS { + +CSSRule::~CSSRule() +{ +} + +} diff --git a/Userland/Libraries/LibWeb/CSS/CSSRule.h b/Userland/Libraries/LibWeb/CSS/CSSRule.h new file mode 100644 index 0000000000..de2a365252 --- /dev/null +++ b/Userland/Libraries/LibWeb/CSS/CSSRule.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2021, the SerenityOS developers. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include +#include +#include +#include + +namespace Web::CSS { + +class CSSRule : public RefCounted { +public: + virtual ~CSSRule(); + + enum class Type : u32 { + Style, + Import, + Media, + __Count, + }; + + virtual StringView class_name() const = 0; + virtual Type type() const = 0; + +private: +}; + +} diff --git a/Userland/Libraries/LibWeb/CSS/Parser/CSSParser.cpp b/Userland/Libraries/LibWeb/CSS/Parser/CSSParser.cpp index 87fcde8d6e..b83b21c238 100644 --- a/Userland/Libraries/LibWeb/CSS/Parser/CSSParser.cpp +++ b/Userland/Libraries/LibWeb/CSS/Parser/CSSParser.cpp @@ -25,8 +25,10 @@ */ #include +#include #include #include +#include #include #include #include @@ -853,7 +855,7 @@ public: private: CSS::ParsingContext m_context; - NonnullRefPtrVector rules; + NonnullRefPtrVector rules; struct CurrentRule { Vector selectors; diff --git a/Userland/Libraries/LibWeb/CSS/StyleInvalidator.cpp b/Userland/Libraries/LibWeb/CSS/StyleInvalidator.cpp index bf5f15c332..d5d7b14ca8 100644 --- a/Userland/Libraries/LibWeb/CSS/StyleInvalidator.cpp +++ b/Userland/Libraries/LibWeb/CSS/StyleInvalidator.cpp @@ -25,6 +25,7 @@ */ #include +#include #include #include diff --git a/Userland/Libraries/LibWeb/CSS/StyleResolver.cpp b/Userland/Libraries/LibWeb/CSS/StyleResolver.cpp index 2ced865baa..544e8cc646 100644 --- a/Userland/Libraries/LibWeb/CSS/StyleResolver.cpp +++ b/Userland/Libraries/LibWeb/CSS/StyleResolver.cpp @@ -1,5 +1,6 @@ /* * Copyright (c) 2018-2020, Andreas Kling + * Copyright (c) 2021, the SerenityOS developers. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -28,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -86,7 +88,7 @@ Vector StyleResolver::collect_matching_rules(const DOM::Element& e size_t style_sheet_index = 0; for_each_stylesheet([&](auto& sheet) { size_t rule_index = 0; - for (auto& rule : sheet.rules()) { + sheet.for_each_effective_style_rule([&](auto& rule) { size_t selector_index = 0; for (auto& selector : rule.selectors()) { if (SelectorEngine::matches(selector, element)) { @@ -96,7 +98,7 @@ Vector StyleResolver::collect_matching_rules(const DOM::Element& e ++selector_index; } ++rule_index; - } + }); ++style_sheet_index; }); diff --git a/Userland/Libraries/LibWeb/CSS/StyleRule.h b/Userland/Libraries/LibWeb/CSS/StyleRule.h index d668c5b42b..8e2d3acf44 100644 --- a/Userland/Libraries/LibWeb/CSS/StyleRule.h +++ b/Userland/Libraries/LibWeb/CSS/StyleRule.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2018-2020, Andreas Kling + * Copyright (c) 2021, the SerenityOS developers. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -27,12 +28,13 @@ #pragma once #include +#include #include #include namespace Web::CSS { -class StyleRule : public RefCounted { +class StyleRule : public CSSRule { AK_MAKE_NONCOPYABLE(StyleRule); AK_MAKE_NONMOVABLE(StyleRule); @@ -47,6 +49,9 @@ public: const Vector& selectors() const { return m_selectors; } const StyleDeclaration& declaration() const { return m_declaration; } + virtual StringView class_name() const { return "StyleRule"; }; + virtual Type type() const { return Type::Style; }; + private: StyleRule(Vector&&, NonnullRefPtr&&); diff --git a/Userland/Libraries/LibWeb/CSS/StyleSheet.cpp b/Userland/Libraries/LibWeb/CSS/StyleSheet.cpp index d4c37ba53e..fd664327b7 100644 --- a/Userland/Libraries/LibWeb/CSS/StyleSheet.cpp +++ b/Userland/Libraries/LibWeb/CSS/StyleSheet.cpp @@ -1,5 +1,6 @@ /* * Copyright (c) 2018-2020, Andreas Kling + * Copyright (c) 2021, the SerenityOS developers. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -28,7 +29,7 @@ namespace Web::CSS { -StyleSheet::StyleSheet(NonnullRefPtrVector&& rules) +StyleSheet::StyleSheet(NonnullRefPtrVector&& rules) : m_rules(move(rules)) { } diff --git a/Userland/Libraries/LibWeb/CSS/StyleSheet.h b/Userland/Libraries/LibWeb/CSS/StyleSheet.h index 9e3695e03d..146a6a172d 100644 --- a/Userland/Libraries/LibWeb/CSS/StyleSheet.h +++ b/Userland/Libraries/LibWeb/CSS/StyleSheet.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2018-2020, Andreas Kling + * Copyright (c) 2021, the SerenityOS developers. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -27,26 +28,37 @@ #pragma once #include -#include +#include +#include +#include namespace Web::CSS { class StyleSheet : public RefCounted { public: - static NonnullRefPtr create(NonnullRefPtrVector&& rules) + static NonnullRefPtr create(NonnullRefPtrVector&& rules) { return adopt(*new StyleSheet(move(rules))); } ~StyleSheet(); - const NonnullRefPtrVector& rules() const { return m_rules; } - NonnullRefPtrVector& rules() { return m_rules; } + const NonnullRefPtrVector& rules() const { return m_rules; } + NonnullRefPtrVector& rules() { return m_rules; } + + template + void for_each_effective_style_rule(Callback callback) const + { + for (auto& rule : m_rules) + if (rule.type() == CSSRule::Type::Style) { + callback(downcast(rule)); + } + } private: - explicit StyleSheet(NonnullRefPtrVector&&); + explicit StyleSheet(NonnullRefPtrVector&&); - NonnullRefPtrVector m_rules; + NonnullRefPtrVector m_rules; }; } diff --git a/Userland/Libraries/LibWeb/Dump.cpp b/Userland/Libraries/LibWeb/Dump.cpp index cb7a8bc62e..2ce412a23a 100644 --- a/Userland/Libraries/LibWeb/Dump.cpp +++ b/Userland/Libraries/LibWeb/Dump.cpp @@ -1,5 +1,6 @@ /* * Copyright (c) 2018-2021, Andreas Kling + * Copyright (c) 2021, the SerenityOS developers. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -27,7 +28,9 @@ #include #include #include +#include #include +#include #include #include #include @@ -389,16 +392,27 @@ void dump_selector(StringBuilder& builder, const CSS::Selector& selector) } } -void dump_rule(const CSS::StyleRule& rule) +void dump_rule(const CSS::CSSRule& rule) { StringBuilder builder; dump_rule(builder, rule); dbgln("{}", builder.string_view()); } -void dump_rule(StringBuilder& builder, const CSS::StyleRule& rule) +void dump_rule(StringBuilder& builder, const CSS::CSSRule& rule) +{ + builder.appendff("{}:\n", rule.class_name()); + switch (rule.type()) { + case CSS::CSSRule::Type::Style: + dump_style_rule(builder, downcast(rule)); + break; + default: + VERIFY_NOT_REACHED(); + } +} + +void dump_style_rule(StringBuilder& builder, const CSS::StyleRule& rule) { - builder.append("Rule:\n"); for (auto& selector : rule.selectors()) { dump_selector(builder, selector); } @@ -417,7 +431,7 @@ void dump_sheet(const CSS::StyleSheet& sheet) void dump_sheet(StringBuilder& builder, const CSS::StyleSheet& sheet) { - builder.appendff("StyleSheet{{{}}}: {} rule(s)", &sheet, sheet.rules().size()); + builder.appendff("StyleSheet{{{}}}: {} rule(s)\n", &sheet, sheet.rules().size()); for (auto& rule : sheet.rules()) { dump_rule(builder, rule); diff --git a/Userland/Libraries/LibWeb/Dump.h b/Userland/Libraries/LibWeb/Dump.h index aabbab6ee0..78ba4a46bd 100644 --- a/Userland/Libraries/LibWeb/Dump.h +++ b/Userland/Libraries/LibWeb/Dump.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2018-2021, Andreas Kling + * Copyright (c) 2021, the SerenityOS developers. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -37,8 +38,9 @@ void dump_tree(StringBuilder&, const Layout::Node&, bool show_box_model = false, void dump_tree(const Layout::Node&, bool show_box_model = false, bool show_specified_style = false); void dump_sheet(StringBuilder&, const CSS::StyleSheet&); void dump_sheet(const CSS::StyleSheet&); -void dump_rule(StringBuilder&, const CSS::StyleRule&); -void dump_rule(const CSS::StyleRule&); +void dump_rule(StringBuilder&, const CSS::CSSRule&); +void dump_rule(const CSS::CSSRule&); +void dump_style_rule(StringBuilder&, const CSS::StyleRule&); void dump_selector(StringBuilder&, const CSS::Selector&); void dump_selector(const CSS::Selector&); diff --git a/Userland/Libraries/LibWeb/Forward.h b/Userland/Libraries/LibWeb/Forward.h index cf5664944a..f7a9b71fc0 100644 --- a/Userland/Libraries/LibWeb/Forward.h +++ b/Userland/Libraries/LibWeb/Forward.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2020-2021, Andreas Kling + * Copyright (c) 2021, the SerenityOS developers. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -27,6 +28,7 @@ #pragma once namespace Web::CSS { +class CSSRule; class Length; class Selector; class StyleDeclaration;