diff --git a/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp b/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp index 0cef7885f1..b68f5e6e8c 100644 --- a/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp +++ b/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp @@ -6200,6 +6200,25 @@ Optional Parser::parse_css_value_for_properties(Readon || any_property_accepts_type(property_ids, ValueType::Time).has_value(); if (property_accepts_dimension) { + if (peek_token.is(Token::Type::Number) && m_context.is_parsing_svg_presentation_attribute()) { + auto transaction = tokens.begin_transaction(); + auto token = tokens.next_token(); + // https://svgwg.org/svg2-draft/types.html#presentation-attribute-css-value + // We need to allow in any place that expects a or . + // FIXME: How should these numbers be interpreted? https://github.com/w3c/svgwg/issues/792 + // For now: Convert them to px lengths, or deg angles. + auto angle = Angle::make_degrees(token.token().number_value()); + if (auto property = any_property_accepts_type(property_ids, ValueType::Angle); property.has_value() && property_accepts_angle(*property, angle)) { + transaction.commit(); + return PropertyAndValue { *property, AngleStyleValue::create(angle) }; + } + auto length = Length::make_px(CSSPixels::nearest_value_for(token.token().number_value())); + if (auto property = any_property_accepts_type(property_ids, ValueType::Length); property.has_value() && property_accepts_length(*property, length)) { + transaction.commit(); + return PropertyAndValue { *property, LengthStyleValue::create(length) }; + } + } + auto transaction = tokens.begin_transaction(); if (auto maybe_dimension = parse_dimension(peek_token); maybe_dimension.has_value()) { (void)tokens.next_token(); @@ -6249,6 +6268,9 @@ Optional Parser::parse_css_value_for_properties(Readon (void)tokens.next_token(); auto& calculated = *maybe_calculated; // This is a bit sensitive to ordering: `` and `` have to be checked before ``. + // FIXME: When parsing SVG presentation attributes, is permitted wherever , , or are. + // The specifics are unclear, so I'm ignoring this for calculated values for now. + // See https://github.com/w3c/svgwg/issues/792 if (calculated.resolves_to_percentage()) { if (auto property = any_property_accepts_type(property_ids, ValueType::Percentage); property.has_value()) return PropertyAndValue { *property, calculated }; diff --git a/Userland/Libraries/LibWeb/CSS/Parser/ParsingContext.cpp b/Userland/Libraries/LibWeb/CSS/Parser/ParsingContext.cpp index 671a2b35c1..4fd1e036d7 100644 --- a/Userland/Libraries/LibWeb/CSS/Parser/ParsingContext.cpp +++ b/Userland/Libraries/LibWeb/CSS/Parser/ParsingContext.cpp @@ -13,29 +13,33 @@ namespace Web::CSS::Parser { -ParsingContext::ParsingContext(JS::Realm& realm) +ParsingContext::ParsingContext(JS::Realm& realm, Mode mode) : m_realm(realm) + , m_mode(mode) { } -ParsingContext::ParsingContext(DOM::Document const& document, AK::URL url) +ParsingContext::ParsingContext(DOM::Document const& document, AK::URL url, Mode mode) : m_realm(const_cast(document.realm())) , m_document(&document) , m_url(move(url)) + , m_mode(mode) { } -ParsingContext::ParsingContext(DOM::Document const& document) +ParsingContext::ParsingContext(DOM::Document const& document, Mode mode) : m_realm(const_cast(document.realm())) , m_document(&document) , m_url(document.url()) + , m_mode(mode) { } -ParsingContext::ParsingContext(DOM::ParentNode& parent_node) +ParsingContext::ParsingContext(DOM::ParentNode& parent_node, Mode mode) : m_realm(parent_node.realm()) , m_document(&parent_node.document()) , m_url(parent_node.document().url()) + , m_mode(mode) { } diff --git a/Userland/Libraries/LibWeb/CSS/Parser/ParsingContext.h b/Userland/Libraries/LibWeb/CSS/Parser/ParsingContext.h index 506cee4f92..a2550e04b8 100644 --- a/Userland/Libraries/LibWeb/CSS/Parser/ParsingContext.h +++ b/Userland/Libraries/LibWeb/CSS/Parser/ParsingContext.h @@ -14,10 +14,18 @@ namespace Web::CSS::Parser { class ParsingContext { public: - explicit ParsingContext(JS::Realm&); - explicit ParsingContext(DOM::Document const&); - explicit ParsingContext(DOM::Document const&, AK::URL); - explicit ParsingContext(DOM::ParentNode&); + enum class Mode { + Normal, + SVGPresentationAttribute, // See https://svgwg.org/svg2-draft/types.html#presentation-attribute-css-value + }; + + explicit ParsingContext(JS::Realm&, Mode = Mode::Normal); + explicit ParsingContext(DOM::Document const&, Mode = Mode::Normal); + explicit ParsingContext(DOM::Document const&, AK::URL, Mode = Mode::Normal); + explicit ParsingContext(DOM::ParentNode&, Mode = Mode::Normal); + + Mode mode() const { return m_mode; } + bool is_parsing_svg_presentation_attribute() const { return m_mode == Mode::SVGPresentationAttribute; } bool in_quirks_mode() const; DOM::Document const* document() const { return m_document; } @@ -34,6 +42,7 @@ private: JS::GCPtr m_document; PropertyID m_current_property_id { PropertyID::Invalid }; AK::URL m_url; + Mode m_mode { Mode::Normal }; }; }