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