diff options
author | Simon Wanner <skyrising@pvpctutorials.de> | 2022-03-29 23:33:50 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2022-03-30 03:18:14 +0200 |
commit | 6437f5da36e824c680b1c9cc3f84c3e10e072bdb (patch) | |
tree | 1b3dc98f5c1a203f6b641ceb72ed624f2e54cd2a /Userland/Libraries/LibWeb/CSS/StyleComputer.cpp | |
parent | ba6ba67fa04d22759d0dc1e52e3994574b1aba5f (diff) | |
download | serenity-6437f5da36e824c680b1c9cc3f84c3e10e072bdb.zip |
LibWeb: Add basic support for the attr() CSS function
CSS Values and Units Module Level 5 defines attr as:
`attr(<q-name> <attr-type>?, <declaration-value>?)`
This implementation does not contain support for the type argument,
effectively supporting `attr(<q-name>, <declaration-value>?)`
Diffstat (limited to 'Userland/Libraries/LibWeb/CSS/StyleComputer.cpp')
-rw-r--r-- | Userland/Libraries/LibWeb/CSS/StyleComputer.cpp | 35 |
1 files changed, 32 insertions, 3 deletions
diff --git a/Userland/Libraries/LibWeb/CSS/StyleComputer.cpp b/Userland/Libraries/LibWeb/CSS/StyleComputer.cpp index c7fd6898cb..0ed30cc942 100644 --- a/Userland/Libraries/LibWeb/CSS/StyleComputer.cpp +++ b/Userland/Libraries/LibWeb/CSS/StyleComputer.cpp @@ -495,7 +495,7 @@ static RefPtr<StyleValue> get_custom_property(DOM::Element const& element, FlySt bool StyleComputer::expand_unresolved_values(DOM::Element& element, StringView property_name, HashMap<FlyString, NonnullRefPtr<PropertyDependencyNode>>& dependencies, Vector<StyleComponentValueRule> const& source, Vector<StyleComponentValueRule>& dest, size_t source_start_index) const { // FIXME: Do this better! - // We build a copy of the tree of StyleComponentValueRules, with all var()s replaced with their contents. + // We build a copy of the tree of StyleComponentValueRules, with all var()s and attr()s replaced with their contents. // This is a very naive solution, and we could do better if the CSS Parser could accept tokens one at a time. // Arbitrary large value chosen to avoid the billion-laughs attack. @@ -553,6 +553,35 @@ bool StyleComputer::expand_unresolved_values(DOM::Element& element, StringView p return false; continue; } + } else if (value.function().name().equals_ignoring_case("attr"sv)) { + // https://drafts.csswg.org/css-values-5/#attr-substitution + auto const& attr_contents = value.function().values(); + if (attr_contents.is_empty()) + return false; + + auto const& attr_name_token = attr_contents.first(); + if (!attr_name_token.is(Token::Type::Ident)) + return false; + auto attr_name = attr_name_token.token().ident(); + + auto attr_value = element.get_attribute(attr_name); + // 1. If the attr() function has a substitution value, replace the attr() function by the substitution value. + if (!attr_value.is_null()) { + // FIXME: attr() should also accept an optional type argument, not just strings. + dest.empend(Token::of_string(attr_value)); + continue; + } + + // 2. Otherwise, if the attr() function has a fallback value as its last argument, replace the attr() function by the fallback value. + // If there are any var() or attr() references in the fallback, substitute them as well. + if (attr_contents.size() > 2 && attr_contents[1].is(Token::Type::Comma)) { + if (!expand_unresolved_values(element, property_name, dependencies, attr_contents, dest, 2)) + return false; + continue; + } + + // 3. Otherwise, the property containing the attr() function is invalid at computed-value time. + return false; } auto const& source_function = value.function(); @@ -580,9 +609,9 @@ bool StyleComputer::expand_unresolved_values(DOM::Element& element, StringView p RefPtr<StyleValue> StyleComputer::resolve_unresolved_style_value(DOM::Element& element, PropertyID property_id, UnresolvedStyleValue const& unresolved) const { - // Unresolved always contains a var(), unless it is a custom property's value, in which case we shouldn't be trying + // Unresolved always contains a var() or attr(), unless it is a custom property's value, in which case we shouldn't be trying // to produce a different StyleValue from it. - VERIFY(unresolved.contains_var()); + VERIFY(unresolved.contains_var_or_attr()); Vector<StyleComponentValueRule> expanded_values; HashMap<FlyString, NonnullRefPtr<PropertyDependencyNode>> dependencies; |