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

How do i use mathjaxContext within a web component. Problem being i'm not loading mathjax externally #17

Open
brendena opened this issue Jun 1, 2022 · 4 comments
Labels
enhancement New feature or request

Comments

@brendena
Copy link

brendena commented Jun 1, 2022

My problem is that MathJaxContext is expecting you to load the src from a external file. Is there a way currently a to pass mathjaxcontext a already included mathjax object. What i'm trying to do is create a webcomponent that will have mathjax include inside of it.

I tried to not include MathJaxContext, but there where some state values about loading that caused it to fail.

@fast-reflexes fast-reflexes added the enhancement New feature or request label Jun 2, 2022
@fast-reflexes
Copy link
Owner

fast-reflexes commented Jun 2, 2022

Hi there!

With the current setup you have to have a MathJaxContext, it's part of the contract so excluding it will simply not work.

Typical MathJax usage in the browser has the pattern where the source is downloaded and installed on the window object and because simplicity is a virtue, similar usage has been the goal of this package since the start. That being said, it's on my agenda to check whether server-side generation using MathJax could be added to this package, and potentially during this process, it could be investigated whether the MathJax object from the MathJax source package could be added to this package in a way so that the downloading of the MathJax script could be removed / optional.

However, due to this atypical use of MathJax in the browser, it's very hard to say how this would affect the package size of this package, how it would affect tree-shaking and whether any additional manual steps would be needed for the resulting MathJax object to function exactly as it does when installed in the typical way. If the functionality could be added in a seamless way without too much hacking and without it changing the behaviour of this package too much, I would be willing to add it, otherwise perhaps your use-case is so specific it warrants its own custom solution or a package taking care of that specific situation.

I'm not too familiar with web components but is it considered bad practice for them to have ANY external dependencies (such as web fonts, JQuery, pictures etc...) taken from elsewhere upon loading them? If not then downloading MathJax from a CDN shouldn't be a problem. Otherwise, I guess there is no solution to your problem within this package at the current time.

Have you tried downloading the MathJax script from the CDN as a file and then storing it as a local script which you load in the src property? I guess a web component is a bundle and if you store the script inside the bundle, then no external dependency would be needed ...

Will keep this ticket open and tag it properly.

PS! You know you can host your own MathJax script to use with the src property, but I guess that won't change anything in this usecase DS

@brendena
Copy link
Author

brendena commented Jun 3, 2022

I'm not the most elegant typescript programmer. So what i was thinking of doing is creating a MathJaxBaseContextPassThrough component. What that would do is basically look for mathjax in the windows context or have some sort of way to pass the mathjax instance into it. The MathJaxContext seems to just primarily set the MathJaxBaseContext. So i thought it would be to hard to do MathJaxContext that didn't handle any of the file loading.

This is something that i think i could probably figure out how to do, i'm just having problems including the library when i build it.

  • i do a npm run build
  • then include it like this import { MathJax, MathJaxContext } from 'better-react-mathjax/build';

I get this error

Warning: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:

  1. You might have mismatching versions of React and the renderer (such as React DOM)
  2. You might be breaking the Rules of Hooks
  3. You might have more than one copy of React in the same app

Which i'm guessing comes down to the fact that i'm using react 16.13 and not the react 18 your using. But whats weird is that it works fine when i just grab it from npm.

Also thanks for the solid quick response. As for loading it externally. I would prefer it to be self contained. But if this turns into a lot of effort. I'll probably do what you suggest and host the file somewhere.

@fast-reflexes
Copy link
Owner

I'm not seeing your idea super clearly... but what you need to do is replace the injected script call for MathJax with an import from the MathJax package and place that in the MathJaxContext and then also make sure that it works in the same way as it does when installed in the browser (not 100% sure exactly what kind of setup and initialization MathJax performs when fetched that you might have perform manually yourself but I think there are some good explanations on this in the MathJax repo). Not a super easy thing to do...

The best thing would probably be to skip the MathJaxContext altogether and just import MathJaxBaseContext from this package and create your own context provider where you supply MathJax. Remember that you need to import the mathjax package into your dependencies since better-react-mathjax only lists it in devDependencies.

Regarding hooks, this library works with React 16.8 + so the version is not a problem. The problem is that you're using MathJaxContext from a non-functional component which is not allowed for any hook, and thereby not the MathJaxContext either (which makes use of hooks).

Do you have a repo or something where I can see what you're creating and how you're creating it? It's hard to understand from the description exactly what the context is and what you want to achieve? :) I might have a short go at this in the weekend if I have some time.

@brendena
Copy link
Author

I will worn you this is not pretty code but i was able to just bypass loading anything.
https://github.com/brendena/better-react-mathjax/blob/06f6dbd03e795f65f3ed1be41b2a28f9a72b7a7d/src/MathJaxContext/MathJaxContext.tsx

basically i just used the MathJaxContext for it's react context promise.

  function scriptInjector<T>(res: (mathJax: T) => void, rej: (error: any) => void) {
      const mathJax = (window as any).MathJax
      res(mathJax)
  }

When it comes to actually building mathjax, the team at mathjax has some good starter code.
https://github.com/mathjax/MathJax-demos-web/tree/master/custom-component

If you want to see it in action here's the component that i have using it
https://github.com/brendena/MathEquations-component/blob/master/src/direflow-components/math-equation-component/components/math-jax-viewer.tsx

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants