Implement Event.composedPath (#31123)

* Implement Event.composedPath

* Implement Event.composedPath

Signed-off-by: Bentaimia Haddadi <haddadi.taym@gmail.com>

* Use documentation comments for EventMethods

Signed-off-by: Bentaimia Haddadi <haddadi.taym@gmail.com>

* Update wpt test expectations

Signed-off-by: Bentaimia Haddadi <haddadi.taym@gmail.com>

---------

Signed-off-by: Bentaimia Haddadi <haddadi.taym@gmail.com>
This commit is contained in:
Taym Haddadi 2024-01-23 15:56:01 +01:00 committed by GitHub
parent 54fb381a0a
commit 5d7e2a8239
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 35 additions and 67 deletions

View file

@ -141,7 +141,7 @@ impl Event {
self.cancelable.set(cancelable); self.cancelable.set(cancelable);
} }
// https://dom.spec.whatwg.org/#event-path /// <https://dom.spec.whatwg.org/#event-path>
// TODO: shadow roots put special flags in the path, // TODO: shadow roots put special flags in the path,
// and it will stop just being a list of bare EventTargets // and it will stop just being a list of bare EventTargets
fn construct_event_path(&self, target: &EventTarget) -> Vec<DomRoot<EventTarget>> { fn construct_event_path(&self, target: &EventTarget) -> Vec<DomRoot<EventTarget>> {
@ -178,7 +178,7 @@ impl Event {
event_path event_path
} }
// https://dom.spec.whatwg.org/#concept-event-dispatch /// <https://dom.spec.whatwg.org/#concept-event-dispatch>
pub fn dispatch( pub fn dispatch(
&self, &self,
target: &EventTarget, target: &EventTarget,
@ -400,7 +400,7 @@ impl Event {
self.trusted.set(trusted); self.trusted.set(trusted);
} }
// https://html.spec.whatwg.org/multipage/#fire-a-simple-event /// <https://html.spec.whatwg.org/multipage/#fire-a-simple-event>
pub fn fire(&self, target: &EventTarget) -> EventStatus { pub fn fire(&self, target: &EventTarget) -> EventStatus {
self.set_trusted(true); self.set_trusted(true);
target.dispatch_event(self) target.dispatch_event(self)
@ -408,89 +408,98 @@ impl Event {
} }
impl EventMethods for Event { impl EventMethods for Event {
// https://dom.spec.whatwg.org/#dom-event-eventphase /// <https://dom.spec.whatwg.org/#dom-event-eventphase>
fn EventPhase(&self) -> u16 { fn EventPhase(&self) -> u16 {
self.phase.get() as u16 self.phase.get() as u16
} }
// https://dom.spec.whatwg.org/#dom-event-type /// <https://dom.spec.whatwg.org/#dom-event-type>
fn Type(&self) -> DOMString { fn Type(&self) -> DOMString {
DOMString::from(&*self.type_()) // FIXME(ajeffrey): Directly convert from Atom to DOMString DOMString::from(&*self.type_()) // FIXME(ajeffrey): Directly convert from Atom to DOMString
} }
// https://dom.spec.whatwg.org/#dom-event-target /// <https://dom.spec.whatwg.org/#dom-event-target>
fn GetTarget(&self) -> Option<DomRoot<EventTarget>> { fn GetTarget(&self) -> Option<DomRoot<EventTarget>> {
self.target.get() self.target.get()
} }
// https://dom.spec.whatwg.org/#dom-event-srcelement /// <https://dom.spec.whatwg.org/#dom-event-srcelement>
fn GetSrcElement(&self) -> Option<DomRoot<EventTarget>> { fn GetSrcElement(&self) -> Option<DomRoot<EventTarget>> {
self.target.get() self.target.get()
} }
// https://dom.spec.whatwg.org/#dom-event-currenttarget /// <https://dom.spec.whatwg.org/#dom-event-currenttarget>
fn GetCurrentTarget(&self) -> Option<DomRoot<EventTarget>> { fn GetCurrentTarget(&self) -> Option<DomRoot<EventTarget>> {
self.current_target.get() self.current_target.get()
} }
// https://dom.spec.whatwg.org/#dom-event-defaultprevented /// <https://dom.spec.whatwg.org/#dom-event-composedpath>
fn ComposedPath(&self) -> Vec<DomRoot<EventTarget>> {
if let Some(target) = self.target.get() {
self.construct_event_path(&target)
} else {
vec![]
}
}
/// <https://dom.spec.whatwg.org/#dom-event-defaultprevented>
fn DefaultPrevented(&self) -> bool { fn DefaultPrevented(&self) -> bool {
self.canceled.get() == EventDefault::Prevented self.canceled.get() == EventDefault::Prevented
} }
// https://dom.spec.whatwg.org/#dom-event-preventdefault /// <https://dom.spec.whatwg.org/#dom-event-preventdefault>
fn PreventDefault(&self) { fn PreventDefault(&self) {
if self.cancelable.get() { if self.cancelable.get() {
self.canceled.set(EventDefault::Prevented) self.canceled.set(EventDefault::Prevented)
} }
} }
// https://dom.spec.whatwg.org/#dom-event-stoppropagation /// <https://dom.spec.whatwg.org/#dom-event-stoppropagation>
fn StopPropagation(&self) { fn StopPropagation(&self) {
self.stop_propagation.set(true); self.stop_propagation.set(true);
} }
// https://dom.spec.whatwg.org/#dom-event-stopimmediatepropagation /// <https://dom.spec.whatwg.org/#dom-event-stopimmediatepropagation>
fn StopImmediatePropagation(&self) { fn StopImmediatePropagation(&self) {
self.stop_immediate.set(true); self.stop_immediate.set(true);
self.stop_propagation.set(true); self.stop_propagation.set(true);
} }
// https://dom.spec.whatwg.org/#dom-event-bubbles /// <https://dom.spec.whatwg.org/#dom-event-bubbles>
fn Bubbles(&self) -> bool { fn Bubbles(&self) -> bool {
self.bubbles.get() self.bubbles.get()
} }
// https://dom.spec.whatwg.org/#dom-event-cancelable /// <https://dom.spec.whatwg.org/#dom-event-cancelable>
fn Cancelable(&self) -> bool { fn Cancelable(&self) -> bool {
self.cancelable.get() self.cancelable.get()
} }
// https://dom.spec.whatwg.org/#dom-event-returnvalue /// <https://dom.spec.whatwg.org/#dom-event-returnvalue>
fn ReturnValue(&self) -> bool { fn ReturnValue(&self) -> bool {
self.canceled.get() == EventDefault::Allowed self.canceled.get() == EventDefault::Allowed
} }
// https://dom.spec.whatwg.org/#dom-event-returnvalue /// <https://dom.spec.whatwg.org/#dom-event-returnvalue>
fn SetReturnValue(&self, val: bool) { fn SetReturnValue(&self, val: bool) {
if !val { if !val {
self.PreventDefault(); self.PreventDefault();
} }
} }
// https://dom.spec.whatwg.org/#dom-event-cancelbubble /// <https://dom.spec.whatwg.org/#dom-event-cancelbubble>
fn CancelBubble(&self) -> bool { fn CancelBubble(&self) -> bool {
self.stop_propagation.get() self.stop_propagation.get()
} }
// https://dom.spec.whatwg.org/#dom-event-cancelbubble /// <https://dom.spec.whatwg.org/#dom-event-cancelbubble>
fn SetCancelBubble(&self, value: bool) { fn SetCancelBubble(&self, value: bool) {
if value { if value {
self.stop_propagation.set(true) self.stop_propagation.set(true)
} }
} }
// https://dom.spec.whatwg.org/#dom-event-timestamp /// <https://dom.spec.whatwg.org/#dom-event-timestamp>
fn TimeStamp(&self) -> DOMHighResTimeStamp { fn TimeStamp(&self) -> DOMHighResTimeStamp {
reduce_timing_resolution( reduce_timing_resolution(
(self.precise_time_ns - (*self.global().performance().TimeOrigin()).round() as u64) (self.precise_time_ns - (*self.global().performance().TimeOrigin()).round() as u64)
@ -498,12 +507,12 @@ impl EventMethods for Event {
) )
} }
// https://dom.spec.whatwg.org/#dom-event-initevent /// <https://dom.spec.whatwg.org/#dom-event-initevent>
fn InitEvent(&self, type_: DOMString, bubbles: bool, cancelable: bool) { fn InitEvent(&self, type_: DOMString, bubbles: bool, cancelable: bool) {
self.init_event(Atom::from(type_), bubbles, cancelable) self.init_event(Atom::from(type_), bubbles, cancelable)
} }
// https://dom.spec.whatwg.org/#dom-event-istrusted /// <https://dom.spec.whatwg.org/#dom-event-istrusted>
fn IsTrusted(&self) -> bool { fn IsTrusted(&self) -> bool {
self.trusted.get() self.trusted.get()
} }
@ -597,7 +606,7 @@ pub enum EventStatus {
NotCanceled, NotCanceled,
} }
// https://dom.spec.whatwg.org/#concept-event-fire /// <https://dom.spec.whatwg.org/#concept-event-fire>
pub struct EventTask { pub struct EventTask {
pub target: Trusted<EventTarget>, pub target: Trusted<EventTarget>,
pub name: Atom, pub name: Atom,
@ -614,7 +623,7 @@ impl TaskOnce for EventTask {
} }
} }
// https://html.spec.whatwg.org/multipage/#fire-a-simple-event /// <https://html.spec.whatwg.org/multipage/#fire-a-simple-event>
pub struct SimpleEventTask { pub struct SimpleEventTask {
pub target: Trusted<EventTarget>, pub target: Trusted<EventTarget>,
pub name: Atom, pub name: Atom,
@ -627,7 +636,7 @@ impl TaskOnce for SimpleEventTask {
} }
} }
// https://dom.spec.whatwg.org/#concept-event-listener-invoke /// <https://dom.spec.whatwg.org/#concept-event-listener-invoke>
fn invoke( fn invoke(
timeline_window: Option<&Window>, timeline_window: Option<&Window>,
object: &EventTarget, object: &EventTarget,
@ -674,7 +683,7 @@ fn invoke(
} }
} }
// https://dom.spec.whatwg.org/#concept-event-listener-inner-invoke /// <https://dom.spec.whatwg.org/#concept-event-listener-inner-invoke>
fn inner_invoke( fn inner_invoke(
timeline_window: Option<&Window>, timeline_window: Option<&Window>,
object: &EventTarget, object: &EventTarget,

View file

@ -14,6 +14,7 @@ interface Event {
readonly attribute EventTarget? target; readonly attribute EventTarget? target;
readonly attribute EventTarget? srcElement; readonly attribute EventTarget? srcElement;
readonly attribute EventTarget? currentTarget; readonly attribute EventTarget? currentTarget;
sequence<EventTarget> composedPath();
const unsigned short NONE = 0; const unsigned short NONE = 0;
const unsigned short CAPTURING_PHASE = 1; const unsigned short CAPTURING_PHASE = 1;

View file

@ -8,9 +8,6 @@
[EventTarget interface: new AbortController().signal must inherit property "addEventListener(DOMString, EventListener, [object Object\],[object Object\])" with the proper type] [EventTarget interface: new AbortController().signal must inherit property "addEventListener(DOMString, EventListener, [object Object\],[object Object\])" with the proper type]
expected: FAIL expected: FAIL
[Event interface: operation composedPath()]
expected: FAIL
[AbortSignal must be primary interface of new AbortController().signal] [AbortSignal must be primary interface of new AbortController().signal]
expected: FAIL expected: FAIL
@ -83,9 +80,6 @@
[AbortSignal interface: new AbortController().signal must inherit property "onabort" with the proper type] [AbortSignal interface: new AbortController().signal must inherit property "onabort" with the proper type]
expected: FAIL expected: FAIL
[Event interface: new CustomEvent("foo") must inherit property "composedPath()" with the proper type]
expected: FAIL
[AbortController interface: existence and properties of interface prototype object's "constructor" property] [AbortController interface: existence and properties of interface prototype object's "constructor" property]
expected: FAIL expected: FAIL
@ -104,9 +98,6 @@
[EventTarget interface: calling dispatchEvent(Event) on new AbortController().signal with too few arguments must throw TypeError] [EventTarget interface: calling dispatchEvent(Event) on new AbortController().signal with too few arguments must throw TypeError]
expected: FAIL expected: FAIL
[Event interface: new Event("foo") must inherit property "composedPath()" with the proper type]
expected: FAIL
[AbortController must be primary interface of new AbortController()] [AbortController must be primary interface of new AbortController()]
expected: FAIL expected: FAIL

View file

@ -74,9 +74,6 @@
[Element interface: operation attachShadow(ShadowRootInit)] [Element interface: operation attachShadow(ShadowRootInit)]
expected: FAIL expected: FAIL
[Event interface: new CustomEvent("foo") must inherit property "composedPath()" with the proper type]
expected: FAIL
[AbortController interface: operation abort()] [AbortController interface: operation abort()]
expected: FAIL expected: FAIL
@ -101,18 +98,12 @@
[StaticRange interface: existence and properties of interface object] [StaticRange interface: existence and properties of interface object]
expected: FAIL expected: FAIL
[Event interface: new Event("foo") must inherit property "composedPath()" with the proper type]
expected: FAIL
[AbortSignal interface: attribute aborted] [AbortSignal interface: attribute aborted]
expected: FAIL expected: FAIL
[AbstractRange interface: existence and properties of interface prototype object] [AbstractRange interface: existence and properties of interface prototype object]
expected: FAIL expected: FAIL
[Event interface: operation composedPath()]
expected: FAIL
[AbstractRange interface: attribute endContainer] [AbstractRange interface: attribute endContainer]
expected: FAIL expected: FAIL
@ -203,9 +194,6 @@
[Element interface: operation prepend([object Object\],[object Object\])] [Element interface: operation prepend([object Object\],[object Object\])]
expected: FAIL expected: FAIL
[Event interface: document.createEvent("Event") must inherit property "composedPath()" with the proper type]
expected: FAIL
[StaticRange interface object length] [StaticRange interface object length]
expected: FAIL expected: FAIL

View file

@ -5,24 +5,15 @@
expected: ERROR expected: ERROR
[idlharness.any.worker.html] [idlharness.any.worker.html]
[Event interface: operation composedPath()]
expected: FAIL
[Event interface: attribute composed] [Event interface: attribute composed]
expected: FAIL expected: FAIL
[Event interface: new Event("foo") must inherit property "composedPath()" with the proper type]
expected: FAIL
[Event interface: new Event("foo") must inherit property "composed" with the proper type] [Event interface: new Event("foo") must inherit property "composed" with the proper type]
expected: FAIL expected: FAIL
[CustomEvent interface: operation initCustomEvent(DOMString, optional boolean, optional boolean, optional any)] [CustomEvent interface: operation initCustomEvent(DOMString, optional boolean, optional boolean, optional any)]
expected: FAIL expected: FAIL
[Event interface: new CustomEvent("foo") must inherit property "composedPath()" with the proper type]
expected: FAIL
[Event interface: new CustomEvent("foo") must inherit property "composed" with the proper type] [Event interface: new CustomEvent("foo") must inherit property "composed" with the proper type]
expected: FAIL expected: FAIL

View file

@ -151,9 +151,6 @@
[XPathResult interface: constant ANY_TYPE on interface prototype object] [XPathResult interface: constant ANY_TYPE on interface prototype object]
expected: FAIL expected: FAIL
[Event interface: new Event("foo") must inherit property "composedPath()" with the proper type]
expected: FAIL
[CharacterData interface: operation before((Node or DOMString)...)] [CharacterData interface: operation before((Node or DOMString)...)]
expected: FAIL expected: FAIL
@ -166,9 +163,6 @@
[XPathResult interface: document.evaluate("//*", document.body) must inherit property "ANY_TYPE" with the proper type] [XPathResult interface: document.evaluate("//*", document.body) must inherit property "ANY_TYPE" with the proper type]
expected: FAIL expected: FAIL
[Event interface: operation composedPath()]
expected: FAIL
[XPathEvaluator interface: operation evaluate(DOMString, Node, optional XPathNSResolver?, optional unsigned short, optional XPathResult?)] [XPathEvaluator interface: operation evaluate(DOMString, Node, optional XPathNSResolver?, optional unsigned short, optional XPathResult?)]
expected: FAIL expected: FAIL
@ -370,9 +364,6 @@
[XPathEvaluator interface: new XPathEvaluator() must inherit property "createNSResolver(Node)" with the proper type] [XPathEvaluator interface: new XPathEvaluator() must inherit property "createNSResolver(Node)" with the proper type]
expected: FAIL expected: FAIL
[Event interface: document.createEvent("Event") must inherit property "composedPath()" with the proper type]
expected: FAIL
[StaticRange interface object length] [StaticRange interface object length]
expected: FAIL expected: FAIL
@ -394,9 +385,6 @@
[AbortSignal interface: new AbortController().signal must inherit property "onabort" with the proper type] [AbortSignal interface: new AbortController().signal must inherit property "onabort" with the proper type]
expected: FAIL expected: FAIL
[Event interface: new CustomEvent("foo") must inherit property "composedPath()" with the proper type]
expected: FAIL
[Document interface: calling evaluate(DOMString, Node, optional XPathNSResolver?, optional unsigned short, optional XPathResult?) on xmlDoc with too few arguments must throw TypeError] [Document interface: calling evaluate(DOMString, Node, optional XPathNSResolver?, optional unsigned short, optional XPathResult?) on xmlDoc with too few arguments must throw TypeError]
expected: FAIL expected: FAIL