1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-24 22:07:34 +00:00

LibWeb: Store custom properties in CSSStyleDeclaration

Keep them around when parsing and store them in the CSSStyleDeclaration
when done.
This commit is contained in:
Tobias Christiansen 2021-05-24 22:54:41 +02:00 committed by Linus Groh
parent f0c6160362
commit 0d7169b91a
3 changed files with 32 additions and 13 deletions

View file

@ -9,8 +9,9 @@
namespace Web::CSS { namespace Web::CSS {
CSSStyleDeclaration::CSSStyleDeclaration(Vector<StyleProperty>&& properties) CSSStyleDeclaration::CSSStyleDeclaration(Vector<StyleProperty>&& properties, HashMap<String, StyleProperty>&& custom_properties)
: m_properties(move(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) ElementInlineCSSStyleDeclaration::ElementInlineCSSStyleDeclaration(DOM::Element& element)
: CSSStyleDeclaration({}) : CSSStyleDeclaration({}, {})
, m_element(element.make_weak_ptr<DOM::Element>()) , m_element(element.make_weak_ptr<DOM::Element>())
{ {
} }

View file

@ -16,6 +16,7 @@ namespace Web::CSS {
struct StyleProperty { struct StyleProperty {
CSS::PropertyID property_id; CSS::PropertyID property_id;
NonnullRefPtr<StyleValue> value; NonnullRefPtr<StyleValue> value;
String custom_name {};
bool important { false }; bool important { false };
}; };
@ -25,25 +26,28 @@ class CSSStyleDeclaration
public: public:
using WrapperType = Bindings::CSSStyleDeclarationWrapper; 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(); virtual ~CSSStyleDeclaration();
const Vector<StyleProperty>& properties() const { return m_properties; } 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(); } size_t length() const { return m_properties.size(); }
String item(size_t index) const; String item(size_t index) const;
protected: protected:
explicit CSSStyleDeclaration(Vector<StyleProperty>&&); explicit CSSStyleDeclaration(Vector<StyleProperty>&&, HashMap<String, StyleProperty>&&);
private: private:
friend class Bindings::CSSStyleDeclarationWrapper; friend class Bindings::CSSStyleDeclarationWrapper;
Vector<StyleProperty> m_properties; Vector<StyleProperty> m_properties;
HashMap<String, StyleProperty> m_custom_properties;
}; };
class ElementInlineCSSStyleDeclaration final : public CSSStyleDeclaration { class ElementInlineCSSStyleDeclaration final : public CSSStyleDeclaration {

View file

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