script/dom/
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::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// 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(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    // https://dom.spec.whatwg.org/#dom-customevent-customevent
89    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    // https://dom.spec.whatwg.org/#dom-customevent-detail
110    fn Detail(&self, _cx: JSContext, mut retval: MutableHandleValue) {
111        retval.set(self.detail.get())
112    }
113
114    // https://dom.spec.whatwg.org/#dom-customevent-initcustomevent
115    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    // https://dom.spec.whatwg.org/#dom-event-istrusted
127    fn IsTrusted(&self) -> bool {
128        self.event.IsTrusted()
129    }
130}