Skip to main content

script/dom/event/
storageevent.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::cell::DomRefCell;
9use script_bindings::reflector::reflect_dom_object_with_proto_and_cx;
10use stylo_atoms::Atom;
11
12use crate::dom::bindings::codegen::Bindings::EventBinding::EventMethods;
13use crate::dom::bindings::codegen::Bindings::StorageEventBinding;
14use crate::dom::bindings::codegen::Bindings::StorageEventBinding::StorageEventMethods;
15use crate::dom::bindings::error::Fallible;
16use crate::dom::bindings::inheritance::Castable;
17use crate::dom::bindings::root::{DomRoot, MutNullableDom};
18use crate::dom::bindings::str::{DOMString, USVString};
19use crate::dom::event::{Event, EventBubbles, EventCancelable};
20use crate::dom::storage::Storage;
21use crate::dom::window::Window;
22
23#[dom_struct]
24pub(crate) struct StorageEvent {
25    event: Event,
26    key: DomRefCell<Option<DOMString>>,
27    old_value: DomRefCell<Option<DOMString>>,
28    new_value: DomRefCell<Option<DOMString>>,
29    url: DomRefCell<DOMString>,
30    storage_area: MutNullableDom<Storage>,
31}
32
33#[expect(non_snake_case)]
34impl StorageEvent {
35    pub(crate) fn new_inherited(
36        key: Option<DOMString>,
37        old_value: Option<DOMString>,
38        new_value: Option<DOMString>,
39        url: DOMString,
40        storage_area: Option<&Storage>,
41    ) -> StorageEvent {
42        StorageEvent {
43            event: Event::new_inherited(),
44            key: DomRefCell::new(key),
45            old_value: DomRefCell::new(old_value),
46            new_value: DomRefCell::new(new_value),
47            url: DomRefCell::new(url),
48            storage_area: MutNullableDom::new(storage_area),
49        }
50    }
51
52    pub(crate) fn new_uninitialized(
53        cx: &mut JSContext,
54        window: &Window,
55        url: DOMString,
56    ) -> DomRoot<StorageEvent> {
57        Self::new_uninitialized_with_proto(cx, window, None, url)
58    }
59
60    fn new_uninitialized_with_proto(
61        cx: &mut JSContext,
62        window: &Window,
63        proto: Option<HandleObject>,
64        url: DOMString,
65    ) -> DomRoot<StorageEvent> {
66        reflect_dom_object_with_proto_and_cx(
67            Box::new(StorageEvent::new_inherited(None, None, None, url, None)),
68            window,
69            proto,
70            cx,
71        )
72    }
73
74    #[allow(clippy::too_many_arguments)]
75    pub(crate) fn new(
76        cx: &mut JSContext,
77        global: &Window,
78        type_: Atom,
79        bubbles: EventBubbles,
80        cancelable: EventCancelable,
81        key: Option<DOMString>,
82        oldValue: Option<DOMString>,
83        newValue: Option<DOMString>,
84        url: DOMString,
85        storageArea: Option<&Storage>,
86    ) -> DomRoot<StorageEvent> {
87        Self::new_with_proto(
88            cx,
89            global,
90            None,
91            type_,
92            bubbles,
93            cancelable,
94            key,
95            oldValue,
96            newValue,
97            url,
98            storageArea,
99        )
100    }
101
102    #[allow(clippy::too_many_arguments)]
103    fn new_with_proto(
104        cx: &mut JSContext,
105        global: &Window,
106        proto: Option<HandleObject>,
107        type_: Atom,
108        bubbles: EventBubbles,
109        cancelable: EventCancelable,
110        key: Option<DOMString>,
111        oldValue: Option<DOMString>,
112        newValue: Option<DOMString>,
113        url: DOMString,
114        storageArea: Option<&Storage>,
115    ) -> DomRoot<StorageEvent> {
116        let ev = reflect_dom_object_with_proto_and_cx(
117            Box::new(StorageEvent::new_inherited(
118                key,
119                oldValue,
120                newValue,
121                url,
122                storageArea,
123            )),
124            global,
125            proto,
126            cx,
127        );
128        {
129            let event = ev.upcast::<Event>();
130            event.init_event(type_, bool::from(bubbles), bool::from(cancelable));
131        }
132        ev
133    }
134}
135
136#[expect(non_snake_case)]
137impl StorageEventMethods<crate::DomTypeHolder> for StorageEvent {
138    /// <https://html.spec.whatwg.org/multipage/#storageevent>
139    fn Constructor(
140        cx: &mut JSContext,
141        global: &Window,
142        proto: Option<HandleObject>,
143        type_: DOMString,
144        init: &StorageEventBinding::StorageEventInit,
145    ) -> Fallible<DomRoot<StorageEvent>> {
146        let key = init.key.clone();
147        let oldValue = init.oldValue.clone();
148        let newValue = init.newValue.clone();
149        let url = init.url.clone();
150        let storageArea = init.storageArea.as_deref();
151        let bubbles = EventBubbles::from(init.parent.bubbles);
152        let cancelable = EventCancelable::from(init.parent.cancelable);
153        let event = StorageEvent::new_with_proto(
154            cx,
155            global,
156            proto,
157            Atom::from(type_),
158            bubbles,
159            cancelable,
160            key,
161            oldValue,
162            newValue,
163            url,
164            storageArea,
165        );
166        Ok(event)
167    }
168
169    /// <https://html.spec.whatwg.org/multipage/#dom-storageevent-key>
170    fn GetKey(&self) -> Option<DOMString> {
171        self.key.borrow().clone()
172    }
173
174    /// <https://html.spec.whatwg.org/multipage/#dom-storageevent-oldvalue>
175    fn GetOldValue(&self) -> Option<DOMString> {
176        self.old_value.borrow().clone()
177    }
178
179    /// <https://html.spec.whatwg.org/multipage/#dom-storageevent-newvalue>
180    fn GetNewValue(&self) -> Option<DOMString> {
181        self.new_value.borrow().clone()
182    }
183
184    /// <https://html.spec.whatwg.org/multipage/#dom-storageevent-url>
185    fn Url(&self) -> DOMString {
186        self.url.borrow().clone()
187    }
188
189    /// <https://html.spec.whatwg.org/multipage/#dom-storageevent-storagearea>
190    fn GetStorageArea(&self) -> Option<DomRoot<Storage>> {
191        self.storage_area.get()
192    }
193
194    /// <https://dom.spec.whatwg.org/#dom-event-istrusted>
195    fn IsTrusted(&self) -> bool {
196        self.event.IsTrusted()
197    }
198
199    /// <https://html.spec.whatwg.org/multipage/#dom-storageevent-initstorageevent>
200    fn InitStorageEvent(
201        &self,
202        type_: DOMString,
203        bubbles: bool,
204        cancelable: bool,
205        key: Option<DOMString>,
206        oldValue: Option<DOMString>,
207        newValue: Option<DOMString>,
208        url: USVString,
209        storageArea: Option<&Storage>,
210    ) {
211        self.event
212            .init_event(Atom::from(type_), bubbles, cancelable);
213        *self.key.borrow_mut() = key;
214        *self.old_value.borrow_mut() = oldValue;
215        *self.new_value.borrow_mut() = newValue;
216        *self.url.borrow_mut() = url.into();
217        self.storage_area.set(storageArea);
218    }
219}