diff --git a/Libraries/LibWeb/CSS/CSSFontFaceDescriptors.cpp b/Libraries/LibWeb/CSS/CSSFontFaceDescriptors.cpp index 528ee08e5ad..2cb99d668b3 100644 --- a/Libraries/LibWeb/CSS/CSSFontFaceDescriptors.cpp +++ b/Libraries/LibWeb/CSS/CSSFontFaceDescriptors.cpp @@ -234,7 +234,7 @@ WebIDL::ExceptionOr CSSFontFaceDescriptors::set_css_text(StringView value) // 3. Parse the given value and, if the return value is not the empty list, insert the items in the list into the // declarations, in specified order. - auto descriptors = parse_css_list_of_descriptors(Parser::ParsingParams {}, AtRuleID::FontFace, value); + auto descriptors = parse_css_descriptor_declaration_block(Parser::ParsingParams {}, AtRuleID::FontFace, value); if (!descriptors.is_empty()) m_descriptors = move(descriptors); diff --git a/Libraries/LibWeb/CSS/CSSStyleProperties.cpp b/Libraries/LibWeb/CSS/CSSStyleProperties.cpp index 6850a3f7e4f..464ce187242 100644 --- a/Libraries/LibWeb/CSS/CSSStyleProperties.cpp +++ b/Libraries/LibWeb/CSS/CSSStyleProperties.cpp @@ -1216,7 +1216,7 @@ void CSSStyleProperties::set_declarations_from_text(StringView css_text) auto parsing_params = owner_node().has_value() ? Parser::ParsingParams(owner_node()->element().document()) : Parser::ParsingParams(); - auto style = parse_css_style_attribute(parsing_params, css_text); + auto style = parse_css_property_declaration_block(parsing_params, css_text); set_the_declarations(style.properties, style.custom_properties); } diff --git a/Libraries/LibWeb/CSS/Parser/Helpers.cpp b/Libraries/LibWeb/CSS/Parser/Helpers.cpp index 5cf6e4b5888..79f2fba2924 100644 --- a/Libraries/LibWeb/CSS/Parser/Helpers.cpp +++ b/Libraries/LibWeb/CSS/Parser/Helpers.cpp @@ -57,18 +57,18 @@ GC::Ref parse_css_stylesheet(CSS::Parser::ParsingParams cons return style_sheet; } -CSS::Parser::Parser::PropertiesAndCustomProperties parse_css_style_attribute(CSS::Parser::ParsingParams const& context, StringView css) +CSS::Parser::Parser::PropertiesAndCustomProperties parse_css_property_declaration_block(CSS::Parser::ParsingParams const& context, StringView css) { if (css.is_empty()) return {}; - return CSS::Parser::Parser::create(context, css).parse_as_style_attribute(); + return CSS::Parser::Parser::create(context, css).parse_as_property_declaration_block(); } -Vector parse_css_list_of_descriptors(CSS::Parser::ParsingParams const& parsing_params, CSS::AtRuleID at_rule_id, StringView css) +Vector parse_css_descriptor_declaration_block(CSS::Parser::ParsingParams const& parsing_params, CSS::AtRuleID at_rule_id, StringView css) { if (css.is_empty()) return {}; - return CSS::Parser::Parser::create(parsing_params, css).parse_as_list_of_descriptors(at_rule_id); + return CSS::Parser::Parser::create(parsing_params, css).parse_as_descriptor_declaration_block(at_rule_id); } RefPtr parse_css_value(CSS::Parser::ParsingParams const& context, StringView string, CSS::PropertyID property_id) diff --git a/Libraries/LibWeb/CSS/Parser/Parser.cpp b/Libraries/LibWeb/CSS/Parser/Parser.cpp index a5b1a36d41d..5bad45a46b6 100644 --- a/Libraries/LibWeb/CSS/Parser/Parser.cpp +++ b/Libraries/LibWeb/CSS/Parser/Parser.cpp @@ -1337,7 +1337,8 @@ Vector> Parser::parse_a_comma_separated_list_of_component return groups; } -Parser::PropertiesAndCustomProperties Parser::parse_as_style_attribute() +// https://drafts.csswg.org/cssom/#parse-a-css-declaration-block +Parser::PropertiesAndCustomProperties Parser::parse_as_property_declaration_block() { auto expand_shorthands = [&](Vector& properties) -> Vector { Vector expanded_properties; @@ -1357,16 +1358,36 @@ Parser::PropertiesAndCustomProperties Parser::parse_as_style_attribute() return expanded_properties; }; + // 1. Let declarations be the returned declarations from invoking parse a block’s contents with string. m_rule_context.append(ContextType::Style); auto declarations_and_at_rules = parse_a_blocks_contents(m_token_stream); m_rule_context.take_last(); - auto properties = extract_properties(declarations_and_at_rules); - properties.properties = expand_shorthands(properties.properties); - return properties; + // 2. Let parsed declarations be a new empty list. + PropertiesAndCustomProperties parsed_declarations; + + // 3. For each item declaration in declarations, follow these substeps: + for (auto const& rule_or_list : declarations_and_at_rules) { + if (rule_or_list.has()) + continue; + + auto& rule_declarations = rule_or_list.get>(); + for (auto const& declaration : rule_declarations) { + // 1. Let parsed declaration be the result of parsing declaration according to the appropriate CSS + // specifications, dropping parts that are said to be ignored. If the whole declaration is dropped, let + // parsed declaration be null. + // 2. If parsed declaration is not null, append it to parsed declarations. + extract_property(declaration, parsed_declarations); + } + } + parsed_declarations.properties = expand_shorthands(parsed_declarations.properties); + + // 4. Return parsed declarations. + return parsed_declarations; } -Vector Parser::parse_as_list_of_descriptors(AtRuleID at_rule_id) +// https://drafts.csswg.org/cssom/#parse-a-css-declaration-block +Vector Parser::parse_as_descriptor_declaration_block(AtRuleID at_rule_id) { auto context_type = [at_rule_id] { switch (at_rule_id) { @@ -1378,22 +1399,32 @@ Vector Parser::parse_as_list_of_descriptors(AtRuleID at_rule_id) VERIFY_NOT_REACHED(); }(); + // 1. Let declarations be the returned declarations from invoking parse a block’s contents with string. m_rule_context.append(context_type); auto declarations_and_at_rules = parse_a_blocks_contents(m_token_stream); m_rule_context.take_last(); - Vector descriptors; + // 2. Let parsed declarations be a new empty list. + Vector parsed_declarations; + + // 3. For each item declaration in declarations, follow these substeps: for (auto const& rule_or_list : declarations_and_at_rules) { if (rule_or_list.has()) continue; - auto& declarations = rule_or_list.get>(); - for (auto const& declaration : declarations) { - if (auto descriptor = convert_to_descriptor(at_rule_id, declaration); descriptor.has_value()) - descriptors.append(descriptor.release_value()); + auto& rule_declarations = rule_or_list.get>(); + for (auto const& declaration : rule_declarations) { + // 1. Let parsed declaration be the result of parsing declaration according to the appropriate CSS + // specifications, dropping parts that are said to be ignored. If the whole declaration is dropped, let + // parsed declaration be null. + // 2. If parsed declaration is not null, append it to parsed declarations. + if (auto parsed_declaration = convert_to_descriptor(at_rule_id, declaration); parsed_declaration.has_value()) + parsed_declarations.append(parsed_declaration.release_value()); } } - return descriptors; + + // 4. Return parsed declarations. + return parsed_declarations; } bool Parser::is_valid_in_the_current_context(Declaration const&) const @@ -1518,22 +1549,6 @@ bool Parser::is_valid_in_the_current_context(QualifiedRule const&) const VERIFY_NOT_REACHED(); } -Parser::PropertiesAndCustomProperties Parser::extract_properties(Vector const& rules_and_lists_of_declarations) -{ - PropertiesAndCustomProperties result; - for (auto const& rule_or_list : rules_and_lists_of_declarations) { - if (rule_or_list.has()) - continue; - - auto& declarations = rule_or_list.get>(); - PropertiesAndCustomProperties& dest = result; - for (auto const& declaration : declarations) { - extract_property(declaration, dest); - } - } - return result; -} - void Parser::extract_property(Declaration const& declaration, PropertiesAndCustomProperties& dest) { if (auto maybe_property = convert_to_style_property(declaration); maybe_property.has_value()) { diff --git a/Libraries/LibWeb/CSS/Parser/Parser.h b/Libraries/LibWeb/CSS/Parser/Parser.h index e6bdd289dda..a37c4ed2a2a 100644 --- a/Libraries/LibWeb/CSS/Parser/Parser.h +++ b/Libraries/LibWeb/CSS/Parser/Parser.h @@ -96,8 +96,8 @@ public: Vector properties; HashMap custom_properties; }; - PropertiesAndCustomProperties parse_as_style_attribute(); - Vector parse_as_list_of_descriptors(AtRuleID); + PropertiesAndCustomProperties parse_as_property_declaration_block(); + Vector parse_as_descriptor_declaration_block(AtRuleID); CSSRule* parse_as_css_rule(); Optional parse_as_supports_condition(); GC::RootVector> parse_as_stylesheet_contents(); @@ -466,7 +466,6 @@ private: static bool has_ignored_vendor_prefix(StringView); - PropertiesAndCustomProperties extract_properties(Vector const&); void extract_property(Declaration const&, Parser::PropertiesAndCustomProperties&); DOM::Document const* document() const; @@ -523,8 +522,8 @@ private: namespace Web { GC::Ref parse_css_stylesheet(CSS::Parser::ParsingParams const&, StringView, Optional<::URL::URL> location = {}, Vector> = {}); -CSS::Parser::Parser::PropertiesAndCustomProperties parse_css_style_attribute(CSS::Parser::ParsingParams const&, StringView); -Vector parse_css_list_of_descriptors(CSS::Parser::ParsingParams const&, CSS::AtRuleID, StringView); +CSS::Parser::Parser::PropertiesAndCustomProperties parse_css_property_declaration_block(CSS::Parser::ParsingParams const&, StringView); +Vector parse_css_descriptor_declaration_block(CSS::Parser::ParsingParams const&, CSS::AtRuleID, StringView); RefPtr parse_css_value(CSS::Parser::ParsingParams const&, StringView, CSS::PropertyID property_id = CSS::PropertyID::Invalid); RefPtr parse_css_descriptor(CSS::Parser::ParsingParams const&, CSS::AtRuleID, CSS::DescriptorID, StringView); Optional parse_selector(CSS::Parser::ParsingParams const&, StringView);