-
-
Notifications
You must be signed in to change notification settings - Fork 3.6k
When an element whose descendants include <slot> is being removed, the slottable that being assigned to the slot does not clear its assign_slot. #42182
Description
Describe the bug:
When an element whose descendants include <slot> is being removed, the slottable that being assigned to the slot does not clear its assign_slot.
According to the spec
If node has an inclusive descendant that is a slot:
Run assign slottables for a tree with parent’s root.
Run assign slottables for a tree with node.
Ideally, the slot assignment should be reset, when running the assign slottables for a tree with node algorithm, but we currently fast return
servo/components/script/dom/node.rs
Lines 1546 to 1555 in 22df064
| pub(crate) fn assign_slottables_for_a_tree(&self) { | |
| // NOTE: This method traverses all descendants of the node and is potentially very | |
| // expensive. If the node is neither a shadowroot nor a slot then assigning slottables | |
| // for it won't have any effect, so we take a fast path out. | |
| let is_shadow_root_with_slots = self | |
| .downcast::<ShadowRoot>() | |
| .is_some_and(|shadow_root| shadow_root.has_slot_descendants()); | |
| if !is_shadow_root_with_slots && !self.is::<HTMLSlotElement>() { | |
| return; | |
| } |
if the node is not a slot element and is not a shadow root with slot element as descendants. But this would affect the below reproducible scenario:
To Reproduce:
Steps to reproduce the behavior.
Consider the below HTML snippet:
<body>
<div id="host">
<div id="content" slot="foo">This is some Text</div>
</div>
<script defer>
let host = document.getElementById("host");
let root = host.attachShadow({mode: "closed"});
let slot = document.createElement("slot");
slot.style = "color: green;"
slot.name = "foo";
let container = document.createElement("div");
container.appendChild(slot);
root.appendChild(container);
container.remove();
// Should be empty, the slot is not in the DOM tree anymore
console.log(slot.assignedNodes());
</script>Click on the toggle button, add log in HTMLSlotElement::assign_slottables() function.
Observe the log: the slot connection would be logged on node insertion. but the slot disconnection would not be triggered on node removal.
Platform:
All platform
cc @xiaochengh