script/dom/
broadcastchannel.rs1use std::cell::Cell;
6
7use constellation_traits::BroadcastChannelMsg;
8use dom_struct::dom_struct;
9use js::context::JSContext;
10use js::rust::{HandleObject, HandleValue};
11use uuid::Uuid;
12
13use crate::dom::bindings::codegen::Bindings::BroadcastChannelBinding::BroadcastChannelMethods;
14use crate::dom::bindings::error::{Error, ErrorResult};
15use crate::dom::bindings::reflector::{DomGlobal, reflect_dom_object_with_proto};
16use crate::dom::bindings::root::DomRoot;
17use crate::dom::bindings::str::DOMString;
18use crate::dom::bindings::structuredclone;
19use crate::dom::eventtarget::EventTarget;
20use crate::dom::globalscope::GlobalScope;
21use crate::script_runtime::CanGc;
22
23#[dom_struct]
24pub(crate) struct BroadcastChannel {
25 eventtarget: EventTarget,
26 name: DOMString,
27 closed: Cell<bool>,
28 #[no_trace]
29 id: Uuid,
30}
31
32impl BroadcastChannel {
33 fn new(
34 global: &GlobalScope,
35 proto: Option<HandleObject>,
36 name: DOMString,
37 can_gc: CanGc,
38 ) -> DomRoot<BroadcastChannel> {
39 let channel = reflect_dom_object_with_proto(
40 Box::new(BroadcastChannel::new_inherited(name)),
41 global,
42 proto,
43 can_gc,
44 );
45 global.track_broadcast_channel(&channel);
46 channel
47 }
48
49 pub(crate) fn new_inherited(name: DOMString) -> BroadcastChannel {
50 BroadcastChannel {
51 eventtarget: EventTarget::new_inherited(),
52 name,
53 closed: Default::default(),
54 id: Uuid::new_v4(),
55 }
56 }
57
58 pub(crate) fn id(&self) -> &Uuid {
61 &self.id
62 }
63
64 pub(crate) fn closed(&self) -> bool {
66 self.closed.get()
67 }
68}
69
70impl BroadcastChannelMethods<crate::DomTypeHolder> for BroadcastChannel {
71 fn Constructor(
73 global: &GlobalScope,
74 proto: Option<HandleObject>,
75 can_gc: CanGc,
76 name: DOMString,
77 ) -> DomRoot<BroadcastChannel> {
78 BroadcastChannel::new(global, proto, name, can_gc)
79 }
80
81 fn PostMessage(&self, cx: &mut JSContext, message: HandleValue) -> ErrorResult {
83 if self.closed.get() {
85 return Err(Error::InvalidState(None));
86 }
87
88 let data = structuredclone::write(cx.into(), message, None)?;
90
91 let global = self.global();
92
93 let msg = BroadcastChannelMsg {
94 origin: global.origin().immutable().clone(),
95 channel_name: self.Name().to_string(),
96 data,
97 };
98
99 global.schedule_broadcast(msg, &self.id);
100 Ok(())
101 }
102
103 fn Name(&self) -> DOMString {
105 self.name.clone()
106 }
107
108 fn Close(&self) {
110 self.closed.set(true);
111 }
112
113 event_handler!(messageerror, GetOnmessageerror, SetOnmessageerror);
115
116 event_handler!(message, GetOnmessage, SetOnmessage);
118}