LibWeb: Remove ElementInlineCSSStyleDeclaration entirely

All of its behavior has now been moved up into its parent classes.
This commit is contained in:
Sam Atkins 2025-03-17 13:04:41 +00:00
parent 50455c2f5e
commit 687d32b712
Notes: github-actions[bot] 2025-03-19 13:54:28 +00:00
7 changed files with 46 additions and 83 deletions

View file

@ -23,7 +23,6 @@ namespace Web::CSS {
GC_DEFINE_ALLOCATOR(CSSStyleDeclaration); GC_DEFINE_ALLOCATOR(CSSStyleDeclaration);
GC_DEFINE_ALLOCATOR(PropertyOwningCSSStyleDeclaration); GC_DEFINE_ALLOCATOR(PropertyOwningCSSStyleDeclaration);
GC_DEFINE_ALLOCATOR(ElementInlineCSSStyleDeclaration);
CSSStyleDeclaration::CSSStyleDeclaration(JS::Realm& realm, Computed computed, Readonly readonly) CSSStyleDeclaration::CSSStyleDeclaration(JS::Realm& realm, Computed computed, Readonly readonly)
: PlatformObject(realm) : PlatformObject(realm)
@ -43,14 +42,21 @@ void CSSStyleDeclaration::initialize(JS::Realm& realm)
GC::Ref<PropertyOwningCSSStyleDeclaration> PropertyOwningCSSStyleDeclaration::create(JS::Realm& realm, Vector<StyleProperty> properties, HashMap<FlyString, StyleProperty> custom_properties) GC::Ref<PropertyOwningCSSStyleDeclaration> PropertyOwningCSSStyleDeclaration::create(JS::Realm& realm, Vector<StyleProperty> properties, HashMap<FlyString, StyleProperty> custom_properties)
{ {
return realm.create<PropertyOwningCSSStyleDeclaration>(realm, move(properties), move(custom_properties)); return realm.create<PropertyOwningCSSStyleDeclaration>(realm, nullptr, move(properties), move(custom_properties));
} }
PropertyOwningCSSStyleDeclaration::PropertyOwningCSSStyleDeclaration(JS::Realm& realm, Vector<StyleProperty> properties, HashMap<FlyString, StyleProperty> custom_properties) GC::Ref<PropertyOwningCSSStyleDeclaration> PropertyOwningCSSStyleDeclaration::create_element_inline_style(JS::Realm& realm, GC::Ref<DOM::Element> element, Vector<StyleProperty> properties, HashMap<FlyString, StyleProperty> custom_properties)
{
return realm.create<PropertyOwningCSSStyleDeclaration>(realm, element, move(properties), move(custom_properties));
}
PropertyOwningCSSStyleDeclaration::PropertyOwningCSSStyleDeclaration(JS::Realm& realm, GC::Ptr<DOM::Element> element, Vector<StyleProperty> properties, HashMap<FlyString, StyleProperty> custom_properties)
: CSSStyleDeclaration(realm, Computed::No, Readonly::No) : CSSStyleDeclaration(realm, Computed::No, Readonly::No)
, m_properties(move(properties)) , m_properties(move(properties))
, m_custom_properties(move(custom_properties)) , m_custom_properties(move(custom_properties))
{ {
if (element)
set_owner_node(DOM::ElementReference { *element });
} }
void PropertyOwningCSSStyleDeclaration::visit_edges(Visitor& visitor) void PropertyOwningCSSStyleDeclaration::visit_edges(Visitor& visitor)
@ -69,18 +75,6 @@ String PropertyOwningCSSStyleDeclaration::item(size_t index) const
return CSS::string_from_property_id(m_properties[index].property_id).to_string(); return CSS::string_from_property_id(m_properties[index].property_id).to_string();
} }
GC::Ref<ElementInlineCSSStyleDeclaration> ElementInlineCSSStyleDeclaration::create(DOM::Element& element, Vector<StyleProperty> properties, HashMap<FlyString, StyleProperty> custom_properties)
{
auto& realm = element.realm();
return realm.create<ElementInlineCSSStyleDeclaration>(element, move(properties), move(custom_properties));
}
ElementInlineCSSStyleDeclaration::ElementInlineCSSStyleDeclaration(DOM::Element& element, Vector<StyleProperty> properties, HashMap<FlyString, StyleProperty> custom_properties)
: PropertyOwningCSSStyleDeclaration(element.realm(), move(properties), move(custom_properties))
{
set_owner_node(DOM::ElementReference { element });
}
size_t PropertyOwningCSSStyleDeclaration::length() const size_t PropertyOwningCSSStyleDeclaration::length() const
{ {
return m_properties.size(); return m_properties.size();
@ -210,7 +204,7 @@ WebIDL::ExceptionOr<String> PropertyOwningCSSStyleDeclaration::remove_property(S
} }
// https://drafts.csswg.org/cssom/#update-style-attribute-for // https://drafts.csswg.org/cssom/#update-style-attribute-for
void ElementInlineCSSStyleDeclaration::update_style_attribute() void CSSStyleDeclaration::update_style_attribute()
{ {
// 1. Assert: declaration blocks computed flag is unset. // 1. Assert: declaration blocks computed flag is unset.
VERIFY(!is_computed()); VERIFY(!is_computed());
@ -640,9 +634,21 @@ String PropertyOwningCSSStyleDeclaration::serialized() const
return MUST(builder.to_string()); return MUST(builder.to_string());
} }
// https://drafts.csswg.org/cssom/#dom-cssstyledeclaration-csstext
WebIDL::ExceptionOr<void> PropertyOwningCSSStyleDeclaration::set_css_text(StringView css_text) WebIDL::ExceptionOr<void> PropertyOwningCSSStyleDeclaration::set_css_text(StringView css_text)
{ {
dbgln("(STUBBED) PropertyOwningCSSStyleDeclaration::set_css_text(css_text='{}')", css_text); // 1. If the readonly flag is set, then throw a NoModificationAllowedError exception.
if (is_readonly()) {
return WebIDL::NoModificationAllowedError::create(realm(), "Cannot modify properties: CSSStyleDeclaration is read-only."_string);
}
// 2. Empty the declarations.
// 3. Parse the given value and, if the return value is not the empty list, insert the items in the list into the declarations, in specified order.
set_declarations_from_text(css_text);
// 4. Update style attribute for the CSS declaration block.
update_style_attribute();
return {}; return {};
} }
@ -658,40 +664,14 @@ void PropertyOwningCSSStyleDeclaration::set_the_declarations(Vector<StylePropert
m_custom_properties = move(custom_properties); m_custom_properties = move(custom_properties);
} }
void ElementInlineCSSStyleDeclaration::set_declarations_from_text(StringView css_text) void PropertyOwningCSSStyleDeclaration::set_declarations_from_text(StringView css_text)
{ {
// FIXME: What do we do if the element is null?
auto element = owner_node();
if (!element.has_value()) {
dbgln("FIXME: Returning from ElementInlineCSSStyleDeclaration::declarations_from_text as element is null.");
return;
}
empty_the_declarations(); empty_the_declarations();
auto style = parse_css_style_attribute(Parser::ParsingParams(element->element().document()), css_text); auto parsing_params = owner_node().has_value()
? Parser::ParsingParams(owner_node()->element().document())
: Parser::ParsingParams();
auto style = parse_css_style_attribute(parsing_params, css_text);
set_the_declarations(style.properties, style.custom_properties); set_the_declarations(style.properties, style.custom_properties);
} }
// https://drafts.csswg.org/cssom/#dom-cssstyledeclaration-csstext
WebIDL::ExceptionOr<void> ElementInlineCSSStyleDeclaration::set_css_text(StringView css_text)
{
// FIXME: What do we do if the element is null?
if (!owner_node().has_value()) {
dbgln("FIXME: Returning from ElementInlineCSSStyleDeclaration::set_css_text as element is null.");
return {};
}
// 1. If the computed flag is set, then throw a NoModificationAllowedError exception.
// NOTE: See ResolvedCSSStyleDeclaration.
// 2. Empty the declarations.
// 3. Parse the given value and, if the return value is not the empty list, insert the items in the list into the declarations, in specified order.
set_declarations_from_text(css_text);
// 4. Update style attribute for the CSS declaration block.
update_style_attribute();
return {};
}
} }

