diff --git a/Libraries/LibWeb/CSS/Parser/Parser.cpp b/Libraries/LibWeb/CSS/Parser/Parser.cpp index dd095b919c2..5a857b996cc 100644 --- a/Libraries/LibWeb/CSS/Parser/Parser.cpp +++ b/Libraries/LibWeb/CSS/Parser/Parser.cpp @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -274,10 +275,11 @@ OwnPtr Parser::parse_boolean_expression_group(TokenStream Parser::parse_supports_feature(TokenStream& tokens) { - // = | + // = | + // | | auto transaction = tokens.begin_transaction(); tokens.discard_whitespace(); auto const& first_token = tokens.consume_a_token(); @@ -307,6 +309,36 @@ OwnPtr Parser::parse_supports_feature(TokenStream = font-tech( )` + if (first_token.is_function("font-tech"sv)) { + TokenStream tech_tokens { first_token.function().value }; + tech_tokens.discard_whitespace(); + auto tech_token = tech_tokens.consume_a_token(); + tech_tokens.discard_whitespace(); + if (tech_tokens.has_next_token() || !tech_token.is(Token::Type::Ident)) + return {}; + + transaction.commit(); + auto tech_name = tech_token.token().ident(); + bool matches = font_tech_is_supported(tech_name); + return Supports::FontTech::create(move(tech_name), matches); + } + + // ` = font-format( )` + if (first_token.is_function("font-format"sv)) { + TokenStream format_tokens { first_token.function().value }; + format_tokens.discard_whitespace(); + auto format_token = format_tokens.consume_a_token(); + format_tokens.discard_whitespace(); + if (format_tokens.has_next_token() || !format_token.is(Token::Type::Ident)) + return {}; + + transaction.commit(); + auto format_name = format_token.token().ident(); + bool matches = font_format_is_supported(format_name); + return Supports::FontFormat::create(move(format_name), matches); + } + return {}; } diff --git a/Libraries/LibWeb/CSS/Supports.cpp b/Libraries/LibWeb/CSS/Supports.cpp index 583074a003f..99112242623 100644 --- a/Libraries/LibWeb/CSS/Supports.cpp +++ b/Libraries/LibWeb/CSS/Supports.cpp @@ -47,6 +47,38 @@ void Supports::Selector::dump(StringBuilder& builder, int indent_levels) const builder.appendff("Selector: `{}` matches={}\n", m_selector, m_matches); } +MatchResult Supports::FontTech::evaluate(HTML::Window const*) const +{ + return as_match_result(m_matches); +} + +String Supports::FontTech::to_string() const +{ + return MUST(String::formatted("font-tech({})", m_tech)); +} + +void Supports::FontTech::dump(StringBuilder& builder, int indent_levels) const +{ + indent(builder, indent_levels); + builder.appendff("FontTech: `{}` matches={}\n", m_tech, m_matches); +} + +MatchResult Supports::FontFormat::evaluate(HTML::Window const*) const +{ + return as_match_result(m_matches); +} + +String Supports::FontFormat::to_string() const +{ + return MUST(String::formatted("font-format({})", m_format)); +} + +void Supports::FontFormat::dump(StringBuilder& builder, int indent_levels) const +{ + indent(builder, indent_levels); + builder.appendff("FontFormat: `{}` matches={}\n", m_format, m_matches); +} + String Supports::to_string() const { return m_condition->to_string(); diff --git a/Libraries/LibWeb/CSS/Supports.h b/Libraries/LibWeb/CSS/Supports.h index 8c9fd403df2..1f19f09e2b9 100644 --- a/Libraries/LibWeb/CSS/Supports.h +++ b/Libraries/LibWeb/CSS/Supports.h @@ -6,6 +6,7 @@ #pragma once +#include #include #include #include @@ -60,6 +61,50 @@ public: bool m_matches; }; + class FontTech final : public BooleanExpression { + public: + static NonnullOwnPtr create(FlyString tech, bool matches) + { + return adopt_own(*new FontTech(move(tech), matches)); + } + virtual ~FontTech() override = default; + + virtual MatchResult evaluate(HTML::Window const*) const override; + virtual String to_string() const override; + virtual void dump(StringBuilder&, int indent_levels = 0) const override; + + private: + FontTech(FlyString tech, bool matches) + : m_tech(move(tech)) + , m_matches(matches) + { + } + FlyString m_tech; + bool m_matches; + }; + + class FontFormat final : public BooleanExpression { + public: + static NonnullOwnPtr create(FlyString format, bool matches) + { + return adopt_own(*new FontFormat(move(format), matches)); + } + virtual ~FontFormat() override = default; + + virtual MatchResult evaluate(HTML::Window const*) const override; + virtual String to_string() const override; + virtual void dump(StringBuilder&, int indent_levels = 0) const override; + + private: + FontFormat(FlyString format, bool matches) + : m_format(move(format)) + , m_matches(matches) + { + } + FlyString m_format; + bool m_matches; + }; + static NonnullRefPtr create(NonnullOwnPtr&& condition) { return adopt_ref(*new Supports(move(condition))); diff --git a/Tests/LibWeb/Ref/expected/wpt-import/css/css-conditional/at-supports-001-ref.html b/Tests/LibWeb/Ref/expected/wpt-import/css/css-conditional/at-supports-001-ref.html new file mode 100644 index 00000000000..a8157aa7521 --- /dev/null +++ b/Tests/LibWeb/Ref/expected/wpt-import/css/css-conditional/at-supports-001-ref.html @@ -0,0 +1,19 @@ + + + + CSS Reftest Reference + + + + + +

Test passes if there is a filled green square and no red.

+
+ + diff --git a/Tests/LibWeb/Ref/input/wpt-import/css/css-conditional/at-supports-font-format-001.html b/Tests/LibWeb/Ref/input/wpt-import/css/css-conditional/at-supports-font-format-001.html new file mode 100644 index 00000000000..1f4f2b49c15 --- /dev/null +++ b/Tests/LibWeb/Ref/input/wpt-import/css/css-conditional/at-supports-font-format-001.html @@ -0,0 +1,56 @@ + +CSS Conditional Test: @supports font-format() + + + + + +

Test passes if there is a filled green square and no red.

+
+
+
+
+
+
+
+
+
+
diff --git a/Tests/LibWeb/Ref/input/wpt-import/css/css-conditional/at-supports-font-tech-001.html b/Tests/LibWeb/Ref/input/wpt-import/css/css-conditional/at-supports-font-tech-001.html new file mode 100644 index 00000000000..ac8d857a6b4 --- /dev/null +++ b/Tests/LibWeb/Ref/input/wpt-import/css/css-conditional/at-supports-font-tech-001.html @@ -0,0 +1,56 @@ + +CSS Conditional Test: @supports font-tech() + + + + + +

Test passes if there is a filled green square and no red.

+
+
+
+
+
+
+
+
+
+