From ed932ec45842075d8ae27aadd35a1f587933096a Mon Sep 17 00:00:00 2001 From: "Davide P. Cervone" Date: Mon, 23 Sep 2013 20:56:25 -0400 Subject: [PATCH 1/9] Properly handle the width of math and mtd elements by explicitly setting the width from the child mrow (works around FF bug that gets these widths wrong). Resolves issue #558. --- unpacked/jax/output/NativeMML/jax.js | 30 ++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/unpacked/jax/output/NativeMML/jax.js b/unpacked/jax/output/NativeMML/jax.js index a47983e01..712419291 100644 --- a/unpacked/jax/output/NativeMML/jax.js +++ b/unpacked/jax/output/NativeMML/jax.js @@ -120,7 +120,8 @@ } }, settings: HUB.config.menuSettings, - ex: 1, // filled in later + ex: 1, scale: 1, // filled in later + adjustWidths: [], // array of elements to have their widths adjusted Config: function () { this.SUPER(arguments).Config.call(this); @@ -258,7 +259,7 @@ if (ex === 0 || ex === "NaN") {ex = this.defaultEx; mex = this.defaultMEx} scale = (mex > 1 ? ex/mex : 1) * this.config.scale; scale = Math.floor(Math.max(this.config.minScaleAdjust/100,scale)); - jax.NativeMML.ex = ex; + jax.NativeMML.ex = ex; jax.NativeMML.scale = scale/100; } else {scale = 100} jax.NativeMML.fontSize = scale+"%"; } @@ -287,6 +288,7 @@ container = span.firstChild, mspan = container.firstChild; span.style.fontSize = jax.NativeMML.fontSize; this.ex = jax.NativeMML.ex || this.defaultEx; + this.scale = jax.NativeMML.scale || 1; // // Convert to MathML (if restarted, remove any partial math) // @@ -814,11 +816,14 @@ toNativeMML: function (parent) { var tag = parent.appendChild(this.NativeMMLelement(this.type)); this.NativeMMLattributes(tag); - if (nMML.widthBug) {tag = tag.appendChild(this.NativeMMLelement("mrow"))} + if (nMML.mtdWidthBug) { + nMML.adjustWidths.push(tag); + tag = tag.appendChild(this.NativeMMLelement("mrow")); + } for (var i = 0, m = this.data.length; i < m; i++) { if (this.data[i]) {this.data[i].toNativeMML(tag)} else {tag.appendChild(this.NativeMMLelement("mrow"))} - } + } } }); @@ -890,6 +895,7 @@ MML.math.Augment({ toNativeMML: function (parent) { var tag = this.NativeMMLelement(this.type), math = tag; + nMML.adjustWidths = []; // // Some browsers don't seem to add the xmlns attribute, so do it by hand. // @@ -936,12 +942,22 @@ // parent element to match. Even if we set the width properly, // it doesn't seem to propagate up to the correctly. // - if (nMML.widthBug && !mtable.nMMLforceWidth && mtable.nMMLlaMatch) { + if (nMML.widthBug && + !(mtable.nMMLhasLabels && (mtable.nMMLforceWidth || !mtable.nMMLlaMatch))) { // // Convert size to ex's so that it scales properly if the print media // has a different font size. // - parent.style.width = (math.firstChild.scrollWidth/nMML.ex).toFixed(3) + "ex"; + parent.style.width = (math.firstChild.scrollWidth/nMML.ex/nMML.scale).toFixed(3) + "ex"; + } + for (var i = 0, m = nMML.adjustWidths.length; i < m; i++) { + var tag = nMML.adjustWidths[i]; + var style = tag.getAttribute("style") || ""; + if (!style.match(/(^|;)\s*width:/)) { + var width = tag.scrollWidth/nMML.ex; + if (style !== "") {style += "; "} + tag.setAttribute("style",style+"width:"+width+"ex"); + } } } }); @@ -1131,6 +1147,8 @@ // correctly and thus the element is displayed incorrectly in . nMML.spaceWidthBug = !browser.versionAtLeast("20.0"); + nMML.mtdWidthBug = true; // widths not properly determined + nMML.tableSpacingBug = true; // mtable@rowspacing/mtable@columnspacing not // supported. nMML.tableLabelBug = true; // mlabeledtr is not implemented. From bbf543a8403728778753cc72e2876370dd1e995d Mon Sep 17 00:00:00 2001 From: "Davide P. Cervone" Date: Mon, 23 Sep 2013 21:19:04 -0400 Subject: [PATCH 2/9] Add some comments, and clear the list of DOM elements once we are done with it. --- unpacked/jax/output/NativeMML/jax.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/unpacked/jax/output/NativeMML/jax.js b/unpacked/jax/output/NativeMML/jax.js index 712419291..dbc5ac7fa 100644 --- a/unpacked/jax/output/NativeMML/jax.js +++ b/unpacked/jax/output/NativeMML/jax.js @@ -950,6 +950,11 @@ // parent.style.width = (math.firstChild.scrollWidth/nMML.ex/nMML.scale).toFixed(3) + "ex"; } + // + // Firefox gets the widths of elements wrong, so run + // through them (now that the math is part of the page) and + // fix them up. Use ex's so that they print properly (see above). + // for (var i = 0, m = nMML.adjustWidths.length; i < m; i++) { var tag = nMML.adjustWidths[i]; var style = tag.getAttribute("style") || ""; @@ -959,6 +964,7 @@ tag.setAttribute("style",style+"width:"+width+"ex"); } } + nMML.adjustWidths = []; // clear it so we don't hold onto the DOM elements } }); From c05ab62eccc05b29de872ae511056b74df2f4d4a Mon Sep 17 00:00:00 2001 From: "Davide P. Cervone" Date: Sun, 29 Sep 2013 08:51:49 -0400 Subject: [PATCH 3/9] Add config option for matching font heights in NativeMML and HTML-CSS output (can't do it for SVG, since we aren't using native fonts) --- unpacked/jax/output/HTML-CSS/config.js | 1 + unpacked/jax/output/HTML-CSS/jax.js | 5 +++-- unpacked/jax/output/NativeMML/config.js | 1 + unpacked/jax/output/NativeMML/jax.js | 9 +++++---- 4 files changed, 10 insertions(+), 6 deletions(-) diff --git a/unpacked/jax/output/HTML-CSS/config.js b/unpacked/jax/output/HTML-CSS/config.js index 8e5d6dac6..a1822c2a5 100644 --- a/unpacked/jax/output/HTML-CSS/config.js +++ b/unpacked/jax/output/HTML-CSS/config.js @@ -35,6 +35,7 @@ MathJax.OutputJax["HTML-CSS"] = MathJax.OutputJax({ webfontDir: MathJax.OutputJax.fontDir + "/HTML-CSS", // font name added later config: { + matchFontHeight: true, // try to match math font height to surrounding font? scale: 100, minScaleAdjust: 50, // global math scaling factor, and minimum adjusted scale factor availableFonts: ["STIX","TeX"], // list of local fonts to check for preferredFont: "TeX", // preferred local font (TeX or STIX) diff --git a/unpacked/jax/output/HTML-CSS/jax.js b/unpacked/jax/output/HTML-CSS/jax.js index c0769ea16..63ce62f24 100644 --- a/unpacked/jax/output/HTML-CSS/jax.js +++ b/unpacked/jax/output/HTML-CSS/jax.js @@ -534,7 +534,8 @@ ex = this.defaultEx; em = this.defaultEm; if (relwidth) {maxwidth = this.defaultWidth} } - scale = Math.floor(Math.max(this.config.minScaleAdjust/100,(ex/this.TeX.x_height)/em) * this.config.scale); + scale = (this.config.matchFontHeight ? ex/this.TeX.x_height/em : 1); + scale = Math.floor(Math.max(this.config.minScaleAdjust/100,scale)*this.config.scale); jax.HTMLCSS.scale = scale/100; jax.HTMLCSS.fontSize = scale+"%"; jax.HTMLCSS.em = jax.HTMLCSS.outerEm = em; this.em = em * scale/100; jax.HTMLCSS.ex = ex; jax.HTMLCSS.lineWidth = (linebreak ? this.length2em(width,1,maxwidth/this.em) : 1000000); @@ -584,7 +585,7 @@ this.em = MML.mbase.prototype.em = jax.HTMLCSS.em * jax.HTMLCSS.scale; this.outerEm = jax.HTMLCSS.em; this.scale = jax.HTMLCSS.scale; this.linebreakWidth = jax.HTMLCSS.lineWidth; - span.style.fontSize = jax.HTMLCSS.fontSize; + if (this.scale !== 1) {span.style.fontSize = jax.HTMLCSS.fontSize} // // Typeset the math // diff --git a/unpacked/jax/output/NativeMML/config.js b/unpacked/jax/output/NativeMML/config.js index 6160f35c4..49b2df19e 100644 --- a/unpacked/jax/output/NativeMML/config.js +++ b/unpacked/jax/output/NativeMML/config.js @@ -32,6 +32,7 @@ MathJax.OutputJax.NativeMML = MathJax.OutputJax({ extensionDir: MathJax.OutputJax.extensionDir + "/NativeMML", config: { + matchFontHeight: true, // try to match math font height to surrounding font? scale: 100, // scaling factor for all math minScaleAdjust: 50, // minimum scaling to adjust to surrounding text // (since the code for that is a bit delicate) diff --git a/unpacked/jax/output/NativeMML/jax.js b/unpacked/jax/output/NativeMML/jax.js index dbc5ac7fa..50e95838e 100644 --- a/unpacked/jax/output/NativeMML/jax.js +++ b/unpacked/jax/output/NativeMML/jax.js @@ -257,11 +257,12 @@ ex = test.firstChild.offsetWidth/60; mex = test.lastChild.offsetWidth/60; if (ex === 0 || ex === "NaN") {ex = this.defaultEx; mex = this.defaultMEx} - scale = (mex > 1 ? ex/mex : 1) * this.config.scale; - scale = Math.floor(Math.max(this.config.minScaleAdjust/100,scale)); - jax.NativeMML.ex = ex; jax.NativeMML.scale = scale/100; + scale = (this.config.matchFontHeight && mex > 1 ? ex/mex : 1); + scale = Math.floor(Math.max(this.config.minScaleAdjust/100,scale) * this.config.scale); + jax.NativeMML.ex = ex; } else {scale = 100} jax.NativeMML.fontSize = scale+"%"; + jax.NativeMML.scale = scale/100; } // // Remove the test spans used for determining scales @@ -286,9 +287,9 @@ var jax = script.MathJax.elementJax, math = jax.root; var span = document.getElementById(jax.inputID+"-Frame"), container = span.firstChild, mspan = container.firstChild; - span.style.fontSize = jax.NativeMML.fontSize; this.ex = jax.NativeMML.ex || this.defaultEx; this.scale = jax.NativeMML.scale || 1; + if (this.scale !== 1) {span.style.fontSize = jax.NativeMML.fontSize} // // Convert to MathML (if restarted, remove any partial math) // From c777547f974d6c35aa98516c8e1c9788c94aa169 Mon Sep 17 00:00:00 2001 From: "Davide P. Cervone" Date: Sun, 29 Sep 2013 16:23:42 -0400 Subject: [PATCH 4/9] Add a loop to check for font changes due to web fonts either in the math or the surrounding font. Resolves issue #558. --- unpacked/MathJax.js | 2 +- unpacked/jax/output/NativeMML/config.js | 4 + unpacked/jax/output/NativeMML/jax.js | 165 ++++++++++++++++++++---- 3 files changed, 147 insertions(+), 24 deletions(-) diff --git a/unpacked/MathJax.js b/unpacked/MathJax.js index 7210d8013..e20d1094b 100644 --- a/unpacked/MathJax.js +++ b/unpacked/MathJax.js @@ -789,7 +789,7 @@ MathJax.fileversion = "2.2"; check = BASE.Callback(check); check.execute = this.execute; check.time = this.time; check.STATUS = AJAX.STATUS; check.timeout = timeout || AJAX.timeout; - check.delay = check.total = 0; + check.delay = check.total = delay || 0; if (delay) {setTimeout(check,delay)} else {check()} }, // diff --git a/unpacked/jax/output/NativeMML/config.js b/unpacked/jax/output/NativeMML/config.js index 49b2df19e..9ebbab39e 100644 --- a/unpacked/jax/output/NativeMML/config.js +++ b/unpacked/jax/output/NativeMML/config.js @@ -36,6 +36,10 @@ MathJax.OutputJax.NativeMML = MathJax.OutputJax({ scale: 100, // scaling factor for all math minScaleAdjust: 50, // minimum scaling to adjust to surrounding text // (since the code for that is a bit delicate) + widthCheckDelay: 500, // initial delay for the first width check for web fonts + // (set to null to prevent the width checks) + widthCheckTimeout: 15 * 1000, // how long to keep looking for width changes (15 seconds) + styles: { "DIV.MathJax_MathML": { "text-align": "center", diff --git a/unpacked/jax/output/NativeMML/jax.js b/unpacked/jax/output/NativeMML/jax.js index 50e95838e..84e7df262 100644 --- a/unpacked/jax/output/NativeMML/jax.js +++ b/unpacked/jax/output/NativeMML/jax.js @@ -253,13 +253,13 @@ script = scripts[i]; if (!script.parentNode) continue; jax = script.MathJax.elementJax; if (!jax) continue; if (!isMSIE) { - test = script.previousSibling; span = test.previousSibling; + test = script.previousSibling; ex = test.firstChild.offsetWidth/60; mex = test.lastChild.offsetWidth/60; if (ex === 0 || ex === "NaN") {ex = this.defaultEx; mex = this.defaultMEx} scale = (this.config.matchFontHeight && mex > 1 ? ex/mex : 1); scale = Math.floor(Math.max(this.config.minScaleAdjust/100,scale) * this.config.scale); - jax.NativeMML.ex = ex; + jax.NativeMML.ex = ex; jax.NativeMML.mex = mex; } else {scale = 100} jax.NativeMML.fontSize = scale+"%"; jax.NativeMML.scale = scale/100; @@ -269,9 +269,10 @@ // if (!isMSIE) { for (i = 0; i < m; i++) { - script = scripts[i]; if (!script.parentNode || !script.MathJax.elementJax) continue; - test = scripts[i].previousSibling; - test.parentNode.removeChild(test); + script = scripts[i]; + if (script.parentNode && script.MathJax.elementJax) { + script.parentNode.removeChild(script.previousSibling); + } } } }, @@ -326,6 +327,15 @@ }, postTranslate: function (state) { + if (!isMSIE && this.config.widthCheckDelay != null) { + // + // 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,["checkWidths",this,state.jax[this.id]], + this.config.widthCheckDelay,this.config.widthCheckTimeout); + } if (this.forceReflow) { // // Firefox messes up some mtable's when they are dynamically created @@ -336,6 +346,101 @@ } }, + // + // 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. + // + checkWidths: function (check,scripts) { + if (check.time(function () {})) return; + var adjust = [], mtd = [], size = [], i, m; + // + // Add the elements used for testing ex and em sizes + // + for (i = 0, m = scripts.length; i < m; i++) { + if (!scripts[i].parentNode || !scripts[i].MathJax.elementJax) continue; + scripts[i].parentNode.insertBefore(this.EmExSpan.cloneNode(true),scripts[i]); + } + // + // Check to see if anything has changed + // + for (i = 0, m = scripts.length; i < m; i++) { + if (!scripts[i].parentNode) continue; + var jax = scripts[i].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 = scripts[i].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) { + 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 (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++) { + if (scripts[i].parentNode && scripts[i].MathJax.elementJax) { + scripts[i].parentNode.removeChild(scripts[i].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); + } + setTimeout(check,check.delay); + }, + // // Remove MathML preceeding the script // @@ -605,7 +710,7 @@ }); if (!isMSIE) { - var SPLIT = MathJax.Hub.SplitList; + var SPLIT = HUB.SplitList; MML.mtable.Augment({ toNativeMML: function (parent) { var i, m; @@ -834,14 +939,13 @@ if (nMML.spaceWidthBug && this.width) { var mspace = parent.lastChild; var width = mspace.getAttribute("width"); - var style = mspace.getAttribute("style") || ""; - if (style != "") {style += ";"} + var style = (mspace.getAttribute("style") || "").replace(/;?\s*/,"; "); mspace.setAttribute("style",style+"width:"+width); } } }); - var fontDir = MathJax.Ajax.fileURL(MathJax.OutputJax.fontDir+"/HTML-CSS/TeX/otf"); + var fontDir = AJAX.fileURL(MathJax.OutputJax.fontDir+"/HTML-CSS/TeX/otf"); /* * Add fix for mathvariant issues in FF @@ -895,7 +999,7 @@ MML.math.Augment({ toNativeMML: function (parent) { - var tag = this.NativeMMLelement(this.type), math = tag; + var tag = this.NativeMMLelement(this.type), math = tag, jax; nMML.adjustWidths = []; // // Some browsers don't seem to add the xmlns attribute, so do it by hand. @@ -950,22 +1054,37 @@ // has a different font size. // parent.style.width = (math.firstChild.scrollWidth/nMML.ex/nMML.scale).toFixed(3) + "ex"; + // + // Save size for later when we check if Web fonts have arrived + // + jax = HUB.getJaxFor(parent); + if (jax) {jax.NativeMML.scrollWidth = math.firstChild.scrollWidth} } - // - // Firefox gets the widths of elements wrong, so run - // through them (now that the math is part of the page) and - // fix them up. Use ex's so that they print properly (see above). - // - for (var i = 0, m = nMML.adjustWidths.length; i < m; i++) { - var tag = nMML.adjustWidths[i]; - var style = tag.getAttribute("style") || ""; - if (!style.match(/(^|;)\s*width:/)) { - var width = tag.scrollWidth/nMML.ex; - if (style !== "") {style += "; "} - tag.setAttribute("style",style+"width:"+width+"ex"); + if (nMML.adjustWidths.length) { + // + // Firefox gets the widths of elements wrong, so run + // through them (now that the math is part of the page) and + // fix them up. Use ex's so that they print properly (see above). + // + var mtd = []; + for (var i = 0, m = nMML.adjustWidths.length; i < m; i++) { + var tag = nMML.adjustWidths[i]; + var style = tag.getAttribute("style") || ""; + if (!style.match(/(^|;)\s*min-width:/)) { + mtd.push(tag.scrollWidth); + var width = (tag.scrollWidth/nMML.ex).toFixed(3)+"ex"; + style = style.replace(/;?\s*$/,"; "); + tag.setAttribute("style",style+"min-width:"+width); + } } + // + // Save the lists so that we can check them later for web font downloads + // + if (!jax) {jax = HUB.getJaxFor(parent)} + if (jax) {jax.NativeMML.mtds = mtd} + math.MathJaxMtds = nMML.adjustWidths; + nMML.adjustWidths = []; // clear it so we don't hold onto the DOM elements } - nMML.adjustWidths = []; // clear it so we don't hold onto the DOM elements } }); From a012354f382e5a1080091a5eb3a32bc1b119ab2b Mon Sep 17 00:00:00 2001 From: "Davide P. Cervone" Date: Sun, 29 Sep 2013 19:44:15 -0400 Subject: [PATCH 5/9] Add support for matching web fonts in HTML-CSS. Change the names of the paramters that control it in NativeMML (so both have the same names). Add a global matchWebFonts option to control whether to do the loop to check for web fonts (off by default). Resolves more of issue #558. --- unpacked/MathJax.js | 11 ++++ unpacked/jax/output/HTML-CSS/config.js | 4 ++ unpacked/jax/output/HTML-CSS/jax.js | 67 +++++++++++++++++++++++-- unpacked/jax/output/NativeMML/config.js | 7 +-- unpacked/jax/output/NativeMML/jax.js | 33 ++++++------ 5 files changed, 102 insertions(+), 20 deletions(-) diff --git a/unpacked/MathJax.js b/unpacked/MathJax.js index e20d1094b..3e16e250c 100644 --- a/unpacked/MathJax.js +++ b/unpacked/MathJax.js @@ -1741,6 +1741,10 @@ MathJax.Hub = { showMathMenuMSIE: true, // separtely determine if MSIE should have math menu // (since the code for that is a bit delicate) + matchWebFonts: false, // true means look for web fonts that may cause changes in the + // scaling factors for the math (off by default since it + // uses a loop every time math is rendered). + menuSettings: { zoom: "None", // when to do MathZoom CTRL: false, // require CTRL for MathZoom? @@ -1906,6 +1910,7 @@ MathJax.Hub = { takeAction: function (action,element,callback) { var ec = this.elementCallback(element,callback); +console.log(element); var queue = MathJax.Callback.Queue(["Clear",this.signal]); for (var i = 0, m = ec.elements.length; i < m; i++) { if (ec.elements[i]) { @@ -2229,6 +2234,12 @@ MathJax.Hub = { }, elementScripts: function (element) { + if (element instanceof Array) { + var scripts = []; + for (var i = 0, m = element.length; i < m; i++) + {scripts.push.apply(scripts,this.elementScripts(element[i]))} + return scripts; + } if (typeof(element) === 'string') {element = document.getElementById(element)} if (!document.body) {document.body = document.getElementsByTagName("body")[0]} if (element == null) {element = document.body} diff --git a/unpacked/jax/output/HTML-CSS/config.js b/unpacked/jax/output/HTML-CSS/config.js index a1822c2a5..6930ba189 100644 --- a/unpacked/jax/output/HTML-CSS/config.js +++ b/unpacked/jax/output/HTML-CSS/config.js @@ -44,6 +44,10 @@ MathJax.OutputJax["HTML-CSS"] = MathJax.OutputJax({ undefinedFamily: "STIXGeneral,'Arial Unicode MS',serif", // fonts to use for unknown unicode characters mtextFontInherit: false, // to make be in page font rather than MathJax font + fontCheckDelay: 500, // initial delay for the first check for web fonts + // (set to null to prevent the checks) + fontCheckTimeout: 15 * 1000, // how long to keep looking for font changes (15 seconds) + EqnChunk: (MathJax.Hub.Browser.isMobile ? 10: 50), // number of equations to process before showing them EqnChunkFactor: 1.5, // chunk size is multiplied by this after each chunk diff --git a/unpacked/jax/output/HTML-CSS/jax.js b/unpacked/jax/output/HTML-CSS/jax.js index 63ce62f24..a0b611e8d 100644 --- a/unpacked/jax/output/HTML-CSS/jax.js +++ b/unpacked/jax/output/HTML-CSS/jax.js @@ -618,15 +618,25 @@ // state.HTMLCSSeqn += (state.i - state.HTMLCSSi); state.HTMLCSSi = state.i; if (state.HTMLCSSeqn >= state.HTMLCSSlast + state.HTMLCSSchunk) { - this.postTranslate(state); + this.postTranslate(state,true); state.HTMLCSSchunk = Math.floor(state.HTMLCSSchunk*this.config.EqnChunkFactor); state.HTMLCSSdelay = true; // delay if there are more scripts } } }, - postTranslate: function (state) { + postTranslate: function (state,partial) { var scripts = state.jax[this.id]; + if (!partial && HUB.config.matchWebFonts && 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]], + this.config.fontCheckDelay,this.config.fontCheckTimeout); + + } if (!this.hideProcessedMath) return; // // Reveal this chunk of math @@ -651,7 +661,7 @@ } if (this.forceReflow) { // WebKit can misplace some elements that should wrap to the next line - // but gets them right ona reflow, so force reflow by toggling a stylesheet + // but gets them right on a reflow, so force reflow by toggling a stylesheet var sheet = (document.styleSheets||[])[0]||{}; sheet.disabled = true; sheet.disabled = false; } @@ -660,6 +670,57 @@ // state.HTMLCSSlast = state.HTMLCSSeqn; }, + + checkFonts: function (check,scripts) { + if (check.time(function () {})) return; + var size = [], i, m; + // + // 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"); + // + // Check if ex or mex has changed + // + var test = script.previousSibling, div = test.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 + // + 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) {MathJax.Hub.Queue(["Rerender",MathJax.Hub,[size],{}])} + // + // Try again later + // + setTimeout(check,check.delay); + }, getJaxFromMath: function (math) { if (math.parentNode.className === "MathJax_Display") {math = math.parentNode} diff --git a/unpacked/jax/output/NativeMML/config.js b/unpacked/jax/output/NativeMML/config.js index 9ebbab39e..6720e7237 100644 --- a/unpacked/jax/output/NativeMML/config.js +++ b/unpacked/jax/output/NativeMML/config.js @@ -36,9 +36,10 @@ MathJax.OutputJax.NativeMML = MathJax.OutputJax({ scale: 100, // scaling factor for all math minScaleAdjust: 50, // minimum scaling to adjust to surrounding text // (since the code for that is a bit delicate) - widthCheckDelay: 500, // initial delay for the first width check for web fonts - // (set to null to prevent the width checks) - widthCheckTimeout: 15 * 1000, // how long to keep looking for width changes (15 seconds) + + fontCheckDelay: 500, // initial delay for the first width check for web fonts + // (set to null to prevent the width checks) + fontCheckTimeout: 15 * 1000, // how long to keep looking for width changes (15 seconds) styles: { "DIV.MathJax_MathML": { diff --git a/unpacked/jax/output/NativeMML/jax.js b/unpacked/jax/output/NativeMML/jax.js index 84e7df262..7f41c8b78 100644 --- a/unpacked/jax/output/NativeMML/jax.js +++ b/unpacked/jax/output/NativeMML/jax.js @@ -327,14 +327,14 @@ }, postTranslate: function (state) { - if (!isMSIE && this.config.widthCheckDelay != null) { + if (!isMSIE && HUB.config.matchWebFonts) { // // 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,["checkWidths",this,state.jax[this.id]], - this.config.widthCheckDelay,this.config.widthCheckTimeout); + AJAX.timer.start(AJAX,["checkFonts",this,state.jax[this.id]], + this.config.fontCheckDelay,this.config.fontCheckTimeout); } if (this.forceReflow) { // @@ -355,36 +355,37 @@ // sizes of these have been stored in the NativeMML object of the // element jax so that we can check for them here. // - checkWidths: function (check,scripts) { + checkFonts: function (check,scripts) { if (check.time(function () {})) return; - var adjust = [], mtd = [], size = [], i, m; + 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++) { - if (!scripts[i].parentNode || !scripts[i].MathJax.elementJax) continue; - scripts[i].parentNode.insertBefore(this.EmExSpan.cloneNode(true),scripts[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++) { - if (!scripts[i].parentNode) continue; - var jax = scripts[i].MathJax.elementJax; - if (!jax) continue; + 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 = scripts[i].previousSibling; + 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) { - scale = (this.config.matchFontHeight && mex > 1 ? ex/mex : 1); + 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; @@ -414,8 +415,9 @@ // Remove markers // for (i = 0, m = scripts.length; i < m; i++) { - if (scripts[i].parentNode && scripts[i].MathJax.elementJax) { - scripts[i].parentNode.removeChild(scripts[i].previousSibling); + script = scripts[i]; + if (script.parentNode && script.MathJax.elementJax) { + script.parentNode.removeChild(script.previousSibling); } } // @@ -438,6 +440,9 @@ 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); }, From c9766d4da88144ada77dd1e48187f464d194533f Mon Sep 17 00:00:00 2001 From: "Davide P. Cervone" Date: Wed, 2 Oct 2013 06:27:28 -0400 Subject: [PATCH 6/9] Remove debugging message --- unpacked/MathJax.js | 1 - 1 file changed, 1 deletion(-) diff --git a/unpacked/MathJax.js b/unpacked/MathJax.js index 3e16e250c..a10c189b6 100644 --- a/unpacked/MathJax.js +++ b/unpacked/MathJax.js @@ -1910,7 +1910,6 @@ MathJax.Hub = { takeAction: function (action,element,callback) { var ec = this.elementCallback(element,callback); -console.log(element); var queue = MathJax.Callback.Queue(["Clear",this.signal]); for (var i = 0, m = ec.elements.length; i < m; i++) { if (ec.elements[i]) { From 2755cbd037842fd09fa15e4fec2e5f83865f7d8a Mon Sep 17 00:00:00 2001 From: "Davide P. Cervone" Date: Sat, 5 Oct 2013 08:21:53 -0400 Subject: [PATCH 7/9] Make web font loop into an extension (first draft) --- unpacked/MathJax.js | 4 - unpacked/jax/output/HTML-CSS/config.js | 4 - unpacked/jax/output/HTML-CSS/jax.js | 61 ------------- unpacked/jax/output/NativeMML/config.js | 4 - unpacked/jax/output/NativeMML/jax.js | 109 ------------------------ 5 files changed, 182 deletions(-) diff --git a/unpacked/MathJax.js b/unpacked/MathJax.js index a10c189b6..d25b2933e 100644 --- a/unpacked/MathJax.js +++ b/unpacked/MathJax.js @@ -1741,10 +1741,6 @@ MathJax.Hub = { showMathMenuMSIE: true, // separtely determine if MSIE should have math menu // (since the code for that is a bit delicate) - matchWebFonts: false, // true means look for web fonts that may cause changes in the - // scaling factors for the math (off by default since it - // uses a loop every time math is rendered). - menuSettings: { zoom: "None", // when to do MathZoom CTRL: false, // require CTRL for MathZoom? diff --git a/unpacked/jax/output/HTML-CSS/config.js b/unpacked/jax/output/HTML-CSS/config.js index 6930ba189..a1822c2a5 100644 --- a/unpacked/jax/output/HTML-CSS/config.js +++ b/unpacked/jax/output/HTML-CSS/config.js @@ -44,10 +44,6 @@ MathJax.OutputJax["HTML-CSS"] = MathJax.OutputJax({ undefinedFamily: "STIXGeneral,'Arial Unicode MS',serif", // fonts to use for unknown unicode characters mtextFontInherit: false, // to make be in page font rather than MathJax font - fontCheckDelay: 500, // initial delay for the first check for web fonts - // (set to null to prevent the checks) - fontCheckTimeout: 15 * 1000, // how long to keep looking for font changes (15 seconds) - EqnChunk: (MathJax.Hub.Browser.isMobile ? 10: 50), // number of equations to process before showing them EqnChunkFactor: 1.5, // chunk size is multiplied by this after each chunk diff --git a/unpacked/jax/output/HTML-CSS/jax.js b/unpacked/jax/output/HTML-CSS/jax.js index a0b611e8d..762e4841d 100644 --- a/unpacked/jax/output/HTML-CSS/jax.js +++ b/unpacked/jax/output/HTML-CSS/jax.js @@ -627,16 +627,6 @@ postTranslate: function (state,partial) { var scripts = state.jax[this.id]; - if (!partial && HUB.config.matchWebFonts && 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]], - this.config.fontCheckDelay,this.config.fontCheckTimeout); - - } if (!this.hideProcessedMath) return; // // Reveal this chunk of math @@ -671,57 +661,6 @@ state.HTMLCSSlast = state.HTMLCSSeqn; }, - checkFonts: function (check,scripts) { - if (check.time(function () {})) return; - var size = [], i, m; - // - // 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"); - // - // Check if ex or mex has changed - // - var test = script.previousSibling, div = test.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 - // - 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) {MathJax.Hub.Queue(["Rerender",MathJax.Hub,[size],{}])} - // - // Try again later - // - setTimeout(check,check.delay); - }, - getJaxFromMath: function (math) { if (math.parentNode.className === "MathJax_Display") {math = math.parentNode} do {math = math.nextSibling} while (math && math.nodeName.toLowerCase() !== "script"); diff --git a/unpacked/jax/output/NativeMML/config.js b/unpacked/jax/output/NativeMML/config.js index 6720e7237..3206d4141 100644 --- a/unpacked/jax/output/NativeMML/config.js +++ b/unpacked/jax/output/NativeMML/config.js @@ -37,10 +37,6 @@ MathJax.OutputJax.NativeMML = MathJax.OutputJax({ minScaleAdjust: 50, // minimum scaling to adjust to surrounding text // (since the code for that is a bit delicate) - fontCheckDelay: 500, // initial delay for the first width check for web fonts - // (set to null to prevent the width checks) - fontCheckTimeout: 15 * 1000, // how long to keep looking for width changes (15 seconds) - styles: { "DIV.MathJax_MathML": { "text-align": "center", diff --git a/unpacked/jax/output/NativeMML/jax.js b/unpacked/jax/output/NativeMML/jax.js index 7f41c8b78..b7f6bb8b7 100644 --- a/unpacked/jax/output/NativeMML/jax.js +++ b/unpacked/jax/output/NativeMML/jax.js @@ -327,15 +327,6 @@ }, postTranslate: function (state) { - if (!isMSIE && HUB.config.matchWebFonts) { - // - // 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]], - this.config.fontCheckDelay,this.config.fontCheckTimeout); - } if (this.forceReflow) { // // Firefox messes up some mtable's when they are dynamically created @@ -346,106 +337,6 @@ } }, - // - // 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 (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); - }, - // // Remove MathML preceeding the script // From 81ed447228554fadbec50323fa8427f0d16078ae Mon Sep 17 00:00:00 2001 From: "Davide P. Cervone" Date: Mon, 7 Oct 2013 06:52:19 -0400 Subject: [PATCH 8/9] Add the MatchWebFonts.js extension file --- unpacked/extensions/MatchWebFonts.js | 309 +++++++++++++++++++++++++++ 1 file changed, 309 insertions(+) create mode 100644 unpacked/extensions/MatchWebFonts.js diff --git a/unpacked/extensions/MatchWebFonts.js b/unpacked/extensions/MatchWebFonts.js new file mode 100644 index 000000000..3d98572af --- /dev/null +++ b/unpacked/extensions/MatchWebFonts.js @@ -0,0 +1,309 @@ +/* -*- 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 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.2"; + + 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) + }); + + var MATCH = 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; + var span = document.getElementById(jax.inputID+"-Frame"); + // + // 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 + // + 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 (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; + var span = document.getElementById(jax.inputID+"-Frame"); + // + // 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; em = this.defaultEm} + if (ex !== jax.SVG.ex) {size.push(script); scripts[i] = {}} + } + // + // 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); + } + } + // + // 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 (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("MathWebFont Extension Ready"); + AJAX.loadComplete("[MathJax]/extensions/MatchWebFonts.js"); + +})(MathJax.Hub,MathJax.Ajax); From 8599abbc4ca246d60ce47b42c0cee7a910ac002f Mon Sep 17 00:00:00 2001 From: "Davide P. Cervone" Date: Mon, 7 Oct 2013 07:30:57 -0400 Subject: [PATCH 9/9] Mark the postTranslate call that does chunk updates as a partial one --- unpacked/jax/output/SVG/jax.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/unpacked/jax/output/SVG/jax.js b/unpacked/jax/output/SVG/jax.js index 6f0531c37..1d5366a6b 100644 --- a/unpacked/jax/output/SVG/jax.js +++ b/unpacked/jax/output/SVG/jax.js @@ -319,14 +319,14 @@ // state.SVGeqn += (state.i - state.SVGi); state.SVGi = state.i; if (state.SVGeqn >= state.SVGlast + state.SVGchunk) { - this.postTranslate(state); + this.postTranslate(state,true); state.SVGchunk = Math.floor(state.SVGchunk*this.config.EqnChunkFactor); state.SVGdelay = true; // delay if there are more scripts } } }, - postTranslate: function (state) { + postTranslate: function (state,partial) { var scripts = state.jax[this.id]; if (!this.hideProcessedMath) return; //