소스 검색

LibWeb: Store custom properties in CSSStyleDeclaration

Keep them around when parsing and store them in the CSSStyleDeclaration
when done.
Tobias Christiansen 4 년 전
부모
커밋
0d7169b91a

+ 3 - 2
Userland/Libraries/LibWeb/CSS/CSSStyleDeclaration.cpp

@@ -9,8 +9,9 @@
 
 namespace Web::CSS {
 
-CSSStyleDeclaration::CSSStyleDeclaration(Vector<StyleProperty>&& properties)
+CSSStyleDeclaration::CSSStyleDeclaration(Vector<StyleProperty>&& properties, HashMap<String, StyleProperty>&& custom_properties)
     : m_properties(move(properties))
+    , m_custom_properties(move(custom_properties))
 {
 }
 
@@ -26,7 +27,7 @@ String CSSStyleDeclaration::item(size_t index) const
 }
 
 ElementInlineCSSStyleDeclaration::ElementInlineCSSStyleDeclaration(DOM::Element& element)
-    : CSSStyleDeclaration({})
+    : CSSStyleDeclaration({}, {})
     , m_element(element.make_weak_ptr<DOM::Element>())
 {
 }

+ 7 - 3
Userland/Libraries/LibWeb/CSS/CSSStyleDeclaration.h

@@ -16,6 +16,7 @@ namespace Web::CSS {
 struct StyleProperty {
     CSS::PropertyID property_id;
     NonnullRefPtr<StyleValue> value;
+    String custom_name {};
     bool important { false };
 };
 
@@ -25,25 +26,28 @@ class CSSStyleDeclaration
 public:
     using WrapperType = Bindings::CSSStyleDeclarationWrapper;
 
-    static NonnullRefPtr<CSSStyleDeclaration> create(Vector<StyleProperty>&& properties)
+    static NonnullRefPtr<CSSStyleDeclaration> create(Vector<StyleProperty>&& properties, HashMap<String, StyleProperty>&& custom_properties)
     {
-        return adopt_ref(*new CSSStyleDeclaration(move(properties)));
+        return adopt_ref(*new CSSStyleDeclaration(move(properties), move(custom_properties)));
     }
 
     virtual ~CSSStyleDeclaration();
 
     const Vector<StyleProperty>& properties() const { return m_properties; }
+    const Optional<StyleProperty> custom_property(const String& custom_property_name) const { return m_custom_properties.get(custom_property_name); }
+    size_t custom_property_count() const { return m_custom_properties.size(); };
 
     size_t length() const { return m_properties.size(); }
     String item(size_t index) const;
 
 protected:
-    explicit CSSStyleDeclaration(Vector<StyleProperty>&&);
+    explicit CSSStyleDeclaration(Vector<StyleProperty>&&, HashMap<String, StyleProperty>&&);
 
 private:
     friend class Bindings::CSSStyleDeclarationWrapper;
 
     Vector<StyleProperty> m_properties;
+    HashMap<String, StyleProperty> m_custom_properties;
 };
 
 class ElementInlineCSSStyleDeclaration final : public CSSStyleDeclaration {

+ 22 - 8
Userland/Libraries/LibWeb/CSS/Parser/DeprecatedCSSParser.cpp

@@ -808,15 +808,23 @@ public:
         auto value = parse_css_value(m_context, property_value, property_id);
         if (!value)
             return {};
-        return CSS::StyleProperty { property_id, value.release_nonnull(), important };
+        if (property_id == CSS::PropertyID::Custom) {
+            return CSS::StyleProperty { property_id, value.release_nonnull(), property_name, important };
+        }
+        return CSS::StyleProperty { property_id, value.release_nonnull(), {}, important };
     }
 
     void parse_declaration()
     {
         for (;;) {
             auto property = parse_property();
-            if (property.has_value())
-                current_rule.properties.append(property.value());
+            if (property.has_value()) {
+                auto property_value = property.value();
+                if (property_value.property_id == CSS::PropertyID::Custom)
+                    current_rule.custom_properties.set(property_value.custom_name, property_value);
+                else
+                    current_rule.properties.append(property_value);
+            }
             consume_whitespace_or_comments();
             if (!peek() || peek() == '}')
                 break;
@@ -836,7 +844,7 @@ public:
             return;
         }
 
-        rules.append(CSS::CSSStyleRule::create(move(current_rule.selectors), CSS::CSSStyleDeclaration::create(move(current_rule.properties))));
+        rules.append(CSS::CSSStyleRule::create(move(current_rule.selectors), CSS::CSSStyleDeclaration::create(move(current_rule.properties), move(current_rule.custom_properties))));
     }
 
     Optional<String> parse_string()
@@ -980,13 +988,18 @@ public:
         consume_whitespace_or_comments();
         for (;;) {
             auto property = parse_property();
-            if (property.has_value())
-                current_rule.properties.append(property.value());
+            if (property.has_value()) {
+                auto property_value = property.value();
+                if (property_value.property_id == CSS::PropertyID::Custom)
+                    current_rule.custom_properties.set(property_value.custom_name, property_value);
+                else
+                    current_rule.properties.append(property_value);
+            }
             consume_whitespace_or_comments();
             if (!peek())
                 break;
         }
-        return CSS::CSSStyleDeclaration::create(move(current_rule.properties));
+        return CSS::CSSStyleDeclaration::create(move(current_rule.properties), move(current_rule.custom_properties));
     }
 
 private:
@@ -997,6 +1010,7 @@ private:
     struct CurrentRule {
         Vector<CSS::Selector> selectors;
         Vector<CSS::StyleProperty> properties;
+        HashMap<String, CSS::StyleProperty> custom_properties;
     };
 
     CurrentRule current_rule;
@@ -1024,7 +1038,7 @@ RefPtr<CSS::CSSStyleSheet> parse_css(const CSS::ParsingContext& context, const S
 RefPtr<CSS::CSSStyleDeclaration> parse_css_declaration(const CSS::ParsingContext& context, const StringView& css)
 {
     if (css.is_empty())
-        return CSS::CSSStyleDeclaration::create({});
+        return CSS::CSSStyleDeclaration::create({}, {});
     CSSParser parser(context, css);
     return parser.parse_standalone_declaration();
 }