Skip to main content

script/dom/event/
customevent.rs

1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
5use dom_struct::dom_struct;
6use js::context::JSContext;
7use js::jsapi::Heap;
8use js::jsval::JSVal;
9use js::rust::{HandleObject, HandleValue, MutableHandleValue};
10use script_bindings::reflector::reflect_dom_object_with_proto_and_cx;
11use stylo_atoms::Atom;
12
13use crate::dom::bindings::codegen::Bindings::CustomEventBinding;
14use crate::dom::bindings::codegen::Bindings::CustomEventBinding::CustomEventMethods;
15use crate::dom::bindings::codegen::Bindings::EventBinding::EventMethods;
16use crate::dom::bindings::inheritance::Castable;
17use crate::dom::bindings::root::DomRoot;
18use crate::dom::bindings::str::DOMString;
19use crate::dom::bindings::trace::RootedTraceableBox;
20use crate::dom::event::Event;
21use crate::dom::globalscope::GlobalScope;
22
23// https://dom.spec.whatwg.org/#interface-customevent
24#[dom_struct]
25pub(crate) struct CustomEvent {
26    event: Event,
27    #[ignore_malloc_size_of = "Defined in rust-mozjs"]
28    detail: Heap<JSVal>,
29}
30
31impl CustomEvent {
32    fn new_inherited() -> CustomEvent {
33        CustomEvent {
34            event: Event::new_inherited(),
35            detail: Heap::default(),
36        }
37    }
38
39    pub(crate) fn new_uninitialized(
40        cx: &mut JSContext,
41        global: &GlobalScope,
42    ) -> DomRoot<CustomEvent> {
43        Self::new_uninitialized_with_proto(cx, global, None)
44    }
45
46    fn new_uninitialized_with_proto(
47        cx: &mut JSContext,
48        global: &GlobalScope,
49        proto: Option<HandleObject>,
50    ) -> DomRoot<CustomEvent> {
51        reflect_dom_object_with_proto_and_cx(
52            Box::new(CustomEvent::new_inherited()),
53            global,
54            proto,
55            cx,
56        )
57    }
58
59    fn new(
60        cx: &mut JSContext,
61        global: &GlobalScope,
62        proto: Option<HandleObject>,
63        type_: Atom,
64        bubbles: bool,
65        cancelable: bool,
66        detail: HandleValue,
67    ) -> DomRoot<CustomEvent> {
68        let ev = CustomEvent::new_uninitialized_with_proto(cx, global, proto);
69        ev.init_custom_event(type_, bubbles, cancelable, detail);
70        ev
71    }
72
73    fn init_custom_event(
74        &self,
75        type_: Atom,
76        can_bubble: bool,
77        cancelable: bool,
78        detail: HandleValue,
79    ) {
80        let event = self.upcast::<Event>();
81        if event.dispatching() {
82            return;
83        }
84
85        self.detail.set(detail.get());
86        event.init_event(type_, can_bubble, cancelable);
87    }
88}
89
90impl CustomEventMethods<crate::DomTypeHolder> for CustomEvent {
91    /// <https://dom.spec.whatwg.org/#dom-customevent-customevent>
92    fn Constructor(
93        cx: &mut JSContext,
94        global: &GlobalScope,
95        proto: Option<HandleObject>,
96        type_: DOMString,
97        init: RootedTraceableBox<CustomEventBinding::CustomEventInit>,
98    ) -> DomRoot<CustomEvent> {
99        let event = CustomEvent::new(
100            cx,
101            global,
102            proto,
103            Atom::from(type_),
104            init.parent.bubbles,
105            init.parent.cancelable,
106            init.detail.handle(),
107        );
108        event.upcast::<Event>().set_composed(init.parent.composed);
109        event
110    }
111
112    /// <https://dom.spec.whatwg.org/#dom-customevent-detail>
113    fn Detail(&self, mut retval: MutableHandleValue) {
114        retval.set(self.detail.get())
115    }
116
117    /// <https://dom.spec.whatwg.org/#dom-customevent-initcustomevent>
118    fn InitCustomEvent(
119        &self,
120        type_: DOMString,
121        can_bubble: bool,
122        cancelable: bool,
123        detail: HandleValue,
124    ) {
125        self.init_custom_event(Atom::from(type_), can_bubble, cancelable, detail)
126    }
127
128    /// <https://dom.spec.whatwg.org/#dom-event-istrusted>
129    fn IsTrusted(&self) -> bool {
130        self.event.IsTrusted()
131    }
132}