summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibWeb/CSS
diff options
context:
space:
mode:
authorTobias Christiansen <tobi@tobyase.de>2021-05-24 23:02:58 +0200
committerLinus Groh <mail@linusgroh.de>2021-05-28 10:45:38 +0100
commitfd6b04055c3ca7d7e0f9e94f9842d83ea213f2ea (patch)
tree0d59699d45330e7854892b136170e6bc25515a61 /Userland/Libraries/LibWeb/CSS
parentbf9c5ffb3f8e1544fe4168fb59d8eecccf7a001d (diff)
downloadserenity-fd6b04055c3ca7d7e0f9e94f9842d83ea213f2ea.zip
LibWeb: Resolve custom properties
The way to get the custom properties is pretty weird and this code is as far from optimized as it gets but somehow it works :^)
Diffstat (limited to 'Userland/Libraries/LibWeb/CSS')
-rw-r--r--Userland/Libraries/LibWeb/CSS/StyleResolver.cpp42
-rw-r--r--Userland/Libraries/LibWeb/CSS/StyleResolver.h7
2 files changed, 48 insertions, 1 deletions
diff --git a/Userland/Libraries/LibWeb/CSS/StyleResolver.cpp b/Userland/Libraries/LibWeb/CSS/StyleResolver.cpp
index bf5720a413..e2837be7ca 100644
--- a/Userland/Libraries/LibWeb/CSS/StyleResolver.cpp
+++ b/Userland/Libraries/LibWeb/CSS/StyleResolver.cpp
@@ -765,6 +765,37 @@ static void set_property_expanding_shorthands(StyleProperties& style, CSS::Prope
style.set_property(property_id, value);
}
+StyleResolver::CustomPropertyResolutionTuple StyleResolver::resolve_custom_property_with_specificity(const DOM::Element& element, const String& custom_property_name) const
+{
+ auto parent_element = element.parent_element();
+ CustomPropertyResolutionTuple parent_resolved {};
+ if (parent_element)
+ parent_resolved = resolve_custom_property_with_specificity(*parent_element, custom_property_name);
+
+ auto matching_rules = collect_matching_rules(element);
+ sort_matching_rules(matching_rules);
+
+ for (int i = matching_rules.size() - 1; i >= 0; --i) {
+ auto& match = matching_rules[i];
+ if (match.specificity < parent_resolved.specificity)
+ continue;
+
+ auto custom_property_style = match.rule->declaration().custom_property(custom_property_name);
+ if (custom_property_style.has_value()) {
+ return { custom_property_style.value(), match.specificity };
+ }
+ }
+
+ return parent_resolved;
+}
+
+Optional<StyleProperty> StyleResolver::resolve_custom_property(const DOM::Element& element, const String& custom_property_name) const
+{
+ auto resolved_with_specificity = resolve_custom_property_with_specificity(element, custom_property_name);
+
+ return resolved_with_specificity.style;
+}
+
NonnullRefPtr<StyleProperties> StyleResolver::resolve_style(const DOM::Element& element) const
{
auto style = StyleProperties::create();
@@ -783,7 +814,16 @@ NonnullRefPtr<StyleProperties> StyleResolver::resolve_style(const DOM::Element&
for (auto& match : matching_rules) {
for (auto& property : match.rule->declaration().properties()) {
- set_property_expanding_shorthands(style, property.property_id, property.value, m_document);
+ auto property_value = property.value;
+ if (property.value->is_custom_property()) {
+ auto prop = reinterpret_cast<const CSS::CustomStyleValue*>(property.value.ptr());
+ auto custom_prop_name = prop->custom_property_name();
+ auto resolved = resolve_custom_property(element, custom_prop_name);
+ if (resolved.has_value()) {
+ property_value = resolved.value().value;
+ }
+ }
+ set_property_expanding_shorthands(style, property.property_id, property_value, m_document);
}
}
diff --git a/Userland/Libraries/LibWeb/CSS/StyleResolver.h b/Userland/Libraries/LibWeb/CSS/StyleResolver.h
index 6b2e980893..35a933e5fc 100644
--- a/Userland/Libraries/LibWeb/CSS/StyleResolver.h
+++ b/Userland/Libraries/LibWeb/CSS/StyleResolver.h
@@ -8,6 +8,7 @@
#include <AK/NonnullRefPtrVector.h>
#include <AK/OwnPtr.h>
+#include <LibWeb/CSS/CSSStyleDeclaration.h>
#include <LibWeb/CSS/StyleProperties.h>
#include <LibWeb/Forward.h>
@@ -33,6 +34,12 @@ public:
Vector<MatchingRule> collect_matching_rules(const DOM::Element&) const;
void sort_matching_rules(Vector<MatchingRule>&) const;
+ struct CustomPropertyResolutionTuple {
+ Optional<StyleProperty> style {};
+ u32 specificity { 0 };
+ };
+ CustomPropertyResolutionTuple resolve_custom_property_with_specificity(const DOM::Element&, const String&) const;
+ Optional<StyleProperty> resolve_custom_property(const DOM::Element&, const String&) const;
static bool is_inherited_property(CSS::PropertyID);