chrome_sys/runtime/scripting/
mod.rs

1use js_sys::{Array, Object};
2use wasm_bindgen::prelude::*;
3
4#[wasm_bindgen]
5extern "C" {
6
7    // #[wasm_bindgen(extends = Array, typescript_type="RegisteredContentScript[]")]
8    // #[derive(Debug)]
9    // pub type RegisteredContentScripts;
10
11    #[wasm_bindgen(extends = Object)]
12    #[derive(Debug)]
13    /// Dynamic content script
14    ///
15    /// ⧉ [Chrome Documentation](https://developer.chrome.com/docs/extensions/reference/api/scripting#type-RegisteredContentScript)
16    ///
17    pub type RegisteredContentScript;
18
19    #[wasm_bindgen(method, getter, js_name = "allFrames")]
20    /// If specified true, it will inject into all frames,
21    /// even if the frame is not the top-most frame in the tab.
22    /// Each frame is checked independently for URL requirements;
23    /// it will not inject into child frames if the URL requirements are not met.
24    /// Defaults to false, meaning that only the top frame is matched.
25    pub fn all_frames(this: &RegisteredContentScript) -> Option<bool>;
26
27    #[wasm_bindgen(method, setter, js_name = "allFrames")]
28    pub fn set_all_frames(this: &RegisteredContentScript, all_frames: bool);
29
30    #[wasm_bindgen(method, getter, js_name = "css")]
31    pub fn css(this: &RegisteredContentScript) -> Option<Array>;
32
33    #[wasm_bindgen(method, setter, js_name = "css")]
34    pub fn set_css(this: &RegisteredContentScript, css: Array);
35
36    #[wasm_bindgen(method, getter, js_name = "excludeMatches")]
37    pub fn exclude_matches(this: &RegisteredContentScript) -> Option<Array>;
38
39    #[wasm_bindgen(method, setter, js_name = "excludeMatches")]
40    pub fn set_exclude_matches(this: &RegisteredContentScript, css: Array);
41
42    #[wasm_bindgen(method, getter, js_name = "id")]
43    pub fn id(this: &RegisteredContentScript) -> String;
44
45    #[wasm_bindgen(method, setter, js_name = "id")]
46    pub fn set_id(this: &RegisteredContentScript, id: String);
47
48    #[wasm_bindgen(method, getter, js_name = "js")]
49    pub fn js_impl(this: &RegisteredContentScript) -> Option<Array>;
50
51    #[wasm_bindgen(method, setter, js_name = "js")]
52    pub fn set_js_impl(this: &RegisteredContentScript, js: Array);
53
54    #[wasm_bindgen(method, getter, js_name = "matchOriginAsFallback")]
55    pub fn match_origin_as_fallback(this: &RegisteredContentScript) -> Option<String>;
56
57    #[wasm_bindgen(method, setter, js_name = "matchOriginAsFallback")]
58    pub fn set_match_origin_as_fallback(
59        this: &RegisteredContentScript,
60        match_origin_as_fallback: bool,
61    );
62
63    #[wasm_bindgen(method, getter, js_name = "matches")]
64    pub fn matches_impl(this: &RegisteredContentScript) -> Option<Array>;
65
66    #[wasm_bindgen(method, setter, js_name = "matches")]
67    pub fn set_matches_impl(this: &RegisteredContentScript, args: Array);
68
69    #[wasm_bindgen(method, getter, js_name = "persistAcrossSessions")]
70    pub fn persist_across_sessions(this: &RegisteredContentScript) -> Option<bool>;
71
72    #[wasm_bindgen(method, setter, js_name = "persistAcrossSessions")]
73    pub fn set_persist_across_sessions(this: &RegisteredContentScript, world: bool);
74
75    #[wasm_bindgen(method, getter, js_name = "runAt")]
76    pub fn run_at(this: &RegisteredContentScript) -> Option<String>;
77
78    #[wasm_bindgen(method, setter, js_name = "runAt")]
79    pub fn set_run_at(this: &RegisteredContentScript, run_at: String);
80
81    #[wasm_bindgen(method, getter, js_name = "world")]
82    pub fn world(this: &RegisteredContentScript) -> String;
83
84    #[wasm_bindgen(method, setter, js_name = "world")]
85    pub fn set_world(this: &RegisteredContentScript, world: String);
86
87    #[wasm_bindgen(extends = Object)]
88    #[derive(Debug)]
89    /// ScriptInjection
90    ///
91    /// ⧉ [Chrome Documentation](https://developer.chrome.com/docs/extensions/reference/api/scripting#type-ScriptInjection)
92    ///
93    pub type ScriptInjection;
94
95    #[wasm_bindgen(method, getter, js_name = "args")]
96    pub fn args_impl(this: &ScriptInjection) -> Option<Array>;
97
98    #[wasm_bindgen(method, setter, js_name = "args")]
99    pub fn set_args_impl(this: &ScriptInjection, args: Array);
100
101    #[wasm_bindgen(method, getter, js_name = "files")]
102    pub fn files_impl(this: &ScriptInjection) -> Option<Array>;
103
104    #[wasm_bindgen(method, setter, js_name = "files")]
105    pub fn set_files_impl(this: &ScriptInjection, args: Array);
106
107    #[wasm_bindgen(method, getter, js_name = "injectImmediately")]
108    pub fn inject_immediately(this: &ScriptInjection) -> Option<bool>;
109
110    #[wasm_bindgen(method, setter, js_name = "injectImmediately")]
111    pub fn set_inject_immediately(this: &ScriptInjection, inject_immediately: bool);
112
113    #[wasm_bindgen(method, getter, js_name = "target")]
114    pub fn target(this: &ScriptInjection) -> InjectionTarget;
115
116    #[wasm_bindgen(method, setter, js_name = "target")]
117    pub fn set_target(this: &ScriptInjection, target: InjectionTarget);
118
119    #[wasm_bindgen(method, getter, js_name = "world")]
120    pub fn world(this: &ScriptInjection) -> Option<String>;
121
122    #[wasm_bindgen(method, setter, js_name = "world")]
123    pub fn set_world(this: &ScriptInjection, world: String);
124
125    #[wasm_bindgen(method, getter, js_name = "func")]
126    pub fn func(this: &ScriptInjection) -> Option<bool>;
127
128    #[wasm_bindgen(method, setter, js_name = "func")]
129    pub fn set_func(this: &ScriptInjection, value: &dyn Fn());
130
131    #[wasm_bindgen(method, setter, js_name = "func")]
132    pub fn set_func_with_arg_u32_closure(this: &ScriptInjection, value: &Closure<dyn FnMut(u32)>);
133
134    #[wasm_bindgen(method, setter, js_name = "func")]
135    pub fn set_func_with_arg_u32(this: &ScriptInjection, value: &js_sys::Function);
136
137    #[wasm_bindgen(method, setter, js_name = "func")]
138    pub fn set_func_with_arg_str(this: &ScriptInjection, value: &mut dyn FnMut(String));
139
140    #[wasm_bindgen(method, setter, js_name = "func")]
141    pub fn set_func_with_arg_array(this: &ScriptInjection, value: &mut dyn FnMut(Array));
142
143    #[wasm_bindgen(extends = Object)]
144    #[derive(Debug)]
145    /// InjectionTarget
146    ///
147    /// ⧉ [Chrome Documentation](https://developer.chrome.com/docs/extensions/reference/api/scripting#type-InjectionTarget)
148    ///
149    pub type InjectionTarget;
150
151    #[wasm_bindgen(method, getter, js_name = "allFrames")]
152    pub fn all_frames(this: &InjectionTarget) -> Option<bool>;
153
154    #[wasm_bindgen(method, setter, js_name = "allFrames")]
155    pub fn set_all_frames(this: &InjectionTarget, value: bool);
156
157    #[wasm_bindgen(method, getter, js_name = "documentIds")]
158    pub fn document_ids_impl(this: &InjectionTarget) -> Option<Array>;
159
160    #[wasm_bindgen(method, setter, js_name = "documentIds")]
161    pub fn set_document_ids_impl(this: &InjectionTarget, value: Array);
162
163    #[wasm_bindgen(method, getter, js_name = "frameIds")]
164    pub fn frame_ids_impl(this: &InjectionTarget) -> Option<Array>;
165
166    #[wasm_bindgen(method, setter, js_name = "frameIds")]
167    pub fn set_frame_ids_impl(this: &InjectionTarget, value: Array);
168
169    #[wasm_bindgen(method, getter, js_name = "tabId")]
170    pub fn tab_id(this: &InjectionTarget) -> Option<u32>;
171
172    #[wasm_bindgen(method, setter, js_name = "tabId")]
173    pub fn set_tab_id(this: &InjectionTarget, value: u32);
174
175    #[wasm_bindgen(extends = Object)]
176    #[derive(Debug)]
177    /// ContentScriptFilter
178    ///
179    /// ⧉ [Chrome Documentation](https://developer.chrome.com/docs/extensions/reference/api/scripting#type-ContentScriptFilter)
180    ///
181    pub type ContentScriptFilter;
182
183    #[wasm_bindgen(method, setter, js_name = "ids")]
184    pub fn set_ids(this: &ContentScriptFilter, value: Array);
185
186    #[wasm_bindgen(js_namespace = ["chrome", "scripting"], js_name="registerContentScripts")]
187    pub async fn register_content_scripts_impl(scripts: Array);
188
189    #[wasm_bindgen(js_namespace = ["chrome", "scripting"], js_name="unregisterContentScripts")]
190    pub async fn unregister_content_scripts_impl(filter: JsValue);
191
192    #[wasm_bindgen(js_namespace = ["chrome", "scripting"], js_name="unregisterContentScripts")]
193    pub async fn unregister_content_scripts_all();
194
195    #[wasm_bindgen(js_namespace = ["chrome", "scripting"], js_name="executeScript")]
196    pub async fn execute_script(script: ScriptInjection) -> JsValue;
197
198}
199
200pub async fn register_content_scripts(scripts: Vec<RegisteredContentScript>) {
201    let scripts = Array::from_iter(scripts.iter().map(JsValue::from).collect::<Vec<JsValue>>());
202    register_content_scripts_impl(scripts).await
203}
204
205pub async fn unregister_content_scripts(filter: Option<Vec<&str>>) {
206    if let Some(list) = filter {
207        let filter = ContentScriptFilter::new();
208        filter.set_ids(vector_to_array(list));
209        unregister_content_scripts_impl(filter.into()).await;
210    } else {
211        unregister_content_scripts_all().await;
212    }
213}
214
215pub fn vector_to_array(values: Vec<&str>) -> Array {
216    Array::from_iter(
217        values
218            .iter()
219            .map(|a| JsValue::from(*a))
220            .collect::<Vec<JsValue>>(),
221    )
222}
223pub fn js_value_vector_to_array(values: Vec<JsValue>) -> Array {
224    Array::from_iter(values.iter())
225}
226
227pub fn array_to_vector(values: Array) -> Vec<String> {
228    values
229        .into_iter()
230        .map(|a| a.as_string().unwrap_or_default())
231        .collect()
232}
233
234pub fn array_to_js_value_vector(values: Array) -> Vec<JsValue> {
235    values.into_iter().collect()
236}
237
238pub trait ObjectHelper {
239    fn new() -> Self
240    where
241        Self: wasm_bindgen::JsCast,
242    {
243        wasm_bindgen::JsCast::unchecked_into(Object::new())
244    }
245}
246
247impl ObjectHelper for RegisteredContentScript {}
248impl ObjectHelper for ScriptInjection {}
249impl ObjectHelper for InjectionTarget {}
250impl ObjectHelper for ContentScriptFilter {}
251
252impl RegisteredContentScript {
253    pub fn matches(&self) -> Option<Vec<String>> {
254        self.matches_impl().map(array_to_vector)
255    }
256
257    pub fn set_matches(&self, values: Vec<&str>) {
258        self.set_matches_impl(vector_to_array(values));
259    }
260
261    pub fn js(&self) -> Option<Vec<String>> {
262        self.js_impl().map(array_to_vector)
263    }
264
265    pub fn set_js(&self, values: Vec<&str>) {
266        self.set_js_impl(vector_to_array(values));
267    }
268}
269
270impl ScriptInjection {
271    pub fn args(&self) -> Option<Vec<JsValue>> {
272        self.args_impl().map(array_to_js_value_vector)
273    }
274
275    pub fn set_args(&self, args: Vec<JsValue>) {
276        self.set_args_impl(js_value_vector_to_array(args))
277    }
278
279    pub fn files(&self) -> Option<Vec<String>> {
280        self.files_impl().map(array_to_vector)
281    }
282
283    pub fn set_files(&self, values: Vec<&str>) {
284        self.set_files_impl(vector_to_array(values));
285    }
286}
287
288impl InjectionTarget {
289    pub fn document_ids(&self) -> Option<Vec<String>> {
290        self.document_ids_impl().map(array_to_vector)
291    }
292
293    pub fn set_document_ids(&self, values: Vec<&str>) {
294        self.set_document_ids_impl(vector_to_array(values));
295    }
296
297    pub fn frame_ids(&self) -> Option<Vec<String>> {
298        self.frame_ids_impl().map(array_to_vector)
299    }
300
301    pub fn set_frame_ids(&self, values: Vec<&str>) {
302        self.set_frame_ids_impl(vector_to_array(values));
303    }
304}
305
306// impl From<Vec<RegisteredContentScript>> for RegisteredContentScripts{
307//     fn from(values: Vec<RegisteredContentScript>) -> Self {
308//         Array::from_iter(values.iter().map(JsValue::from).collect::<Vec<JsValue>>()).dyn_into().unwrap()
309//     }
310// }