diff --git a/Userland/Libraries/LibWeb/DOM/Element.cpp b/Userland/Libraries/LibWeb/DOM/Element.cpp index 27bdb08643..da2908ea9c 100644 --- a/Userland/Libraries/LibWeb/DOM/Element.cpp +++ b/Userland/Libraries/LibWeb/DOM/Element.cpp @@ -71,38 +71,6 @@ Element::Element(Document& document, DOM::QualifiedName qualified_name) , m_qualified_name(move(qualified_name)) { make_html_uppercased_qualified_name(); - - // https://dom.spec.whatwg.org/#ref-for-concept-element-attributes-change-ext① - add_attribute_change_steps([this](auto const& local_name, auto const& old_value, auto const& value, auto const& namespace_) { - // 1. If localName is slot and namespace is null, then: - if (local_name == HTML::AttributeNames::slot && !namespace_.has_value()) { - // 1. If value is oldValue, then return. - if (value == old_value) - return; - - // 2. If value is null and oldValue is the empty string, then return. - if (!value.has_value() && old_value == String {}) - return; - - // 3. If value is the empty string and oldValue is null, then return. - if (value == String {} && !old_value.has_value()) - return; - - // 4. If value is null or the empty string, then set element’s name to the empty string. - if (!value.has_value() || value->is_empty()) - set_slottable_name({}); - // 5. Otherwise, set element’s name to value. - else - set_slottable_name(*value); - - // 6. If element is assigned, then run assign slottables for element’s assigned slot. - if (auto assigned_slot = assigned_slot_internal()) - assign_slottables(*assigned_slot); - - // 7. Run assign a slot for element. - assign_a_slot(JS::NonnullGCPtr { *this }); - } - }); } Element::~Element() = default; @@ -463,15 +431,9 @@ CSS::CSSStyleDeclaration const* Element::inline_style() const return m_inline_style.ptr(); } -void Element::add_attribute_change_steps(AttributeChangeSteps steps) -{ - m_attribute_change_steps.append(move(steps)); -} - void Element::run_attribute_change_steps(FlyString const& local_name, Optional const& old_value, Optional const& value, Optional const& namespace_) { - for (auto const& attribute_change_steps : m_attribute_change_steps) - attribute_change_steps(local_name, old_value, value, namespace_); + attribute_change_steps(local_name, old_value, value, namespace_); // AD-HOC: Run our own internal attribute change handler. attribute_changed(local_name, value); @@ -2270,4 +2232,37 @@ Element::Directionality Element::directionality() const VERIFY_NOT_REACHED(); } +// https://dom.spec.whatwg.org/#ref-for-concept-element-attributes-change-ext① +void Element::attribute_change_steps(FlyString const& local_name, Optional const& old_value, Optional const& value, Optional const& namespace_) +{ + // 1. If localName is slot and namespace is null, then: + if (local_name == HTML::AttributeNames::slot && !namespace_.has_value()) { + // 1. If value is oldValue, then return. + if (value == old_value) + return; + + // 2. If value is null and oldValue is the empty string, then return. + if (!value.has_value() && old_value == String {}) + return; + + // 3. If value is the empty string and oldValue is null, then return. + if (value == String {} && !old_value.has_value()) + return; + + // 4. If value is null or the empty string, then set element’s name to the empty string. + if (!value.has_value() || value->is_empty()) + set_slottable_name({}); + // 5. Otherwise, set element’s name to value. + else + set_slottable_name(*value); + + // 6. If element is assigned, then run assign slottables for element’s assigned slot. + if (auto assigned_slot = assigned_slot_internal()) + assign_slottables(*assigned_slot); + + // 7. Run assign a slot for element. + assign_a_slot(JS::NonnullGCPtr { *this }); + } +} + } diff --git a/Userland/Libraries/LibWeb/DOM/Element.h b/Userland/Libraries/LibWeb/DOM/Element.h index f087ed9f8f..f36daf0e2f 100644 --- a/Userland/Libraries/LibWeb/DOM/Element.h +++ b/Userland/Libraries/LibWeb/DOM/Element.h @@ -147,9 +147,8 @@ public: virtual void apply_presentational_hints(CSS::StyleProperties&) const { } // https://dom.spec.whatwg.org/#concept-element-attributes-change-ext - using AttributeChangeSteps = Function const& old_value, Optional const& value, Optional const& namespace_)>; + virtual void attribute_change_steps(FlyString const& local_name, Optional const& old_value, Optional const& value, Optional const& namespace_); - void add_attribute_change_steps(AttributeChangeSteps steps); void run_attribute_change_steps(FlyString const& local_name, Optional const& old_value, Optional const& value, Optional const& namespace_); virtual void attribute_changed(FlyString const& name, Optional const& value); @@ -395,7 +394,6 @@ private: FlyString 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; diff --git a/Userland/Libraries/LibWeb/HTML/HTMLSlotElement.cpp b/Userland/Libraries/LibWeb/HTML/HTMLSlotElement.cpp index a0bf9d1434..eca9dcd5db 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLSlotElement.cpp +++ b/Userland/Libraries/LibWeb/HTML/HTMLSlotElement.cpp @@ -17,33 +17,6 @@ JS_DEFINE_ALLOCATOR(HTMLSlotElement); HTMLSlotElement::HTMLSlotElement(DOM::Document& document, DOM::QualifiedName qualified_name) : HTMLElement(document, move(qualified_name)) { - // https://dom.spec.whatwg.org/#ref-for-concept-element-attributes-change-ext - add_attribute_change_steps([this](auto const& local_name, auto const& old_value, auto const& value, auto const& namespace_) { - // 1. If element is a slot, localName is name, and namespace is null, then: - if (local_name == AttributeNames::name && !namespace_.has_value()) { - // 1. If value is oldValue, then return. - if (value == old_value) - return; - - // 2. If value is null and oldValue is the empty string, then return. - if (!value.has_value() && old_value == String {}) - return; - - // 3. If value is the empty string and oldValue is null, then return. - if (value == String {} && !old_value.has_value()) - return; - - // 4. If value is null or the empty string, then set element’s name to the empty string. - if (!value.has_value()) - set_slot_name({}); - // 5. Otherwise, set element’s name to value. - else - set_slot_name(*value); - - // 6. Run assign slottables for a tree with element’s root. - DOM::assign_slottables_for_a_tree(root()); - } - }); } HTMLSlotElement::~HTMLSlotElement() = default; @@ -142,4 +115,35 @@ void HTMLSlotElement::assign(Vector nodes) assign_slottables_for_a_tree(root()); } +// https://dom.spec.whatwg.org/#ref-for-concept-element-attributes-change-ext +void HTMLSlotElement::attribute_change_steps(FlyString const& local_name, Optional const& old_value, Optional const& value, Optional const& namespace_) +{ + Base::attribute_change_steps(local_name, old_value, value, namespace_); + + // 1. If element is a slot, localName is name, and namespace is null, then: + if (local_name == AttributeNames::name && !namespace_.has_value()) { + // 1. If value is oldValue, then return. + if (value == old_value) + return; + + // 2. If value is null and oldValue is the empty string, then return. + if (!value.has_value() && old_value == String {}) + return; + + // 3. If value is the empty string and oldValue is null, then return. + if (value == String {} && !old_value.has_value()) + return; + + // 4. If value is null or the empty string, then set element’s name to the empty string. + if (!value.has_value()) + set_slot_name({}); + // 5. Otherwise, set element’s name to value. + else + set_slot_name(*value); + + // 6. Run assign slottables for a tree with element’s root. + DOM::assign_slottables_for_a_tree(root()); + } +} + } diff --git a/Userland/Libraries/LibWeb/HTML/HTMLSlotElement.h b/Userland/Libraries/LibWeb/HTML/HTMLSlotElement.h index a540a025fc..2ab591bc5d 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLSlotElement.h +++ b/Userland/Libraries/LibWeb/HTML/HTMLSlotElement.h @@ -45,6 +45,8 @@ private: virtual void initialize(JS::Realm&) override; virtual void visit_edges(JS::Cell::Visitor&) override; + virtual void attribute_change_steps(FlyString const& local_name, Optional const& old_value, Optional const& value, Optional const& namespace_) override; + // https://html.spec.whatwg.org/multipage/scripting.html#manually-assigned-nodes Vector m_manually_assigned_nodes; };