script/dom/testing/
testworklet.rs1use std::rc::Rc;
7
8use crossbeam_channel::unbounded;
9use dom_struct::dom_struct;
10use js::context::JSContext;
11use js::realm::CurrentRealm;
12use js::rust::HandleObject;
13use script_bindings::inheritance::Castable;
14use script_bindings::reflector::{Reflector, reflect_dom_object_with_proto};
15
16use crate::dom::bindings::codegen::Bindings::TestWorkletBinding::TestWorkletMethods;
17use crate::dom::bindings::codegen::Bindings::WorkletBinding::Worklet_Binding::WorkletMethods;
18use crate::dom::bindings::codegen::Bindings::WorkletBinding::WorkletOptions;
19use crate::dom::bindings::error::Fallible;
20use crate::dom::bindings::root::{Dom, DomRoot};
21use crate::dom::bindings::str::{DOMString, USVString};
22use crate::dom::types::{TestWorkletGlobalScope, WorkletGlobalScope};
23use crate::dom::window::Window;
24use crate::dom::worklet::Worklet;
25use crate::dom::workletglobalscope::WorkletGlobalScopeType;
26use crate::dom::{RootedPromise, StatelessWorkletThreadPool};
27
28#[dom_struct]
29pub(crate) struct TestWorklet {
30 reflector: Reflector,
31 worklet: Dom<Worklet>,
32}
33
34impl TestWorklet {
35 fn new_inherited(worklet: &Worklet) -> TestWorklet {
36 TestWorklet {
37 reflector: Reflector::new(),
38 worklet: Dom::from_ref(worklet),
39 }
40 }
41
42 fn new(
43 cx: &mut JSContext,
44 window: &Window,
45 proto: Option<HandleObject>,
46 ) -> DomRoot<TestWorklet> {
47 let worklet_global_scope_init = window.into();
48 let worklet = Worklet::new(
49 cx,
50 window,
51 WorkletGlobalScopeType::Test,
52 Box::new(|| Rc::new(StatelessWorkletThreadPool::spawn(worklet_global_scope_init))),
53 );
54 reflect_dom_object_with_proto(
55 cx,
56 Box::new(TestWorklet::new_inherited(&worklet)),
57 window,
58 proto,
59 )
60 }
61}
62
63impl TestWorkletMethods<crate::DomTypeHolder> for TestWorklet {
64 fn Constructor(
65 cx: &mut JSContext,
66 window: &Window,
67 proto: Option<HandleObject>,
68 ) -> Fallible<DomRoot<TestWorklet>> {
69 Ok(TestWorklet::new(cx, window, proto))
70 }
71
72 fn AddModule(
73 &self,
74 realm: &mut CurrentRealm,
75 module_url: USVString,
76 options: &WorkletOptions,
77 ) -> RootedPromise {
78 self.worklet.AddModule(realm, module_url, options)
79 }
80
81 fn Lookup(&self, key: DOMString) -> Option<DOMString> {
82 let id = self.worklet.worklet_id();
83
84 let (sender, receiver) = unbounded();
85 let key = String::from(key);
86
87 let lookup_task = move |_cx: &mut JSContext, global_scope: &WorkletGlobalScope| {
88 let test_worklet_global_scope = global_scope
89 .downcast::<TestWorkletGlobalScope>()
90 .expect("TestWorklet's task should be run only on TestWorkletGlobalScope.");
91 let value = test_worklet_global_scope.lookup_value(&key);
92 let _ = sender.send(value);
93 };
94
95 self.worklet
96 .worklet_thread_pool()
97 .perform_a_worklet_task(id, Box::new(lookup_task));
98
99 match receiver.recv() {
100 Ok(value) => value.map(DOMString::from),
101 Err(err) => {
102 error!("Test Worklet died? {}", err);
103 None
104 },
105 }
106 }
107}