View file

@ -84,6 +84,8 @@ protected:
virtual CSSStyleDeclaration& generated_style_properties_to_css_style_declaration() override { return *this; } virtual CSSStyleDeclaration& generated_style_properties_to_css_style_declaration() override { return *this; }
void update_style_attribute();
private: private:
// ^PlatformObject // ^PlatformObject
virtual Optional<JS::Value> item_value(size_t index) const override; virtual Optional<JS::Value> item_value(size_t index) const override;
@ -109,12 +111,13 @@ class PropertyOwningCSSStyleDeclaration : public CSSStyleDeclaration {
WEB_PLATFORM_OBJECT(PropertyOwningCSSStyleDeclaration, CSSStyleDeclaration); WEB_PLATFORM_OBJECT(PropertyOwningCSSStyleDeclaration, CSSStyleDeclaration);
GC_DECLARE_ALLOCATOR(PropertyOwningCSSStyleDeclaration); GC_DECLARE_ALLOCATOR(PropertyOwningCSSStyleDeclaration);
friend class ElementInlineCSSStyleDeclaration;
public: public:
[[nodiscard]] static GC::Ref<PropertyOwningCSSStyleDeclaration> [[nodiscard]] static GC::Ref<PropertyOwningCSSStyleDeclaration>
create(JS::Realm&, Vector<StyleProperty>, HashMap<FlyString, StyleProperty> custom_properties); create(JS::Realm&, Vector<StyleProperty>, HashMap<FlyString, StyleProperty> custom_properties);
[[nodiscard]] static GC::Ref<PropertyOwningCSSStyleDeclaration>
create_element_inline_style(JS::Realm&, GC::Ref<DOM::Element>, Vector<StyleProperty>, HashMap<FlyString, StyleProperty> custom_properties);
virtual ~PropertyOwningCSSStyleDeclaration() override = default; virtual ~PropertyOwningCSSStyleDeclaration() override = default;
virtual size_t length() const override; virtual size_t length() const override;
@ -133,10 +136,10 @@ public:
virtual String serialized() const final override; virtual String serialized() const final override;
virtual WebIDL::ExceptionOr<void> set_css_text(StringView) override; virtual WebIDL::ExceptionOr<void> set_css_text(StringView) override;
protected: void set_declarations_from_text(StringView);
PropertyOwningCSSStyleDeclaration(JS::Realm&, Vector<StyleProperty>, HashMap<FlyString, StyleProperty>);
virtual void update_style_attribute() { } protected:
PropertyOwningCSSStyleDeclaration(JS::Realm&, GC::Ptr<DOM::Element> owner_node, Vector<StyleProperty>, HashMap<FlyString, StyleProperty>);
void empty_the_declarations(); void empty_the_declarations();
void set_the_declarations(Vector<StyleProperty> properties, HashMap<FlyString, StyleProperty> custom_properties); void set_the_declarations(Vector<StyleProperty> properties, HashMap<FlyString, StyleProperty> custom_properties);
@ -150,23 +153,4 @@ private:
HashMap<FlyString, StyleProperty> m_custom_properties; HashMap<FlyString, StyleProperty> m_custom_properties;
}; };
class ElementInlineCSSStyleDeclaration final : public PropertyOwningCSSStyleDeclaration {
WEB_PLATFORM_OBJECT(ElementInlineCSSStyleDeclaration, PropertyOwningCSSStyleDeclaration);
GC_DECLARE_ALLOCATOR(ElementInlineCSSStyleDeclaration);
public:
[[nodiscard]] static GC::Ref<ElementInlineCSSStyleDeclaration> create(DOM::Element&, Vector<StyleProperty>, HashMap<FlyString, StyleProperty> custom_properties);
virtual ~ElementInlineCSSStyleDeclaration() override = default;
void set_declarations_from_text(StringView);
virtual WebIDL::ExceptionOr<void> set_css_text(StringView) override;
private:
ElementInlineCSSStyleDeclaration(DOM::Element&, Vector<StyleProperty> properties, HashMap<FlyString, StyleProperty> custom_properties);
virtual void update_style_attribute() override;
};
} }

View file

@ -921,7 +921,7 @@ void Element::set_shadow_root(GC::Ptr<ShadowRoot> shadow_root)
CSS::CSSStyleDeclaration* Element::style_for_bindings() CSS::CSSStyleDeclaration* Element::style_for_bindings()
{ {
if (!m_inline_style) if (!m_inline_style)
m_inline_style = CSS::ElementInlineCSSStyleDeclaration::create(*this, {}, {}); m_inline_style = CSS::PropertyOwningCSSStyleDeclaration::create_element_inline_style(realm(), *this, {}, {});
return m_inline_style; return m_inline_style;
} }
@ -3524,7 +3524,7 @@ void Element::attribute_changed(FlyString const& local_name, Optional<String> co
if (m_inline_style && m_inline_style->is_updating()) if (m_inline_style && m_inline_style->is_updating())
return; return;
if (!m_inline_style) if (!m_inline_style)
m_inline_style = CSS::ElementInlineCSSStyleDeclaration::create(*this, {}, {}); m_inline_style = CSS::PropertyOwningCSSStyleDeclaration::create_element_inline_style(realm(), *this, {}, {});
m_inline_style->set_declarations_from_text(*value); m_inline_style->set_declarations_from_text(*value);
set_needs_style_update(true); set_needs_style_update(true);
} }

