diff --git a/Meta/Lagom/Tools/CodeGenerators/LibWeb/GenerateCSSPropertyID.cpp b/Meta/Lagom/Tools/CodeGenerators/LibWeb/GenerateCSSPropertyID.cpp index 60e8ac8610..e0c1b53146 100644 --- a/Meta/Lagom/Tools/CodeGenerators/LibWeb/GenerateCSSPropertyID.cpp +++ b/Meta/Lagom/Tools/CodeGenerators/LibWeb/GenerateCSSPropertyID.cpp @@ -105,6 +105,7 @@ namespace Web::CSS { enum class PropertyID { Invalid, Custom, + All, )~~~")); Vector shorthand_property_ids; @@ -361,6 +362,8 @@ Optional property_id_from_camel_case_string(StringView string) Optional property_id_from_string(StringView string) { + if (Infra::is_ascii_case_insensitive_match(string, "all"sv)) + return PropertyID::All; )~~~")); TRY(properties.try_for_each_member([&](auto& name, auto& value) -> ErrorOr { diff --git a/Tests/LibWeb/Layout/expected/css-all-unset.txt b/Tests/LibWeb/Layout/expected/css-all-unset.txt new file mode 100644 index 0000000000..1ae7a33672 --- /dev/null +++ b/Tests/LibWeb/Layout/expected/css-all-unset.txt @@ -0,0 +1,12 @@ +Viewport <#document> at (0,0) content-size 800x600 children: inline + line 0 width: 238.125, height: 17.46875, bottom: 17.46875, baseline: 13.53125 + frag 0 from TextNode start: 1, length: 18, rect: [0,0 134.984375x17.46875] + "* { all: unset; } " + frag 1 from TextNode start: 0, length: 13, rect: [134.984375,0 103.140625x17.46875] + "Hello friends" + InlineNode + InlineNode + InlineNode Hello friends diff --git a/Userland/Libraries/LibWeb/CSS/StyleComputer.cpp b/Userland/Libraries/LibWeb/CSS/StyleComputer.cpp index 0733ddfd25..4abf9d50df 100644 --- a/Userland/Libraries/LibWeb/CSS/StyleComputer.cpp +++ b/Userland/Libraries/LibWeb/CSS/StyleComputer.cpp @@ -83,6 +83,9 @@ struct Traits : public GenericTraits); +static NonnullRefPtr get_inherit_value(JS::Realm& initial_value_context_realm, CSS::PropertyID, DOM::Element const*, Optional); + StyleComputer::StyleComputer(DOM::Document& document) : m_document(document) , m_default_font_metrics(16, Gfx::FontDatabase::default_font().pixel_metrics(), 16) @@ -830,6 +833,31 @@ static void set_property_expanding_shorthands(StyleProperties& style, CSS::Prope style.set_property(property_id, value, declaration); } +void StyleComputer::set_all_properties(DOM::Element& element, Optional pseudo_element, StyleProperties& style, StyleValue const& value, DOM::Document& document, CSS::CSSStyleDeclaration const* declaration) const +{ + for (auto i = to_underlying(CSS::first_longhand_property_id); i <= to_underlying(CSS::last_longhand_property_id); ++i) { + auto property_id = (CSS::PropertyID)i; + + if (value.is_unset()) { + if (is_inherited_property(property_id)) + style.m_property_values[to_underlying(property_id)] = { { get_inherit_value(document.realm(), property_id, &element, pseudo_element), nullptr } }; + else + style.m_property_values[to_underlying(property_id)] = { { property_initial_value(document.realm(), property_id).release_value_but_fixme_should_propagate_errors(), nullptr } }; + continue; + } + + NonnullRefPtr property_value = value; + if (property_value->is_unresolved()) { + if (auto resolved = resolve_unresolved_style_value(element, pseudo_element, property_id, property_value->as_unresolved())) + property_value = resolved.release_nonnull(); + } + if (!property_value->is_unresolved()) + set_property_expanding_shorthands(style, property_id, property_value, document, declaration); + + set_property_expanding_shorthands(style, property_id, value, document, declaration); + } +} + static RefPtr get_custom_property(DOM::Element const& element, Optional pseudo_element, FlyString const& custom_property_name) { if (pseudo_element.has_value()) { @@ -1054,6 +1082,12 @@ void StyleComputer::cascade_declarations(StyleProperties& style, DOM::Element& e for (auto const& property : verify_cast(match.rule->declaration()).properties()) { if (important != property.important) continue; + + if (property.property_id == CSS::PropertyID::All) { + set_all_properties(element, pseudo_element, style, property.value, m_document, &match.rule->declaration()); + continue; + } + auto property_value = property.value; if (property.value->is_unresolved()) { if (auto resolved = resolve_unresolved_style_value(element, pseudo_element, property.property_id, property.value->as_unresolved())) @@ -1069,6 +1103,12 @@ void StyleComputer::cascade_declarations(StyleProperties& style, DOM::Element& e for (auto const& property : inline_style->properties()) { if (important != property.important) continue; + + if (property.property_id == CSS::PropertyID::All) { + set_all_properties(element, pseudo_element, style, property.value, m_document, inline_style); + continue; + } + auto property_value = property.value; if (property.value->is_unresolved()) { if (auto resolved = resolve_unresolved_style_value(element, pseudo_element, property.property_id, property.value->as_unresolved())) @@ -1804,7 +1844,7 @@ ErrorOr StyleComputer::compute_cascaded_values(StyleProperties& style, DOM return {}; } -static DOM::Element const* element_to_inherit_style_from(DOM::Element const* element, Optional pseudo_element) +DOM::Element const* element_to_inherit_style_from(DOM::Element const* element, Optional pseudo_element) { // Pseudo-elements treat their originating element as their parent. DOM::Element const* parent_element = nullptr; @@ -1816,7 +1856,7 @@ static DOM::Element const* element_to_inherit_style_from(DOM::Element const* ele return parent_element; } -static NonnullRefPtr get_inherit_value(JS::Realm& initial_value_context_realm, CSS::PropertyID property_id, DOM::Element const* element, Optional pseudo_element) +NonnullRefPtr get_inherit_value(JS::Realm& initial_value_context_realm, CSS::PropertyID property_id, DOM::Element const* element, Optional pseudo_element) { auto* parent_element = element_to_inherit_style_from(element, pseudo_element); diff --git a/Userland/Libraries/LibWeb/CSS/StyleComputer.h b/Userland/Libraries/LibWeb/CSS/StyleComputer.h index 1df1f3aa9b..8f8a8601c7 100644 --- a/Userland/Libraries/LibWeb/CSS/StyleComputer.h +++ b/Userland/Libraries/LibWeb/CSS/StyleComputer.h @@ -154,6 +154,8 @@ private: bool expand_variables(DOM::Element&, Optional, StringView property_name, HashMap>& dependencies, Parser::TokenStream& source, Vector& dest) const; bool expand_unresolved_values(DOM::Element&, StringView property_name, Parser::TokenStream& source, Vector& dest) const; + void set_all_properties(DOM::Element&, Optional, StyleProperties&, StyleValue const&, DOM::Document&, CSS::CSSStyleDeclaration const*) const; + template void for_each_stylesheet(CascadeOrigin, Callback) const;