reed/turbolinks-compatibility

Rails 4 - Turbolinks - MathJax

Closed this issue · 11 comments

Hi, I have a Rails4 app which uses MathJax. I use MathJax CDN by placing the following line in the <head> section of my app/views/layouts/application.html.erb file:

<script type="text/javascript" src="path-to-mathjax/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>

More information on: http://docs.mathjax.org/en/latest/start.html#mathjax-cdn

Because of Turbolinks, MathJax loads only on the homepage and won't load on other pages unless I refresh the page (which is not desirable). Instead I want MathJax to load only on /Math/New and Physics/Show pages. What should I do?

Thanks a lot for your help.

reed commented

Would this work?

Remove the script tag add this to your JS:

$ ->
  $(document).on 'page:load', ->
    window.MathJax = null
    $.getScript "http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"

I did a small test and it worked for me. Let me know.

Hi Reed,
As you instructed, I removed the script tag in my layouts/application.html.erb and added the code above to app/assets/javascripts/mathjax.js.coffee. MathJax did not load even in homepage and after refreshing the page multiple times. Then I added the code to app/assets/application.js, but the result was the same and MathJax didn't load.
Thank you very much.

reed commented

Sorry, that's my mistake. Try this:

$ ->
  loadMathJax()
  $(document).on 'page:load', loadMathJax

loadMathJax = ->
  if page is Math/New or Physics/Show # optional check
    window.MathJax = null
    $.getScript "http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"

If you have a way of checking what page you're on, that optional check is ideal since it will reduce the number of times you fetch and load the MathJax library.

Hi Reed,
Yessssssss, you made my day. Thanks.
Because I'm using jquery.turbolinks, I had to remove the 3rd line $(document).on 'page:load', loadMathJax in order to avoid loading MathJax twice:

Now, would you please help me with any of the following 3 questions:

  1. Is there a downside to using jquery.turbolinks vs the line above?
  2. Before I was using the following script to deactivate the Math Menu in MathJax
<script type="text/x-mathjax-config">
  MathJax.Hub.Config({
    showMathMenu: false
  });
</script>

How should I implement this in my .js.coffeescript file now?
3. How did you go about solving question 2?

Thanks again for your help.
Best.

reed commented
  1. The only downside to using jquery.turbolinks (in general) is that it takes away the ability to run a callback only on page:load, as opposed to both page:load AND DOM ready. If you would like the functionality of jquery.turbolinks without this restriction, you can use the master branch (v2.0.0) of Turbolinks and then bind to page:change instead of page:load, as it will fire on DOM ready.
  2. Do you need to move it? The MathJax script looks for the script tags with text/x-mathjax-config and runs them, so I would think they would work as they are. Is that not the case? If not, try just adding that config line after the $.getScript line. If that doesn't work, try adding it before the $.getScript line.
  3. Well, I'm just making educated guesses at this point. If neither one works, I'll take a deeper look at the MathJax script and see if I can figure it out.

Thanks reed, I really appreciate it. If I don't move the text/x-mathjax-config script and leave it in the head section of layouts/application.html.erb, It works only on the homepage and not other pages unless I refresh the page. When I added the config line after or before the $.getScript it didn't work at all.

reed commented

Ah, I thought your config script tag was in the body. Regardless, this works for me:

$ ->
  loadMathJax()
  $(document).on 'page:load', loadMathJax

loadMathJax = ->
  if page is Math/New or Physics/Show # optional check
    window.MathJax = null
    $.getScript "http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML", ->
      MathJax.Hub.Config
        showMathMenu: false

Or, if you feel like going overboard with it, like I apparently did, you can use this:

class MathJax
  constructor: (@options) ->
    @bind()

  load: =>
    window.MathJax = null
    @_fetch().done =>
      window.MathJax.Hub.Config @options

  bind: ->
    $ => @load()
    $(document).on 'page:load', @load

  unbind: ->
    $(document).off 'page:load', @load

  # private

  _fetch: ->
    $.ajax
      dataType: 'script'
      cache: true
      url: "http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=AM_HTMLorMML"

# usage
new MathJax
  showMathMenu: false

This solution takes advantage of jQuery's ajax caching, so you'll only be downloading the script once.

Wow, Awesome. You really made my day. Thanks a lot.
Best,
Rostam

reed commented

Glad I could help. I posted the solution to the site:

http://reed.github.io/turbolinks-compatibility/mathjax.html

Just a quick update:

In Turbolinks 5, you have to use turbolinks:load instead of page:load.

for caching behavior, cache must be disabled, by adding
<meta name="turbolinks-cache-control" content="no-cache">