TinyMCE and the non-breaking space problem

Let’s get right to it then: TinyMCE is great, but I am annoyed by its willingness to take users’ multiple spaces literally! Collapsing multiple spaces is a basic characteristic of HTML, and allowing users to carelessly (or intentionally, which they still shouldn’t do) insert multiple spaces by converting every other one of those spaces into the   (non-breaking space) character is BAD!

IMHO.

Anyway… start with a pinch of Stack Overflow, add a dash of the official TinyMCE documentation, along with a heaping tablespoon of reading between the lines, and I have a working solution to the problem. My installation of TinyMCE now automatically converts any   characters in the text back into regular ol’ spaces.

It’s a bit draconian; after all there are legitimate uses for non-breaking spaces. But 95% of the times they’re inserted by TinyMCE are user accidents, and another 4.9% of those times are abuses like faked “tabs” that would be solved better by another approach altogether. (There are reasonable CSS-based solutions that work in some cases, but let’s talk HTML’s need for tabs another time.)

Anyway… here’s the gist of the solution. You need to create a callback function. Here’s mine:

function my_cleanup_callback(type,value) {
  switch (type) {
    case 'get_from_editor':
      // Remove   characters
      value = value.replace(/ /ig, ' ');
      break;
    case 'insert_to_editor':
    case 'submit_content':
    case 'get_from_editor_dom':
    case 'insert_to_editor_dom':
    case 'setup_content_dom':
    case 'submit_content_dom':
    default:
      break;
  }
  return value;
}

It may look like there’s a lot of extra stuff in here you don’t need; I included all possible values for type inside the switch to be prepared for the future. You do want to check for type == 'get_from_editor' though; otherwise your replace() is going to run under way too many conditions and may cause weird behavior like new paragraphs appearing when you just want to insert new text into an existing one, or browser-generated warnings about leaving the page when you try to save. (I ran into both as I was fine-tuning this.)

Now that you have your callback function, you just need to… you know… call it. That’s done inside tinyMCE.init(). You’ll need to include this line somewhere:

cleanup_callback: 'my_cleanup_callback',

Be sure to check if cleanup_callback is already declared somewhere, and also don’t forget the comma at the end, unless you’re inserting this as the last line.

Once you’ve got it all rolled out to your site, you’ll need to clear your cache. I’ve found TinyMCE’s configuration files can be annoyingly persistent in the browser cache.

Yes… you have correctly observed that I had to use non-breaking spaces myself in this post, to get the indents in the code samples to show. Pay no attention to the man behind the curtain. And remember my complaint about the lack of tab characters in HTML. Another day.