View file

@ -211,8 +211,8 @@ public:
void reset_animated_css_properties(); void reset_animated_css_properties();
GC::Ptr<CSS::ElementInlineCSSStyleDeclaration> inline_style() { return m_inline_style; } GC::Ptr<CSS::PropertyOwningCSSStyleDeclaration> inline_style() { return m_inline_style; }
GC::Ptr<CSS::ElementInlineCSSStyleDeclaration const> inline_style() const { return m_inline_style; } GC::Ptr<CSS::PropertyOwningCSSStyleDeclaration const> inline_style() const { return m_inline_style; }
CSS::CSSStyleDeclaration* style_for_bindings(); CSS::CSSStyleDeclaration* style_for_bindings();
@ -499,7 +499,7 @@ private:
FlyString m_html_uppercased_qualified_name; FlyString m_html_uppercased_qualified_name;
GC::Ptr<NamedNodeMap> m_attributes; GC::Ptr<NamedNodeMap> m_attributes;
GC::Ptr<CSS::ElementInlineCSSStyleDeclaration> m_inline_style; GC::Ptr<CSS::PropertyOwningCSSStyleDeclaration> m_inline_style;
GC::Ptr<DOMTokenList> m_class_list; GC::Ptr<DOMTokenList> m_class_list;
GC::Ptr<ShadowRoot> m_shadow_root; GC::Ptr<ShadowRoot> m_shadow_root;

View file

@ -189,7 +189,6 @@ class Display;
class DisplayStyleValue; class DisplayStyleValue;
class EasingStyleValue; class EasingStyleValue;
class EdgeStyleValue; class EdgeStyleValue;
class ElementInlineCSSStyleDeclaration;
class ExplicitGridTrack; class ExplicitGridTrack;
class FilterValueListStyleValue; class FilterValueListStyleValue;
class FitContentStyleValue; class FitContentStyleValue;

View file

@ -2,8 +2,7 @@ Harness status: OK
Found 13 tests Found 13 tests
12 Pass 13 Pass
1 Fail
Pass CSSStyleRule is a CSSGroupingRule Pass CSSStyleRule is a CSSGroupingRule
Pass Simple CSSOM manipulation of subrules Pass Simple CSSOM manipulation of subrules
Pass Simple CSSOM manipulation of subrules 1 Pass Simple CSSOM manipulation of subrules 1
@ -13,7 +12,7 @@ Pass Simple CSSOM manipulation of subrules 4
Pass Simple CSSOM manipulation of subrules 5 Pass Simple CSSOM manipulation of subrules 5
Pass Simple CSSOM manipulation of subrules 6 Pass Simple CSSOM manipulation of subrules 6
Pass Simple CSSOM manipulation of subrules 7 Pass Simple CSSOM manipulation of subrules 7
Fail Simple CSSOM manipulation of subrules 8 Pass Simple CSSOM manipulation of subrules 8
Pass Simple CSSOM manipulation of subrules 9 Pass Simple CSSOM manipulation of subrules 9
Pass Simple CSSOM manipulation of subrules 10 Pass Simple CSSOM manipulation of subrules 10
Pass Mutating the selectorText of outer rule invalidates inner rules Pass Mutating the selectorText of outer rule invalidates inner rules

View file

@ -2,6 +2,7 @@ Harness status: OK
Found 2 tests Found 2 tests
2 Fail 1 Pass
Fail Empty CSSNestedDeclarations do not affect outer serialization 1 Fail
Pass Empty CSSNestedDeclarations do not affect outer serialization
Fail Empty CSSNestedDeclarations do not affect outer serialization (nested grouping rule) Fail Empty CSSNestedDeclarations do not affect outer serialization (nested grouping rule)