Skip to content

Commit c777547

Browse files
committed
Add a loop to check for font changes due to web fonts either in the math or the surrounding font. Resolves issue #558.
1 parent c05ab62 commit c777547

File tree

3 files changed

+147
-24
lines changed

3 files changed

+147
-24
lines changed

unpacked/MathJax.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -789,7 +789,7 @@ MathJax.fileversion = "2.2";
789789
check = BASE.Callback(check);
790790
check.execute = this.execute; check.time = this.time;
791791
check.STATUS = AJAX.STATUS; check.timeout = timeout || AJAX.timeout;
792-
check.delay = check.total = 0;
792+
check.delay = check.total = delay || 0;
793793
if (delay) {setTimeout(check,delay)} else {check()}
794794
},
795795
//

unpacked/jax/output/NativeMML/config.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,10 @@ MathJax.OutputJax.NativeMML = MathJax.OutputJax({
3636
scale: 100, // scaling factor for all math
3737
minScaleAdjust: 50, // minimum scaling to adjust to surrounding text
3838
// (since the code for that is a bit delicate)
39+
widthCheckDelay: 500, // initial delay for the first width check for web fonts
40+
// (set to null to prevent the width checks)
41+
widthCheckTimeout: 15 * 1000, // how long to keep looking for width changes (15 seconds)
42+
3943
styles: {
4044
"DIV.MathJax_MathML": {
4145
"text-align": "center",

unpacked/jax/output/NativeMML/jax.js

Lines changed: 142 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -253,13 +253,13 @@
253253
script = scripts[i]; if (!script.parentNode) continue;
254254
jax = script.MathJax.elementJax; if (!jax) continue;
255255
if (!isMSIE) {
256-
test = script.previousSibling; span = test.previousSibling;
256+
test = script.previousSibling;
257257
ex = test.firstChild.offsetWidth/60;
258258
mex = test.lastChild.offsetWidth/60;
259259
if (ex === 0 || ex === "NaN") {ex = this.defaultEx; mex = this.defaultMEx}
260260
scale = (this.config.matchFontHeight && mex > 1 ? ex/mex : 1);
261261
scale = Math.floor(Math.max(this.config.minScaleAdjust/100,scale) * this.config.scale);
262-
jax.NativeMML.ex = ex;
262+
jax.NativeMML.ex = ex; jax.NativeMML.mex = mex;
263263
} else {scale = 100}
264264
jax.NativeMML.fontSize = scale+"%";
265265
jax.NativeMML.scale = scale/100;
@@ -269,9 +269,10 @@
269269
//
270270
if (!isMSIE) {
271271
for (i = 0; i < m; i++) {
272-
script = scripts[i]; if (!script.parentNode || !script.MathJax.elementJax) continue;
273-
test = scripts[i].previousSibling;
274-
test.parentNode.removeChild(test);
272+
script = scripts[i];
273+
if (script.parentNode && script.MathJax.elementJax) {
274+
script.parentNode.removeChild(script.previousSibling);
275+
}
275276
}
276277
}
277278
},
@@ -326,6 +327,15 @@
326327
},
327328

328329
postTranslate: function (state) {
330+
if (!isMSIE && this.config.widthCheckDelay != null) {
331+
//
332+
// Check for changes in the web fonts that might affect the sizes
333+
// of math elements. This is a periodic check that goes on until
334+
// a timeout is reached.
335+
//
336+
AJAX.timer.start(AJAX,["checkWidths",this,state.jax[this.id]],
337+
this.config.widthCheckDelay,this.config.widthCheckTimeout);
338+
}
329339
if (this.forceReflow) {
330340
//
331341
// Firefox messes up some mtable's when they are dynamically created
@@ -336,6 +346,101 @@
336346
}
337347
},
338348

349+
//
350+
// Check to see if web fonts have been loaded that change the ex size
351+
// of the surrounding font, the ex size within the math, or the widths
352+
// of math elements. We do this by rechecking the ex and mex sizes
353+
// (to see if the font scaling needs adjusting) and by checking the
354+
// size of the inner mrow of math elements and mtd elements. The
355+
// sizes of these have been stored in the NativeMML object of the
356+
// element jax so that we can check for them here.
357+
//
358+
checkWidths: function (check,scripts) {
359+
if (check.time(function () {})) return;
360+
var adjust = [], mtd = [], size = [], i, m;
361+
//
362+
// Add the elements used for testing ex and em sizes
363+
//
364+
for (i = 0, m = scripts.length; i < m; i++) {
365+
if (!scripts[i].parentNode || !scripts[i].MathJax.elementJax) continue;
366+
scripts[i].parentNode.insertBefore(this.EmExSpan.cloneNode(true),scripts[i]);
367+
}
368+
//
369+
// Check to see if anything has changed
370+
//
371+
for (i = 0, m = scripts.length; i < m; i++) {
372+
if (!scripts[i].parentNode) continue;
373+
var jax = scripts[i].MathJax.elementJax;
374+
if (!jax) continue;
375+
var span = document.getElementById(jax.inputID+"-Frame");
376+
var math = span.getElementsByTagName("math")[0]; if (!math) continue;
377+
jax = jax.NativeMML;
378+
//
379+
// Check if ex or mex has changed
380+
//
381+
var test = scripts[i].previousSibling;
382+
var ex = test.firstChild.offsetWidth/60;
383+
var mex = test.lastChild.offsetWidth/60;
384+
if (ex === 0 || ex === "NaN") {ex = this.defaultEx; mex = this.defaultMEx}
385+
var newEx = (ex !== jax.ex);
386+
if (newEx || mex != jax.mex) {
387+
scale = (this.config.matchFontHeight && mex > 1 ? ex/mex : 1);
388+
scale = Math.floor(Math.max(this.config.minScaleAdjust/100,scale) * this.config.scale);
389+
if (scale/100 !== jax.scale) {size.push([span.style,scale])}
390+
jax.scale = scale/100; jax.fontScale = scale+"%"; jax.ex = ex; jax.mex = mex;
391+
}
392+
393+
//
394+
// Check width of math elements
395+
//
396+
if ("scrollWidth" in jax && (newEx || jax.scrollWidth !== math.firstChild.scrollWidth)) {
397+
jax.scrollWidth = math.firstChild.scrollWidth;
398+
adjust.push([math.parentNode.style,jax.scrollWidth/jax.ex/jax.scale]);
399+
}
400+
//
401+
// Check widths of mtd elements
402+
//
403+
if (math.MathJaxMtds) {
404+
for (j = 0, n = math.MathJaxMtds.length; j < n; j++) {
405+
if (!math.MathJaxMtds[j].parentNode) continue;
406+
if (newEx || math.MathJaxMtds[j].firstChild.scrollWidth !== jax.mtds[j]) {
407+
jax.mtds[j] = math.MathJaxMtds[j].firstChild.scrollWidth;
408+
mtd.push([math.MathJaxMtds[j],jax.mtds[j]/jax.ex]);
409+
}
410+
}
411+
}
412+
}
413+
//
414+
// Remove markers
415+
//
416+
for (i = 0, m = scripts.length; i < m; i++) {
417+
if (scripts[i].parentNode && scripts[i].MathJax.elementJax) {
418+
scripts[i].parentNode.removeChild(scripts[i].previousSibling);
419+
}
420+
}
421+
//
422+
// Adjust scaling factor
423+
//
424+
for (i = 0, m = size.length; i < m; i++) {
425+
size[i][0].fontSize = size[i][1] + "%";
426+
}
427+
//
428+
// Adjust width of spans containing math elements that have changed
429+
//
430+
for (i = 0, m = adjust.length; i < m; i++) {
431+
adjust[i][0].width = adjust[i][1].toFixed(3)+"ex";
432+
}
433+
//
434+
// Adjust widths of mtd elements that have changed
435+
//
436+
for (i = 0, m = mtd.length; i < m; i++) {
437+
var style = mtd[i][0].getAttribute("style");
438+
style = style.replace(/(($|;)\s*min-width:).*?ex/,"$1 "+mtd[i][1].toFixed(3)+"ex");
439+
mtd[i][0].setAttribute("style",style);
440+
}
441+
setTimeout(check,check.delay);
442+
},
443+
339444
//
340445
// Remove MathML preceeding the script
341446
//
@@ -605,7 +710,7 @@
605710
});
606711

