aboutsummaryrefslogtreecommitdiff
path: root/js/mathjax/extensions/MatchWebFonts.js
diff options
context:
space:
mode:
Diffstat (limited to 'js/mathjax/extensions/MatchWebFonts.js')
-rw-r--r--js/mathjax/extensions/MatchWebFonts.js311
1 files changed, 311 insertions, 0 deletions
diff --git a/js/mathjax/extensions/MatchWebFonts.js b/js/mathjax/extensions/MatchWebFonts.js
new file mode 100644
index 0000000..95e168c
--- /dev/null
+++ b/js/mathjax/extensions/MatchWebFonts.js
@@ -0,0 +1,311 @@
+// @license magnet:?xt=urn:btih:8e4f440f4c65981c5bf93c76d35135ba5064d8b7dn=apache-2.0.txt Apache-2.0
+/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+
+/*************************************************************
+ *
+ * MathJax/extensions/MatchWebFonts.js
+ *
+ * Adds code to the output jax so that if web fonts are used on the page,
+ * MathJax will be able to detect their arrival and update the math to
+ * accommodate the change in font. For the NativeMML output, this works
+ * both for web fonts in main text, and for web fonts in the math as well.
+ *
+ * ---------------------------------------------------------------------
+ *
+ * Copyright (c) 2013-2020 The MathJax Consortium
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+(function (HUB,AJAX) {
+ var VERSION = "2.7.9";
+
+ var CONFIG = MathJax.Hub.CombineConfig("MatchWebFonts",{
+ matchFor: {
+ "HTML-CSS": true,
+ NativeMML: true,
+ SVG: true
+ },
+ fontCheckDelay: 500, // initial delay for the first check for web fonts
+ fontCheckTimeout: 15 * 1000, // how long to keep looking for fonts (15 seconds)
+ });
+
+ MathJax.Extension.MatchWebFonts = {
+ version: VERSION,
+ config: CONFIG
+ };
+
+ HUB.Register.StartupHook("HTML-CSS Jax Ready",function () {
+ var HTMLCSS = MathJax.OutputJax["HTML-CSS"];
+ var POSTTRANSLATE = HTMLCSS.postTranslate;
+
+ HTMLCSS.Augment({
+ postTranslate: function (state,partial) {
+ if (!partial && CONFIG.matchFor["HTML-CSS"] && this.config.matchFontHeight) {
+ //
+ // Check for changes in the web fonts that might affect the font
+ // size for math elements. This is a periodic check that goes on
+ // until a timeout is reached.
+ //
+ AJAX.timer.start(AJAX,["checkFonts",this,state.jax[this.id]],
+ CONFIG.fontCheckDelay,CONFIG.fontCheckTimeout);
+ }
+ return POSTTRANSLATE.apply(this,arguments); // do the original function
+ },
+
+ checkFonts: function (check,scripts) {
+ if (check.time(function () {})) return;
+ var size = [], i, m, retry = false;
+ //
+ // Add the elements used for testing ex and em sizes
+ //
+ for (i = 0, m = scripts.length; i < m; i++) {
+ script = scripts[i];
+ if (script.parentNode && script.MathJax.elementJax) {
+ script.parentNode.insertBefore(this.EmExSpan.cloneNode(true),script);
+ }
+ }
+ //
+ // Check to see if anything has changed
+ //
+ for (i = 0, m = scripts.length; i < m; i++) {
+ script = scripts[i]; if (!script.parentNode) continue; retry = true;
+ var jax = script.MathJax.elementJax; if (!jax) continue;
+ //
+ // Check if ex or mex has changed
+ //
+ var test = script.previousSibling;
+ var ex = test.firstChild.offsetHeight/60;
+ var em = test.lastChild.lastChild.offsetHeight/60;
+ if (ex === 0 || ex === "NaN") {ex = this.defaultEx; em = this.defaultEm}
+ if (ex !== jax.HTMLCSS.ex || em !== jax.HTMLCSS.em) {
+ var scale = ex/this.TeX.x_height/em;
+ scale = Math.floor(Math.max(this.config.minScaleAdjust/100,scale)*this.config.scale);
+ if (scale/100 !== jax.scale) {size.push(script); scripts[i] = {}}
+ }
+ }
+ //
+ // Remove markers
+ //
+ scripts = scripts.concat(size); // some scripts have been moved to the size array
+ for (i = 0, m = scripts.length; i < m; i++) {
+ script = scripts[i];
+ if (script && script.parentNode && script.MathJax.elementJax) {
+ script.parentNode.removeChild(script.previousSibling);
+ }
+ }
+ //
+ // Rerender the changed items
+ //
+ if (size.length) {HUB.Queue(["Rerender",HUB,[size],{}])}
+ //
+ // Try again later
+ //
+ if (retry) {setTimeout(check,check.delay)}
+ }
+ });
+ });
+
+ HUB.Register.StartupHook("SVG Jax Ready",function () {
+ var SVG = MathJax.OutputJax.SVG;
+ var POSTTRANSLATE = SVG.postTranslate;
+
+ SVG.Augment({
+ postTranslate: function (state,partial) {
+ if (!partial && CONFIG.matchFor.SVG) {
+ //
+ // Check for changes in the web fonts that might affect the font
+ // size for math elements. This is a periodic check that goes on
+ // until a timeout is reached.
+ //
+ AJAX.timer.start(AJAX,["checkFonts",this,state.jax[this.id]],
+ CONFIG.fontCheckDelay,CONFIG.fontCheckTimeout);
+ }
+ return POSTTRANSLATE.apply(this,arguments); // do the original function
+ },
+
+ checkFonts: function (check,scripts) {
+ if (check.time(function () {})) return;
+ var size = [], i, m, retry = false;
+ //
+ // Add the elements used for testing ex and em sizes
+ //
+ for (i = 0, m = scripts.length; i < m; i++) {
+ script = scripts[i];
+ if (script.parentNode && script.MathJax.elementJax) {
+ script.parentNode.insertBefore(this.ExSpan.cloneNode(true),script);
+ }
+ }
+ //
+ // Check to see if anything has changed
+ //
+ for (i = 0, m = scripts.length; i < m; i++) {
+ script = scripts[i]; if (!script.parentNode) continue; retry = true;
+ var jax = script.MathJax.elementJax; if (!jax) continue;
+ //
+ // Check if ex or mex has changed
+ //
+ var test = script.previousSibling;
+ var ex = test.firstChild.offsetHeight/60;
+ if (ex === 0 || ex === "NaN") {ex = this.defaultEx}
+ if (ex !== jax.SVG.ex) {size.push(script); scripts[i] = {}}
+ }
+ //
+ // Remove markers
+ //
+ scripts = scripts.concat(size); // some scripts have been moved to the size array
+ for (i = 0, m = scripts.length; i < m; i++) {
+ script = scripts[i];
+ if (script.parentNode && script.MathJax.elementJax) {
+ script.parentNode.removeChild(script.previousSibling);
+ }
+ }
+ //
+ // Rerender the changed items
+ //
+ if (size.length) {HUB.Queue(["Rerender",HUB,[size],{}])}
+ //
+ // Try again later (if not all the scripts are null)
+ //
+
+ if (retry) setTimeout(check,check.delay);
+ }
+ });
+ });
+
+ HUB.Register.StartupHook("NativeMML Jax Ready",function () {
+ var nMML = MathJax.OutputJax.NativeMML;
+ var POSTTRANSLATE = nMML.postTranslate;
+
+ nMML.Augment({
+ postTranslate: function (state) {
+ if (!HUB.Browser.isMSIE && CONFIG.matchFor.NativeMML) {
+ //
+ // Check for changes in the web fonts that might affect the sizes
+ // of math elements. This is a periodic check that goes on until
+ // a timeout is reached.
+ //
+ AJAX.timer.start(AJAX,["checkFonts",this,state.jax[this.id]],
+ CONFIG.fontCheckDelay,CONFIG.fontCheckTimeout);
+ }
+ POSTTRANSLATE.apply(this,arguments); // do the original routine
+ },
+
+ //
+ // Check to see if web fonts have been loaded that change the ex size
+ // of the surrounding font, the ex size within the math, or the widths
+ // of math elements. We do this by rechecking the ex and mex sizes
+ // (to see if the font scaling needs adjusting) and by checking the
+ // size of the inner mrow of math elements and mtd elements. The
+ // sizes of these have been stored in the NativeMML object of the
+ // element jax so that we can check for them here.
+ //
+ checkFonts: function (check,scripts) {
+ if (check.time(function () {})) return;
+ var adjust = [], mtd = [], size = [], i, m, script;
+ //
+ // Add the elements used for testing ex and em sizes
+ //
+ for (i = 0, m = scripts.length; i < m; i++) {
+ script = scripts[i];
+ if (script.parentNode && script.MathJax.elementJax) {
+ script.parentNode.insertBefore(this.EmExSpan.cloneNode(true),script);
+ }
+ }
+ //
+ // Check to see if anything has changed
+ //
+ for (i = 0, m = scripts.length; i < m; i++) {
+ script = scripts[i]; if (!script.parentNode) continue;
+ var jax = script.MathJax.elementJax; if (!jax) continue;
+ var span = document.getElementById(jax.inputID+"-Frame");
+ var math = span.getElementsByTagName("math")[0]; if (!math) continue;
+ jax = jax.NativeMML;
+ //
+ // Check if ex or mex has changed
+ //
+ var test = script.previousSibling;
+ var ex = test.firstChild.offsetWidth/60;
+ var mex = test.lastChild.offsetWidth/60;
+ if (ex === 0 || ex === "NaN") {ex = this.defaultEx; mex = this.defaultMEx}
+ var newEx = (ex !== jax.ex);
+ if (newEx || mex != jax.mex) {
+ var scale = (this.config.matchFontHeight && mex > 1 ? ex/mex : 1);
+ scale = Math.floor(Math.max(this.config.minScaleAdjust/100,scale) * this.config.scale);
+ if (scale/100 !== jax.scale) {size.push([span.style,scale])}
+ jax.scale = scale/100; jax.fontScale = scale+"%"; jax.ex = ex; jax.mex = mex;
+ }
+
+ //
+ // Check width of math elements
+ //
+ if ("scrollWidth" in jax && (newEx || jax.scrollWidth !== math.firstChild.scrollWidth)) {
+ jax.scrollWidth = math.firstChild.scrollWidth;
+ adjust.push([math.parentNode.style,jax.scrollWidth/jax.ex/jax.scale]);
+ }
+ //
+ // Check widths of mtd elements
+ //
+ if (math.MathJaxMtds) {
+ for (var j = 0, n = math.MathJaxMtds.length; j < n; j++) {
+ if (!math.MathJaxMtds[j].parentNode) continue;
+ if (newEx || math.MathJaxMtds[j].firstChild.scrollWidth !== jax.mtds[j]) {
+ jax.mtds[j] = math.MathJaxMtds[j].firstChild.scrollWidth;
+ mtd.push([math.MathJaxMtds[j],jax.mtds[j]/jax.ex]);
+ }
+ }
+ }
+ }
+ //
+ // Remove markers
+ //
+ for (i = 0, m = scripts.length; i < m; i++) {
+ script = scripts[i];
+ if (script.parentNode && script.MathJax.elementJax) {
+ script.parentNode.removeChild(script.previousSibling);
+ }
+ }
+ //
+ // Adjust scaling factor
+ //
+ for (i = 0, m = size.length; i < m; i++) {
+ size[i][0].fontSize = size[i][1] + "%";
+ }
+ //
+ // Adjust width of spans containing math elements that have changed
+ //
+ for (i = 0, m = adjust.length; i < m; i++) {
+ adjust[i][0].width = adjust[i][1].toFixed(3)+"ex";
+ }
+ //
+ // Adjust widths of mtd elements that have changed
+ //
+ for (i = 0, m = mtd.length; i < m; i++) {
+ var style = mtd[i][0].getAttribute("style");
+ style = style.replace(/(($|;)\s*min-width:).*?ex/,"$1 "+mtd[i][1].toFixed(3)+"ex");
+ mtd[i][0].setAttribute("style",style);
+ }
+ //
+ // Try again later
+ //
+ setTimeout(check,check.delay);
+ }
+ });
+ });
+
+ HUB.Startup.signal.Post("MatchWebFonts Extension Ready");
+ AJAX.loadComplete("[MathJax]/extensions/MatchWebFonts.js");
+
+})(MathJax.Hub,MathJax.Ajax);
+// @license-end