Elm-file-reader

I made a little package using a technique I’ve used some times before, custom events. This means that instead of having to hook up javascript with a port, we can inline the javascript in an event handler, and have it send a custom event when done.

This means that a package can have self-contained javascript code to access different API:s. In this case the FileReader to get the contents of files from file input and file drop zones.

Please let me know what you think. I think this is a pretty useful technique.

Next on the list for this package is the ability to chunk file uploads, for large files.

http://package.elm-lang.org/packages/norpan/elm-file-reader/latest

12 Likes

I am glad to see this package as I want to support saving to and loading from local files in my app but did not have experience on how to implement this in elm.

Had no idea about inline javascript in elm. Thanks for this. – MTS

2 Likes

Would this package continue to work under the premise of 0.19 and “native” code being limited to elm-lang/ and elm-explorations/ ? I know it would work with ports, but not sure about custom event handlers and inline javascript. :man_shrugging:

1 Like

For sure. This has nothing to do with native code but uses inline JavaScript on html attributes, which is a very old and stable technique.

This relies on a known issue that’s planned to be fixed: https://github.com/elm-lang/html/issues/56

I wouldn’t recommend using it, since it’s safe to assume it’ll just stop working at some point.

5 Likes

I’m sure by the time that’s implemented, there will be a proper api for FileReader in Elm. Maybe even a binary type :slight_smile:

5 Likes

This is the most practical solution, I could not think in a simpler API, without ports and native stuff. It will be very useful until Evan implements an official way. Thanks a lot!

1 Like

Simple and nice API :slight_smile:
Question: How do I convert content/dataURL to normal text ? (I’m importing an XML file)

There is a FileReader method to read the file as text, I just haven’t implemented that yet. Right now it’s a base64 encoded data url, so you’d need to split out the actual data and base64 decode it.

A beautiful hack, @norpan!

I’ve now published version 2.0.0 which lets you chose if you want to read the file using DataURL, Base64, or Text.

2 Likes

@norpan, I do not think it makes sense to publish packages that rely on known bugs. It looks like you maybe did not know it was relying on a bug though.

Since it is already published, I think there should be a very clear message in the README that “This package relies on a known bug and it will stop working in future releases of core libraries.” I would personally want to know that, and I suspect many others would as well.

Can you add a very clear message about that?

3 Likes

I’ve already added that to the top of the README.

I’m not sure agree with the conclusion though. If Elm makes it so that you can’t use some HTML features, so be it, but until then, it’s not relying on any buggy behavior. It’s standard, well defined HTML.

5 Likes

I made a quick search for “attribute onclick” on github. It seems there is pretty much code using this already. Many of these can be changed to various onWithOptions, for sure. But I’m not sure the benefit outweighs the cost in this case. I’ve added the warning to norpan/elm-html5-drag-drop too (I’m not sure how to do https://github.com/norpan/elm-html5-drag-drop/blob/793b35807bfc77270bd47790479e454b2d7087d9/src/Html5/DragDrop.elm#L214 without this feature either. Using a port for this seems a bit much).

2 Likes

The vulnerability means that view code shared on elm-package is no safer than it is on npm.

Fixing it means I can use Html values published on elm-package without having to read 100% of their source code to see if they are sneaking in arbitrary JavaScript which takes over the entire Elm runtime and uses it to snoop on all my users’ data, or worse.

The costs are that it makes it less convenient to do a few things. Easily worth it in my book!

3 Likes

Yeah, it will be less convenient for sure. Somebody wanting to read in a file from a file input will, instead of just installing a package and call a function from it will have to make sure they put the four different attributes needed in the right place, make sure to take differences between browsers and their handling of FileReader events and errors into account, and adding a polyfill for the CustomEvent for IE11 etc. We may just have different opinions on how much that is worth.

I also think it’s a good thing that you can trust packages from the package manager, but I’m saying that perhaps we can do this in some other way than removing a well established HTML feature that is pretty useful.

I think if that well established HTML feature wasn’t related to running pure Javascript inside elm via Html.Attribute without going through the established API for handling such code, it probably wouldn’t be a problem. The problem is its code that is basically just hidden from the compiler, and because of that, can’t be trusted.

What I gather from your posts, is that you are mostly frustrated with the removal of a tool you’ve used many times before (in places other than Elm-land most likely as well) without much discussion on the merits of having this feature. On many other topics, I think you’d be right in your request for additional discussion regarding a change, I just think this is something that is too core to the design principals of Elm.

1 Like

I actually think this feature works very well with the design principles of Elm. It’s a clear separation of javascript code from Elm code (albeit in the same file in the form of string constants). Nowhere is Elm calling javascript code or vice versa. All communication between the two is done through events and html attributes.

It doesn’t work well with the principle of the package manager, but I think that removing the feature even from user code makes little sense. Disallowing it in packages, let’s say only allowing “safe html”, a type separate from “unsafe html”, or clearly flagging packages using “unsafe html”, may be a solution.

The problem is its a String that does something other than act like a string. It’s a string with the side effects of running a function, or “LaunchMissles();” The compiler doesn’t have a clue, it just sees a string and passes it to the HTML Attribute.

In fact here is the actual code from the elm-lang/html package:

attribute : String -> String -> Attribute msg
attribute =
  VirtualDom.attribute