mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 11:18:11 +00:00
LibWeb: Implement automatic slottable assignment
This implements automatic slottable assignment by way of hooking into the element attribute change steps. When the `name` attribute of a slot or the `slot` attribute of a slottable changes, assignment is performed.
This commit is contained in:
parent
e9da74ebe0
commit
b602ee7ddd
3 changed files with 85 additions and 4 deletions
|
@ -71,6 +71,38 @@ Element::Element(Document& document, DOM::QualifiedName qualified_name)
|
||||||
, m_qualified_name(move(qualified_name))
|
, m_qualified_name(move(qualified_name))
|
||||||
{
|
{
|
||||||
make_html_uppercased_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_.is_null()) {
|
||||||
|
// 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.is_null() && old_value == DeprecatedString::empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
// 3. If value is the empty string and oldValue is null, then return.
|
||||||
|
if (value == DeprecatedString::empty() && old_value.is_null())
|
||||||
|
return;
|
||||||
|
|
||||||
|
// 4. If value is null or the empty string, then set element’s name to the empty string.
|
||||||
|
if (value.is_empty())
|
||||||
|
set_slottable_name({});
|
||||||
|
// 5. Otherwise, set element’s name to value.
|
||||||
|
else
|
||||||
|
set_slottable_name(MUST(String::from_deprecated_string(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;
|
Element::~Element() = default;
|
||||||
|
|
|
@ -84,8 +84,19 @@ JS::GCPtr<HTML::HTMLSlotElement> find_a_slot(Slottable const& slottable, OpenFla
|
||||||
return slot;
|
return slot;
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: 6. Return the first slot in tree order in shadow’s descendants whose name is slottable’s name, if any; otherwise null.
|
// 6. Return the first slot in tree order in shadow’s descendants whose name is slottable’s name, if any; otherwise null.
|
||||||
return nullptr;
|
auto const& slottable_name = slottable.visit([](auto const& node) { return node->slottable_name(); });
|
||||||
|
JS::GCPtr<HTML::HTMLSlotElement> slot;
|
||||||
|
|
||||||
|
shadow->for_each_in_subtree_of_type<HTML::HTMLSlotElement>([&](auto& child) {
|
||||||
|
if (child.slot_name() != slottable_name)
|
||||||
|
return IterationDecision::Continue;
|
||||||
|
|
||||||
|
slot = child;
|
||||||
|
return IterationDecision::Break;
|
||||||
|
});
|
||||||
|
|
||||||
|
return slot;
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://dom.spec.whatwg.org/#find-slotables
|
// https://dom.spec.whatwg.org/#find-slotables
|
||||||
|
@ -118,8 +129,19 @@ Vector<Slottable> find_slottables(JS::NonnullGCPtr<HTML::HTMLSlotElement> slot)
|
||||||
}
|
}
|
||||||
// 6. Otherwise, for each slottable child slottable of host, in tree order:
|
// 6. Otherwise, for each slottable child slottable of host, in tree order:
|
||||||
else {
|
else {
|
||||||
// FIXME: 1. Let foundSlot be the result of finding a slot given slottable.
|
host->for_each_child([&](auto& node) {
|
||||||
// FIXME: 2. If foundSlot is slot, then append slottable to result.
|
if (!node.is_slottable())
|
||||||
|
return;
|
||||||
|
|
||||||
|
auto slottable = node.as_slottable();
|
||||||
|
|
||||||
|
// 1. Let foundSlot be the result of finding a slot given slottable.
|
||||||
|
auto found_slot = find_a_slot(slottable);
|
||||||
|
|
||||||
|
// 2. If foundSlot is slot, then append slottable to result.
|
||||||
|
if (found_slot == slot)
|
||||||
|
result.append(move(slottable));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// 7. Return result.
|
// 7. Return result.
|
||||||
|
|
|
@ -15,6 +15,33 @@ namespace Web::HTML {
|
||||||
HTMLSlotElement::HTMLSlotElement(DOM::Document& document, DOM::QualifiedName qualified_name)
|
HTMLSlotElement::HTMLSlotElement(DOM::Document& document, DOM::QualifiedName qualified_name)
|
||||||
: HTMLElement(document, move(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_.is_null()) {
|
||||||
|
// 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.is_null() && old_value == DeprecatedString::empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
// 3. If value is the empty string and oldValue is null, then return.
|
||||||
|
if (value == DeprecatedString::empty() && old_value.is_null())
|
||||||
|
return;
|
||||||
|
|
||||||
|
// 4. If value is null or the empty string, then set element’s name to the empty string.
|
||||||
|
if (value.is_empty())
|
||||||
|
set_slot_name({});
|
||||||
|
// 5. Otherwise, set element’s name to value.
|
||||||
|
else
|
||||||
|
set_slot_name(MUST(String::from_deprecated_string(value)));
|
||||||
|
|
||||||
|
// 6. Run assign slottables for a tree with element’s root.
|
||||||
|
DOM::assign_slottables_for_a_tree(root());
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
HTMLSlotElement::~HTMLSlotElement() = default;
|
HTMLSlotElement::~HTMLSlotElement() = default;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue