Skip to content

a kind of GlobalProxy utility and expose global self for universal window/worker usage #1046

Closed
@royaltm

Description

@royaltm

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions