mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-09-19 17:27:51 +03:00
LibWeb: Implement @supports
rule :^)
The main thing missing is that we don't serialize the supports clause, but for actually using a `@supports (something: cool) {}` rule in CSS, it works!
This commit is contained in:
parent
439d978ea5
commit
57a25139a5
Notes:
sideshowbarker
2024-07-18 02:54:56 +09:00
Author: https://github.com/AtkinsSJ Commit: https://github.com/SerenityOS/serenity/commit/57a25139a55 Pull-request: https://github.com/SerenityOS/serenity/pull/10400 Reviewed-by: https://github.com/Lubrsi
@ -25,6 +25,7 @@ set(SOURCES
|
||||
CSS/CSSStyleDeclaration.cpp
|
||||
CSS/CSSStyleRule.cpp
|
||||
CSS/CSSStyleSheet.cpp
|
||||
CSS/CSSSupportsRule.cpp
|
||||
CSS/ResolvedCSSStyleDeclaration.cpp
|
||||
CSS/DefaultStyleSheetSource.cpp
|
||||
CSS/Length.cpp
|
||||
|
@ -26,6 +26,7 @@ public:
|
||||
Style,
|
||||
Import,
|
||||
Media,
|
||||
Supports,
|
||||
__Count,
|
||||
};
|
||||
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include <LibWeb/CSS/CSSImportRule.h>
|
||||
#include <LibWeb/CSS/CSSMediaRule.h>
|
||||
#include <LibWeb/CSS/CSSRuleList.h>
|
||||
#include <LibWeb/CSS/CSSSupportsRule.h>
|
||||
#include <LibWeb/DOM/ExceptionOr.h>
|
||||
|
||||
namespace Web::CSS {
|
||||
@ -93,6 +94,9 @@ void CSSRuleList::for_each_effective_style_rule(Function<void(CSSStyleRule const
|
||||
case CSSRule::Type::Media:
|
||||
verify_cast<CSSMediaRule>(rule).for_each_effective_style_rule(callback);
|
||||
break;
|
||||
case CSSRule::Type::Supports:
|
||||
verify_cast<CSSSupportsRule>(rule).for_each_effective_style_rule(callback);
|
||||
break;
|
||||
case CSSRule::Type::__Count:
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
@ -114,6 +118,8 @@ bool CSSRuleList::for_first_not_loaded_import_rule(Function<void(CSSImportRule&)
|
||||
}
|
||||
} else if (rule.type() == CSSRule::Type::Media) {
|
||||
return verify_cast<CSSMediaRule>(rule).for_first_not_loaded_import_rule(callback);
|
||||
} else if (rule.type() == CSSRule::Type::Supports) {
|
||||
return verify_cast<CSSSupportsRule>(rule).for_first_not_loaded_import_rule(callback);
|
||||
}
|
||||
}
|
||||
|
||||
|
34
Userland/Libraries/LibWeb/CSS/CSSSupportsRule.cpp
Normal file
34
Userland/Libraries/LibWeb/CSS/CSSSupportsRule.cpp
Normal file
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Sam Atkins <atkinssj@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <LibWeb/CSS/CSSSupportsRule.h>
|
||||
#include <LibWeb/CSS/Parser/Parser.h>
|
||||
|
||||
namespace Web::CSS {
|
||||
|
||||
CSSSupportsRule::CSSSupportsRule(NonnullRefPtr<Supports>&& supports, NonnullRefPtrVector<CSSRule>&& rules)
|
||||
: CSSConditionRule(move(rules))
|
||||
, m_supports(move(supports))
|
||||
{
|
||||
}
|
||||
|
||||
CSSSupportsRule::~CSSSupportsRule()
|
||||
{
|
||||
}
|
||||
|
||||
String CSSSupportsRule::condition_text() const
|
||||
{
|
||||
// FIXME: Serializing supports rules!
|
||||
return "<supports-condition>";
|
||||
}
|
||||
|
||||
void CSSSupportsRule::set_condition_text(String text)
|
||||
{
|
||||
if (auto new_supports = parse_css_supports({}, text))
|
||||
m_supports = new_supports.release_nonnull();
|
||||
}
|
||||
|
||||
}
|
47
Userland/Libraries/LibWeb/CSS/CSSSupportsRule.h
Normal file
47
Userland/Libraries/LibWeb/CSS/CSSSupportsRule.h
Normal file
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Sam Atkins <atkinssj@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AK/NonnullRefPtr.h>
|
||||
#include <AK/NonnullRefPtrVector.h>
|
||||
#include <LibWeb/CSS/CSSConditionRule.h>
|
||||
#include <LibWeb/CSS/CSSRule.h>
|
||||
#include <LibWeb/CSS/Supports.h>
|
||||
#include <LibWeb/Forward.h>
|
||||
|
||||
namespace Web::CSS {
|
||||
|
||||
// https://www.w3.org/TR/css-conditional-3/#the-csssupportsrule-interface
|
||||
class CSSSupportsRule final : public CSSConditionRule {
|
||||
AK_MAKE_NONCOPYABLE(CSSSupportsRule);
|
||||
AK_MAKE_NONMOVABLE(CSSSupportsRule);
|
||||
|
||||
public:
|
||||
static NonnullRefPtr<CSSSupportsRule> create(NonnullRefPtr<Supports>&& supports, NonnullRefPtrVector<CSSRule>&& rules)
|
||||
{
|
||||
return adopt_ref(*new CSSSupportsRule(move(supports), move(rules)));
|
||||
}
|
||||
|
||||
~CSSSupportsRule();
|
||||
|
||||
virtual StringView class_name() const override { return "CSSSupportsRule"; };
|
||||
virtual Type type() const override { return Type::Supports; };
|
||||
|
||||
String condition_text() const override;
|
||||
void set_condition_text(String) override;
|
||||
virtual bool condition_matches() const override { return m_supports->matches(); }
|
||||
|
||||
private:
|
||||
explicit CSSSupportsRule(NonnullRefPtr<Supports>&&, NonnullRefPtrVector<CSSRule>&&);
|
||||
|
||||
NonnullRefPtr<Supports> m_supports;
|
||||
};
|
||||
|
||||
template<>
|
||||
inline bool CSSRule::fast_is<CSSSupportsRule>() const { return type() == CSSRule::Type::Supports; }
|
||||
|
||||
}
|
@ -16,6 +16,7 @@
|
||||
#include <LibWeb/CSS/CSSStyleDeclaration.h>
|
||||
#include <LibWeb/CSS/CSSStyleRule.h>
|
||||
#include <LibWeb/CSS/CSSStyleSheet.h>
|
||||
#include <LibWeb/CSS/CSSSupportsRule.h>
|
||||
#include <LibWeb/CSS/Parser/DeclarationOrAtRule.h>
|
||||
#include <LibWeb/CSS/Parser/Parser.h>
|
||||
#include <LibWeb/CSS/Parser/StyleBlockRule.h>
|
||||
@ -1735,6 +1736,29 @@ RefPtr<CSSRule> Parser::convert_to_rule(NonnullRefPtr<StyleRule> rule)
|
||||
return CSSImportRule::create(url.value());
|
||||
else
|
||||
dbgln("Unable to parse url from @import rule");
|
||||
|
||||
} else if (rule->m_name.equals_ignoring_case("supports"sv)) {
|
||||
|
||||
auto supports_tokens = TokenStream { rule->prelude() };
|
||||
auto supports = parse_a_supports(supports_tokens);
|
||||
if (!supports) {
|
||||
if constexpr (CSS_PARSER_DEBUG) {
|
||||
dbgln("CSSParser: @supports rule invalid; discarding.");
|
||||
supports_tokens.dump_all_tokens();
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
auto child_tokens = TokenStream { rule->block().values() };
|
||||
auto parser_rules = consume_a_list_of_rules(child_tokens, false);
|
||||
NonnullRefPtrVector<CSSRule> child_rules;
|
||||
for (auto& raw_rule : parser_rules) {
|
||||
if (auto child_rule = convert_to_rule(raw_rule))
|
||||
child_rules.append(*child_rule);
|
||||
}
|
||||
|
||||
return CSSSupportsRule::create(supports.release_nonnull(), move(child_rules));
|
||||
|
||||
} else {
|
||||
dbgln("Unrecognized CSS at-rule: @{}", rule->m_name);
|
||||
}
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include <LibWeb/CSS/CSSRule.h>
|
||||
#include <LibWeb/CSS/CSSStyleRule.h>
|
||||
#include <LibWeb/CSS/CSSStyleSheet.h>
|
||||
#include <LibWeb/CSS/CSSSupportsRule.h>
|
||||
#include <LibWeb/CSS/PropertyID.h>
|
||||
#include <LibWeb/DOM/Comment.h>
|
||||
#include <LibWeb/DOM/Document.h>
|
||||
@ -500,6 +501,9 @@ void dump_rule(StringBuilder& builder, CSS::CSSRule const& rule, int indent_leve
|
||||
case CSS::CSSRule::Type::Media:
|
||||
dump_media_rule(builder, verify_cast<CSS::CSSMediaRule const>(rule), indent_levels);
|
||||
break;
|
||||
case CSS::CSSRule::Type::Supports:
|
||||
dump_supports_rule(builder, verify_cast<CSS::CSSSupportsRule const>(rule), indent_levels);
|
||||
break;
|
||||
case CSS::CSSRule::Type::__Count:
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
@ -521,6 +525,16 @@ void dump_media_rule(StringBuilder& builder, CSS::CSSMediaRule const& media, int
|
||||
}
|
||||
}
|
||||
|
||||
void dump_supports_rule(StringBuilder& builder, CSS::CSSSupportsRule const& supports, int indent_levels)
|
||||
{
|
||||
indent(builder, indent_levels);
|
||||
builder.appendff(" Supports: {}\n Rules ({}):\n", supports.condition_text(), supports.css_rules().length());
|
||||
|
||||
for (auto& rule : supports.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()) {
|
||||
|
@ -23,6 +23,7 @@ void dump_rule(CSS::CSSRule 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_supports_rule(StringBuilder&, CSS::CSSSupportsRule const&, int indent_levels = 0);
|
||||
void dump_selector(StringBuilder&, CSS::Selector const&);
|
||||
void dump_selector(CSS::Selector const&);
|
||||
|
||||
|
@ -26,6 +26,7 @@ class CSSRuleList;
|
||||
class CSSStyleDeclaration;
|
||||
class CSSStyleRule;
|
||||
class CSSStyleSheet;
|
||||
class CSSSupportsRule;
|
||||
class Display;
|
||||
class ElementInlineCSSStyleDeclaration;
|
||||
class Length;
|
||||
|
Loading…
Reference in New Issue
Block a user