Description
Currently trying to use web_sys::window from the worker context ends up in a uncatchable error as Window
name does not exists in a worker context and fails hard in wasm_bindgen generated js code:
export function __widl_instanceof_Window(idx) {
return getObject(idx) instanceof Window ? 1 : 0;
}
There is however a WorkerGlobalScope and similar structs, but they share a lot of "global" functions with the Window
, like fetch
or createImageBitmapWithImageData
.
The workaround solution would be to create a GlobalProxy
enum with all those common utility methods and then implement it for each of the *GlobalScope structs.
Also exposing the following self function would be very helpfull in this context, with a signature like this:
fn self_() -> Option<GlobalProxy>;
Currently my workaround solution looks like this:
enum GlobalProxy {
Window(Window),
WorkerGlobalScope(WorkerGlobalScope),
//... more scopes
}
impl GlobalProxy {
fn create_image_bitmap_with_image_data(&self, a_image: &ImageData) -> Result<js_sys::Promise, JsValue> {
match self {
GlobalProxy::Window(window) => window.create_image_bitmap_with_image_data(a_image),
GlobalProxy::WorkerGlobalScope(scope) => scope.create_image_bitmap_with_image_data(a_image),
//... more of that
}
}
}
fn self_() -> Result<GlobalProxy, JsValue> {
let global = js_sys::global();
// how to properly detect this in wasm_bindgen?
if js_sys::eval("typeof WorkerGlobalScope !== 'undefined'")?.as_bool().unwrap() {
Ok(global.dyn_into::<WorkerGlobalScope>().map(GlobalProxy::WorkerGlobalScope)?)
}
else {
Ok(global.dyn_into::<Window>().map(GlobalProxy::Window)?)
}
}
so i could:
let scope = self_().unwrap();
scope.create_image_bitmap_with_image_data(&image_data)
which works regardless if run in a window or a worker context.
However this is very verbose and would be great if such an auto-generated solution would be provided in web-sys. This would be very tedious for an external crate to be in-sync with web-sys.
There is a mixin webidl: https://github.com/rustwasm/wasm-bindgen/blob/master/crates/web-sys/webidls/enabled/WindowOrWorkerGlobalScope.webidl which could be used to auto-generate common global methods of GlobalProxy.