script/dom/
customevent.rs1use dom_struct::dom_struct;
6use js::jsapi::Heap;
7use js::jsval::JSVal;
8use js::rust::{HandleObject, HandleValue, MutableHandleValue};
9use stylo_atoms::Atom;
10
11use crate::dom::bindings::codegen::Bindings::CustomEventBinding;
12use crate::dom::bindings::codegen::Bindings::CustomEventBinding::CustomEventMethods;
13use crate::dom::bindings::codegen::Bindings::EventBinding::EventMethods;
14use crate::dom::bindings::inheritance::Castable;
15use crate::dom::bindings::reflector::reflect_dom_object_with_proto;
16use crate::dom::bindings::root::DomRoot;
17use crate::dom::bindings::str::DOMString;
18use crate::dom::bindings::trace::RootedTraceableBox;
19use crate::dom::event::Event;
20use crate::dom::globalscope::GlobalScope;
21use crate::script_runtime::{CanGc, JSContext};
22
23#[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(global: &GlobalScope, can_gc: CanGc) -> DomRoot<CustomEvent> {
40 Self::new_uninitialized_with_proto(global, None, can_gc)
41 }
42
43 fn new_uninitialized_with_proto(
44 global: &GlobalScope,
45 proto: Option<HandleObject>,
46 can_gc: CanGc,
47 ) -> DomRoot<CustomEvent> {
48 reflect_dom_object_with_proto(
49 Box::new(CustomEvent::new_inherited()),
50 global,
51 proto,
52 can_gc,
53 )
54 }
55
56 fn new(
57 global: &GlobalScope,
58 proto: Option<HandleObject>,
59 type_: Atom,
60 bubbles: bool,
61 cancelable: bool,
62 detail: HandleValue,
63 can_gc: CanGc,
64 ) -> DomRoot<CustomEvent> {
65 let ev = CustomEvent::new_uninitialized_with_proto(global, proto, can_gc);
66 ev.init_custom_event(type_, bubbles, cancelable, detail);
67 ev
68 }
69
70 fn init_custom_event(
71 &self,
72 type_: Atom,
73 can_bubble: bool,
74 cancelable: bool,
75 detail: HandleValue,
76 ) {
77 let event = self.upcast::<Event>();
78 if event.dispatching() {
79 return;
80 }
81
82 self.detail.set(detail.get());
83 event.init_event(type_, can_bubble, cancelable);
84 }
85}
86
87impl CustomEventMethods<crate::DomTypeHolder> for CustomEvent {
88 fn Constructor(
90 global: &GlobalScope,
91 proto: Option<HandleObject>,
92 can_gc: CanGc,
93 type_: DOMString,
94 init: RootedTraceableBox<CustomEventBinding::CustomEventInit>,
95 ) -> DomRoot<CustomEvent> {
96 let event = CustomEvent::new(
97 global,
98 proto,
99 Atom::from(type_),
100 init.parent.bubbles,
101 init.parent.cancelable,
102 init.detail.handle(),
103 can_gc,
104 );
105 event.upcast::<Event>().set_composed(init.parent.composed);
106 event
107 }
108
109 fn Detail(&self, _cx: JSContext, mut retval: MutableHandleValue) {
111 retval.set(self.detail.get())
112 }
113
114 fn InitCustomEvent(
116 &self,
117 _cx: JSContext,
118 type_: DOMString,
119 can_bubble: bool,
120 cancelable: bool,
121 detail: HandleValue,
122 ) {
123 self.init_custom_event(Atom::from(type_), can_bubble, cancelable, detail)
124 }
125
126 fn IsTrusted(&self) -> bool {
128 self.event.IsTrusted()
129 }
130}