1use dom_struct::dom_struct;
6use js::rust::HandleObject;
7use stylo_atoms::Atom;
8
9use crate::dom::bindings::cell::DomRefCell;
10use crate::dom::bindings::codegen::Bindings::EventBinding::EventMethods;
11use crate::dom::bindings::codegen::Bindings::StorageEventBinding;
12use crate::dom::bindings::codegen::Bindings::StorageEventBinding::StorageEventMethods;
13use crate::dom::bindings::error::Fallible;
14use crate::dom::bindings::inheritance::Castable;
15use crate::dom::bindings::reflector::reflect_dom_object_with_proto;
16use crate::dom::bindings::root::{DomRoot, MutNullableDom};
17use crate::dom::bindings::str::{DOMString, USVString};
18use crate::dom::event::{Event, EventBubbles, EventCancelable};
19use crate::dom::storage::Storage;
20use crate::dom::window::Window;
21use crate::script_runtime::CanGc;
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#[allow(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 window: &Window,
54 url: DOMString,
55 can_gc: CanGc,
56 ) -> DomRoot<StorageEvent> {
57 Self::new_uninitialized_with_proto(window, None, url, can_gc)
58 }
59
60 fn new_uninitialized_with_proto(
61 window: &Window,
62 proto: Option<HandleObject>,
63 url: DOMString,
64 can_gc: CanGc,
65 ) -> DomRoot<StorageEvent> {
66 reflect_dom_object_with_proto(
67 Box::new(StorageEvent::new_inherited(None, None, None, url, None)),
68 window,
69 proto,
70 can_gc,
71 )
72 }
73
74 #[allow(clippy::too_many_arguments)]
75 pub(crate) fn new(
76 global: &Window,
77 type_: Atom,
78 bubbles: EventBubbles,
79 cancelable: EventCancelable,
80 key: Option<DOMString>,
81 oldValue: Option<DOMString>,
82 newValue: Option<DOMString>,
83 url: DOMString,
84 storageArea: Option<&Storage>,
85 can_gc: CanGc,
86 ) -> DomRoot<StorageEvent> {
87 Self::new_with_proto(
88 global,
89 None,
90 type_,
91 bubbles,
92 cancelable,
93 key,
94 oldValue,
95 newValue,
96 url,
97 storageArea,
98 can_gc,
99 )
100 }
101
102 #[allow(clippy::too_many_arguments)]
103 fn new_with_proto(
104 global: &Window,
105 proto: Option<HandleObject>,
106 type_: Atom,
107 bubbles: EventBubbles,
108 cancelable: EventCancelable,
109 key: Option<DOMString>,
110 oldValue: Option<DOMString>,
111 newValue: Option<DOMString>,
112 url: DOMString,
113 storageArea: Option<&Storage>,
114 can_gc: CanGc,
115 ) -> DomRoot<StorageEvent> {
116 let ev = reflect_dom_object_with_proto(
117 Box::new(StorageEvent::new_inherited(
118 key,
119 oldValue,
120 newValue,
121 url,
122 storageArea,
123 )),
124 global,
125 proto,
126 can_gc,
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#[allow(non_snake_case)]
137impl StorageEventMethods<crate::DomTypeHolder> for StorageEvent {
138 fn Constructor(
140 global: &Window,
141 proto: Option<HandleObject>,
142 can_gc: CanGc,
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 global,
155 proto,
156 Atom::from(type_),
157 bubbles,
158 cancelable,
159 key,
160 oldValue,
161 newValue,
162 url,
163 storageArea,
164 can_gc,
165 );
166 Ok(event)
167 }
168
169 fn GetKey(&self) -> Option<DOMString> {
171 self.key.borrow().clone()
172 }
173
174 fn GetOldValue(&self) -> Option<DOMString> {
176 self.old_value.borrow().clone()
177 }
178
179 fn GetNewValue(&self) -> Option<DOMString> {
181 self.new_value.borrow().clone()
182 }
183
184 fn Url(&self) -> DOMString {
186 self.url.borrow().clone()
187 }
188
189 fn GetStorageArea(&self) -> Option<DomRoot<Storage>> {
191 self.storage_area.get()
192 }
193
194 fn IsTrusted(&self) -> bool {
196 self.event.IsTrusted()
197 }
198
199 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() = DOMString::from_string(url.0);
217 self.storage_area.set(storageArea);
218 }
219}