MathJax icon indicating copy to clipboard operation
MathJax copied to clipboard

mathjax with swiper.js render blocking

Open Daisy1213 opened this issue 2 years ago • 2 comments

Replace the text below with the details of the issue you are facing.
DO NOT simply erase the form and type a free-form response.

Issue Summary

A summary of the issue and the browser/OS environment in which it occurs. If suitable, include the steps required to reproduce the bug.

Steps to Reproduce:

  1. This is the first step
  2. This is the second step
  3. Further steps, etc.

When swiper.js is used in the project, each slide will render the formula, because when slide is sliding, the translate attribute will be modified to achieve the effect of switching. At the same time, the next slide will render the formula, and then the two will block, resulting in uneven page sliding. It also affects the rendering of the page. I have tried to render without mathjax and this problem will not occur. I hope you can give me some insights to see if this intractable problem can be solved

Technical details:

  • MathJax Version: 3.2
  • Client OS: (e.g., Mac OS X 10.8.4)
  • Browser: (e.g., Chrome 29.0.1547.57)

I am using the following MathJax configuration:

    window.MathJax = {
      chtml: {
        matchFontHeight: false,
        mtextInheritFont: false
      },
      options: {
        enableMenu: false,
        renderActions: {
          handleErrors: [199,
            function (doc) {
              try {
                // 低版本手机解决symbol兼容性问题
                for (var math of doc.math) MathJax.config.handleError(math)
              } catch(e) {
                //
              }
            },
            function (doc, math) { MathJax.config.handleError(math) }
          ]
        },
        skipHtmlTags: ['script', 'noscript', 'style', 'textarea', 'a', 'pre', 'code'],
        includeHtmlTags: {
          br: '\n',
          wbr: '',
          '#comment': ''
        },
        ignoreHtmlClass: 'tex2jax_ignore',
        processHtmlClass: 'tex2jax_process'
      },
      tex: {
        inlineMath: [['<latex>', '</latex>'], ['$', '$'], ['_mathjax_','_mathjax_'], ['$','$'], ['$$','$$'], ['\\(','\\)']],
        displayMath: [],
        macros: {
          ykparallelogram: '\\unicode{x25B1}',
          ykparallel: '//'
        },
        autoload: {
          color: [],
          colorV2: ['color']
        },
        packages: {
          '[+]': ['trap-undefined'],
          '[-]': ['noundefined']
        }
      },
      loader: {
        load: ['[tex]/noerrors']
      },
      startup: {
        ready: function () {
          var tex = null;
          // 根据chrome版本解决字体问题
          try {
            var ua = navigator.userAgent.toLowerCase();
            if (ua.match) { // 兼容match做版本判断
              var matchs = ua.match(/chrome\/([0-9.]+)/);
              if (matchs.length && matchs[1] && matchs[1][0]) {
                var version = matchs[1][0]
                if (matchs[1][1]) {
                  version = version + matchs[1][1]
                }
                if (matchs[1][2] && /[0-9]/.test(matchs[1][2])) {
                  version = version + matchs[1][2]
                }
                if (+version < 42) {
                  var TeXFont = MathJax._.output.chtml.fonts.tex_ts.TeXFont
                  TeXFont.defaultStyles['.MJX-TEX'] = {
                    'font-family': 'sans-serif'
                  }
                  TeXFont.defaultStyles['.TEX-I'] = {
                    'font-family': 'sans-serif'
                  }
                  TeXFont.defaultStyles['.TEX-B'] = {
                    'font-family': 'sans-serif'
                  }
                  TeXFont.defaultStyles['.TEX-MI'] = {
                    'font-family': 'sans-serif'
                  }
                  TeXFont.defaultStyles['.TEX-BI'] = {
                    'font-family': 'sans-serif'
                  }
                  TeXFont.defaultStyles['.TEX-S'] = {
                    'font-family': 'sans-serif'
                  }
                  TeXFont.defaultStyles['.TEX-S2'] = {
                    'font-family': 'sans-serif'
                  }
                  TeXFont.defaultStyles['.TEX-S3'] = {
                    'font-family': 'sans-serif'
                  }
                  TeXFont.defaultStyles['.TEX-S4'] = {
                    'font-family': 'sans-serif'
                  }
                  TeXFont.defaultStyles['.TEX-A'] = {
                    'font-family': 'sans-serif'
                  }
                  TeXFont.defaultStyles['.TEX-C'] = {
                    'font-family': 'sans-serif'
                  }
                  TeXFont.defaultStyles['.TEX-CB'] = {
                    'font-family': 'sans-serif'
                  }
                  TeXFont.defaultStyles['.TEX-FR'] = {
                    'font-family': 'sans-serif'
                  }
                  TeXFont.defaultStyles['.TEX-FRB'] = {
                    'font-family': 'sans-serif'
                  }
                  TeXFont.defaultStyles['.TEX-SS'] = {
                    'font-family': 'sans-serif'
                  }
                  TeXFont.defaultStyles['.TEX-SSB'] = {
                    'font-family': 'sans-serif'
                  }
                  TeXFont.defaultStyles['.TEX-SSI'] = {
                    'font-family': 'sans-serif'
                  }
                  TeXFont.defaultStyles['.TEX-SC'] = {
                    'font-family': 'sans-serif'
                  }
                  TeXFont.defaultStyles['.TEX-T'] = {
                    'font-family': 'sans-serif'
                  }
                  TeXFont.defaultStyles['.TEX-V'] = {
                    'font-family': 'sans-serif'
                  }
                  TeXFont.defaultStyles['.TEX-VB'] = {
                    'font-family': 'sans-serif'
                  }
                  TeXFont.defaultStyles['mjx-stretchy-v mjx-c, mjx-stretchy-h mjx-c'] = {
                    'font-family': 'sans-serif'
                  }
                }
              }
            } else { // 不兼容match,webview版本较低直接替换字体
              var TeXFont = MathJax._.output.chtml.fonts.tex_ts.TeXFont
              TeXFont.defaultStyles['.MJX-TEX'] = {
                'font-family': 'sans-serif'
              }
              TeXFont.defaultStyles['.TEX-I'] = {
                'font-family': 'sans-serif'
              }
              TeXFont.defaultStyles['.TEX-B'] = {
                'font-family': 'sans-serif'
              }
              TeXFont.defaultStyles['.TEX-MI'] = {
                'font-family': 'sans-serif'
              }
              TeXFont.defaultStyles['.TEX-BI'] = {
                'font-family': 'sans-serif'
              }
              TeXFont.defaultStyles['.TEX-S'] = {
                'font-family': 'sans-serif'
              }
              TeXFont.defaultStyles['.TEX-S2'] = {
                'font-family': 'sans-serif'
              }
              TeXFont.defaultStyles['.TEX-S3'] = {
                'font-family': 'sans-serif'
              }
              TeXFont.defaultStyles['.TEX-S4'] = {
                'font-family': 'sans-serif'
              }
              TeXFont.defaultStyles['.TEX-A'] = {
                'font-family': 'sans-serif'
              }
              TeXFont.defaultStyles['.TEX-C'] = {
                'font-family': 'sans-serif'
              }
              TeXFont.defaultStyles['.TEX-CB'] = {
                'font-family': 'sans-serif'
              }
              TeXFont.defaultStyles['.TEX-FR'] = {
                'font-family': 'sans-serif'
              }
              TeXFont.defaultStyles['.TEX-FRB'] = {
                'font-family': 'sans-serif'
              }
              TeXFont.defaultStyles['.TEX-SS'] = {
                'font-family': 'sans-serif'
              }
              TeXFont.defaultStyles['.TEX-SSB'] = {
                'font-family': 'sans-serif'
              }
              TeXFont.defaultStyles['.TEX-SSI'] = {
                'font-family': 'sans-serif'
              }
              TeXFont.defaultStyles['.TEX-SC'] = {
                'font-family': 'sans-serif'
              }
              TeXFont.defaultStyles['.TEX-T'] = {
                'font-family': 'sans-serif'
              }
              TeXFont.defaultStyles['.TEX-V'] = {
                'font-family': 'sans-serif'
              }
              TeXFont.defaultStyles['.TEX-VB'] = {
                'font-family': 'sans-serif'
              }
              TeXFont.defaultStyles['mjx-stretchy-v mjx-c, mjx-stretchy-h mjx-c'] = {
                'font-family': 'sans-serif'
              }
            }
          } catch(e) {
            //
          }
          var Configuration = MathJax._.input.tex.Configuration.Configuration;
          var TexError = MathJax._.input.tex.TexError.default;
          Configuration.create('trap-undefined', {
            fallback: {
              macro: function (parser, cs) {
                tex.inputData.codecogs = true;
              },
              environment: function (parser, env) {
                tex.inputData.codecogs = true;
              }
            }
          });
          var toDOM = function (math, node, html) {
            this.setDocument(html);
            if (math.inputData.codecogs) {
              var adaptor = html.adaptor;
              if (math.display) adaptor.setAttribute(node, 'display', true);
              // 兜底src
              var encodeLatex = encodeURIComponent(math.math.trim() + '\\quad')
              var questiontoken = math.start.node.parentElement.getAttribute('questiontoken') || ''
              var defaultSrc = 'https://gallery.fbcontent.cn/latex?decode=false&fontSize=34&latex=' + encodeLatex + (questiontoken ? '&questiontoken=' + questiontoken : '')
              var originSrc = math.start.node && math.start.node.parentElement && math.start.node.parentElement.getAttribute && math.start.node.parentElement.getAttribute('origin-src')
              var imageNode = adaptor.node('img', {
                src: originSrc || defaultSrc,
                alt: tex.math.trim()
              })
              imageNode.onload = function () {
                imageNode.style.height = imageNode.naturalHeight / 2 + 'px'
                imageNode.style.width = imageNode.naturalWidth / 2 + 'px'
              }
              html.adaptor.append(node, imageNode);
              math.display = null;
              var src = originSrc || defaultSrc
              window.VUE_APP && window.VUE_APP.$emit('sendError', {
                url: '/debug/solarResultsPage/parseError',
                src: src,
                alt: math.math.trim(),
                srcWithOutQuestionToken: src && src.replace(/[&?]questiontoken=.*/, '')
              })
            } else {
              this._toDOM(math, node, html);
            }
          };

          var getOutputJax = MathJax.startup.getOutputJax;
          MathJax.startup.getOutputJax = function () {
            var output = getOutputJax();
            output._toDOM = output.toDOM;
            output.toDOM = toDOM;
            return output;
          }

          MathJax.startup.defaultReady();

          MathJax.startup.input[0].preFilters.add(function (filter) {
            var math = filter.math
            tex = math
          });

          MathJax.startup.output._toDOM = MathJax.startup.output.toDOM;
          MathJax.startup.output.toDOM = toDOM;

        }
      }
    }

and loading MathJax via

<script src="https://solar.fbcontent.cn/h5/solar-web-mathjax3/es5/tex-chtml.js"></script>

Supporting information:

  • Please supply a link to a (live) minimal example page, when possible.
  • If your issue is with the display of the mathematics produced by MathJax, include a screen snapshot that illustrates the problem, when possible.
  • Check your browser console window for any error messages, and include them here.
  • Include the MathJax configuration you are using, and the script tag that loads MathJax itself.

Daisy1213 avatar Dec 31 '23 11:12 Daisy1213

Some key information is missing, here, namely how you are integrating MathJax with swiper's slide-changing code. There doesn't seem to be a MathJax extension for swiper, so I'm assuming you are doing this yourself. Without that information, there is not much I can tell you. From the description, it sounds like the MathJax typesetting and slide changing is trying to occur simultaneously, but since javascript is single-threaded, type sliding is blocked while the typesetting is performed, leading to the sliding not being very smooth.

That suggests that you need to either perform the typesetting before the sliding starts, or wait to do the typesetting until after the sliding is performed. The former would be better, but there may not be an event that you can use to make that happen, since the typesetting may need to be asynchronously performed (using MathJax.typesetPromise()), though if you are careful, you can load all the needed extensions ahead of time, so that you can use MathJax.typeset().

In any case, it all depends on how you are hooking into swiper's events to perform the MathJax typesetting, and you haven't told us that. A sample page that illustrates the problem (as requested under "Supporting information" above) would be most helpful.

dpvc avatar Jan 02 '24 16:01 dpvc

Your configuration that modifies the font-family for the MathJax TeX font is a very bad idea. MathJax needs to know a lot of information about the characters in the fonts that it uses (like the bounding boxes of the glyphs, which glyphs are actually in the font, and so on), and some of the fonts include characters in different sizes (e.g., the parentheses in TeX-S3 are larger than those in TeX-S2), so if you switch the fonts actually being used, you will cause some expressions to render incorrectly.

If you are only interested in using sans-serif for letters and numbers, then it would be possible to transfer the data from the Mathematica AlphaNumerics section into the right places to override the original serifed characters.

Alternatively, you could switch to v4, which it out in beta release, which has support for additional fonts, including a sans-serif one.

dpvc avatar Jan 02 '24 16:01 dpvc