Skip to main content

script/dom/event/
toggleevent.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::rust::HandleObject;
8use script_bindings::codegen::GenericBindings::NodeBinding::NodeMethods;
9use script_bindings::inheritance::Castable;
10use script_bindings::reflector::reflect_dom_object_with_proto_and_cx;
11use stylo_atoms::Atom;
12
13use crate::dom::bindings::codegen::Bindings::EventBinding::EventMethods;
14use crate::dom::bindings::codegen::Bindings::ToggleEventBinding;
15use crate::dom::bindings::codegen::Bindings::ToggleEventBinding::ToggleEventMethods;
16use crate::dom::bindings::error::Fallible;
17use crate::dom::bindings::root::DomRoot;
18use crate::dom::bindings::str::DOMString;
19use crate::dom::element::Element;
20use crate::dom::event::{Event, EventBubbles, EventCancelable};
21use crate::dom::eventtarget::EventTarget;
22use crate::dom::node::Node;
23use crate::dom::types::Window;
24
25#[dom_struct]
26pub(crate) struct ToggleEvent {
27    event: Event,
28    /// <https://html.spec.whatwg.org/multipage/#dom-toggleevent-oldstate>
29    old_state: DOMString,
30    /// <https://html.spec.whatwg.org/multipage/#dom-toggleevent-newstate>
31    new_state: DOMString,
32    /// <https://html.spec.whatwg.org/multipage/#dom-toggleevent-source>
33    source: Option<DomRoot<Element>>,
34}
35
36impl ToggleEvent {
37    pub(crate) fn new_inherited(
38        old_state: DOMString,
39        new_state: DOMString,
40        source: Option<DomRoot<Element>>,
41    ) -> ToggleEvent {
42        ToggleEvent {
43            event: Event::new_inherited(),
44            old_state,
45            new_state,
46            source,
47        }
48    }
49
50    #[allow(clippy::too_many_arguments)]
51    pub(crate) fn new(
52        cx: &mut JSContext,
53        window: &Window,
54        type_: Atom,
55        bubbles: EventBubbles,
56        cancelable: EventCancelable,
57        old_state: DOMString,
58        new_state: DOMString,
59        source: Option<DomRoot<Element>>,
60    ) -> DomRoot<ToggleEvent> {
61        Self::new_with_proto(
62            cx, window, None, type_, bubbles, cancelable, old_state, new_state, source,
63        )
64    }
65
66    #[allow(clippy::too_many_arguments)]
67    fn new_with_proto(
68        cx: &mut JSContext,
69        window: &Window,
70        proto: Option<HandleObject>,
71        type_: Atom,
72        bubbles: EventBubbles,
73        cancelable: EventCancelable,
74        old_state: DOMString,
75        new_state: DOMString,
76        source: Option<DomRoot<Element>>,
77    ) -> DomRoot<ToggleEvent> {
78        let event = Box::new(ToggleEvent::new_inherited(old_state, new_state, source));
79        let event = reflect_dom_object_with_proto_and_cx(event, window, proto, cx);
80        {
81            let event = event.upcast::<Event>();
82            event.init_event(type_, bool::from(bubbles), bool::from(cancelable));
83        }
84        event
85    }
86}
87
88impl ToggleEventMethods<crate::DomTypeHolder> for ToggleEvent {
89    /// <https://html.spec.whatwg.org/multipage/#toggleevent>
90    fn Constructor(
91        cx: &mut JSContext,
92        window: &Window,
93        proto: Option<HandleObject>,
94
95        type_: DOMString,
96        init: &ToggleEventBinding::ToggleEventInit,
97    ) -> Fallible<DomRoot<ToggleEvent>> {
98        let bubbles = EventBubbles::from(init.parent.bubbles);
99        let cancelable = EventCancelable::from(init.parent.cancelable);
100        Ok(ToggleEvent::new_with_proto(
101            cx,
102            window,
103            proto,
104            Atom::from(type_),
105            bubbles,
106            cancelable,
107            init.oldState.clone(),
108            init.newState.clone(),
109            init.source.as_ref().map(|s| DomRoot::from_ref(&**s)),
110        ))
111    }
112
113    /// <https://dom.spec.whatwg.org/#dom-event-istrusted>
114    fn IsTrusted(&self) -> bool {
115        self.event.IsTrusted()
116    }
117
118    /// <https://html.spec.whatwg.org/multipage/#dom-toggleevent-oldstate>
119    fn OldState(&self) -> DOMString {
120        self.old_state.clone()
121    }
122
123    /// <https://html.spec.whatwg.org/multipage/#dom-toggleevent-newstate>
124    fn NewState(&self) -> DOMString {
125        self.new_state.clone()
126    }
127
128    /// <https://html.spec.whatwg.org/multipage/#dom-toggleevent-source>
129    fn GetSource(&self) -> Option<DomRoot<Element>> {
130        // The source getter steps are to return the result of retargeting source against this's currentTarget.
131        let source = self.source.as_ref()?;
132
133        if let Some(current_target) = self.event.GetCurrentTarget() {
134            let retargeted = source.upcast::<EventTarget>().retarget(&current_target);
135            return retargeted.downcast::<Element>().map(DomRoot::from_ref);
136        }
137
138        let document = source.upcast::<Node>().GetOwnerDocument().unwrap();
139        let retargeted = source
140            .upcast::<EventTarget>()
141            .retarget(document.upcast::<EventTarget>());
142        retargeted.downcast::<Element>().map(DomRoot::from_ref)
143    }
144}