I looked around for a long time for a way to embed a code editor (such as Ace or CodeMirror) in an Elm application. Most things didn’t work, or had unexpected behavior, probably due to the fact that those JC libraries modify the DOM, which Elm doesn’t play well with.
It uses native code, in some way that I don’t fully understand, to be able to embed the Ace code editor in an Elm application (as opposed to what I think Ellie does, which is to have a JS application with Elm components, keeping the editor itself away from Elm). My question in the subject line may be misplaced, in the sense that I’m not sure whether DOM-modifying is the crucial idea here.
Perhaps it will never be the case that a DOM-modifying library such as Ace could ever be used within an Elm application, so perhaps the answer is “this will never happen, so there will be no embeddable code editor for Elm until someone writes one from scratch in Elm”. If I’m wrong about there, is there an “officially suggested” way to handle this, now that native code will be out?
I dont think a native module is necessary to implement an ace code editor in an Elm application. I think you could do it just with custom elements (https://github.com/webcomponents/custom-elements) @luke mentioned them in another thread and said he uses them at work in their Elm code base. We actually do the same thing where I work.
They work like this.
0 You can make custom html elements like <ace-editor/> in your DOM.
1 You can write a bit of code that automatically runs when an <ace-editor/> is rendered.
2 That code can initialize an ace editor and render it inside your <ace-editor/> tag.
Put those parts together, and that means that you can make your project work in such a way that whenever Elm renders an <ace-editor/> a bit of JavaScript fires up and does the rest of the work rendering an ace editor in that element.
It works because Elm doesn’t think there are any children in that div, so it doesn’t bother to try and mess with any of the children and the CodeMirror content is left alone to do what it wants.
In the next iteration of Ellie this will all be accomplished inside of a custom element:
It works for the same reasons as above, but is nicer from a state management perspective. As far as I’m concerned, using a custom element is the recommended way to embed JavaScript-based DOM widgets when your browsers support them, and ports will work just fine for this use-case otherwise.
@luke I have a question about using customElements. You must be polyfilling this in Ellie, yes? As it works on MS Edge. I looked at the source code but could not easily find where it is polyfilled.
The example you posted above is on the ‘server-purs’ branch. So I wonder if this is not production code? I am guessing this is currently something you are experimenting with in a branch?
It’s in progress and will be published in conjunction with the 0.19 public release. I haven’t installed the polyfill for Ellie yet, but I wouldn’t call it an experiment either. We’re using a custom element in production at NoRedInk for this exact purpose as well. Our error reporting shows occasional runtime errors for very old versions of browsers that we do not support, but all of the browsers in our support range work with the polyfill, including Edge and IE11.