Handle assigned slottables in an Event's path (#35380)

* Handle slots in an event's path

Signed-off-by: Simon Wülker <simon.wuelker@arcor.de>

* Update WPT expectations

Signed-off-by: Simon Wülker <simon.wuelker@arcor.de>

---------

Signed-off-by: Simon Wülker <simon.wuelker@arcor.de>
This commit is contained in:
Simon Wülker 2025-02-08 03:21:22 +01:00 committed by GitHub
parent 9c769efb06
commit 39c1e5d5d6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 44 additions and 18 deletions

View file

@ -32,8 +32,9 @@ use crate::dom::element::Element;
use crate::dom::eventtarget::{CompiledEventListener, EventTarget, ListenerPhase}; use crate::dom::eventtarget::{CompiledEventListener, EventTarget, ListenerPhase};
use crate::dom::globalscope::GlobalScope; use crate::dom::globalscope::GlobalScope;
use crate::dom::htmlinputelement::InputActivationState; use crate::dom::htmlinputelement::InputActivationState;
use crate::dom::htmlslotelement::HTMLSlotElement;
use crate::dom::mouseevent::MouseEvent; use crate::dom::mouseevent::MouseEvent;
use crate::dom::node::Node; use crate::dom::node::{Node, NodeTraits};
use crate::dom::shadowroot::ShadowRoot; use crate::dom::shadowroot::ShadowRoot;
use crate::dom::virtualmethods::vtable_for; use crate::dom::virtualmethods::vtable_for;
use crate::dom::window::Window; use crate::dom::window::Window;
@ -333,9 +334,19 @@ impl Event {
} }
} }
// TODO Step 5.6 Let slottable be target, if target is a slottable and is assigned, and null otherwise. // Step 5.6 Let slottable be target, if target is a slottable and is assigned, and null otherwise.
let mut slottable = if target
.downcast::<Node>()
.and_then(Node::assigned_slot)
.is_some()
{
Some(target.clone())
} else {
None
};
// Step 5.7 Let slot-in-closed-tree be false // Step 5.7 Let slot-in-closed-tree be false
let slot_in_closed_tree = false; let mut slot_in_closed_tree = false;
// Step 5.8 Let parent be the result of invoking targets get the parent with event. // Step 5.8 Let parent be the result of invoking targets get the parent with event.
let mut parent_or_none = target.get_the_parent(self); let mut parent_or_none = target.get_the_parent(self);
@ -343,8 +354,34 @@ impl Event {
// Step 5.9 While parent is non-null: // Step 5.9 While parent is non-null:
while let Some(parent) = parent_or_none.clone() { while let Some(parent) = parent_or_none.clone() {
// TODO: Step 5.9.1 If slottable is non-null: // Step 5.9.1 If slottable is non-null:
// TODO: Step 5.9.2 If parent is a slottable and is assigned, then set slottable to parent. if slottable.is_some() {
// Step 5.9.1.1 Assert: parent is a slot.
let slot = parent
.downcast::<HTMLSlotElement>()
.expect("parent of slottable is not a slot");
// Step 5.9.1.2 Set slottable to null.
slottable = None;
// Step 5.9.1.3 If parents root is a shadow root whose mode is "closed",
// then set slot-in-closed-tree to true.
if slot
.containing_shadow_root()
.is_some_and(|root| root.Mode() == ShadowRootMode::Closed)
{
slot_in_closed_tree = true;
}
}
// Step 5.9.2 If parent is a slottable and is assigned, then set slottable to parent.
if parent
.downcast::<Node>()
.and_then(Node::assigned_slot)
.is_some()
{
slottable = Some(parent.clone());
}
// Step 5.9.3 Let relatedTarget be the result of retargeting events relatedTarget against parent. // Step 5.9.3 Let relatedTarget be the result of retargeting events relatedTarget against parent.
let related_target = self let related_target = self
@ -423,7 +460,8 @@ impl Event {
parent_or_none = parent.get_the_parent(self); parent_or_none = parent.get_the_parent(self);
} }
// TODO Step 5.9.10 Set slot-in-closed-tree to false. // Step 5.9.10 Set slot-in-closed-tree to false.
slot_in_closed_tree = false;
} }
// Step 5.10 Let clearTargetsStruct be the last struct in events path whose shadow-adjusted target // Step 5.10 Let clearTargetsStruct be the last struct in events path whose shadow-adjusted target

View file

@ -1,6 +0,0 @@
[capturing-and-bubbling-event-listeners-across-shadow-trees.html]
[Capturing event listeners should be invoked before bubbling event listeners when an event is dispatched via a slot]
expected: FAIL
[Capturing event listeners should be invoked before bubbling event listeners when an event is dispatched inside a shadow tree which passes through another shadow tree]
expected: FAIL

View file

@ -1,6 +0,0 @@
[event-composed-path.html]
[Event Path with a slot in a closed Shadow Root.]
expected: FAIL
[Event Path with slots in nested ShadowRoots: closed > closed.]
expected: FAIL