LibWeb: Implement the CSS all property

This sets all longhand values to one of initial, inherit, unset or
revert. Note that revert is not supported yet, but will be soon.
This commit is contained in:
Andreas Kling 2023-07-29 10:53:24 +02:00
parent de31a8a425
commit 13d5d47b56
Notes: sideshowbarker 2024-07-17 07:16:27 +09:00
5 changed files with 62 additions and 2 deletions

View file

@ -105,6 +105,7 @@ namespace Web::CSS {
enum class PropertyID {
Invalid,
Custom,
All,
)~~~"));
Vector<DeprecatedString> shorthand_property_ids;
@ -361,6 +362,8 @@ Optional<PropertyID> property_id_from_camel_case_string(StringView string)
Optional<PropertyID> 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<void> {

View file

@ -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 <html>
InlineNode <head>
InlineNode <style>
TextNode <#text>
InlineNode <body>
TextNode <#text>

View file

@ -0,0 +1,3 @@
<!doctype html><style>
* { all: unset; }
</style>Hello friends

View file

@ -83,6 +83,9 @@ struct Traits<Web::CSS::FontFaceKey> : public GenericTraits<Web::CSS::FontFaceKe
namespace Web::CSS {
static DOM::Element const* element_to_inherit_style_from(DOM::Element const*, Optional<CSS::Selector::PseudoElement>);
static NonnullRefPtr<StyleValue const> get_inherit_value(JS::Realm& initial_value_context_realm, CSS::PropertyID, DOM::Element const*, Optional<CSS::Selector::PseudoElement>);
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<CSS::Selector::PseudoElement> 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<StyleValue> 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<StyleValue const> get_custom_property(DOM::Element const& element, Optional<CSS::Selector::PseudoElement> 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<PropertyOwningCSSStyleDeclaration>(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<void> StyleComputer::compute_cascaded_values(StyleProperties& style, DOM
return {};
}
static DOM::Element const* element_to_inherit_style_from(DOM::Element const* element, Optional<CSS::Selector::PseudoElement> pseudo_element)
DOM::Element const* element_to_inherit_style_from(DOM::Element const* element, Optional<CSS::Selector::PseudoElement> 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<StyleValue const> get_inherit_value(JS::Realm& initial_value_context_realm, CSS::PropertyID property_id, DOM::Element const* element, Optional<CSS::Selector::PseudoElement> pseudo_element)
NonnullRefPtr<StyleValue const> get_inherit_value(JS::Realm& initial_value_context_realm, CSS::PropertyID property_id, DOM::Element const* element, Optional<CSS::Selector::PseudoElement> pseudo_element)
{
auto* parent_element = element_to_inherit_style_from(element, pseudo_element);

View file

@ -154,6 +154,8 @@ private:
bool expand_variables(DOM::Element&, Optional<CSS::Selector::PseudoElement>, StringView property_name, HashMap<FlyString, NonnullRefPtr<PropertyDependencyNode>>& dependencies, Parser::TokenStream<Parser::ComponentValue>& source, Vector<Parser::ComponentValue>& dest) const;
bool expand_unresolved_values(DOM::Element&, StringView property_name, Parser::TokenStream<Parser::ComponentValue>& source, Vector<Parser::ComponentValue>& dest) const;
void set_all_properties(DOM::Element&, Optional<CSS::Selector::PseudoElement>, StyleProperties&, StyleValue const&, DOM::Document&, CSS::CSSStyleDeclaration const*) const;
template<typename Callback>
void for_each_stylesheet(CascadeOrigin, Callback) const;