From b85a25275336c1050de92689822cd88faf3e48fa Mon Sep 17 00:00:00 2001 From: Timothy Flynn Date: Fri, 1 Sep 2023 17:45:22 -0400 Subject: [PATCH] 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. --- Userland/Libraries/LibWeb/DOM/Element.cpp | 11 ++++++++--- Userland/Libraries/LibWeb/DOM/Element.h | 5 +++++ 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/Userland/Libraries/LibWeb/DOM/Element.cpp b/Userland/Libraries/LibWeb/DOM/Element.cpp index b559c0b940..d24d2ea932 100644 --- a/Userland/Libraries/LibWeb/DOM/Element.cpp +++ b/Userland/Libraries/LibWeb/DOM/Element.cpp @@ -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); diff --git a/Userland/Libraries/LibWeb/DOM/Element.h b/Userland/Libraries/LibWeb/DOM/Element.h index b311221d68..385ed16472 100644 --- a/Userland/Libraries/LibWeb/DOM/Element.h +++ b/Userland/Libraries/LibWeb/DOM/Element.h @@ -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 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 m_attributes; + Vector m_attribute_change_steps; JS::GCPtr m_inline_style; JS::GCPtr m_class_list; JS::GCPtr m_shadow_root;