1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-27 05:47:35 +00:00

LibWeb: Implement the attribute-change-steps extension

This is similar to the run activation behavior in that elements may
define these steps themselves. HTMLSlotElement is one such element. The
existing (ad-hoc) Element::attribute_changed() method is not sufficient
there as the steps require knowledge of the attribute's old value and
its namespace, which this extension provides.

Unlike the run activation behavior, we store these steps in a list. An
element may end up defining multiple attribute change steps. For example
all DOM elements must define steps to handle the "slot" attribute, and
HTMLSlotElement must define steps to handle the "name" attribute.
This commit is contained in:
Timothy Flynn 2023-09-01 17:45:22 -04:00 committed by Andreas Kling
parent 54b5a431a3
commit b85a252753
2 changed files with 13 additions and 3 deletions

View file

@ -409,10 +409,15 @@ CSS::CSSStyleDeclaration const* Element::inline_style() const
return m_inline_style.ptr(); return m_inline_style.ptr();
} }
void Element::run_attribute_change_steps(DeprecatedFlyString const& local_name, DeprecatedString const&, DeprecatedString const& value, DeprecatedFlyString const&) void Element::add_attribute_change_steps(AttributeChangeSteps steps)
{ {
// FIXME: Implement the element's attribute change steps: m_attribute_change_steps.append(move(steps));
// https://dom.spec.whatwg.org/#concept-element-attributes-change-ext }
void Element::run_attribute_change_steps(DeprecatedFlyString const& local_name, DeprecatedString const& old_value, DeprecatedString const& value, DeprecatedFlyString const& namespace_)
{
for (auto const& attribute_change_steps : m_attribute_change_steps)
attribute_change_steps(local_name, old_value, value, namespace_);
// AD-HOC: Run our own internal attribute change handler. // AD-HOC: Run our own internal attribute change handler.
attribute_changed(local_name, value); attribute_changed(local_name, value);

View file

@ -139,6 +139,10 @@ public:
virtual void apply_presentational_hints(CSS::StyleProperties&) const { } virtual void apply_presentational_hints(CSS::StyleProperties&) const { }
// https://dom.spec.whatwg.org/#concept-element-attributes-change-ext
using AttributeChangeSteps = Function<void(DeprecatedFlyString const& /*local_name*/, DeprecatedString const& /*old_value*/, DeprecatedString const& /*value*/, DeprecatedFlyString const& /*namespace_*/)>;
void add_attribute_change_steps(AttributeChangeSteps steps);
void run_attribute_change_steps(DeprecatedFlyString const& local_name, DeprecatedString const& old_value, DeprecatedString const& value, DeprecatedFlyString const& namespace_); void run_attribute_change_steps(DeprecatedFlyString const& local_name, DeprecatedString const& old_value, DeprecatedString const& value, DeprecatedFlyString const& namespace_);
virtual void attribute_changed(DeprecatedFlyString const& name, DeprecatedString const& value); virtual void attribute_changed(DeprecatedFlyString const& name, DeprecatedString const& value);
@ -379,6 +383,7 @@ private:
DeprecatedString m_html_uppercased_qualified_name; DeprecatedString m_html_uppercased_qualified_name;
JS::GCPtr<NamedNodeMap> m_attributes; JS::GCPtr<NamedNodeMap> m_attributes;
Vector<AttributeChangeSteps> m_attribute_change_steps;
JS::GCPtr<CSS::ElementInlineCSSStyleDeclaration> m_inline_style; JS::GCPtr<CSS::ElementInlineCSSStyleDeclaration> m_inline_style;
JS::GCPtr<DOMTokenList> m_class_list; JS::GCPtr<DOMTokenList> m_class_list;
JS::GCPtr<ShadowRoot> m_shadow_root; JS::GCPtr<ShadowRoot> m_shadow_root;