LibWeb/CSS: Add basic registered properties with initial values

Add global registry for registered properties and partial support
for `@property` rule. Enables registering properties with initial
values. Also adds basic retrieval via `var()`.

Note: This is not a complete `@property` implementation.
This commit is contained in:
norbiros 2025-07-17 14:51:22 +02:00 committed by Sam Atkins
commit 7ad01d28a8
Notes: github-actions[bot] 2025-07-18 10:13:56 +00:00
9 changed files with 73 additions and 20 deletions

View file

@ -29,6 +29,7 @@ public:
FlyString const& syntax() const { return m_syntax; }
bool inherits() const { return m_inherits; }
Optional<String> initial_value() const;
RefPtr<CSSStyleValue const> initial_style_value() const { return m_initial_value; }
private:
CSSPropertyRule(JS::Realm&, FlyString name, FlyString syntax, bool inherits, RefPtr<CSSStyleValue const> initial_value);

View file

@ -145,6 +145,13 @@ GC::RootVector<GC::Ref<CSSRule>> Parser::convert_rules(Vector<Rule> const& raw_r
m_declared_namespaces.set(as<CSSNamespaceRule>(*rule).prefix());
break;
case CSSRule::Type::Property: {
auto& property_rule = as<CSSPropertyRule>(*rule);
if (m_document) {
const_cast<DOM::Document*>(m_document.ptr())->registered_custom_properties().set(property_rule.name(), property_rule);
}
[[fallthrough]];
}
default:
import_rules_valid = false;
namespace_rules_valid = false;

View file

@ -3106,33 +3106,25 @@ void StyleComputer::unload_fonts_from_sheet(CSSStyleSheet& sheet)
}
}
static NonnullRefPtr<CSSStyleValue const> custom_property_initial_value(FlyString const& name)
{
// FIXME: Look-up initial value for registered properties. (@property)
(void)name;
// For non-registered properties, the initial value is the guaranteed-invalid value.
return GuaranteedInvalidStyleValue::create();
}
NonnullRefPtr<CSSStyleValue const> StyleComputer::compute_value_of_custom_property(DOM::AbstractElement abstract_element, FlyString const& name, Optional<Parser::GuardedSubstitutionContexts&> guarded_contexts)
{
// https://drafts.csswg.org/css-variables/#propdef-
// The computed value of a custom property is its specified value with any arbitrary-substitution functions replaced.
// FIXME: These should probably be part of ComputedProperties.
auto& document = abstract_element.document();
auto value = abstract_element.get_custom_property(name);
if (!value || value->is_initial())
return custom_property_initial_value(name);
return document.custom_property_initial_value(name);
// Unset is the same as inherit for inherited properties, and by default all custom properties are inherited.
// FIXME: Support non-inherited registered custom properties.
if (value->is_inherit() || value->is_unset()) {
if (!abstract_element.parent_element())
return custom_property_initial_value(name);
return document.custom_property_initial_value(name);
auto inherited_value = DOM::AbstractElement { const_cast<DOM::Element&>(*abstract_element.parent_element()) }.get_custom_property(name);
if (!inherited_value)
return custom_property_initial_value(name);
return document.custom_property_initial_value(name);
return inherited_value.release_nonnull();
}