-
Notifications
You must be signed in to change notification settings - Fork 97
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
WebAssembly (emscripten) support #110
Comments
AFAIK this is a sort of hard/impossible thing to do properly. TL;DR Browsers are designed to run websites in a sandbox so interacting with the host filesystem is not straightforward. I don't know of a good design to make what you are requesting work properly, and there are many complications. Opening/saving files the traditional way The traditional way to load a file from the user's machine is to add an There has also been no way to show a save dialog in a browser. The best you can do is to save something to the downloads folder automatically. I wrote this Brainfuck compiler a long time ago but the "Open" and "Download" buttons on the top bar demonstrate how any browser-based implementation would behave. There is also no way to show a folder picker. The experimental File System API This new API contains ways to show a file picker (both single and multiple files) or directory picker for input, and a file picker for output (save dialog). This is the most promising, however, there are two reasons (at least that I can tell) that make it problematic for NFDe:
Also, this is experimental and currently only available in Chrome, Edge, and Opera (not sure if behind a feature flag). Emscripten's file system I haven't actually used Emscripten before, but from what I understand, they use an in-memory file system that has no access to the real files on the host filesystem. All the files in that file system must be downloaded (from the web) with the website. I suppose it's possible to write new files to that filesystem, so we can read a file from the host filesystem either using the traditional or experimental way, and then create the corresponding file in Emscripten's filesystem and write the data there. This should be mostly transparent for reading files, except if somebody else is concurrently modifying the file (Emscripten's in-memory file system will not get the modifications). However, writing files will pose a problem because the files will be written to the in-memory file system, so the changes will not be persisted by default. If we manually copy the file out after it is done writing, at this point we would have to ask the user for the real location to store the file (or just download it to the downloads directory if using the traditional way), which would surprise the user. The proper way to resolve this (not sure if doable in Emscripten at this point, but I doubt so) would be to install some hook on Emscripten's filesystem API to invoke a custom handler instead of just reading/writing from the in-memory storage, and then in that custom handler we call the experimental File System API to open/save to the host filesystem. I don't know how difficult this would be, but it seems like the only proper way to do what the user would expect when they click on the "Save" button in your application. (Of course this would still not solve the two concerns with the experimental File System API above.) So yeah I don't expect this to work anytime soon. Integrating with the experimental File System API sounds like something that the Emscripten project should be interested in implementing, so I think we might just need to wait for them to get around to doing this. I don't think any of the other cross platform file dialog libraries out there have a proper Emscripten implementation, but do let me know if you come across one - I'd be interested to see how they implement it. |
Hey ! Thanks for your thorough answer ! This helped me a lot to bring ImHex to the web (spoiler, in the end I did the same thing as you with https://btzy.github.io/jelly/bf.html, you can see https://github.com/WerWolv/ImHex/blob/ed8c0794bb4be617f969d455b37370c0a0cb5ae3/lib/libimhex/source/helpers/fs.cpp#L99 for implementation details) So, a few things to note that might be interesting to you:
There is https://caniuse.com/?search=webkitdirectory which seems to do just that, and have relatively large adoption
You can indeed solve this with the emscripten file system, that's how we do it in ImHex (see the impl details)
I don't know much about it, but there seem to be an
I think you could solve this problem with https://emscripten.org/docs/api_reference/Filesystem-API.html#FS.trackingDelegate%5Bcallback%20name%5D to detect when the file is closed, but you would still need the experimental API, yeah All in all, I don't feel like implementing this anymore, as this solution is complicated, half-baked and not even compatible with every browser, but I learned a lot of things by discussing here, so thank you ! |
Thanks for the information! What you've described seems to more or less work (though it would take quite a bit of effort and I'm not sure if it's really worth it). There might be an issue if the user opens two files with the same name but different paths though, e.g. |
Hi, I'm not committing to anything, but I'd like to add support for WebAssembly/emscripten to this library. (WerWolv/ImHex#1299)
(The implementation would use the browser's methods to let the user pick a file/folder in their filesystem)
Is that something you'd be interested in ?
The text was updated successfully, but these errors were encountered: