How can I load fonts from a different location in MathJax? - javascript

MathJax enforces a directory structure based on its library design. Fonts bundled with the library are in a subdirectory alongside some Javascript configuration and other components.
I want to serve the fonts from a different location on disk but I'm not seeing any configuration values that allow me to do that. I've checked the documentation and while I'm seeing different ways to load the full library and pieces of configuration, I'm not seeing how to isolate the fonts.
How can I load fonts from a different location in MathJax?
Edit: This is a client-side solution; we're doing this in the browser. We're using the TeX-AMS_CHTML.js configuration, which uses the CommonHTML rendering strategy. In the configuration (which is minified) it looks like there's a MathJax.OutputJax.fontDir that could be edited?

You want to override the CommonHTML webfontDir. Try
<script type="text/x-mathjax-config">
MathJax.Hub.Register.StartupHook('CommonHTML Jax Ready", function () {
MathJax.OutputJax.CommonHTML.webfontDir = 'myURL/myDontDirectory';
});
</script>
where myURL/myFontDirectory is the full URL to the directory containing your fonts. You may need to set the access control for the fonts directory to allow cross-domain access if the URL domain is not the same as the domain of the page loading MathJax. See the MathJax documentation on shared installations for more details.

From v3 onwards, use the following:
<script type="text/javascript">
window.MathJax = {
startup: {
ready: () => {
MathJax.config.chtml.fontURL = "/your-path/es5/output/chtml/fonts/woff-v2";
MathJax.config.chtml.font.options.fontURL = "/your-path/es5/output/chtml/fonts/woff-v2";
MathJax.startup.defaultReady();
}
}
}
</script>
<script type="text/javascript" src="/your-path/es5/tex-mml-chtml.js"></script>

Related

Cache misses for lazy loaded resources (using dynamic imports)

In a Vue.js project created with Vue CLI (internally using webpack), I implement code splitting and lazy loading with dynamic imports like so:
import(/* webpackChunkName: "my-feature" */ "./my-feature.js");
As a result I get the expected set of files:
dist/myApp.umd.min.js
dist/myApp.umd.min.vendors~my-feature.js (my-feature dependencies)
dist/myApp.umd.min.my-feature.js
The Vue application is built as a library and then used for an existing web site. What I do is include myApp.umd.min.js in <head> (common to all pages), and then in <body> request code I need for that page (for example myApp.umd.min.my-feature.js). Dependencies (myApp.umd.min.vendors~my-feature.js) are automatically requested by the earlier script.
Problem
When I navigate to a page, that uses the Vue app (and specifically my-feature), all 3 of the above files are loaded. That is expected for the first visit, but if I move to a different page and then return, only the first file (myApp.umd.min.js) is loaded from cache. The other ones are loaded from server every time I visit the page.
What approach to take for the lazy-loaded scripts to come from cache once already loaded? Thank you!
So far I have not found anything better than including all the scripts, I need on the page, in its <head> section. Moreover only using <script> tag helped; <link href="..." rel="preload" as="script"> was useless.
Use a version parameter for the script url.
There's a code snippet that showcase this:
<script type="text/javascript" src="myApp.umd.min.js?v=123"></script>
Also this is a valid solution:
<link rel="preload" href="myFont.woff2" as="font"
type="font/woff2" crossorigin="anonymous">
From docs:
A rel value of preload indicates that the browser should preload this resource with the as attribute indicating the specific class of content being fetched. The crossorigin attribute indicates whether the resource should be fetched with a CORS request.

Can A Javascript File Load Itself Asynchronously?

