Hello,
I am working on a MathJax TinyMCE plugin and am having some trouble
getting it working in IE. The purpose of the plug-in is to display
typeset math in the design view of the editor. So there are two
conversions - one to convert MathML into typeset math (MathML in FF,
otherwise HTML+CSS) to be displayed in the editor, and the other to
convert back to the original math when extracting the content from the
editor.
In the plug-in, MathJax is loaded dynamically into tinyMCE's iFrame
and used to typeset the math in a temp node, and then the typeset math
is subsequently swapped into the editor. The tyepset math is wrapped
in a div and the original math is stored encoded in a data attribute
for future retrieval of the editor's HTML.
The plug-in successfully displays typeset math in both FF and Chrome.
In IE, the math is typeset and added to the editor's DOM (as I can see
it if I inspect the DOM), but is is not displayed. It seems like some
problem with styles/css, but I am not sure. This could also be
tinyMCE related. I am hoping that someone can take a look and perhaps
have some suggestion to get displaying in IE.
Thanks in advance!
John
Here's the plug-in code:
(function() {
var each = tinymce.each;
tinymce.create( 'tinymce.plugins.AcmeMathPlugin', {
/**
* Initializes the plugin, this will be executed after the plugin
has been created.
* @param {tinymce.Editor} ed Editor instance that the plugin is
initialized in.
* @param {string} url Absolute URL to where the plugin is located.
*/
init : function( ed, url ) {
var me = this;
me.editor = ed;
me.url = url;
me.mathTypesets;
me.mathIndex = 0;
ed.onPreInit.add( function( ed ) {
me.dom = ed.dom;
me.doc = ed.getDoc();
me._initializeMathJax();
} );
// dispatched when plugin initializes
ed.onInit.add( function() {
ed.dom.loadCSS( url + "/css/acme_math.css" );
});
// Note: "o" is a JavaScript object containing details, including
the content
// dispatched before content inserted into editor (ex. when closing
HTML source dialog)
ed.onBeforeSetContent.add( function( ed, o ) {
me._convertToTypesetPlaceholder( ed, o );
});
// dispatched after content inserted into editor (ex. when closing
HTML source dialog)
ed.onSetContent.add( function( ed, o ) {
me._convertToTypesetMath( ed, o );
} );
// dispatched when getting content from editor (ex. when opening
HTML source dialog)
ed.onPostProcess.add( function( ed, o ) {
me._convertToRawMath( ed, o );
} );
},
_convertToTypesetPlaceholder : function( ed, o ) {
var me = this;
me.mathTypesets = [];
var replaceMath = function( match ) {
me.mathIndex += 1;
var mathId = 'acme_math_' + me.mathIndex;
var tempNode = me.doc.createElement( 'div' );
tempNode.innerHTML = match;
MathJax.Hub.Queue( ["Typeset", MathJax.Hub, tempNode] );
MathJax.Hub.Queue( function() {
if ( tempNode.childNodes.length > 1 ) {
// remove the script element - we're only interested in the
typeset HTML
tempNode.removeChild( tempNode.childNodes[1] );
// store typeset HTML so that is can replace placeholder in
editor body later
me.mathTypesets.push( { id : mathId, html : tempNode.innerHTML,
math : match } );
}
} );
return '<span id="' + mathId + '" style="display:none;">Temp</
span>';
};
// replace math elements with a placeholder (but do not replace if
MathJax output was MathML... i.e. FF)
if ( o.content.indexOf( 'class="MathJax_MathML"' ) == -1 ) {
o.content = o.content.replace( /<math[^>]*>(.|\n|\r)*?<\/math>/gi,
replaceMath );
}
},
_convertToTypesetMath : function( ed, o ) {
var me = this;
var content = o.content;
MathJax.Hub.Queue( function() {
if ( me.mathTypesets == null || me.mathTypesets.length == 0 ) {
return;
}
// replace placeholder with the typset math, store the original
math in a data attribute
var tempContent = content;
for( var i=0; i<me.mathTypesets.length; i++ ) {
var regExp = new RegExp( '<span id="' + me.mathTypesets[i].id +
'"(.|\n|\r)*?</span>' );
tempContent = tempContent.replace( regExp, '<div class="acme-math-
p" data-acme-math="' + encodeURIComponent( me.mathTypesets[i].math ) +
'" style="display:inline;"><!--MathStart-->' + me.mathTypesets[i].html
+ '<!--MathEnd--></div>' );
}
// call back to tinymce to update the revised content
ed.setContent( tempContent );
} );
},
_convertToRawMath : function( ed, o ) {
var me = this;
if ( o.get ) {
var replaceMath = function( match ) {
// exract the original math from the data attribute
var startIndex = match.indexOf( 'data-acme-math="' );
if ( startIndex != -1 ) {
startIndex += 15;
var endIndex = match.indexOf( '"', startIndex );
return decodeURIComponent( match.substring( startIndex,
endIndex ) );
}
return match;
};
// replace the type set math with the original math
var regExp = new RegExp( '<div class="acme-math-p"(.|\n|\r)*?<!--
MathEnd--></div>', 'g' );
o.content = o.content.replace( regExp, replaceMath );
return;
}
},
_initializeMathJax : function() {
var me = this;
var dom = me.dom;
var doc = me.doc;
var config = 'MathJax.Hub.Config({showProcessingMessages:
false});MathJax.Hub.Startup.onload();';
var onLoadScript = dom.create( 'script', {
type : "text/x-mathjax-config"
}, config );
var script = dom.create( 'script', {
type : 'text/javascript',
src : '/acme/common/mathjax/1.1a/MathJax.js?config=MML_HTMLorMML,/
acme/math/display/config.js'
} );
var head = doc.getElementsByTagName( 'head' )[0];
head.appendChild( onLoadScript );
head.appendChild( script );
},
/**
* Creates control instances based in the incomming name.
*/
createControl : function( n, cm ) {
return null;
},
/**
* Returns information about the plugin as a name/value array.
*/
getInfo : function() {
return {
longname : 'Acme Insert',
author : 'Acme Inc.',
authorurl : '
http://www.acme.com',
infourl : '
http://www.acme.com',
version : "1.0"
};
}
});
// Register plugin
tinymce.PluginManager.add( 'acme_math',
tinymce.plugins.AcmeMathPlugin );
})();
And here is the content of the css file loaded by the plug-in:
.MathJax_Display {text-align: center; margin: 1em 0em; position:
relative; display: block; width: 100%; zoom:1;}
.MathJax .merror {background-color: #FFFF88; color: #CC0000; border:
1px solid #CC0000; padding: 1px 3px; font-family: serif; font-style:
normal; font-size: 90%;}
.MathJax_Preview {color: #888888;}
#MathJax_Tooltip {background-color: InfoBackground; color: InfoText;
border: 1px solid black; box-shadow: 2px 2px 5px #AAAAAA; -webkit-box-
shadow: 2px 2px 5px #AAAAAA; -moz-box-shadow: 2px 2px 5px #AAAAAA; -
khtml-box-shadow: 2px 2px 5px #AAAAAA; filter:
progid:DXImageTransform.Microsoft.dropshadow(OffX=2, OffY=2,
Color='gray', Positive='true'); padding: 3px 4px; position: absolute;
left: 0; top: 0; width: auto; height: auto; display: none;}
.MathJax {display: inline; font-family: serif; font-style: normal;
font-weight: normal; line-height: normal; font-size: 100%; font-size-
adjust: none; text-indent: 0; text-align: left; text-transform: none;
letter-spacing: normal; word-spacing: normal; word-wrap: normal; white-
space: nowrap; float: none; direction: ltr; border: 0; padding: 0;
margin: 0;}
.MathJax img, .MathJax nobr, .MathJax a {border: 0; padding: 0;
margin: 0; max-width: none; max-height: none; vertical-align: 0; line-
height: normal; text-decoration: none}
img.MathJax_strut {border: 0 !important; padding: 0 !important;
margin: 0 !important; vertical-align: 0 !important;}
.MathJax span {display: inline; position: static; border: 0; padding:
0; margin: 0; vertical-align: 0; line-height: normal; text-decoration:
none;}
.MathJax nobr {white-space: nowrap;}
.MathJax img {display: inline ! important;}
.MathJax_Processing {visibility: hidden; position: fixed; width: 0;
height: 0; overflow: hidden;}
.MathJax .MathJax_HitBox {cursor: text;}
#MathJax_Tooltip * {filter: none; background: transparent;}
@font-face {font-family: MathJax_Main; src: url('/acme/common/mathjax/
1.1a/fonts/HTML-CSS/TeX/otf/MathJax_Main-Regular.otf');}
@font-face {font-family: MathJax_Main; src: url('/acme/common/mathjax/
1.1a/fonts/HTML-CSS/TeX/otf/MathJax_Main-Bold.otf'); font-weight:
bold;}
@font-face {font-family: MathJax_Main; src: url('/acme/common/mathjax/
1.1a/fonts/HTML-CSS/TeX/otf/MathJax_Main-Italic.otf'); font-style:
italic;}
@font-face {font-family: MathJax_Math; src: url('/acme/common/mathjax/
1.1a/fonts/HTML-CSS/TeX/otf/MathJax_Math-Italic.otf'); font-style:
italic;}
@font-face {font-family: MathJax_Caligraphic; src: url('/acme/common/
mathjax/1.1a/fonts/HTML-CSS/TeX/otf/MathJax_Caligraphic-
Regular.otf');}
@font-face {font-family: MathJax_Size1; src: url('/acme/common/mathjax/
1.1a/fonts/HTML-CSS/TeX/otf/MathJax_Size1-Regular.otf');}
@font-face {font-family: MathJax_Size2; src: url('/acme/common/mathjax/
1.1a/fonts/HTML-CSS/TeX/otf/MathJax_Size2-Regular.otf');}
@font-face {font-family: MathJax_Size3; src: url('/acme/common/mathjax/
1.1a/fonts/HTML-CSS/TeX/otf/MathJax_Size3-Regular.otf');}
@font-face {font-family: MathJax_Size4; src: url('/acme/common/mathjax/
1.1a/fonts/HTML-CSS/TeX/otf/MathJax_Size4-Regular.otf');}
#MathJax_getScales {font-family:
MathJax_Main,MathJax_Size1,MathJax_AMS;}
.MathJax .math span {font-family:
MathJax_Main,MathJax_Size1,MathJax_AMS;}