1use std::cell::{RefCell, RefMut};
6use std::default::Default;
7use std::rc::Rc;
8use std::sync::Arc;
9use std::sync::atomic::{AtomicBool, Ordering};
10use std::time::Duration;
11
12use base::cross_process_instant::CrossProcessInstant;
13use base::id::{PipelineId, PipelineNamespace};
14use constellation_traits::WorkerGlobalScopeInit;
15use content_security_policy::CspList;
16use crossbeam_channel::Receiver;
17use devtools_traits::{DevtoolScriptControlMsg, WorkerId};
18use dom_struct::dom_struct;
19use fonts::FontContext;
20use ipc_channel::ipc::IpcSender;
21use js::jsval::UndefinedValue;
22use js::panic::maybe_resume_unwind;
23use js::rust::{HandleValue, MutableHandleValue, ParentRuntime};
24use net_traits::policy_container::PolicyContainer;
25use net_traits::request::{
26 CredentialsMode, Destination, InsecureRequestsPolicy, ParserMetadata,
27 RequestBuilder as NetRequestInit,
28};
29use net_traits::{IpcSend, ReferrerPolicy};
30use profile_traits::mem::{ProcessReports, perform_memory_report};
31use servo_url::{MutableOrigin, ServoUrl};
32use timers::TimerScheduler;
33use uuid::Uuid;
34
35use super::bindings::codegen::Bindings::MessagePortBinding::StructuredSerializeOptions;
36use crate::dom::bindings::cell::{DomRefCell, Ref};
37use crate::dom::bindings::codegen::Bindings::ImageBitmapBinding::{
38 ImageBitmapOptions, ImageBitmapSource,
39};
40use crate::dom::bindings::codegen::Bindings::ReportingObserverBinding::Report;
41use crate::dom::bindings::codegen::Bindings::RequestBinding::RequestInit;
42use crate::dom::bindings::codegen::Bindings::VoidFunctionBinding::VoidFunction;
43use crate::dom::bindings::codegen::Bindings::WorkerBinding::WorkerType;
44use crate::dom::bindings::codegen::Bindings::WorkerGlobalScopeBinding::WorkerGlobalScopeMethods;
45use crate::dom::bindings::codegen::UnionTypes::{
46 RequestOrUSVString, TrustedScriptOrString, TrustedScriptOrStringOrFunction,
47 TrustedScriptURLOrUSVString,
48};
49use crate::dom::bindings::error::{Error, ErrorResult, Fallible, report_pending_exception};
50use crate::dom::bindings::inheritance::Castable;
51use crate::dom::bindings::refcounted::Trusted;
52use crate::dom::bindings::reflector::DomObject;
53use crate::dom::bindings::root::{DomRoot, MutNullableDom};
54use crate::dom::bindings::settings_stack::AutoEntryScript;
55use crate::dom::bindings::str::{DOMString, USVString};
56use crate::dom::bindings::trace::RootedTraceableBox;
57use crate::dom::crypto::Crypto;
58use crate::dom::csp::{GlobalCspReporting, Violation};
59use crate::dom::dedicatedworkerglobalscope::DedicatedWorkerGlobalScope;
60use crate::dom::globalscope::GlobalScope;
61use crate::dom::idbfactory::IDBFactory;
62use crate::dom::performance::Performance;
63use crate::dom::promise::Promise;
64use crate::dom::reportingendpoint::{ReportingEndpoint, SendReportsToEndpoints};
65use crate::dom::reportingobserver::ReportingObserver;
66use crate::dom::trustedscripturl::TrustedScriptURL;
67use crate::dom::trustedtypepolicyfactory::TrustedTypePolicyFactory;
68use crate::dom::types::ImageBitmap;
69#[cfg(feature = "webgpu")]
70use crate::dom::webgpu::identityhub::IdentityHub;
71use crate::dom::window::{base64_atob, base64_btoa};
72use crate::dom::workerlocation::WorkerLocation;
73use crate::dom::workernavigator::WorkerNavigator;
74use crate::fetch::{CspViolationsProcessor, Fetch, load_whole_resource};
75use crate::messaging::{CommonScriptMsg, ScriptEventLoopReceiver, ScriptEventLoopSender};
76use crate::realms::{InRealm, enter_realm};
77use crate::script_runtime::{CanGc, IntroductionType, JSContext, JSContextHelper, Runtime};
78use crate::task::TaskCanceller;
79use crate::timers::{IsInterval, TimerCallback};
80
81pub(crate) fn prepare_workerscope_init(
82 global: &GlobalScope,
83 devtools_sender: Option<IpcSender<DevtoolScriptControlMsg>>,
84 worker_id: Option<WorkerId>,
85) -> WorkerGlobalScopeInit {
86 WorkerGlobalScopeInit {
87 resource_threads: global.resource_threads().clone(),
88 mem_profiler_chan: global.mem_profiler_chan().clone(),
89 to_devtools_sender: global.devtools_chan().cloned(),
90 time_profiler_chan: global.time_profiler_chan().clone(),
91 from_devtools_sender: devtools_sender,
92 script_to_constellation_chan: global.script_to_constellation_chan().clone(),
93 script_to_embedder_chan: global.script_to_embedder_chan().clone(),
94 worker_id: worker_id.unwrap_or_else(|| WorkerId(Uuid::new_v4())),
95 pipeline_id: global.pipeline_id(),
96 origin: global.origin().immutable().clone(),
97 creation_url: global.creation_url().clone(),
98 inherited_secure_context: Some(global.is_secure_context()),
99 }
100}
101
102#[dom_struct]
104pub(crate) struct WorkerGlobalScope {
105 globalscope: GlobalScope,
106
107 worker_name: DOMString,
108 worker_type: WorkerType,
109
110 #[no_trace]
111 worker_id: WorkerId,
112 #[no_trace]
113 worker_url: DomRefCell<ServoUrl>,
114 #[ignore_malloc_size_of = "Arc"]
115 closing: Arc<AtomicBool>,
116 #[ignore_malloc_size_of = "Defined in js"]
117 runtime: DomRefCell<Option<Runtime>>,
118 location: MutNullableDom<WorkerLocation>,
119 navigator: MutNullableDom<WorkerNavigator>,
120 #[no_trace]
121 policy_container: DomRefCell<PolicyContainer>,
123
124 #[ignore_malloc_size_of = "Defined in ipc-channel"]
125 #[no_trace]
126 _devtools_sender: Option<IpcSender<DevtoolScriptControlMsg>>,
129
130 #[ignore_malloc_size_of = "Defined in crossbeam"]
131 #[no_trace]
132 devtools_receiver: Option<Receiver<DevtoolScriptControlMsg>>,
134
135 #[no_trace]
136 navigation_start: CrossProcessInstant,
137 performance: MutNullableDom<Performance>,
138 indexeddb: MutNullableDom<IDBFactory>,
139 trusted_types: MutNullableDom<TrustedTypePolicyFactory>,
140
141 #[no_trace]
144 timer_scheduler: RefCell<TimerScheduler>,
145
146 #[no_trace]
147 insecure_requests_policy: InsecureRequestsPolicy,
148
149 reporting_observer_list: DomRefCell<Vec<DomRoot<ReportingObserver>>>,
151
152 report_list: DomRefCell<Vec<Report>>,
154
155 #[no_trace]
157 endpoints_list: DomRefCell<Vec<ReportingEndpoint>>,
158}
159
160impl WorkerGlobalScope {
161 #[allow(clippy::too_many_arguments)]
162 pub(crate) fn new_inherited(
163 init: WorkerGlobalScopeInit,
164 worker_name: DOMString,
165 worker_type: WorkerType,
166 worker_url: ServoUrl,
167 runtime: Runtime,
168 devtools_receiver: Receiver<DevtoolScriptControlMsg>,
169 closing: Arc<AtomicBool>,
170 #[cfg(feature = "webgpu")] gpu_id_hub: Arc<IdentityHub>,
171 insecure_requests_policy: InsecureRequestsPolicy,
172 font_context: Option<Arc<FontContext>>,
173 ) -> Self {
174 PipelineNamespace::auto_install();
176
177 let devtools_receiver = match init.from_devtools_sender {
178 Some(..) => Some(devtools_receiver),
179 None => None,
180 };
181
182 Self {
183 globalscope: GlobalScope::new_inherited(
184 init.pipeline_id,
185 init.to_devtools_sender,
186 init.mem_profiler_chan,
187 init.time_profiler_chan,
188 init.script_to_constellation_chan,
189 init.script_to_embedder_chan,
190 init.resource_threads,
191 MutableOrigin::new(init.origin),
192 init.creation_url,
193 None,
194 runtime.microtask_queue.clone(),
195 #[cfg(feature = "webgpu")]
196 gpu_id_hub,
197 init.inherited_secure_context,
198 false,
199 font_context,
200 ),
201 worker_id: init.worker_id,
202 worker_name,
203 worker_type,
204 worker_url: DomRefCell::new(worker_url),
205 closing,
206 runtime: DomRefCell::new(Some(runtime)),
207 location: Default::default(),
208 navigator: Default::default(),
209 policy_container: Default::default(),
210 devtools_receiver,
211 _devtools_sender: init.from_devtools_sender,
212 navigation_start: CrossProcessInstant::now(),
213 performance: Default::default(),
214 indexeddb: Default::default(),
215 timer_scheduler: RefCell::default(),
216 insecure_requests_policy,
217 trusted_types: Default::default(),
218 reporting_observer_list: Default::default(),
219 report_list: Default::default(),
220 endpoints_list: Default::default(),
221 }
222 }
223
224 pub(crate) fn insecure_requests_policy(&self) -> InsecureRequestsPolicy {
226 self.insecure_requests_policy
227 }
228
229 pub(crate) fn clear_js_runtime(&self) {
231 self.upcast::<GlobalScope>()
232 .remove_web_messaging_and_dedicated_workers_infra();
233
234 let runtime = self.runtime.borrow_mut().take();
236 drop(runtime);
237 }
238
239 pub(crate) fn runtime_handle(&self) -> ParentRuntime {
240 self.runtime
241 .borrow()
242 .as_ref()
243 .unwrap()
244 .prepare_for_new_child()
245 }
246
247 pub(crate) fn devtools_receiver(&self) -> Option<&Receiver<DevtoolScriptControlMsg>> {
248 self.devtools_receiver.as_ref()
249 }
250
251 #[allow(unsafe_code)]
252 pub(crate) fn get_cx(&self) -> JSContext {
253 unsafe { JSContext::from_ptr(self.runtime.borrow().as_ref().unwrap().cx()) }
254 }
255
256 pub(crate) fn is_closing(&self) -> bool {
257 self.closing.load(Ordering::SeqCst)
258 }
259
260 pub(crate) fn get_url(&self) -> Ref<'_, ServoUrl> {
261 self.worker_url.borrow()
262 }
263
264 pub(crate) fn set_url(&self, url: ServoUrl) {
265 *self.worker_url.borrow_mut() = url;
266 }
267
268 pub(crate) fn get_worker_id(&self) -> WorkerId {
269 self.worker_id
270 }
271
272 pub(crate) fn pipeline_id(&self) -> PipelineId {
273 self.globalscope.pipeline_id()
274 }
275
276 pub(crate) fn policy_container(&self) -> Ref<'_, PolicyContainer> {
277 self.policy_container.borrow()
278 }
279
280 pub(crate) fn set_csp_list(&self, csp_list: Option<CspList>) {
281 self.policy_container.borrow_mut().set_csp_list(csp_list);
282 }
283
284 pub(crate) fn set_referrer_policy(&self, referrer_policy: ReferrerPolicy) {
285 self.policy_container
286 .borrow_mut()
287 .set_referrer_policy(referrer_policy);
288 }
289
290 pub(crate) fn append_reporting_observer(&self, reporting_observer: DomRoot<ReportingObserver>) {
291 self.reporting_observer_list
292 .borrow_mut()
293 .push(reporting_observer);
294 }
295
296 pub(crate) fn remove_reporting_observer(&self, reporting_observer: &ReportingObserver) {
297 if let Some(index) = self
298 .reporting_observer_list
299 .borrow()
300 .iter()
301 .position(|observer| &**observer == reporting_observer)
302 {
303 self.reporting_observer_list.borrow_mut().remove(index);
304 }
305 }
306
307 pub(crate) fn registered_reporting_observers(&self) -> Vec<DomRoot<ReportingObserver>> {
308 self.reporting_observer_list.borrow().clone()
309 }
310
311 pub(crate) fn append_report(&self, report: Report) {
312 self.report_list.borrow_mut().push(report);
313 let trusted_worker = Trusted::new(self);
314 self.upcast::<GlobalScope>()
315 .task_manager()
316 .dom_manipulation_task_source()
317 .queue(task!(send_to_reporting_endpoints: move || {
318 let worker = trusted_worker.root();
319 let reports = std::mem::take(&mut *worker.report_list.borrow_mut());
320 worker.upcast::<GlobalScope>().send_reports_to_endpoints(
321 reports,
322 worker.endpoints_list.borrow().clone(),
323 );
324 }));
325 }
326
327 pub(crate) fn buffered_reports(&self) -> Vec<Report> {
328 self.report_list.borrow().clone()
329 }
330
331 pub(crate) fn set_endpoints_list(&self, endpoints: Option<Vec<ReportingEndpoint>>) {
332 if let Some(endpoints) = endpoints {
333 *self.endpoints_list.borrow_mut() = endpoints;
334 }
335 }
336
337 pub(crate) fn timer_scheduler(&self) -> RefMut<'_, TimerScheduler> {
339 self.timer_scheduler.borrow_mut()
340 }
341
342 pub(crate) fn shared_task_canceller(&self) -> TaskCanceller {
345 TaskCanceller {
346 cancelled: self.closing.clone(),
347 }
348 }
349}
350
351impl WorkerGlobalScopeMethods<crate::DomTypeHolder> for WorkerGlobalScope {
352 fn Self_(&self) -> DomRoot<WorkerGlobalScope> {
354 DomRoot::from_ref(self)
355 }
356
357 fn IndexedDB(&self) -> DomRoot<IDBFactory> {
359 self.indexeddb.or_init(|| {
360 let global_scope = self.upcast::<GlobalScope>();
361 IDBFactory::new(global_scope, CanGc::note())
362 })
363 }
364
365 fn Location(&self) -> DomRoot<WorkerLocation> {
367 self.location
368 .or_init(|| WorkerLocation::new(self, self.worker_url.borrow().clone(), CanGc::note()))
369 }
370
371 error_event_handler!(error, GetOnerror, SetOnerror);
373
374 fn ImportScripts(
376 &self,
377 url_strings: Vec<TrustedScriptURLOrUSVString>,
378 can_gc: CanGc,
379 ) -> ErrorResult {
380 let mut urls = Vec::with_capacity(url_strings.len());
382 for url in url_strings {
384 let url = TrustedScriptURL::get_trusted_script_url_compliant_string(
388 self.upcast::<GlobalScope>(),
389 url,
390 "WorkerGlobalScope",
391 "importScripts",
392 can_gc,
393 )?;
394 let url = self.worker_url.borrow().join(&url);
395 match url {
396 Ok(url) => urls.push(url),
397 Err(_) => return Err(Error::Syntax(None)),
398 };
399 }
400
401 rooted!(in(self.runtime.borrow().as_ref().unwrap().cx()) let mut rval = UndefinedValue());
402 for url in urls {
403 let global_scope = self.upcast::<GlobalScope>();
404 let request = NetRequestInit::new(
405 global_scope.webview_id(),
406 url.clone(),
407 global_scope.get_referrer(),
408 )
409 .destination(Destination::Script)
410 .credentials_mode(CredentialsMode::Include)
411 .parser_metadata(ParserMetadata::NotParserInserted)
412 .use_url_credentials(true)
413 .origin(global_scope.origin().immutable().clone())
414 .insecure_requests_policy(self.insecure_requests_policy())
415 .policy_container(global_scope.policy_container())
416 .has_trustworthy_ancestor_origin(
417 global_scope.has_trustworthy_ancestor_or_current_origin(),
418 )
419 .pipeline_id(Some(self.upcast::<GlobalScope>().pipeline_id()));
420
421 let (url, source) = match load_whole_resource(
422 request,
423 &global_scope.resource_threads().sender(),
424 global_scope,
425 &WorkerCspProcessor {
426 global_scope: DomRoot::from_ref(global_scope),
427 },
428 can_gc,
429 ) {
430 Err(_) => return Err(Error::Network),
431 Ok((metadata, bytes)) => (metadata.final_url, String::from_utf8(bytes).unwrap()),
432 };
433
434 let options = self
435 .runtime
436 .borrow()
437 .as_ref()
438 .unwrap()
439 .new_compile_options(url.as_str(), 1);
440 let result = self.runtime.borrow().as_ref().unwrap().evaluate_script(
441 self.reflector().get_jsobject(),
442 &source,
443 rval.handle_mut(),
444 options,
445 );
446
447 maybe_resume_unwind();
448
449 match result {
450 Ok(_) => (),
451 Err(_) => {
452 if self.is_closing() {
453 println!("evaluate_script failed (terminated)");
456 } else {
457 println!("evaluate_script failed");
458 return Err(Error::JSFailed);
459 }
460 },
461 }
462 }
463
464 Ok(())
465 }
466
467 fn Navigator(&self) -> DomRoot<WorkerNavigator> {
469 self.navigator
470 .or_init(|| WorkerNavigator::new(self, CanGc::note()))
471 }
472
473 fn Crypto(&self) -> DomRoot<Crypto> {
475 self.upcast::<GlobalScope>().crypto(CanGc::note())
476 }
477
478 fn Btoa(&self, btoa: DOMString) -> Fallible<DOMString> {
480 base64_btoa(btoa)
481 }
482
483 fn Atob(&self, atob: DOMString) -> Fallible<DOMString> {
485 base64_atob(atob)
486 }
487
488 fn SetTimeout(
490 &self,
491 _cx: JSContext,
492 callback: TrustedScriptOrStringOrFunction,
493 timeout: i32,
494 args: Vec<HandleValue>,
495 can_gc: CanGc,
496 ) -> Fallible<i32> {
497 let callback = match callback {
498 TrustedScriptOrStringOrFunction::String(i) => {
499 TimerCallback::StringTimerCallback(TrustedScriptOrString::String(i))
500 },
501 TrustedScriptOrStringOrFunction::TrustedScript(i) => {
502 TimerCallback::StringTimerCallback(TrustedScriptOrString::TrustedScript(i))
503 },
504 TrustedScriptOrStringOrFunction::Function(i) => TimerCallback::FunctionTimerCallback(i),
505 };
506 self.upcast::<GlobalScope>().set_timeout_or_interval(
507 callback,
508 args,
509 Duration::from_millis(timeout.max(0) as u64),
510 IsInterval::NonInterval,
511 can_gc,
512 )
513 }
514
515 fn ClearTimeout(&self, handle: i32) {
517 self.upcast::<GlobalScope>()
518 .clear_timeout_or_interval(handle);
519 }
520
521 fn SetInterval(
523 &self,
524 _cx: JSContext,
525 callback: TrustedScriptOrStringOrFunction,
526 timeout: i32,
527 args: Vec<HandleValue>,
528 can_gc: CanGc,
529 ) -> Fallible<i32> {
530 let callback = match callback {
531 TrustedScriptOrStringOrFunction::String(i) => {
532 TimerCallback::StringTimerCallback(TrustedScriptOrString::String(i))
533 },
534 TrustedScriptOrStringOrFunction::TrustedScript(i) => {
535 TimerCallback::StringTimerCallback(TrustedScriptOrString::TrustedScript(i))
536 },
537 TrustedScriptOrStringOrFunction::Function(i) => TimerCallback::FunctionTimerCallback(i),
538 };
539 self.upcast::<GlobalScope>().set_timeout_or_interval(
540 callback,
541 args,
542 Duration::from_millis(timeout.max(0) as u64),
543 IsInterval::Interval,
544 can_gc,
545 )
546 }
547
548 fn ClearInterval(&self, handle: i32) {
550 self.ClearTimeout(handle);
551 }
552
553 fn QueueMicrotask(&self, callback: Rc<VoidFunction>) {
555 self.upcast::<GlobalScope>()
556 .queue_function_as_microtask(callback);
557 }
558
559 fn CreateImageBitmap(
561 &self,
562 image: ImageBitmapSource,
563 options: &ImageBitmapOptions,
564 can_gc: CanGc,
565 ) -> Rc<Promise> {
566 ImageBitmap::create_image_bitmap(self.upcast(), image, 0, 0, None, None, options, can_gc)
567 }
568
569 fn CreateImageBitmap_(
571 &self,
572 image: ImageBitmapSource,
573 sx: i32,
574 sy: i32,
575 sw: i32,
576 sh: i32,
577 options: &ImageBitmapOptions,
578 can_gc: CanGc,
579 ) -> Rc<Promise> {
580 ImageBitmap::create_image_bitmap(
581 self.upcast(),
582 image,
583 sx,
584 sy,
585 Some(sw),
586 Some(sh),
587 options,
588 can_gc,
589 )
590 }
591
592 #[cfg_attr(crown, allow(crown::unrooted_must_root))]
593 fn Fetch(
595 &self,
596 input: RequestOrUSVString,
597 init: RootedTraceableBox<RequestInit>,
598 comp: InRealm,
599 can_gc: CanGc,
600 ) -> Rc<Promise> {
601 Fetch(self.upcast(), input, init, comp, can_gc)
602 }
603
604 fn Performance(&self) -> DomRoot<Performance> {
606 self.performance.or_init(|| {
607 let global_scope = self.upcast::<GlobalScope>();
608 Performance::new(global_scope, self.navigation_start, CanGc::note())
609 })
610 }
611
612 fn Origin(&self) -> USVString {
614 USVString(
615 self.upcast::<GlobalScope>()
616 .origin()
617 .immutable()
618 .ascii_serialization(),
619 )
620 }
621
622 fn IsSecureContext(&self) -> bool {
624 self.upcast::<GlobalScope>().is_secure_context()
625 }
626
627 fn StructuredClone(
629 &self,
630 cx: JSContext,
631 value: HandleValue,
632 options: RootedTraceableBox<StructuredSerializeOptions>,
633 retval: MutableHandleValue,
634 ) -> Fallible<()> {
635 self.upcast::<GlobalScope>()
636 .structured_clone(cx, value, options, retval)
637 }
638
639 fn TrustedTypes(&self, can_gc: CanGc) -> DomRoot<TrustedTypePolicyFactory> {
641 self.trusted_types.or_init(|| {
642 let global_scope = self.upcast::<GlobalScope>();
643 TrustedTypePolicyFactory::new(global_scope, can_gc)
644 })
645 }
646}
647
648impl WorkerGlobalScope {
649 #[allow(unsafe_code)]
650 pub(crate) fn execute_script(&self, source: DOMString, can_gc: CanGc) {
651 let _aes = AutoEntryScript::new(self.upcast());
652 let cx = self.runtime.borrow().as_ref().unwrap().cx();
653 rooted!(in(cx) let mut rval = UndefinedValue());
654 let mut options = self
655 .runtime
656 .borrow()
657 .as_ref()
658 .unwrap()
659 .new_compile_options(self.worker_url.borrow().as_str(), 1);
660 options.set_introduction_type(IntroductionType::WORKER);
661 match self.runtime.borrow().as_ref().unwrap().evaluate_script(
662 self.reflector().get_jsobject(),
663 &source,
664 rval.handle_mut(),
665 options,
666 ) {
667 Ok(_) => (),
668 Err(_) => {
669 if self.is_closing() {
670 println!("evaluate_script failed (terminated)");
671 } else {
672 println!("evaluate_script failed");
675 unsafe {
676 let ar = enter_realm(self);
677 report_pending_exception(
678 JSContext::from_ptr(cx),
679 true,
680 InRealm::Entered(&ar),
681 can_gc,
682 );
683 }
684 }
685 },
686 }
687 }
688
689 pub(crate) fn new_script_pair(&self) -> (ScriptEventLoopSender, ScriptEventLoopReceiver) {
690 let dedicated = self.downcast::<DedicatedWorkerGlobalScope>();
691 if let Some(dedicated) = dedicated {
692 dedicated.new_script_pair()
693 } else {
694 panic!("need to implement a sender for SharedWorker/ServiceWorker")
695 }
696 }
697
698 #[allow(unsafe_code)]
702 pub(crate) fn process_event(&self, msg: CommonScriptMsg) -> bool {
703 if self.is_closing() {
704 return false;
705 }
706 match msg {
707 CommonScriptMsg::Task(_, task, _, _) => task.run_box(),
708 CommonScriptMsg::CollectReports(reports_chan) => {
709 let cx = self.get_cx();
710 perform_memory_report(|ops| {
711 let reports = cx.get_reports(format!("url({})", self.get_url()), ops);
712 reports_chan.send(ProcessReports::new(reports));
713 });
714 },
715 CommonScriptMsg::ReportCspViolations(_, violations) => {
716 self.upcast::<GlobalScope>()
717 .report_csp_violations(violations, None, None);
718 },
719 }
720 true
721 }
722
723 pub(crate) fn close(&self) {
724 self.closing.store(true, Ordering::SeqCst);
725 self.upcast::<GlobalScope>()
726 .task_manager()
727 .cancel_all_tasks_and_ignore_future_tasks();
728 }
729}
730
731struct WorkerCspProcessor {
732 global_scope: DomRoot<GlobalScope>,
733}
734
735impl CspViolationsProcessor for WorkerCspProcessor {
736 fn process_csp_violations(&self, violations: Vec<Violation>) {
737 self.global_scope
738 .report_csp_violations(violations, None, None);
739 }
740}