bbfy: BBCode in the Age of JavaScript

By: on February 3, 2016

Some readers might remember BBCode, a dated HTML-like syntax that enables users of forums to apply markup to their posts while minimising the danger of injecting malicious content into the whole website.

(note: modern HTML doesn’t use these tags, anymore)

While ubiquitous back in the early noughties, it has become a rare sight these days. WYSIWYG editing components have become the norm and powerful back-end processing can easily pre-process permitted subsets of HTML. However, some unique advantages of BBCode remain, and with heavy computations returning back to the browser thanks to advancements in the compilation of JavaScript, it was only a question of time till BBCode had to make its comeback in one of our customer’s projects.

The existing platform works like this:

  • The back-end only stores messages without any parsing or other processing
  • All markup transformations have to be performed client-side, in web browsers and iOS
  • Encountered HTML is automatically quoted and not processed as markup
  • The way messages are stored does not allow for retroactive augmentation

The requirements were as follows:

  • Users must be able to use a WYSIWYG editor to apply markup
  • Existing messages must continue to be displayed as before
  • Notifications must be stripped off all BBCode, since they don’t support any markup

After a short time of consideration, we decided BBCode was the ideal solution to our problem: Existing messages would not be affected in case they contained HTML tags, we would not have to invent a proprietary solution without existing tools and on top of all that, experienced users of the platform would be able to exploit BBCode’s easy syntax to write complex markup faster than with any WYSIWYG component.

To our surprise, there was no such component for iOS, and for JavaScript we found that ckeditor supports BBCode both for input and output through a supplied plug-in. However, we also needed to transform BBCode to HTML outside the editing widget, which ckeditor unfortunately doesn’t support. Existing libraries for JavaScript were evaluated but all of them had issues: Either they were only providing a global object, making it impossible to support two different sets of conversion rules for the notifications, or they were naively relying on the browser to clean up messy tags.

Messy tags come in many variations, with different possible solutions – none of them being perfect. Consider this chunk of messed-up BBCode:

If we naively convert the opening and closing BBCode tags to corresponding HTML, we might end up with something like this:

What is a modern web browser going to do with this? You’ll be surprised.

Oops. The b and i tags have automatically been closed, but only at the end of the website body – the next post, here enclosed in another div, has been wrapped by the markup, as well. Clearly, this is completely undesirable. Also, not being able to predict what’s in between opening and closing tags means that the possibilities for transforming content are limited. For instance, adding custom tags which URL-encode the enclosed text.

At this point, just looking for opening and closing tags independently from each other is not good enough, anymore. A BBCode-enriched text has to be parsed as a context-free language, and handling unbalanced tags adds complexity that can become especially unpleasant once the parsing has to be done in each client.

To solve these problems once and for all, bbfy was written. bbfy is a runtime-independent JavaScript library that handles unbalanced BBCode tags gracefully and yet efficiently enough for client execution. For the example above, BBCode parses the broken code as

by keeping track of opened tags and closing them implicitly if not done correctly in the input string. That way, every input can ultimately be re-read as a correct BBCode string and each chunk transformed accordingly. We decided to make bbfy available to the general public under the Apache 2.0 license as an npm package. You can also test bbfy in your browser before installing it.

Share

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*