mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 12:48:10 +00:00
LibWeb: Convert Element "attribute change steps" from vector to virtual
By using a virtual function and overriding it on HTMLSlotElement, we shrink every DOM element by 24 bytes. :^)
This commit is contained in:
parent
aa23a7b58d
commit
bdac94870c
4 changed files with 68 additions and 69 deletions
|
@ -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<String> const& old_value, Optional<String> const& value, Optional<FlyString> 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<String> const& old_value, Optional<String> const& value, Optional<FlyString> 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 });
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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<void(FlyString const& local_name, Optional<String> const& old_value, Optional<String> const& value, Optional<FlyString> const& namespace_)>;
|
||||
virtual void attribute_change_steps(FlyString const& local_name, Optional<String> const& old_value, Optional<String> const& value, Optional<FlyString> const& namespace_);
|
||||
|
||||
void add_attribute_change_steps(AttributeChangeSteps steps);
|
||||
void run_attribute_change_steps(FlyString const& local_name, Optional<String> const& old_value, Optional<String> const& value, Optional<FlyString> const& namespace_);
|
||||
virtual void attribute_changed(FlyString const& name, Optional<String> const& value);
|
||||
|
||||
|
@ -395,7 +394,6 @@ private:
|
|||
FlyString 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;
|
||||
|
|
|
@ -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<SlottableHandle> 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<String> const& old_value, Optional<String> const& value, Optional<FlyString> 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());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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<String> const& old_value, Optional<String> const& value, Optional<FlyString> const& namespace_) override;
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/scripting.html#manually-assigned-nodes
|
||||
Vector<DOM::Slottable> m_manually_assigned_nodes;
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue