Wasm32, input type=file, upload, ipad

The objective is to have a rust/wasm32 app, on a user event, to fire up the "select file" dialog to select an image for upload.

The current code I have is:

        let document = stdweb::web::document();
        let file_selector = Rc::new(document.create_element("input").unwrap());

        use crate::stdweb::web::{IElement, IEventTarget};

        let _ = file_selector.set_attribute("type", "file");
        let _ = file_selector.set_attribute("accept", "image/*");
        let _ = file_selector.set_attribute("capture", "camera");

        /*

        inside some event handler:

                let r = file_selector.as_ref();
                js! {
                console.log( @{r} );
                @{r}.click();
                 }

        */

This works in Chrome/desktop, Firefox/desktop, Safari/desktop, and no-ops on iPad on Ios 13.3. On ios 13.3, the console log is fired, but it does not open the camera app to either select an existing image or capture a new image.

Anyone know what I am doing wrong?

Pre-emptive questions:

  1. Are you triggering this inside a callback for an event handler?

Yes, I am. Before this fix, it only worked in Chrome/Firefox, but not Safari. After ensuing that the click is running inside the callback handler, it now also works on Safari/desktop.

  1. Do you get any error message on Ipad / ios13.3 ?

No. I have the ipad 13.3 attached in debug mode so that Safari/Desktop can see the 'console output' of the ipad/ios13.3 The console log happens, but the input type=file click seems to no-op.

Does html+js of minimal form of the code work? Do you add the file selector to the document?

If we take https://www.w3schools.com/jsref/tryit.asp?filename=tryjsref_fileupload_create , and replace the "document.write" with "x.click" , it works for me on ipad ios 13.3

js!{
                var x = document.createElement("INPUT");
                console.log(x);
                x.setAttribute("type", "file");
                x.click();
                };

Here is the crazy thing.

The above code (compiled in rust/wasm32)

  • works in Chrome, Firefox, Safari
  • does not work on iPad ios 13.3

If we remove the js! and put it in plain js, it works in iPad ios 13.3

I figured out what's wrong.

Opening 'select file' dialog from touch start event handler => fail.
Opening 'select file' dialog from mouse down event handler => works.

On the desktop, there is no touch start event, so it's always running in the mouse down event.

On ipad, the difference is not rust vs js, but all the demo js code was firing from mouse down event / click event, whereas my rust code was trying to fire from touch start event.

1 Like