Browser.application and custom elements

Hello all! I would like to be able to use Browser.application with custom elements that modify the DOM. One particular use case is having an editor that renders Markdown to HTML using this. The library renders text via

   Markdown.Elm.toHtml : Option -> String -> Html msg

where Option = Standard | Extended | ExtendedMath. No problem with the first two options, but the last requires some javascript in index.html + a custom element for rendering the math text using MathJax. This messes with DOM, and Browser.application doesn’t like that (I think that is the problem).

I’d very much like to find a way around this, but don’t understand the custom element - DOM - Browser.application interaction, so don’t know where to start.

PS. Here is one use of the above library: math-markdown-demo

Is the problem that MathJax adds a DOM element as a direct child to the body and that Elm removes it or does not like it seeing there? If so, maybe you can add this element via Elm, identified by some id, and configure MathJax to use this element you now control?
Or is it that MathJax messes with the DOM on each instance? Keyed elements could then help to tell Elm not to replace specific DOM nodes.

It seems like you are loading the script fine, but have trouble creating instances of the mathjax custom element? As long as it’s is a leaf node (that is, it is not wrapping other things that Elm is expecting to render) you can do something like:

Html.node "mathjax"
    [ "content" (Json.Encode.string "$a \\ne 0$")
    , Html.Events.on "customMessage" customMessageToMsgDecoder
    [ {- nothing in here! You don't want Elm to look inside the children at all or you'll get errors. -} ]

(n.b. property may need to be attribute—it’s been a while since I wrote a custom element and get them confused all the time.)

After this, you can set whatever properties you want (e.g. update your raw mathjax string that way.) Elm will update them, invoking the callbacks in the custom element. If you need messages to be passed back to Elm, listen for the custom messages with Html.Events.on as shown.

Another reading of what you said is that the mathjax script is looking for strings like $a \ne 0$ in the body after rendering and is replacing them with rendered images. That is never going to play well with Elm—if you can use the custom element approach then things will be much better for you!

1 Like

Hi Jonas, I tried wrapping in a keyed node, but unfortunately that did not help. I’m trying to understand better what Mathjax is doing. Thanks!

Hi Brian, Thanks so much for the suggestions!

I think that I am doing something quite similar to what you suggest, so this my just be inherently incompatible MathJax behavior. The two functions below are used to render $ ... $ and $$ .. $$:

inlineMathText : String -> Html msg
inlineMathText str =
    mathText <| "$ " ++ String.trim str ++ " $ "

displayMathText : String -> Html msg
displayMathText str =
        str2 =
            String.trim str
    mathText <| "$$\n" ++ str2 ++ "\n$$"

And they call

mathText : String -> Html msg
mathText content =
    Html.node "math-text"
        [ HA.class "mm-math", "content" (Json.Encode.string content) ]

which in turn relies on some custom element code that Luke supplied me with. I have a poor understanding of what is happening with custom elements – it was Luke’s code that saved the day for me when we went to 0.19, and I’ve used it like a black box.

If I haven’t figured this out by the time StrangeLoop happens, perhaps Luke, you, and I could look at things together. The current solution works fine with Browser.element, by the way.

NOTE: Another possibility is MathJax 3, which is now in Beta 4. As I I understand it, MathJax 2.7.* just looks at the DOM finds .. etc, and performs/wreaks its special magic/havoc. The new version apparently gives the developer more choice and control.

it sounds like MathJax 4 might be the best bet—do you know why it’s in beta? Is it unstable?

It is MathJax 3, beta 4. I complete rewrite & modernization. Beta 4 was in May, so there should be an official release soon, I would think (hope).

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.