New Formatting Engine

January 25th, 2010 by Spocke

The new 3.3 version of TinyMCE comes with a new engine for applying formatting such as bold, italic, font size etc to the selected text. This is a powerful new feature that enables you to specify exactly what output you want when a user for example clicks the bold button. It also makes it a lot easier to add and use custom formats and it reduces the browser quirks.

Issues with execCommand

Most JavaScript rich text editors out there uses something called execCommand for applying formatting so did TinyMCE before this release. The problem with this approach is that each browser vendor has implemented this feature in there own way and most of the implementations are buggy. We have reported many of these bugs over the years but very few have been resolved, I guess it’s more fun to add 3d canvas support than fixing bugs.

We used to tackle these bugs by letting the browser execute the command then try to cleanup the mess that was produced. The problem with this approach is that it requires lots of ugly hacks and it’s also hard to handle all special cases. So we decided that something had to be done. If the browser vendors can’t do it then we have to do it for our self.

New options, new possibilities

We exposed the formatting engine though a new formats option. This option enables you to override the built in formats and also add custom ones. For example you can now change the output of bold and italic to produce spans with classes instead of the default strong and em. Check out the custom formats example for a live demo of these options.

tinyMCE.init({
  ...
  // Override internal formats
  formats : {
    bold : {inline : 'span', 'classes' : 'bold'},
    italic : {inline : 'span', 'classes' : 'italic'}
  },

  // Formats used in the styles dropdown
  style_formats : [
    {title : 'Bold text', inline : 'b'},
    {title : 'Red text', inline : 'span', styles : {color : '#ff0000'}}
  ]
});

New formatter engine API

The new formatter engine is fairly simple to use. All you need to do is register your custom format either by adding it to the formats option or by using the register function. Here is an example how to register a format and apply it to the current selection.

tinymce.activeEditor.formatter.register('mycustomformat', {
   inline : 'span',
   styles : {color : '#ff0000'}
});

tinymce.activeEditor.formatter.apply('mycustomformat');

Better HTML output

The new engine produces a lot better output than before since we are now merging styles to reduce the overall HTML output size. What this means is that when you apply for example a font size and color to a selected word we used to produce two spans like this:

<span style="font-size: medium;"><span style="color: #ff0000;">word</span>

The new engine is a lot smarter and will combine these two into one span:

<span style="font-size: medium; color: #ff0000;">word</span>

I will do the same for classes as well so using the bold and italic formats in the example above would produce:

<span class="bold italic">word</span>

This is just some simple example of what the engine handles when it comes to merging.

Posted in Work

8 Responses

  1. Pascal Says:

    is force_br_newlines broken with that update?

  2. Spocke Says:

    I don’t think so just tested it seems to work as before. If you think there is a bug file a bug report at sourceforge with steps for us to reproduce it an we will take a look at it.

  3. Pascal Says:

    force_br_newlines : true,
    forced_root_block : ”, // Needed for 3.x
    convert_urls : false,

    that is my config.

    i am getting div-tags

  4. Spocke Says:

    Use force_p_newlines : false as well. If you still have problems ask at the forums easier to track the issue there. Thanks.

  5. Silvio Sosio Says:

    One thing that would be useful, expecially in the case of classes applied to blocks: clear other classes already present. That is, change the class with the chosen one.
    And, a way to remove all the classes.
    S*

  6. Spocke Says:

    There is a way to set all the classes by specifying the class attribute in the attributes collection however been thinking that some times you want to clear specific classes and keep some of them and that is currently not possible styles can be cleared by setting them to an empty value.

    Thanks for the feedback.

  7. Silvio Sosio Says:

    Using the attribute works well, I think that this would cover 90% of real life cases, thank you very much!

  8. Pascal Says:

    I filed a bug at sourceforge.net

Leave a Comment

Please note: Comment moderation is enabled and may delay your comment. There is no need to resubmit your comment.