WordPress 3.3 introduced wp_editor()
. It’s a big improvement over the earlier hacks needed to get a TinyMCE instance on the WP front end. But it broke the feature in my BuddyPress Docs that detected idle time. The problem, in short, was two-fold: my idle-detection JavaScript was loading before the editor was initialized, and it wasn’t detecting key presses inside of the TinyMCE iframe. The solution to both parts of the problem required passing callbacks to the TinyMCE initialization array, in the setup
array. It took me a long time to figure out how to do this, so for posterity’s sake, here are some takeaways.
First, the code:
[code language=”php”]
function bp_docs_add_idle_function_to_tinymce( $initArray ) {
if ( bp_docs_is_bp_docs_page() ) {
$initArray[‘setup’] = ‘function(ed) {
ed.onInit.add(
function(ed) {
_initJQuery();
// Set up listeners
jQuery(‘#’ + ed.id + ‘_parent’).bind(‘mousemove’,function (evt){
_active(evt);
});
bp_docs_load_idle();
}
);
ed.onKeyDown.add(
function(ed) {
_active();
}
);
}’;
}
return $initArray;
}
add_filter( ‘tiny_mce_before_init’, ‘bp_docs_add_idle_function_to_tinymce’ );
[/code]
Some notes:
- I’m passing a ‘setup’ parameter to the TinyMCE init array by filtering
tiny_mce_before_init
- Only do this when you’re editing a BuddyPress Doc – that’s the
bp_docs_is_bp_docs_page()
check. I don’t want to mess with every instance of TinyMCE on the installation. - The
setup
parameter has to be a string. This gets tricky when the string is supposed to define an unnamed JS callback, because you have to be very careful about escaping quotes. As a string, your callback has to be wrapped in quotes. Also, when WP prints the TinyMCE parameters (and when it sees that your paramater begins with the string ‘function’) it’s going to wrap it in double-quotes. After lots of messing around, I was able to get this to work by using escaped single-quotes. (If you need to double-embed quotes – like a chain of callbacks – use escaped double-quotes.) - Where possible, use TinyMCE’s native events.
ed.onKeyDown
is one of them. It allows me to call my_active()
function whenever a key is pressed inside the editor. - There are some kinds of actions that aren’t really detectable using TinyMCE’s events. For instance, I wanted to be able to detect when someone was moving their mouse around the iframe and especially TinyMCE’s toolbar. You can see this where I’m binding my callback to
mousemove
in the TinyMCE_parent
element. _initJQuery()
andbp_docs_load_idle()
are my own functions that need to run after the editor has finished setting up. That’s why they, along with thebind
, are called in a callback ofed.onInit
– that’s the generic place to put things that need to happen once the editor is up and running.
This came in handy today and it is still working in WP 3.7.