607712
if (!isMSIE) {
608-
var SPLIT = MathJax.Hub.SplitList;
713+
var SPLIT = HUB.SplitList;
609714
MML.mtable.Augment({
610715
toNativeMML: function (parent) {
611716
var i, m;
@@ -834,14 +939,13 @@
834939
if (nMML.spaceWidthBug && this.width) {
835940
var mspace = parent.lastChild;
836941
var width = mspace.getAttribute("width");
837-
var style = mspace.getAttribute("style") || "";
838-
if (style != "") {style += ";"}
942+
var style = (mspace.getAttribute("style") || "").replace(/;?\s*/,"; ");
839943
mspace.setAttribute("style",style+"width:"+width);
840944
}
841945
}
842946
});
843947

844-
var fontDir = MathJax.Ajax.fileURL(MathJax.OutputJax.fontDir+"/HTML-CSS/TeX/otf");
948+
var fontDir = AJAX.fileURL(MathJax.OutputJax.fontDir+"/HTML-CSS/TeX/otf");
845949

846950
/*
847951
* Add fix for mathvariant issues in FF
@@ -895,7 +999,7 @@
895999

8961000
MML.math.Augment({
8971001
toNativeMML: function (parent) {
898-
var tag = this.NativeMMLelement(this.type), math = tag;
1002+
var tag = this.NativeMMLelement(this.type), math = tag, jax;
8991003
nMML.adjustWidths = [];
9001004
//
9011005
// Some browsers don't seem to add the xmlns attribute, so do it by hand.
@@ -950,22 +1054,37 @@
9501054
// has a different font size.
9511055
//
9521056
parent.style.width = (math.firstChild.scrollWidth/nMML.ex/nMML.scale).toFixed(3) + "ex";
1057+
//
1058+
// Save size for later when we check if Web fonts have arrived
1059+
//
1060+
jax = HUB.getJaxFor(parent);
1061+
if (jax) {jax.NativeMML.scrollWidth = math.firstChild.scrollWidth}
9531062
}
954-
//
955-
// Firefox gets the widths of <mtd> elements wrong, so run
956-
// through them (now that the math is part of the page) and
957-
// fix them up. Use ex's so that they print properly (see above).
958-
//
959-
for (var i = 0, m = nMML.adjustWidths.length; i < m; i++) {
960-
var tag = nMML.adjustWidths[i];
961-
var style = tag.getAttribute("style") || "";
962-
if (!style.match(/(^|;)\s*width:/)) {
963-
var width = tag.scrollWidth/nMML.ex;
964-
if (style !== "") {style += "; "}
965-
tag.setAttribute("style",style+"width:"+width+"ex");
1063+
if (nMML.adjustWidths.length) {
1064+
//
1065+
// Firefox gets the widths of <mtd> elements wrong, so run
1066+
// through them (now that the math is part of the page) and
1067+
// fix them up. Use ex's so that they print properly (see above).
1068+
//
1069+
var mtd = [];
1070+
for (var i = 0, m = nMML.adjustWidths.length; i < m; i++) {
1071+
var tag = nMML.adjustWidths[i];
1072+
var style = tag.getAttribute("style") || "";
1073+
if (!style.match(/(^|;)\s*min-width:/)) {
1074+
mtd.push(tag.scrollWidth);
1075+
var width = (tag.scrollWidth/nMML.ex).toFixed(3)+"ex";
1076+
style = style.replace(/;?\s*$/,"; ");
1077+
tag.setAttribute("style",style+"min-width:"+width);
1078+
}
9661079
}
1080+
//
1081+
// Save the lists so that we can check them later for web font downloads
1082+
//
1083+
if (!jax) {jax = HUB.getJaxFor(parent)}
1084+
if (jax) {jax.NativeMML.mtds = mtd}
1085+
math.MathJaxMtds = nMML.adjustWidths;
1086+
nMML.adjustWidths = []; // clear it so we don't hold onto the DOM elements
9671087
}
968-
nMML.adjustWidths = []; // clear it so we don't hold onto the DOM elements
9691088
}
9701089
});
9711090

0 commit comments

Comments
 (0)