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

CHTML causes errors with some latex environments, when rendered outside main DOM tree #1185

Closed
cben opened this issue May 4, 2015 · 4 comments
Labels
Expected Behavior This is how MathJax works

Comments

@cben
Copy link
Contributor

cben commented May 4, 2015

I'm dynamically typesetting nodes created outside the document and only insert them afterwards [*].
I started getting some [Math Processing Error]s with 2.5.
It happens only if Fast Preview is enabled or if Fast HTML renderer is chosen.
Observed in Chrome and Firefox (on linux), didn't try other browsers.

Here is a minimal case: http://codepen.io/cben/pen/BNNXvQ

The errors I saw were with latex environments but I don't think all environments are broken; e.g. example 2 only errors with equation numbering enabled.

With the help of #1184 I got the following stack traces:

1:

Error: Cannot read property 'firstChild' of null

stack:
TypeError: Cannot read property 'firstChild' of null
    at MML.mo.Augment.CHTMLstretchV (https://rawgit.com/cben/MathJax/error-stack/unpacked/jax/output/CommonHTML/jax.js?rev=2.5.3:745:29)
    at MML.mbase.Augment.CHTMLstretchChild (https://rawgit.com/cben/MathJax/error-stack/unpacked/jax/output/CommonHTML/jax.js?rev=2.5.3:549:16)
    at MML.mrow.Augment.toCommonHTML (https://rawgit.com/cben/MathJax/error-stack/unpacked/jax/output/CommonHTML/jax.js?rev=2.5.3:1039:64)
    at MML.mbase.Augment.CHTMLaddChild (https://rawgit.com/cben/MathJax/error-stack/unpacked/jax/output/CommonHTML/jax.js?rev=2.5.3:535:17)
    at MML.mbase.Augment.CHTMLdefaultSpan (https://rawgit.com/cben/MathJax/error-stack/unpacked/jax/output/CommonHTML/jax.js?rev=2.5.3:527:64)
    at MML.mbase.Augment.toCommonHTML (https://rawgit.com/cben/MathJax/error-stack/unpacked/jax/output/CommonHTML/jax.js?rev=2.5.3:518:21)
    at MML.mbase.Augment.CHTMLaddChild (https://rawgit.com/cben/MathJax/error-stack/unpacked/jax/output/CommonHTML/jax.js?rev=2.5.3:535:17)
    at MML.mbase.Augment.CHTMLdefaultSpan (https://rawgit.com/cben/MathJax/error-stack/unpacked/jax/output/CommonHTML/jax.js?rev=2.5.3:527:64)
    at MML.mbase.Augment.toCommonHTML (https://rawgit.com/cben/MathJax/error-stack/unpacked/jax/output/CommonHTML/jax.js?rev=2.5.3:518:21)
    at MML.mbase.Augment.CHTMLaddChild (https://rawgit.com/cben/MathJax/error-stack/unpacked/jax/output/CommonHTML/jax.js?rev=2.5.3:535:17)

2, 3:

Error: Cannot read property 'style' of null

stack:
TypeError: Cannot read property 'style' of null
    at MML.mtable.Augment.toCommonHTML (https://rawgit.com/cben/MathJax/error-stack/unpacked/jax/output/CommonHTML/jax.js?rev=2.5.3:1089:18)
    at MML.mbase.Augment.CHTMLaddChild (https://rawgit.com/cben/MathJax/error-stack/unpacked/jax/output/CommonHTML/jax.js?rev=2.5.3:535:17)
    at MML.mbase.Augment.CHTMLdefaultSpan (https://rawgit.com/cben/MathJax/error-stack/unpacked/jax/output/CommonHTML/jax.js?rev=2.5.3:527:64)
    at MML.mrow.Augment.toCommonHTML (https://rawgit.com/cben/MathJax/error-stack/unpacked/jax/output/CommonHTML/jax.js?rev=2.5.3:1037:21)
    at MML.mbase.Augment.CHTMLaddChild (https://rawgit.com/cben/MathJax/error-stack/unpacked/jax/output/CommonHTML/jax.js?rev=2.5.3:535:17)
    at MML.mbase.Augment.CHTMLdefaultSpan (https://rawgit.com/cben/MathJax/error-stack/unpacked/jax/output/CommonHTML/jax.js?rev=2.5.3:527:64)
    at MML.math.Augment.toCommonHTML (https://rawgit.com/cben/MathJax/error-stack/unpacked/jax/output/CommonHTML/jax.js?rev=2.5.3:675:21)
    at Object.MathJax.Extension.CHTML-preview.postFilter (https://rawgit.com/cben/MathJax/error-stack/unpacked/extensions/CHTML-preview.js?rev=2.5.3:110:22)
    at Object.MathJax.Extension.CHTML-preview.Preview (https://rawgit.com/cben/MathJax/error-stack/unpacked/extensions/CHTML-preview.js?rev=2.5.3:96:19)
    at Function.CALLBACK.execute (https://rawgit.com/cben/MathJax/error-stack/unpacked/MathJax.js?config=TeX-AMS_HTML:236:26)

I briefly dived into debugging those but gave up. That code is too dense with unfamiliar context for me.

[*] I believe I have no choice as I'm inserting them as into CodeMirror [https://cben.github.io/CodeMirror-MathJax/demo.html]; even if I inserted nodes first and typeset later, CodeMirror doesn't materialize the whole DOM but only the currently scrolled portion. The codepen I linked doesn't involve CodeMirror.

@pkra
Copy link
Contributor

pkra commented May 4, 2015

Hm... I thought MathJax could not render nodes that are unattached because certain DOM operations fail. @dpvc?

@dpvc
Copy link
Member

dpvc commented May 4, 2015

I thought MathJax could not render nodes that are unattached because certain DOM operations fail.

Correct, and that is what is happening here.

The problem is that MathJax needs to use element ID's to look up elements on the page in some circumstances, and if the elements are not actually in the page (as in this case), they won't be found, and MathJax will fail.

In this case, the span at line 745 for equation 1 and the rspan at line 1089 in equations 2 and 3 are ones that have been looked up by ID. When the math is not actually in the page, these end up being null, and when MathJax tries to access their properties, the browser throws an error. Such lookups occur in a number of situations, including the handling of stretchy characters and line breaking that I can think of off the top of my head.

In addition to needing to look up the elements by ID, MathJax needs an active DOM to measure the font em-size and ex-height, and may need to measure some other items like characters that are not in its fonts, or "foreign" elements like HTML or SVG embedded in <semantics> elements. If the math is not in the actual document, MathJax won't be able to get those measurements when it needs them. The final equation is also measured by MathJax to make sure that the right space is left for it.

So for all these reasons, you need to be in the actual page. Processing math in an HTML fragment that is not part of the page is not a supported use case.

What is actually happening for your HTML-CSS output is the following (I suspect -- I didn't actually confirm this): when MathJax tries to determine the em-size and ex-height, if it gets 0 (usually meaning that the measurements can't be taken because the math is in a container with display:none), it moves the math to a hidden location elsewhere on the page where measurements can be taken, typesets it there, and moves it back afterward. In your case, in a disembodied HTML fragment, the measurements will be 0, and so MathJax moves the math to its hidden area. Since that actually is part of the DOM, typesetting can occur properly. Then the math is moved back into your HTML fragment.

The current Fast HTML output is still very preliminary, and does not move the math if it can't determine the ex-height. So if you use that output (either as a preview, or as the actual final version), you will run into the lookup-by-ID problems described above. But for HTML-CSS and SVG, a side effect of our handling display:none makes it possible to handle your HTML fragments. But beware that the results may not be as accurate, especially if the fonts or other CSS in use in your fragment are different from those in the hidden area that MathJax uses (basically the fonts and style of the <body> element).

@dpvc dpvc added Expected Behavior This is how MathJax works and removed Investigate labels May 4, 2015
@cben
Copy link
Contributor Author

cben commented May 4, 2015

Thanks for the explanation. Everything worked fine till 2.5 so I assumed
it's a supported use case...
(Also it may be worth pointing it out in the docs. I've read quite a lot
of the docs, especially everything related to dynamic typesetting, and
don't remember seeing this constraint.)

I'll try placing it in my own hidden area before typesetting.

@pkra
Copy link
Contributor

pkra commented May 7, 2015

Issue filed on mathjax-docs

=> closed as "expected behavior"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Expected Behavior This is how MathJax works
Projects
None yet
Development

No branches or pull requests

3 participants