rriegs / rriegs-wiki

A single-page, small-content wiki implemented in Elm.
MIT License
0 stars 0 forks source link

Transition from elm-markdown to markdown-it #4

Closed rriegs closed 6 years ago

rriegs commented 6 years ago

As mentioned in #3, the front end presently renders Markdown with elm-markdown, which is based on marked rather than the intended markdown-it. This sidesteps a few technical hurdles. Specifically, the most appropriate way to link a third-party JavaScript package like markdown-it is with ports, however:

The elm-markdown package instead wraps this behavior using the (not officially documented) Elm native module system. This permits direct calls to JavaScript from within Elm, and elm-markdown's source even shows how to interact with the virtual DOM in doing so. elm-markdown actually contains the source for marked, rather than linking to external code; however, it's entirely possible to modify elm-markdown to call window.markdownit instead. Regardless, the port system is still more appropriate for markdown-it because it would allow for the easy configuration of plugins and other settings.

A compromise between ports and native modules might be to use ports to obtain the raw HTML but then pass this into a native module that updates the virtual DOM. No package seems to exist to do this kind of thing, though it should be relatively straightforward given elm-markdown's implementation. There's elm-raw-html, which doesn't even require a native module (though it's implemented with a massive hack). Understandably, any injection of raw HTML comes with the risk of XSS attacks, but in this case only if Markdown output can be compromised.

rriegs commented 6 years ago

Another option is to use the HtmlParser module to parse the raw HTML output of markdown-it into a virtual DOM object and then insert this as appropriate. This is preferable to using a native module because the native module system has an extremely unstable API and is apparently slated for removal at some point in the future.

rriegs commented 6 years ago

The use of ports with HtmlParser works adequately. I'm not fully satisfied with the amount of parsing going on in this solution, nor do I like the relay of messages needed to retrieve results from markdown-it (even though it's synchronous), but such is the nature of ports. Operation seems fast enough for small-content Markdown, and I've taken care only to re-parse source on load and on edit.