Skip to main content

script/dom/testing/
testworklet.rs

1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
5// check-tidy: no specs after this line
6use 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}