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
Notes: sideshowbarker 2024-07-16 21:45:42 +09:00
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();
}
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:
// https://dom.spec.whatwg.org/#concept-element-attributes-change-ext
m_attribute_change_steps.append(move(steps));
}
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.
attribute_changed(local_name, value);

View File

@ -139,6 +139,10 @@ public:
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_);
virtual void attribute_changed(DeprecatedFlyString const& name, DeprecatedString const& value);
@ -379,6 +383,7 @@ private:
DeprecatedString m_html_uppercased_qualified_name;
JS::GCPtr<NamedNodeMap> m_attributes;
Vector<AttributeChangeSteps> m_attribute_change_steps;
JS::GCPtr<CSS::ElementInlineCSSStyleDeclaration> m_inline_style;
JS::GCPtr<DOMTokenList> m_class_list;
JS::GCPtr<ShadowRoot> m_shadow_root;