Better support for Loader.preLoaded() when used in combined components in node #1310
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This PR fixes a problem when combined components are loaded via the
loader.load
configuration array in node applications and one of the preloaded components needs to perform additional loads (like when the output jax needs to load a font). In the past, the load of the combined component would complete before the extra components are loaded, and so MathJax could process the page with the wrong font, for example.In the current
develop
branch, the codeproduces
Note the
NCM-N
class on themjx-math
element indicating it is still using themathjax-newcm
font.With this patch, it will produce
with the correct
TEX-N
class formathjax-tex
.It took me several days to figure out a means of handling this cleanly. The
Package
object is quite complicated, and probably deserves a rewrite now that MathJax has matured since it was originally written, but that will have to wait for another release.The process used here is to have
Loader.load()
keep track of anyLoader.load()
calls that occur before it completes. this is done using an array created in theload()
call that is used to store the promises produces by anyload()
calls that are made while the first one is waiting to complete. We keep an array of these arrays so that if a nestedload()
call causes every moreload()
calls, they are stored for the nested call (so it knows when all the calls it initiated are resolved). They are also added to any higher-up parentload()
call arrays so that those higher-up loads wait for all the lower-down ones as well. (This was a key step in getting this to work.) Then when the initial loading is complete, we check if any additional loads have been added to the nested list, and if so, we wait for those after clearing the list. If more loads occurred during that wait, we do it again, and keep doing so until no more loads were processed during the wait. Then we remove our nested list from the list of lists, and finally are able to resolve the load promise.We could also remove our promise from any higher-up lists at that point, since we now know our load is complete, but since our promise will now be resolved, it doesn't really hurt to leave it in place as it will not add any delay to the
Promise.all()
for any of the higher up loads. So we don't take time to go through any of the higher lists to remove our promise. If you think that is a good idea, I can add that it.Finally, the change to
Package.ts
is to combine the loading of anyextraLoads
components into a singleLoader.load()
call rather than making one for each extra load. That is a little more efficient.It may be easier to look at the diff with spaces being ignored, as some of the changes are indentations.