Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

v3: MathJax.typesetPromise() fails after overwriting .innerText of a previously typeset element #2191

Closed
MihaiB opened this issue Sep 8, 2019 · 4 comments

Comments

@MihaiB
Copy link

@MihaiB MihaiB commented Sep 8, 2019

https://jsbin.com/sutikuxefi/edit?html,output
I've pasted the same code below.

I'm following the docs for v3 to make a simple dynamic page: change the page content and ask MathJax to re-render it.
http://docs.mathjax.org/en/latest/advanced/typeset.html
http://docs.mathjax.org/en/latest/web/typeset.html

The automatic typeset on page load renders math in '#target". Later (setTimeout 2 seconds):

const e = document.getElementById('target');
// MathJax.typesetClear();
e.innerText = '\\(x^2 - y\\)';
MathJax.typesetPromise();

does not render the new math. It prints an error in the browser console:
Chromium 76: Uncaught (in promise) TypeError: Cannot read property 'appendChild' of null
Firefox 69: TypeError: t is null

Fiddling with it before reporting this issue, I've noticed that calling MathJax.typesetClear(); before mutating the DOM solves the problem. The new math expression is rendered and the browser console shows no error.

If I understand correctly Version 3 is the current stable version. I don't know what is the proper fix. But I suggest mentioning something in the docs soon so other new users won't run into this same problem and will be able to get a minimal working example of editing and re-typesetting a dynamic page.
I've stumbled over MathJax.typesetClear(); by accident.

The complete minimal example which reproduces this at v3.0.0:

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <script id="MathJax-script" async
          src="https://cdn.jsdelivr.net/npm/mathjax@3.0.0/es5/tex-chtml.js">
  </script>
  <script>
    setTimeout(() => {
      const e = document.getElementById('target');
      // MathJax.typesetClear();
      e.innerText = '\\(x^2 - y\\)';
      MathJax.typesetPromise();
    }, 2000);
  </script>
</head>
<body>
  <p id="target">\(a^2+b\)</p>
</body>
</html>
@dpvc

This comment has been minimized.

Copy link
Member

@dpvc dpvc commented Sep 22, 2019

Sorry, I just realized that I submitted a fix for the problem over a week ago, but neglected to make a comment here. First, thanks for reporting the issue. You are correct that you should use MathJax.typesetClear() if you have removed previously typeset math from the page. (In version 3, there is information stored about the math in a list of typeset expressions, and if you remove typeset math from the page and replace it with new math, that list will hold pointers to math that no longer exists in the page. That is what is causing the error you are seeing, and can cause MathJax to use more memory than necessary (since it holds onto the math that is no longer needed).

The commit listed above prevents the error message in the case where you don't call MathJax.typesetClear().

@70ray

This comment has been minimized.

Copy link

@70ray 70ray commented Oct 5, 2019

A similar thing happens with MathJax.typeset() after changing the page. In this case the error in the console is:
TypeError: Q is null tex-svg.js:1:255722.
calling MathJax.typesetClear() first fixes the problem.

dpvc added a commit to mathjax/MathJax-src that referenced this issue Oct 19, 2019
Check that parent is defined before getting its metrics.  mathjax/MathJax#2191
@dpvc dpvc added Merged and removed Ready for Review labels Oct 19, 2019
@costerwi

This comment has been minimized.

Copy link

@costerwi costerwi commented Nov 28, 2019

What is the consequence if I call MathJax.typesetClear() which takes no arguments but, for efficiency, only MathJax.typeset(specificElements) ?

The math in other parts of the document are still typeset but they will no longer have information stored "in a list of typeset expressions." Is this a problem?

@dpvc

This comment has been minimized.

Copy link
Member

@dpvc dpvc commented Dec 2, 2019

You are correct that the math that was previously typeset will remain typeset, but that the list of math will no loner contain that earlier typesetting information. This is not a problem in most situations, but if someone were to use the MathJax contextual menu to switch renderers, for example, only the math currently in the mat list will be re-rendered using the new renderer. Or if they were to turn on accessibility features, like speech text generation, only the ones in the list will be affected. That could cause confusion, and would make the earlier math inaccessible. So there are potential consequences to working the way you have suggested.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
4 participants
You can’t perform that action at this time.