I use Squarespace as my CMS. I'd like to know if there's a way to have the actual .JS file load itself asynchronously to ultimately reduce the site load time.
For those who don't know, Squarespace gives very limited access to backend content and files. So I'd like to know if there are any alternatives to reduce render-blocking resources.
The file is located in [websitename]/scripts/site-bundle.js found through SFTP.
EDIT: Here's the full code https://codepen.io/anon/pen/MMKZyQ, as you can see I can't find any script tags to insert the defer or async values.
!function(e){function t(o){if(n[o])return n[o].exports;var r=n[o]={exports:{},id:o,loaded:!1};return e[o].call(r.exports,r,r.exports,t),r.loaded=!0,r.exports}var n={};return t.m=e,t.c=n,t.p="",t(0)}([function(e,t,n){e.exports=n(1)},function(e,t,n){"use strict";function o(e){return e&&e.__esModule?e:{default:e}}n(2);var r=n(6),i=o(r),a=n(60),u=n(65),c=o(u),l=n(85),s=o(l);n(86);var d=n(87),f=o(d),p=n(100),h=o(p),v=n(101),y=o(v),m=n(104),A=o(m),g=n(121),b=o(g),w=n(189),_=o(w),x=n(190),E=o(x),k=n(191),S=o(k),T=n(192),L=o(T),O=n(193),M=o(O),P=n(194),j=o(P),C=n(195),R=o(C),I=n(103),F=o(I),V=n(196),N=o(V),D=n(199),B=o(D),G=n(200),U=o(G),H=n(207),z=o(H);i.default.register("AncillaryLayout",f.default),i.default.register("FooterBreakpoints",h.default),i.default.register("HashManager",y.default),i.default.register("IndexFirstSectionHeight",A.default),i.default.register("IndexGallery",b.default),i.default.register("IndexGalleryVideo",_.default),i.default.register("IndexNavigation",E.default),i.default.register("HeaderNavFolderTouch",S.default),i.default.register("HeaderOverlay",L.default),i.default.register("MobileClassname",M.default),i.default.register("MobileOverlayFolders",j.default),i.default.register("MobileOffset",R.default),i.default.register("MobileOverlayToggle",F.default),i.default.register("Parallax",N.default),i.default.register("ScrollIndicator",B.default),i.default.register("SiteLoader",U.default),i.default.register("UserAccountLink",z.default),i.default.register("VideoBackground",function(e){return(0,c.default)(e,function(e){var t=e.handleResize,n=e.handleTweak;(0,s.default)(t,105),a.Tweak.watch("tweak-overlay-parallax-enabled",n)})}),window.addEventListener("controller:refresh",i.default.refresh)},function(e,t,n){n(3).polyfill()},function(e,t,n){(function(t){for(var o=n(4),r="undefined"==typeof window?t:window,i=["moz","webkit"],a="AnimationFrame",u=r["request"+a],c=r["cancel"+a]||r["cancelRequest"+a],l=0;!u&&l<i.length;l++)u=r[i[l]+"Request"+a],c=r[i[l]+"Cancel"+a]||r[i[l]+"CancelRequest"+a];if(!u||!c){var s=0,d=0,f=[],p=1e3/60;u=function(e){if(0===f.length){var t=o(),n=Math.max(0,p-(t-s));s=n+t,setTimeout(function(){var e=f.slice(0);f.length=0;for(var t=0;t<e.length;t++)if(!e[t].cancelled)try{e[t].callback(s)}catch(e){setTimeout(function(){throw e},0)}},Math.round(n))}return f.push({handle:++d,callback:e,cancelled:!1}),d},c=function(e){for(var t=0;t<f.length;t++)f[t].handle===e&&(f[t].cancelled=!0)}}e.exports=function(e){return u.call(r,e)},e.exports.cancel=function()
This can be accomplished for the Brine/Wright family of templates by doing the following:
Enable Developer Mode (Settings > Advanced > Developer Mode)
Using SFTP or Git, obtain access to the template files.
Within site.region file, change:
<squarespace:script src="site-bundle.js" combo="false" />
to
<squarespace:script src="site-bundle.js" combo="false" async="true"/>
Use SFTP or Git to update your template files on Squarespace's servers.
You may also use <script src="/scripts/site-bundle.js" async></script> instead of using Squarespace's script loader. Simply replace the aforementioned line in step 3.
As an aside, the unbundled code can be found in Squarespace's Wright GitHub repository.
For other templates not in the Brine/Wright family, similar steps may apply, though file names may differ.
There are two properties on a script tag to do exactly what you want to do:
specifying defer will defer the loading of the script until the page has been fully parsed (and rendered)
specifying async will indicate to the browser that this script can be loaded asynchronously at any point of its choosing.
Those two properties are both well supported (defer, async) and as such, you can and should make use of them to achieve this.

Q about static configuration of javascript/css URL?

I have a single page web application that utilizes DOJO (1.9.x). It normally loads the DOJO library from the Google CDN and my application functions as expected. But, some customers offer limited internet connection that excludes most of the internet for security (!?) reasons. So I have to host DOJO library locally on the server.
For this to work, I should point the URL to the local copy of dojo.js and relevant CSS files. As only the prefix of the URL changes, I am curious if there is a trick to achieve this by some external CSS file so that the URL in the HTML gets its prefix from this small CSS. By simply editing/changing this small CSS file, One site will load DOJO from the Google CDN and Another will load the locally hosted DOJO.
Is this possible with a static CSS file ?
This is not possible with CSS.
A few alternatives, in order of preference:
SAFEST - Distribute two versions of the page/app, with local and remote dojo.
If you have server-side rendering of any sort, configure that to update the dojo URL.
Always distribute the dojo loader with your application. Thereafter, load dojo modules from CDN or locally according to your config. This could get hairy.
More details on option 3:
dojoConfig.js
//var dojoRoot = ".."; // For LOCAL builds - relative to dojo.js
var dojoRoot = "//ajax.googleapis.com/ajax/libs/dojo/1.9.3"; // For CDN builds
var dojoConfig = {
packages: [
// Depending on your project structure, you may need to
// insert entries here for your local packages.
// Here, we override the location for dojo packages
{
name: "dojo",
location: dojoRoot + "/dojo"
},
{
name: "dojox",
location: dojoRoot + "/dojox"
},
{
name: "dijit",
location: dojoRoot + "/dijit"
}
]
};
HTML snippet to use it
<script src="dojoConfig.js"></script>
<script src="dojo/dojo.js"></script>
<script>
require(["dojo/_base/config", "dojo/json"], function(config, JSON) {
console.log(JSON.stringify(config.packages, null, "\t"));
});
</script>

javascript file not loading

Trying to import my js file from my page.
My page is in webcontent/mydomain/templates/page.xhtml
My js is in webcontent/mydomain/test/scripts
In page.xhtml
<script type="text/javascript" src="../test/scripts/test.js"></script>
But still the script is not getting picked.
Can anyone tell how I need to give the path in src.
Try this:
<script src="/test/scripts/test.js"></script>
Provided that webcontent is the root of public web content and thus /mydomain is also a public folder and thus your JavaScript is standalone available by http://localhost:8080/context/mydomain/test/scripts/test.js, assuming a domain of http://localhost:8080 and a context path of /context, then the following should do:
<script src="#{request.contextPath}/mydomain/test/scripts/test.js"></script>
This will generate a domain-relative URL with a dynamically inlined context path, which is much more robust than fiddling with ../ which would make the URI relative to the current request URI (as you see in browser's address bar) and not to the physical location of the template file as many starters incorrectly assume.

Load OpenLayers library with it's dependencies (Google and OSM) async possible?

I build a AJAX application and have a dedicated part of my application that uses OpenLayers.
At the moment I have the following in my Application.html file, so it gets included at application start:
<script src="http://openlayers.org/api/2.11/OpenLayers.js"></script>
<script src="http://maps.google.com/maps/api/js?sensor=false"></script>
<script src="http://www.openstreetmap.org/openlayers/OpenStreetMap.js"></script>
Now I want to load all this stuff when it's needed, because it has about 500-1000kb size. But I don't know how to do it.
What I've tried:
Load OpenLayers.js and in its callback: ...
... Load GoogleMaps.js and OpenStreetMap.js. And when these both are finished: ...
... Display my map.
Sometimes it works, but most of the time it doesn't, because: GoogleMaps.js and OpenStreetMap.js have some additional .js, .css, .png, etc. dependencies that load independently from my callbacks.
This means: The 3 .js files have finished loading, the callback tells my application to display the map, but in the background those .js files still fetch additional content that's necessary for using OpenLayers.
Is there a way to solve this problem?
You might be interested in using either of the following approaches or combination of them.
1) https://developers.google.com/web-toolkit/doc/latest/DevGuideServerCommunication#DevGuideHttpRequests
2) https://developers.google.com/web-toolkit/doc/latest/tutorial/Xsite
Maybe you can try GWT-OpenLayers instead.
https://bitbucket.org/gwtopenlayers/gwt-openlayers

Categories

Resources