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::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}