How to Get TypeKit to Working Inside TinyMCE
Monday, 2nd April 2012, 20:36
TinyMCE is the best WYSIWYG editor for web browser on the internet, but it isn't without it's quirks. However nothing else I've looked at comes close, and the plugin system is very handy for adding your own functionality.
Actually, most of its drawbacks seem unfair to pin on the editor itself, because ultimately it is limited by the technology of the web browser, so to achieve what it manages with as much cross-browser compatibility as it does is no small feat.
One thing that it doesn't directly manage is a direct result of the fact it uses an IFRAME to show the content. If you are using TypeKit to make your web fonts look a little more special than Georgia, these won't show up in the IFRAME in various browsers, Firefox included.
But after much playing around, I found a way to manage it that works. And here I share it with you, so WYSIWYG for fellow TypeKit users will genuinely be WYSIWYG. And if it isn't then you screwed up your TinyMCE style sheet. :p
The first thing I did was find working async code for TypeKit, which I found on the official TypeKit Blog. Once I'd got hold of that, it was just a matter of working out that could best be injected into the dynamically created IFRAME.
Trawling through the API documentation, and with a bit of playing with Firebug, I narrowed things down to the onPreInit editor event. I actually tried adding the non-async script tags inside a function called during that event, but it didn't work. However the async code worked fine, which means yes it looks a bit messy because the script is created in a variable before being injected.
Anyway, to use it, just make sure you change kitId to your TypeKit kit ID for the site you are using it on:
tinyMCE.init({
// General options
mode : "textareas",
theme : "advanced",
// Setup function
setup: function(ed) {
// Add TypeKit script to the iframe header
ed.onPreInit.add(function(ed) {
// Get the DOM document object for the IFRAME
var doc = ed.getDoc();
// Create the script we will add to the header asynchronously
var jscript = "var TypekitConfig = {\n\
kitId: 'abcdefghijk'\n\
};\n\
(function() {\n\
var tk = document.createElement('script');\n\
tk.src = '//use.typekit.com/' + TypekitConfig.kitId + '.js';\n\
tk.type = 'text/javascript';\n\
tk.async = 'true';\n\
tk.onload = tk.onreadystatechange = function() {\n\
var rs = this.readyState;\n\
if (rs && rs != 'complete' && rs != 'loaded') return;\n\
try { Typekit.load(TypekitConfig); } catch (e) {}\n\
};\n\
var s = document.getElementsByTagName('script')[0];\n\
s.parentNode.insertBefore(tk, s);\n\
})();";
// Create a script element and insert the TypeKit code into it
var script = doc.createElement("script");
script.type = "text/javascript";
script.appendChild(doc.createTextNode(jscript));
// Add the script to the header
doc.getElementsByTagName("head")[0].appendChild(script);
});
}
});