Added missing JSDoc
authorAlexander Ebert <ebert@woltlab.com>
Tue, 7 Jul 2015 17:40:55 +0000 (19:40 +0200)
committerAlexander Ebert <ebert@woltlab.com>
Tue, 7 Jul 2015 17:40:55 +0000 (19:40 +0200)
wcfsetup/install/files/js/WoltLab/WCF/BBCode/FromHtml.js
wcfsetup/install/files/js/WoltLab/WCF/BBCode/Parser.js
wcfsetup/install/files/js/WoltLab/WCF/BBCode/ToHtml.js

index f05b2bef0a7cb3fb84626f1457079c9d94f923f1..34c7ecbd94c281f1af32a4e63261ad070f4b8e5d 100644 (file)
@@ -1,3 +1,11 @@
+/**
+ * Converts a message containing HTML tags into BBCodes.
+ * 
+ * @author     Alexander Ebert
+ * @copyright  2001-2015 WoltLab GmbH
+ * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @module     WoltLab/WCF/BBCode/FromHtml
+ */
 define(['EventHandler', 'StringUtil', 'DOM/Traverse'], function(EventHandler, StringUtil, DOMTraverse) {
        "use strict";
        
@@ -5,6 +13,13 @@ define(['EventHandler', 'StringUtil', 'DOM/Traverse'], function(EventHandler, St
        var _inlineConverter = {};
        var _sourceConverter = [];
        
+       /**
+        * Returns true if a whitespace should be inserted before or after the smiley.
+        * 
+        * @param       {Element}       element         image element
+        * @param       {boolean}       before          evaluate previous node
+        * @return      {boolean}       true if a whitespace should be inserted
+        */
        function addSmileyPadding(element, before) {
                var target = element[(before ? 'previousSibling' : 'nextSibling')];
                if (target === null || target.nodeType !== Node.TEXT_NODE || !/\s$/.test(target.textContent)) {
@@ -14,7 +29,16 @@ define(['EventHandler', 'StringUtil', 'DOM/Traverse'], function(EventHandler, St
                return false;
        }
        
+       /**
+        * @module      WoltLab/WCF/BBCode/FromHtml
+        */
        var BBCodeFromHtml = {
+               /**
+                * Converts a message containing HTML elements into BBCodes.
+                * 
+                * @param       {string}        message         message containing HTML elements
+                * @return      {string}        message containing BBCodes
+                */
                convert: function(message) {
                        if (message.length) this._setup();
                        
@@ -25,22 +49,38 @@ define(['EventHandler', 'StringUtil', 'DOM/Traverse'], function(EventHandler, St
                        var elements = container.getElementsByTagName('P');
                        while (elements.length) elements[0].outerHTML = elements[0].innerHTML;
                        
-                       var elements = container.getElementsByTagName('BR');
+                       elements = container.getElementsByTagName('BR');
                        while (elements.length) elements[0].outerHTML = "\n";
                        
+                       // prevent conversion taking place inside source bbcodes
                        var sourceElements = this._preserveSourceElements(container);
                        
+                       EventHandler.fire('com.woltlab.wcf.bbcode.fromHtml', 'beforeConvert', { container: container });
+                       
                        for (var i = 0, length = _converter.length; i < length; i++) {
                                this._convert(container, _converter[i]);
                        }
                        
+                       EventHandler.fire('com.woltlab.wcf.bbcode.fromHtml', 'afterConvert', { container: container });
+                       
                        this._restoreSourceElements(container, sourceElements);
                        
+                       // remove remaining HTML elements
+                       elements = container.getElementsByTagName('*');
+                       while (elements.length) elements[0].outerHTML = elements[0].innerHTML;
+                       
                        message = this._convertSpecials(container.innerHTML);
                        
                        return message;
                },
                
+               /**
+                * Replaces HTML elements mapping to source BBCodes to avoid
+                * them being handled by other converters.
+                * 
+                * @param       {Element}       container       container element
+                * @return      {array<object>} list of source elements and their placeholder
+                */
                _preserveSourceElements: function(container) {
                        var elements, sourceElements = [], tmp;
                        
@@ -58,6 +98,32 @@ define(['EventHandler', 'StringUtil', 'DOM/Traverse'], function(EventHandler, St
                        return sourceElements;
                },
                
+               /**
+                * Replaces an element with a placeholder.
+                * 
+                * @param       {Element}       element         target element
+                * @param       {array<object>} list of removed elements and their placeholders
+                */
+               _preserveSourceElement: function(element, sourceElements) {
+                       var placeholder = document.createElement('var');
+                       placeholder.setAttribute('data-source', 'wcf');
+                       element.parentNode.insertBefore(placeholder, element);
+                       
+                       var fragment = document.createDocumentFragment();
+                       fragment.appendChild(element);
+                       
+                       sourceElements.push({
+                               fragment: fragment,
+                               placeholder: placeholder
+                       });
+               },
+               
+               /**
+                * Reinserts source elements for parsing.
+                * 
+                * @param       {Element}       container       container element
+                * @param       {array<object>} sourceElements  list of removed elements and their placeholders
+                */
                _restoreSourceElements: function(container, sourceElements) {
                        var element, elements, placeholder;
                        for (var i = 0, length = sourceElements.length; i < length; i++) {
@@ -80,6 +146,12 @@ define(['EventHandler', 'StringUtil', 'DOM/Traverse'], function(EventHandler, St
                        }
                },
                
+               /**
+                * Converts special entities.
+                * 
+                * @param       {string}        message         HTML message
+                * @return      {string}        HTML message
+                */
                _convertSpecials: function(message) {
                        message = message.replace(/&amp;/g, '&');
                        message = message.replace(/&lt;/g, '<');
@@ -88,6 +160,9 @@ define(['EventHandler', 'StringUtil', 'DOM/Traverse'], function(EventHandler, St
                        return message;
                },
                
+               /**
+                * Sets up converters applied to elements in linear order.
+                */
                _setup: function() {
                        if (_converter.length) {
                                return;
@@ -139,6 +214,12 @@ define(['EventHandler', 'StringUtil', 'DOM/Traverse'], function(EventHandler, St
                        });
                },
                
+               /**
+                * Converts an element into a raw string.
+                * 
+                * @param       {Element}       container       container element
+                * @param       {object}        converter       converter object
+                */
                _convert: function(container, converter) {
                        if (typeof converter === 'function') {
                                converter(container);
@@ -158,6 +239,11 @@ define(['EventHandler', 'StringUtil', 'DOM/Traverse'], function(EventHandler, St
                        }
                },
                
+               /**
+                * Converts <blockquote> into [quote].
+                * 
+                * @param       {Element}       element         target element
+                */
                _convertBlockquote: function(element) {
                        var author = element.getAttribute('data-author') || '';
                        var link = element.getAttribute('cite') || '';
@@ -184,6 +270,11 @@ define(['EventHandler', 'StringUtil', 'DOM/Traverse'], function(EventHandler, St
                        element.outerHTML = open + element.innerHTML.replace(/^\n*/, '').replace(/\n*$/, '') + '[/quote]\n';
                },
                
+               /**
+                * Converts <img> into smilies, [attach] or [img].
+                * 
+                * @param       {Element}       element         target element
+                */
                _convertImage: function(element) {
                        if (element.classList.contains('smiley')) {
                                // smiley
@@ -224,6 +315,11 @@ define(['EventHandler', 'StringUtil', 'DOM/Traverse'], function(EventHandler, St
                        }
                },
                
+               /**
+                * Converts <ol> and <ul> into [list].
+                * 
+                * @param       {Element}       element         target element
+                */
                _convertList: function(element) {
                        var open;
                        
@@ -243,6 +339,11 @@ define(['EventHandler', 'StringUtil', 'DOM/Traverse'], function(EventHandler, St
                        element.outerHTML = open + element.innerHTML + '[/list]';
                },
                
+               /**
+                * Converts <li> into [*] unless it is not encapsulated in <ol> or <ul>.
+                * 
+                * @param       {Element}       element         target element
+                */
                _convertListItem: function(element) {
                        if (element.parentNode.nodeName !== 'UL' && element.parentNode.nodeName !== 'OL') {
                                element.outerHTML = element.innerHTML;
@@ -252,6 +353,11 @@ define(['EventHandler', 'StringUtil', 'DOM/Traverse'], function(EventHandler, St
                        }
                },
                
+               /**
+                * Converts <span> into a series of BBCodes including [color], [font] and [size].
+                * 
+                * @param       {Element}       element         target element
+                */
                _convertSpan: function(element) {
                        if (element.style.length || element.className) {
                                var converter, value;
@@ -275,6 +381,11 @@ define(['EventHandler', 'StringUtil', 'DOM/Traverse'], function(EventHandler, St
                        element.outerHTML = element.innerHTML;
                },
                
+               /**
+                * Converts <div> into a series of BBCodes including [align].
+                * 
+                * @param       {Element}       element         target element
+                */
                _convertDiv: function(element) {
                        if (element.className.length || element.style.length) {
                                var converter, value;
@@ -296,6 +407,11 @@ define(['EventHandler', 'StringUtil', 'DOM/Traverse'], function(EventHandler, St
                        element.outerHTML = element.innerHTML;
                },
                
+               /**
+                * Converts the CSS style `color` into [color].
+                * 
+                * @param       {Element}       element         target element
+                */
                _convertInlineColor: function(element, value) {
                        if (value.match(/^rgb\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3})\)$/i)) {
                                var r = RegExp.$1;
@@ -309,6 +425,11 @@ define(['EventHandler', 'StringUtil', 'DOM/Traverse'], function(EventHandler, St
                        element.innerHTML = '[color=' + value + ']' + element.innerHTML + '[/color]';
                },
                
+               /**
+                * Converts the CSS style `font-size` into [size].
+                * 
+                * @param       {Element}       element         target element
+                */
                _convertInlineFontSize: function(element, value) {
                        if (value.match(/^(\d+)pt$/)) {
                                value = RegExp.$1;
@@ -330,16 +451,31 @@ define(['EventHandler', 'StringUtil', 'DOM/Traverse'], function(EventHandler, St
                        }
                },
                
+               /**
+                * Converts the CSS style `font-family` into [font].
+                * 
+                * @param       {Element}       element         target element
+                */
                _convertInlineFontFamily: function(element, value) {
                        element.innerHTML = '[font=' + value.replace(/'/g, '') + ']' + element.innerHTML + '[/font]';
                },
                
+               /**
+                * Converts the CSS style `text-align` into [align].
+                * 
+                * @param       {Element}       element         target element
+                */
                _convertInlineTextAlign: function(element, value) {
                        if (value === 'left' || value === 'right' || value === 'justify') {
                                element.innerHTML = '[align=' + value + ']' + innerHTML + '[/align]';
                        }
                },
                
+               /**
+                * Converts tables and their children into BBCodes.
+                * 
+                * @param       {Element}       element         target element
+                */
                _convertTable: function(element) {
                        var elements = element.getElementsByTagName('TD');
                        while (elements.length) {
@@ -356,6 +492,11 @@ define(['EventHandler', 'StringUtil', 'DOM/Traverse'], function(EventHandler, St
                        element.outerHTML = '\n[table]' + innerHtml + '\n[/table]\n';
                },
                
+               /**
+                * Converts <a> into [email] or [url].
+                * 
+                * @param       {Element}       element         target element
+                */
                _convertUrl: function(element) {
                        var content = element.textContent.trim(), href = element.href.trim(), tagName = 'url';
                        
@@ -378,6 +519,11 @@ define(['EventHandler', 'StringUtil', 'DOM/Traverse'], function(EventHandler, St
                        }
                },
                
+               /**
+                * Converts <div class="codeBox"> into [code].
+                * 
+                * @param       {Element}       element         target element
+                */
                _convertSourceCodeBox: function(element) {
                        var filename = element.getAttribute('data-filename').trim() || '';
                        var highlighter = element.getAttribute('data-highlighter') || '';
@@ -394,19 +540,6 @@ define(['EventHandler', 'StringUtil', 'DOM/Traverse'], function(EventHandler, St
                        var open = "[code='" + highlighter + "'," + lineNumber + ",'" + filename + "']";
                        
                        element.outerHTML = open + content + '[/code]';
-               },
-               
-               _preserveSourceElement: function(element, sourceElements) {
-                       var placeholder = document.createElement('var');
-                       element.parentNode.insertBefore(placeholder, element);
-                       
-                       var fragment = document.createDocumentFragment();
-                       fragment.appendChild(element);
-                       
-                       sourceElements.push({
-                               fragment: fragment,
-                               placeholder: placeholder
-                       });
                }
        };
        
index 0e3fb360544c80c73843ea17fae141340a4b0c97..3fbb4a14080b9c34c1d1bbb55d24e84654df2538 100644 (file)
@@ -1,7 +1,24 @@
+/**
+ * Versatile BBCode parser based upon the PHP implementation.
+ * 
+ * @author     Alexander Ebert
+ * @copyright  2001-2015 WoltLab GmbH
+ * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @module     WoltLab/WCF/BBCode/Parser
+ */
 define([], function() {
        "use strict";
        
+       /**
+        * @module      WoltLab/WCF/BBCode/Parser
+        */
        var BBCodeParser = {
+               /**
+                * Parses a message and returns an XML-conform linear tree.
+                * 
+                * @param       {string}        message         message containing BBCodes
+                * @return      {array<mixed>}  linear tree
+                */
                parse: function(message) {
                        var stack = this._splitTags(message);
                        this._buildLinearTree(stack);
@@ -9,8 +26,13 @@ define([], function() {
                        return stack;
                },
                
+               /**
+                * Splits message into strings and BBCode objects.
+                * 
+                * @param       {string}        message         message containing BBCodes
+                * @returns     {array<mixed>}  linear tree
+                */
                _splitTags: function(message) {
-                       // TODO: `validTags` should be dynamic similar to the PHP implementation
                        var validTags = __REDACTOR_BBCODES.join('|');
                        var pattern = '(\\\[(?:/(?:' + validTags + ')|(?:' + validTags + ')'
                                + '(?:='
@@ -51,8 +73,13 @@ define([], function() {
                        return stack;
                },
                
+               /**
+                * Finds pairs and enforces XML-conformity in terms of pairing and proper nesting.
+                * 
+                * @param       {array<mixed>}  stack   linear tree
+                */
                _buildLinearTree: function(stack) {
-                       var item, openTags = [], reopenTags, sourceBBCode = '', tag;
+                       var item, openTags = [], reopenTags, sourceBBCode = '';
                        for (var i = 0; i < stack.length; i++) { // do not cache stack.length, its size is dynamic
                                item = stack[i];
                                
@@ -95,6 +122,15 @@ define([], function() {
                        this._closeUnclosedTags(stack, openTags, '');
                },
                
+               /**
+                * Closes unclosed BBCodes and returns a list of BBCodes in order of appearance that should be
+                * opened again to enforce proper nesting.
+                * 
+                * @param       {array<mixed>}  stack           linear tree
+                * @param       {array<object>} openTags        list of unclosed elements
+                * @param       {string}        until           tag name to stop at
+                * @return      {array<mixed>}  list of tags to open in order of appearance
+                */
                _closeUnclosedTags: function(stack, openTags, until) {
                        var item, reopenTags = [], tag;
                        
@@ -117,6 +153,13 @@ define([], function() {
                        return reopenTags.reverse();
                },
                
+               /**
+                * Returns true if given BBCode was opened before.
+                * 
+                * @param       {array<object>} openTags        list of unclosed elements
+                * @param       {string}        name            BBCode to search for
+                * @returns     {boolean}       false if tag was not opened before
+                */
                _hasOpenTag: function(openTags, name) {
                        for (var i = openTags.length - 1; i >= 0; i--) {
                                if (openTags[i].name === name) {
@@ -127,6 +170,12 @@ define([], function() {
                        return false;
                },
                
+               /**
+                * Parses the attribute list and returns a list of attributes without enclosing quotes.
+                * 
+                * @param       {string}        attrString      comma separated string with optional quotes per attribute
+                * @returns     {array<string>} list of attributes
+                */
                _parseAttributes: function(attrString) {
                        var tmp = attrString.split(/(?:^|,)('[^'\\\\]*(?:\\\\.[^'\\\\]*)*'|[^,]*)/g);
                        
index 413ac4c145d405649dadbcb84bcc4b4968586cfa..b77d9308bf6b9ad55beb31051702ea8fbf758013 100644 (file)
@@ -1,3 +1,11 @@
+/**
+ * Converts a message containing BBCodes into HTML.
+ * 
+ * @author     Alexander Ebert
+ * @copyright  2001-2015 WoltLab GmbH
+ * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @module     WoltLab/WCF/BBCode/ToHtml
+ */
 define(['Core', 'EventHandler', 'Language', 'StringUtil', 'WoltLab/WCF/BBCode/Parser'], function(Core, EventHandler, Language, StringUtil, BBCodeParser) {
        "use strict";
        
@@ -6,11 +14,47 @@ define(['Core', 'EventHandler', 'Language', 'StringUtil', 'WoltLab/WCF/BBCode/Pa
        var _removeNewlineAfter = [];
        var _removeNewlineBefore = [];
        
-       function isNumber(value) { return value && value == ~~value; }
-       function isFilename(value) { return (value.indexOf('.') !== -1) || (!isNumber(value) && !isHighlighter(value)); }
-       function isHighlighter(value) { return __REDACTOR_CODE_HIGHLIGHTERS.hasOwnProperty(value); }
+       /**
+        * Returns true if given value is a non-zero integer.
+        * 
+        * @param       {string}        value           target value
+        * @return      {boolean}       true if `value` is a non-zero integer
+        */
+       function isNumber(value) {
+               return value && value == ~~value;
+       }
        
+       /**
+        * Returns true if given value appears to be a filename, which means that it contains a dot
+        * or is neither numeric nor a known highlighter.
+        * 
+        * @param       {string}        value           target value
+        * @return      {boolean}       true if `value` appears to be a filename
+        */
+       function isFilename(value) {
+               return (value.indexOf('.') !== -1) || (!isNumber(value) && !isHighlighter(value));
+       }
+       
+       /**
+        * Returns true if given value is a known highlighter.
+        * 
+        * @param       {string}        value           target value
+        * @return      {boolean}       true if `value` is a known highlighter
+        */
+       function isHighlighter(value) {
+               return __REDACTOR_CODE_HIGHLIGHTERS.hasOwnProperty(value);
+       }
+       
+       /**
+        * @module      WoltLab/WCF/BBCode/ToHtml
+        */
        var BBCodeToHtml = {
+               /**
+                * Converts a message containing BBCodes to HTML.
+                * 
+                * @param       {string}        message         message containing BBCodes
+                * @return      {string}        HTML message
+                */
                convert: function(message, options) {
                        _options = Core.extend({
                                attachments: {
@@ -28,6 +72,8 @@ define(['Core', 'EventHandler', 'Language', 'StringUtil', 'WoltLab/WCF/BBCode/Pa
                                this._initBBCodes();
                        }
                        
+                       EventHandler.fire('com.woltlab.wcf.bbcode.toHtml', 'beforeConvert', { stack: stack });
+                       
                        var item, value;
                        for (var i = 0, length = stack.length; i < length; i++) {
                                item = stack[i];
@@ -44,6 +90,8 @@ define(['Core', 'EventHandler', 'Language', 'StringUtil', 'WoltLab/WCF/BBCode/Pa
                                }
                        }
                        
+                       EventHandler.fire('com.woltlab.wcf.bbcode.toHtml', 'afterConvert', { stack: stack });
+                       
                        message = stack.join('');
                        
                        message = message.replace(/\n/g, '<br>');
@@ -51,6 +99,12 @@ define(['Core', 'EventHandler', 'Language', 'StringUtil', 'WoltLab/WCF/BBCode/Pa
                        return message;
                },
                
+               /**
+                * Converts special characters to their entities.
+                * 
+                * @param       {string}        message         message containing BBCodes
+                * @return      {string}        message with replaced special characters
+                */
                _convertSpecials: function(message) {
                        message = message.replace(/&/g, '&amp;');
                        message = message.replace(/</g, '&lt;');
@@ -59,6 +113,9 @@ define(['Core', 'EventHandler', 'Language', 'StringUtil', 'WoltLab/WCF/BBCode/Pa
                        return message;
                },
                
+               /**
+                * Sets up converters applied to HTML elements.
+                */
                _initBBCodes: function() {
                        if (_bbcodes !== null) {
                                return;
@@ -99,6 +156,15 @@ define(['Core', 'EventHandler', 'Language', 'StringUtil', 'WoltLab/WCF/BBCode/Pa
                        });
                },
                
+               /**
+                * Converts an item from the stack.
+                * 
+                * @param       {array<mixed>}          stack           linear list of BBCode tags and regular strings
+                * @param       {object}                item            current BBCode tag object
+                * @param       {integer}               index           current stack index representing `item`
+                * @return      {(string|array)}        string if only the current item should be replaced or an array with
+                *                                      the first item used for the opening tag and the second item for the closing tag
+                */
                _convert: function(stack, item, index) {
                        var replace = _bbcodes[item.name], tmp;
                        
@@ -146,6 +212,14 @@ define(['Core', 'EventHandler', 'Language', 'StringUtil', 'WoltLab/WCF/BBCode/Pa
                        }
                },
                
+               /**
+                * Converts [attach] into an <img> or to plain text if attachment is a non-image.
+                * 
+                * @param       {array<mixed>}  stack   linear list of BBCode tags and regular strings
+                * @param       {object}        item    current BBCode tag object
+                * @param       {integer}       index   current stack index representing `item`
+                * @returns     {array}         first item represents the opening tag, the second the closing one
+                */
                _convertAttachment: function(stack, item, index) {
                        var attachmentId = 0, attributes = item.attributes, length = attributes.length;
                        if (!_options.attachments.url) {
@@ -190,6 +264,14 @@ define(['Core', 'EventHandler', 'Language', 'StringUtil', 'WoltLab/WCF/BBCode/Pa
                        ];
                },
                
+               /**
+                * Converts [code] to <div class="codeBox">.
+                * 
+                * @param       {array<mixed>}  stack   linear list of BBCode tags and regular strings
+                * @param       {object}        item    current BBCode tag object
+                * @param       {integer}       index   current stack index representing `item`
+                * @returns     {array}         first item represents the opening tag, the second the closing one
+                */
                _convertCode: function(stack, item, index) {
                        var attributes = item.attributes, filename = '', highlighter = 'auto', lineNumber = 0;
                        
@@ -273,6 +355,14 @@ define(['Core', 'EventHandler', 'Language', 'StringUtil', 'WoltLab/WCF/BBCode/Pa
                        ];
                },
                
+               /**
+                * Converts [color] to <span style="color: ...">.
+                * 
+                * @param       {array<mixed>}  stack   linear list of BBCode tags and regular strings
+                * @param       {object}        item    current BBCode tag object
+                * @param       {integer}       index   current stack index representing `item`
+                * @returns     {array}         first item represents the opening tag, the second the closing one
+                */
                _convertColor: function(stack, item, index) {
                        if (!item.attributes.length || !item.attributes[0].match(/^[a-z0-9#]+$/i)) {
                                return [null, null];
@@ -281,6 +371,14 @@ define(['Core', 'EventHandler', 'Language', 'StringUtil', 'WoltLab/WCF/BBCode/Pa
                        return ['<span style="color: ' + StringUtil.escapeHTML(item.attributes[0]) + '">', '</span>'];
                },
                
+               /**
+                * Converts [email] to <a href="mailto: ...">.
+                * 
+                * @param       {array<mixed>}  stack   linear list of BBCode tags and regular strings
+                * @param       {object}        item    current BBCode tag object
+                * @param       {integer}       index   current stack index representing `item`
+                * @returns     {array}         first item represents the opening tag, the second the closing one
+                */
                _convertEmail: function(stack, item, index) {
                        var email = '';
                        if (item.attributes.length) {
@@ -309,6 +407,14 @@ define(['Core', 'EventHandler', 'Language', 'StringUtil', 'WoltLab/WCF/BBCode/Pa
                        return ['<a href="mailto:' + StringUtil.escapeHTML(email) + '">', '</a>'];
                },
                
+               /**
+                * Converts [img] to <img>.
+                * 
+                * @param       {array<mixed>}  stack   linear list of BBCode tags and regular strings
+                * @param       {object}        item    current BBCode tag object
+                * @param       {integer}       index   current stack index representing `item`
+                * @returns     {array}         first item represents the opening tag, the second the closing one
+                */
                _convertImage: function(stack, item, index) {
                        var float = 'none', source = '', width = 0;
                        
@@ -355,6 +461,14 @@ define(['Core', 'EventHandler', 'Language', 'StringUtil', 'WoltLab/WCF/BBCode/Pa
                        return ['<img src="' + StringUtil.escapeHTML(source) + '"' + (styles.length ? ' style="' + styles.join(';') + '"' : '') + '>', ''];
                },
                
+               /**
+                * Converts [list] to <ol> or <ul>.
+                * 
+                * @param       {array<mixed>}  stack   linear list of BBCode tags and regular strings
+                * @param       {object}        item    current BBCode tag object
+                * @param       {integer}       index   current stack index representing `item`
+                * @returns     {array}         first item represents the opening tag, the second the closing one
+                */
                _convertList: function(stack, item, index) {
                        var type = (items.attributes.length) ? item.attributes[0] : '';
                        
@@ -376,6 +490,14 @@ define(['Core', 'EventHandler', 'Language', 'StringUtil', 'WoltLab/WCF/BBCode/Pa
                        return ['<ul>', '</ul>'];
                },
                
+               /**
+                * Converts [quote] to <blockquote>.
+                * 
+                * @param       {array<mixed>}  stack   linear list of BBCode tags and regular strings
+                * @param       {object}        item    current BBCode tag object
+                * @param       {integer}       index   current stack index representing `item`
+                * @returns     {array}         first item represents the opening tag, the second the closing one
+                */
                _convertQuote: function(stack, item, index) {
                        var author = '', link = '';
                        if (item.attributes.length > 1) {
@@ -417,6 +539,11 @@ define(['Core', 'EventHandler', 'Language', 'StringUtil', 'WoltLab/WCF/BBCode/Pa
                        ];
                },
                
+               /**
+                * Converts smiley codes into <img>.
+                * 
+                * @param       {array<mixed>}  stack   linear list of BBCode tags and regular strings
+                */
                _convertSmilies: function(stack) {
                        var altValue, item, regexp;
                        for (var i = 0, length = stack.length; i < length; i++) {
@@ -440,6 +567,14 @@ define(['Core', 'EventHandler', 'Language', 'StringUtil', 'WoltLab/WCF/BBCode/Pa
                        }
                },
                
+               /**
+                * Converts [size] to <span style="font-size: ...">.
+                * 
+                * @param       {array<mixed>}  stack   linear list of BBCode tags and regular strings
+                * @param       {object}        item    current BBCode tag object
+                * @param       {integer}       index   current stack index representing `item`
+                * @returns     {array}         first item represents the opening tag, the second the closing one
+                */
                _convertSize: function(stack, item, index) {
                        if (!item.attributes.length || ~~item.attributes[0] === 0) {
                                return [null, null];
@@ -448,6 +583,14 @@ define(['Core', 'EventHandler', 'Language', 'StringUtil', 'WoltLab/WCF/BBCode/Pa
                        return ['<span style="font-size: ' + ~~item.attributes[0] + 'pt">', '</span>'];
                },
                
+               /**
+                * Converts [url] to <a>.
+                * 
+                * @param       {array<mixed>}  stack   linear list of BBCode tags and regular strings
+                * @param       {object}        item    current BBCode tag object
+                * @param       {integer}       index   current stack index representing `item`
+                * @returns     {array}         first item represents the opening tag, the second the closing one
+                */
                _convertUrl: function(stack, item, index) {
                        // ignore url bbcode without arguments
                        if (!item.attributes.length) {