Fix multiple problems with zoom box sizing and position in IE (various emulation and document modes) and firefox. (Resolves issues #151, #88, and #59.)

This commit is contained in:
Davide P. Cervone 2011-07-31 15:17:44 -04:00
parent bb154cabcd
commit f27e16ef0a
10 changed files with 107 additions and 51 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -23,7 +23,7 @@
*/ */
(function (HUB,HTML,AJAX,HTMLCSS,nMML) { (function (HUB,HTML,AJAX,HTMLCSS,nMML) {
var VERSION = "1.1.2"; var VERSION = "1.1.3";
var CONFIG = HUB.CombineConfig("MathZoom",{ var CONFIG = HUB.CombineConfig("MathZoom",{
delay: 400, // mouse must be still this long (milliseconds) delay: 400, // mouse must be still this long (milliseconds)
@ -181,30 +181,30 @@
if (this.msieZIndexBug) { if (this.msieZIndexBug) {
// MSIE doesn't do z-index properly, so move the div to the document.body, // MSIE doesn't do z-index properly, so move the div to the document.body,
// and use an empty span as a tracker for the usual position // and use an empty span as a tracker for the usual position
var tracker = HTML.Element("img",{ var tracker = HTML.addElement(document.body,"img",{
src:"about:blank", id:"MathJax_ZoomTracker", src:"about:blank", id:"MathJax_ZoomTracker", width: 0, height: 0,
style:{width:0, height:0, position:"relative"} style:{width:0, height:0, position:"relative"}
}); });
document.body.appendChild(div); div.style.position = "relative";
div.style.position = "absolute";
div.style.zIndex = CONFIG.styles["#MathJax_ZoomOverlay"]["z-index"]; div.style.zIndex = CONFIG.styles["#MathJax_ZoomOverlay"]["z-index"];
div = tracker; div = tracker;
} }
var bbox = (this["Zoom"+JAX])(root,span,math);
var bbox = (this["Zoom"+JAX])(root,span,math,Mw,Mh);
//
// Fix up size and position for browsers with bugs (IE)
//
if (this.msiePositionBug) { if (this.msiePositionBug) {
if (this.msieIE8Bug) { if (this.msieSizeBug)
// IE8 gets height completely wrong {zoom.style.height = bbox.zH+"px"; zoom.style.width = bbox.zW+"px"} // IE8 gets the dimensions completely wrong
span.style.position = "absolute"; zoom.style.height = span.offsetHeight; span.style.position = ""; if (zoom.offsetHeight > Mh) {zoom.style.height = Mh+"px"} // IE doesn't do max-height?
if (zoom.offsetHeight <= Mh && zoom.offsetWidth <= Mw) {zoom.style.overflow = "visible"} if (zoom.offsetWidth > Mw) {zoom.style.width = Mw+"px"}
}
if (this.msieWidthBug) {zoom.style.width = Math.min(Mw,bbox.w)}
else if (bbox.w > Mw) {zoom.style.width = Mw}
if (zoom.offsetHeight > Mh) {zoom.style.Height = Mh+"px"} // IE doesn't do max-height?
if (math.nextSibling) {math.parentNode.insertBefore(div,math.nextSibling)} if (math.nextSibling) {math.parentNode.insertBefore(div,math.nextSibling)}
else {parent.appendChild(div)} // needs to be after to be above? else {parent.appendChild(div)} // needs to be after to be above?
} else if (this.operaPositionBug) {
zoom.style.width = Math.min(Mw,span.offsetWidth)+"px"; // gets width as 0?
} }
if (this.operaPositionBug) {zoom.style.width = Math.min(Mw,bbox.zW)+"px"} // Opera gets width as 0?
if (zoom.offsetWidth <= Mw && zoom.offsetHeight <= Mh) {zoom.style.overflow = "visible"}
this.Position(zoom,bbox,(JAX === "MathML" && parent.nodeName.toLowerCase() === "div")); this.Position(zoom,bbox,(JAX === "MathML" && parent.nodeName.toLowerCase() === "div"));
zoom.style.visibility = ""; zoom.style.visibility = "";
@ -225,7 +225,10 @@
// //
// Handle the jax-specific output // Handle the jax-specific output
// //
ZoomHTMLCSS: function (root,span,math) { ZoomHTMLCSS: function (root,span,math,Mw,Mh) {
//
// Re-render at larger size
//
span.className = "MathJax"; span.className = "MathJax";
HTMLCSS.idPostfix = "-zoom"; HTMLCSS.idPostfix = "-zoom";
HTMLCSS.getScales(span,span); HTMLCSS.getScales(span,span);
@ -235,35 +238,85 @@
if (bbox.width) { if (bbox.width) {
// Handle full-width displayed equations // Handle full-width displayed equations
// FIXME: this is a hack for now // FIXME: this is a hack for now
var Mw = Math.floor(.85*document.body.clientWidth); span.style.width = Math.floor(Mw-1.5*HTMLCSS.em)+"px"; span.style.display="inline-block";
span.style.width = Mw+"px"; span.style.display="inline-block";
var id = (root.id||"MathJax-Span-"+root.spanID)+"-zoom"; var id = (root.id||"MathJax-Span-"+root.spanID)+"-zoom";
var child = document.getElementById(id).firstChild; var child = document.getElementById(id).firstChild;
while (child && child.style.width !== bbox.width) {child = child.nextSibling} while (child && child.style.width !== bbox.width) {child = child.nextSibling}
if (child) {child.style.width = "100%"} if (child) {child.style.width = "100%"}
} }
span.appendChild(this.topImg); var top = this.topImg.offsetTop; span.removeChild(this.topImg); //
var W = (this.msieWidthBug ? HTMLCSS.getW(math)*HTMLCSS.em : math.offsetWidth); // Get height and width of zoomed math and original math
return {w:bbox.w*HTMLCSS.em, Y:-top, W:W}; //
span.style.position = math.style.position = "absolute";
var zW = span.offsetWidth, zH = span.offsetHeight,
mH = math.offsetHeight, mW = math.offsetWidth;
span.style.position = math.style.position = "";
if (mW === 0) {mW = math.offseWidth || math.parentNode.offsetWidth}; // IE7 gets mW == 0?
//
return {Y:-this.getTop(root,span,math,this.msieTopBug,this.msieBorderBug,false),
mW:mW, mH:mH, zW:zW, zH:zH};
}, },
ZoomMathML: function (root,span,math) { ZoomMathML: function (root,span,math) {
root.toNativeMML(span,span); root.toNativeMML(span,span);
if (!this.msiePositionBug) {math.previousSibling.style.display = "inline"} var top = this.getTop(root,span,math,this.msieTopMMLBug,false,this.ffMMLdisplayBug);
var node = (this.ffMMLwidthBug ? math.parentNode : math); var mW = math.offsetWidth || math.scrollWidth,
var h = (math.parentNode.nodeName.toLowerCase() === "div" ? span : span.parentNode).offsetHeight; mH = math.offsetHeight || math.scrollHeight;
var W = node.offsetWidth, H = node.offsetHeight; if (this.msieIE8HeightBug) {span.style.position = "absolute"}
return {w:span.offsetWidth, Y:Math.floor((H-h)/2), W:W} var zW = span.offsetWidth, zH = span.offsetHeight;
if (this.msieIE8HeightBug) {span.style.position = ""}
if (this.ffMMLdisplayBug) {
// Force width in FF, since it gets the math element width wrong
span.style.display="inline-block";
span.style.width = zW+"px";
}
return {Y:-top, mW:mW, mH:mH, zW:zW, zH:zH}
},
//
// Get top offset from baseline
//
getTop: function (root,span,math,topBug,borderBug,mmlBug) {
span.appendChild(this.topImg);
if (mmlBug && math.getAttribute("display") === "block") {
// FF breaks between the display math and the image, so
// convert display to inline with displaystyle true
math.setAttribute("display","inline"); math.MJinline = true;
var mstyle = root.NativeMMLelement("mstyle");
while (math.firstChild) {mstyle.appendChild(math.firstChild)}
math.appendChild(mstyle); mstyle.setAttribute("displaystyle","true");
}
if (math.MJinline) {
// FF breaks between the display math and the image, so
// convert display to inline with displaystyle true
span.insertBefore(this.topImg,span.firstChild);
var zmath = span.childNodes[1], zstyle = root.NativeMMLelement("mstyle");
zmath.setAttribute("display","inline");
while (zmath.firstChild) {zstyle.appendChild(zmath.firstChild)}
zmath.appendChild(zstyle); zstyle.setAttribute("displaystyle","true");
zstyle.setAttribute("displaystyle","true");
}
var top = this.topImg.offsetTop;
if (topBug) {
// For IE, frame is not at the baseline, so remove extra height
var wrap = math.parentNode.style.whiteSpace;
math.parentNode.style.whiteSpace = "nowrap";
math.parentNode.insertBefore(this.topImg,math);
top -= this.topImg.offsetTop - span.parentNode.parentNode.offsetTop;
math.parentNode.style.whiteSpace = wrap;
}
if (borderBug) {top += Math.floor(.5*HTMLCSS.em)} // adjust for zoom box padding
this.topImg.parentNode.removeChild(this.topImg);
return top;
}, },
// //
// Set the position of the zoom box and overlay // Set the position of the zoom box and overlay
// //
Position: function (zoom,bbox,MMLdisplay) { Position: function (zoom,bbox,MMLdisplay) {
var XY = this.Resize(), x = XY.x, y = XY.y, W = bbox.W; var XY = this.Resize(), x = XY.x, y = XY.y, W = bbox.mW;
if (this.msiePositionBug) {W = -W} if (this.msieIE8Bug) {W = -W}
if (MMLdisplay && this.ffMMLcenterBug) {W = 0}
var dx = -Math.floor((zoom.offsetWidth-W)/2), dy = bbox.Y; var dx = -Math.floor((zoom.offsetWidth-W)/2), dy = bbox.Y;
zoom.style.left = Math.max(dx,20-x)+"px"; zoom.style.top = Math.max(dy,20-y)+"px"; zoom.style.left = Math.max(dx,10-x)+"px"; zoom.style.top = Math.max(dy,10-y)+"px";
}, },
// //
@ -272,15 +325,13 @@
Resize: function (event) { Resize: function (event) {
if (ZOOM.onresize) {ZOOM.onresize(event)} if (ZOOM.onresize) {ZOOM.onresize(event)}
var x = 0, y = 0, var x = 0, y = 0,
div = document.getElementById("MathJax_ZoomFrame"), div = document.getElementById("MathJax_ZoomFrame"), obj = div,
overlay = document.getElementById("MathJax_ZoomOverlay"); overlay = document.getElementById("MathJax_ZoomOverlay");
var obj = (ZOOM.msieZIndexBug ? document.getElementById("MathJax_ZoomTracker") : div);
if (ZOOM.operaPositionBug) {div.style.border = "1px solid"} // to get vertical position right if (ZOOM.operaPositionBug) {div.style.border = "1px solid"} // to get vertical position right
if (obj.offsetParent) { if (obj.offsetParent) {
do {x += obj.offsetLeft; y += obj.offsetTop} while (obj = obj.offsetParent); do {x += obj.offsetLeft; y += obj.offsetTop} while (obj = obj.offsetParent);
} }
if (ZOOM.operaPositionBug) {div.style.border = ""} if (ZOOM.operaPositionBug) {div.style.border = ""}
if (ZOOM.msieZIndexBug) {div.style.left = x+"px"; div.style.top = y+"px"}
overlay.style.left = (-x)+"px"; overlay.style.top = (-y)+"px"; overlay.style.left = (-x)+"px"; overlay.style.top = (-y)+"px";
if (ZOOM.msiePositionBug) {setTimeout(ZOOM.SetWH,0)} else {ZOOM.SetWH()} if (ZOOM.msiePositionBug) {setTimeout(ZOOM.SetWH,0)} else {ZOOM.SetWH()}
return {x:x, y:y}; return {x:x, y:y};
@ -374,10 +425,16 @@
MSIE: function (browser) { MSIE: function (browser) {
var quirks = (document.compatMode === "BackCompat"); var quirks = (document.compatMode === "BackCompat");
var isIE8 = browser.versionAtLeast("8.0") && document.documentMode > 7; var isIE8 = browser.versionAtLeast("8.0") && document.documentMode > 7;
ZOOM.msiePositionBug = true; var isIE9 = document.documentMode >= 9;
ZOOM.msieWidthBug = !quirks; ZOOM.msiePositionBug = !isIE9;
ZOOM.msieIE8Bug = isIE8; ZOOM.msieSizeBug = browser.versionAtLeast("7.0") &&
(!document.documentMode || document.documentMode === 7 || document.documentMode === 8);
ZOOM.msieIE8Bug = isIE8 && (document.documentMode === 8);
ZOOM.msieIE8HeightBug = (document.documentMode === 8);
ZOOM.msieZIndexBug = !isIE8; ZOOM.msieZIndexBug = !isIE8;
ZOOM.msieTopBug = (!browser.versionAtLeast("8.0") || document.documentMode === 7);
ZOOM.msieTopMMLBug = ZOOM.msieTopBug || (!isIE8 || document.documentMode >= 9);
ZOOM.msieBorderBug = quirks && browser.versionAtLeast("8.0");
ZOOM.msieInlineBlockAlignBug = (!isIE8 || quirks); ZOOM.msieInlineBlockAlignBug = (!isIE8 || quirks);
if (document.documentMode >= 9) {delete CONFIG.styles["#MathJax_Zoom"].filter} if (document.documentMode >= 9) {delete CONFIG.styles["#MathJax_Zoom"].filter}
}, },
@ -388,16 +445,15 @@
}, },
Firefox: function (browser) { Firefox: function (browser) {
ZOOM.ffMMLwidthBug = true; ZOOM.ffMMLdisplayBug = true;
ZOOM.ffMMLcenterBug = true;
} }
}); });
ZOOM.topImg = (ZOOM.msieInlineBlockAlignBug ? ZOOM.topImg = (ZOOM.msieInlineBlockAlignBug ?
HTML.Element("img",{style:{width:0,height:0},src:"about:blank"}) : HTML.Element("img",{style:{width:0,height:0,position:"relative"},src:"about:blank"}) :
HTML.Element("span",{style:{width:0,height:0,display:"inline-block"}}) HTML.Element("span",{style:{width:0,height:0,display:"inline-block"}})
); );
if (ZOOM.operaPositionBug) {ZOOM.topImg.style.border="1px solid"} if (ZOOM.operaPositionBug || ZOOM.msieTopBug) {ZOOM.topImg.style.border="1px solid"}
/*************************************************************/ /*************************************************************/