diff --git a/Libraries/LibWeb/CSS/CSSImportRule.cpp b/Libraries/LibWeb/CSS/CSSImportRule.cpp index e3340cd7960..9c9d77088e3 100644 --- a/Libraries/LibWeb/CSS/CSSImportRule.cpp +++ b/Libraries/LibWeb/CSS/CSSImportRule.cpp @@ -23,16 +23,17 @@ namespace Web::CSS { GC_DEFINE_ALLOCATOR(CSSImportRule); -GC::Ref CSSImportRule::create(URL::URL url, DOM::Document& document) +GC::Ref CSSImportRule::create(URL::URL url, DOM::Document& document, RefPtr supports) { auto& realm = document.realm(); - return realm.create(move(url), document); + return realm.create(move(url), document, supports); } -CSSImportRule::CSSImportRule(URL::URL url, DOM::Document& document) +CSSImportRule::CSSImportRule(URL::URL url, DOM::Document& document, RefPtr supports) : CSSRule(document.realm(), Type::Import) , m_url(move(url)) , m_document(document) + , m_supports(supports) { } @@ -70,6 +71,11 @@ String CSSImportRule::serialized() const // 2. The result of performing serialize a URL on the rule’s location. serialize_a_url(builder, m_url.to_string()); + // AD-HOC: Serialize the rule's supports condition if it exists. + // This isn't currently specified, but major browsers include this in their serialization of import rules + if (m_supports) + builder.appendff(" supports({})", m_supports->to_string()); + // FIXME: 3. If the rule’s associated media list is not empty, a single SPACE (U+0020) followed by the result of performing serialize a media query list on the media list. // 4. The string ";", i.e., SEMICOLON (U+003B). @@ -88,7 +94,10 @@ void CSSImportRule::fetch() VERIFY(parent_style_sheet()); auto& parent_style_sheet = *this->parent_style_sheet(); - // FIXME: 2. If rule has a , and that condition is not true, return. + // 2. If rule has a , and that condition is not true, return. + if (m_supports && !m_supports->matches()) { + return; + } // 3. Let parsedUrl be the result of the URL parser steps with rule’s URL and parentStylesheet’s location. // If the algorithm returns an error, return. [CSSOM] diff --git a/Libraries/LibWeb/CSS/CSSImportRule.h b/Libraries/LibWeb/CSS/CSSImportRule.h index cd5f971ea04..bfb6a2dcbe7 100644 --- a/Libraries/LibWeb/CSS/CSSImportRule.h +++ b/Libraries/LibWeb/CSS/CSSImportRule.h @@ -21,7 +21,7 @@ class CSSImportRule final GC_DECLARE_ALLOCATOR(CSSImportRule); public: - [[nodiscard]] static GC::Ref create(URL::URL, DOM::Document&); + [[nodiscard]] static GC::Ref create(URL::URL, DOM::Document&, RefPtr); virtual ~CSSImportRule() = default; @@ -34,7 +34,7 @@ public: CSSStyleSheet* style_sheet_for_bindings() { return m_style_sheet; } private: - CSSImportRule(URL::URL, DOM::Document&); + CSSImportRule(URL::URL, DOM::Document&, RefPtr); virtual void initialize(JS::Realm&) override; virtual void visit_edges(Cell::Visitor&) override; @@ -48,6 +48,7 @@ private: URL::URL m_url; GC::Ptr m_document; + RefPtr m_supports; GC::Ptr m_style_sheet; Optional m_document_load_event_delayer; }; diff --git a/Libraries/LibWeb/CSS/Parser/RuleParsing.cpp b/Libraries/LibWeb/CSS/Parser/RuleParsing.cpp index b4be2aac584..622929ba722 100644 --- a/Libraries/LibWeb/CSS/Parser/RuleParsing.cpp +++ b/Libraries/LibWeb/CSS/Parser/RuleParsing.cpp @@ -161,16 +161,35 @@ GC::Ptr Parser::convert_to_import_rule(AtRule const& rule) } tokens.discard_whitespace(); - // TODO: Support layers and import-conditions + // FIXME: Implement layer support. + RefPtr supports {}; + if (tokens.next_token().is_function("supports"sv)) { + auto component_value = tokens.consume_a_token(); + TokenStream supports_tokens { component_value.function().value }; + if (supports_tokens.next_token().is_block()) { + supports = parse_a_supports(supports_tokens); + } else { + m_rule_context.append(ContextType::SupportsCondition); + auto declaration = consume_a_declaration(supports_tokens); + m_rule_context.take_last(); + if (declaration.has_value()) { + auto supports_declaration = Supports::Declaration::create(declaration->to_string(), convert_to_style_property(*declaration).has_value()); + supports = Supports::create(supports_declaration.release_nonnull()); + } + } + } + + // FIXME: Implement media query support. + if (tokens.has_next_token()) { if constexpr (CSS_PARSER_DEBUG) { - dbgln("Failed to parse @import rule: Trailing tokens after URL are not yet supported."); + dbgln("Failed to parse @import rule:"); tokens.dump_all_tokens(); } return {}; } - return CSSImportRule::create(url.value(), const_cast(*document())); + return CSSImportRule::create(url.value(), const_cast(*document()), supports); } Optional Parser::parse_layer_name(TokenStream& tokens, AllowBlankLayerName allow_blank_layer_name) diff --git a/Tests/LibWeb/Ref/expected/wpt-import/css/css-cascade/reference/ref-filled-green-100px-square.xht b/Tests/LibWeb/Ref/expected/wpt-import/css/css-cascade/reference/ref-filled-green-100px-square.xht new file mode 100644 index 00000000000..05a13794482 --- /dev/null +++ b/Tests/LibWeb/Ref/expected/wpt-import/css/css-cascade/reference/ref-filled-green-100px-square.xht @@ -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-cascade/import-conditional-002.html b/Tests/LibWeb/Ref/input/wpt-import/css/css-cascade/import-conditional-002.html new file mode 100644 index 00000000000..08ba12f54f8 --- /dev/null +++ b/Tests/LibWeb/Ref/input/wpt-import/css/css-cascade/import-conditional-002.html @@ -0,0 +1,30 @@ + + + + + CSS Cascade: @import with basic supports condition + + + + + + + +

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

+ +
+ + diff --git a/Tests/LibWeb/Ref/input/wpt-import/css/css-cascade/support/test-green.css b/Tests/LibWeb/Ref/input/wpt-import/css/css-cascade/support/test-green.css new file mode 100644 index 00000000000..da8e1014d2a --- /dev/null +++ b/Tests/LibWeb/Ref/input/wpt-import/css/css-cascade/support/test-green.css @@ -0,0 +1,4 @@ +.test { + background: green; + color: green; +} diff --git a/Tests/LibWeb/Ref/input/wpt-import/css/css-cascade/support/test-red.css b/Tests/LibWeb/Ref/input/wpt-import/css/css-cascade/support/test-red.css new file mode 100644 index 00000000000..bb309fcd570 --- /dev/null +++ b/Tests/LibWeb/Ref/input/wpt-import/css/css-cascade/support/test-red.css @@ -0,0 +1,4 @@ +.test { + background: red; + color: red; +}