Added support for smileys and [email]
authorAlexander Ebert <ebert@woltlab.com>
Sat, 4 Jul 2015 09:18:42 +0000 (11:18 +0200)
committerAlexander Ebert <ebert@woltlab.com>
Sat, 4 Jul 2015 09:18:42 +0000 (11:18 +0200)
wcfsetup/install/files/js/3rdParty/redactor/plugins/wbbcode.js
wcfsetup/install/files/js/WoltLab/WCF/BBCode/FromHtml.js
wcfsetup/install/files/js/WoltLab/WCF/BBCode/ToHtml.js

index 19640e5f828e5e0f9e42906b16c2d21da8a2246e..b66cd10bd7bfb0fee9545c76550931943a09765a 100644 (file)
@@ -350,27 +350,11 @@ RedactorPlugins.wbbcode = function() {
                                return '[attach=' + $attachmentID + '][/attach]';
                        });
                        
-                       // cache redactor's selection markers
-                       var $cachedMarkers = { };
-                       html.replace(/<span id="selection-marker-\d+" class="redactor-selection-marker"><\/span>/, function(match) {
-                               var $key = match.hashCode();
-                               $cachedMarkers[$key] = match.replace(/\$/g, '$$$$');
-                               return '@@' + $key + '@@';
-                       });
-                       
                        WCF.System.Event.fireEvent('com.woltlab.wcf.redactor', 'convertFromHtml', { html: html });
                        
                        // Remove remaining tags.
                        html = html.replace(/<[^(<|>)]+>/g, '');
                        
-                       // insert redactor's selection markers
-                       if ($.getLength($cachedMarkers)) {
-                               for (var $key in $cachedMarkers) {
-                                       var $regex = new RegExp('@@' + $key + '@@', 'g');
-                                       data = data.replace($regex, $cachedMarkers[$key]);
-                               }
-                       }
-                       
                        // Restore <, > and &
                        html = html.replace(/&lt;/g, '<');
                        html = html.replace(/&gt;/g, '>');
@@ -399,36 +383,6 @@ RedactorPlugins.wbbcode = function() {
                        // remove 0x200B (unicode zero width space)
                        data = this.wutil.removeZeroWidthSpace(data);
                        
-                       // [email]
-                       data = data.replace(/\[email\]([^"]+?)\[\/email]/gi, '<a href="mailto:$1">$1</a>' + this.opts.invisibleSpace);
-                       data = data.replace(/\[email\=([^"\]]+)](.+?)\[\/email]/gi, '<a href="mailto:$1">$2</a>' + this.opts.invisibleSpace);
-                       
-                       // [img]
-                       data = data.replace(/\[img\]([^"]+?)\[\/img\]/gi,'<img src="$1" />');
-                       data = data.replace(/\[img='?([^"]*?)'?,'?(left|right)'?\]\[\/img\]/gi, function(match, src, alignment) {
-                               var $style = 'float: ' + alignment + ';';
-                               if (alignment === 'left') {
-                                       $style += 'margin: 0 15px 7px 0';
-                               }
-                               else {
-                                       $style += 'margin: 0 0 7px 15px';
-                               }
-                               
-                               return '<img src="' + src + '" style="' + $style + '" />';
-                       });
-                       data = data.replace(/\[img='?([^"]*?)'?,'?(left|right|none)'?,'?(\d+)'?\]\[\/img\]/gi, function(match, src, alignment, width) {
-                               var $style = 'float: ' + alignment + '; width: ' + width + 'px;';
-                               if (alignment === 'left') {
-                                       $style += 'margin: 0 15px 7px 0';
-                               }
-                               else {
-                                       $style += 'margin: 0 0 7px 15px';
-                               }
-                               
-                               return '<img src="' + src + '" style="' + $style + '" />';
-                       });
-                       data = data.replace(/\[img='?([^"]*?)'?\]\[\/img\]/gi,'<img src="$1" />');
-                       
                        // attachments
                        var $attachmentUrl = this.wutil.getOption('woltlab.attachmentUrl');
                        var $attachmentThumbnailUrl = this.wutil.getOption('woltlab.attachmentThumbnailUrl');
@@ -494,13 +448,6 @@ RedactorPlugins.wbbcode = function() {
                                });
                        }
                        
-                       // smileys
-                       for (var smileyCode in __REDACTOR_SMILIES) {
-                               var $smileyCode = smileyCode.replace(/</g, '&lt;').replace(/>/g, '&gt;');
-                               var regExp = new RegExp('(\\s|>|^)' + WCF.String.escapeRegExp($smileyCode) + '(?=\\s|<|$)', 'gi');
-                               data = data.replace(regExp, '$1<img src="' + __REDACTOR_SMILIES[smileyCode] + '" class="smiley" alt="' + $smileyCode + '" />');
-                       }
-                       
                        // remove "javascript:"
                        data = data.replace(/(javascript):/gi, '$1<span></span>:');
                        
index 9382df05218a8883facd37e2a0eb3cce9d27dd0d..4616e97ba4fb4d1c8ec3f51ae07ed5e03c479c90 100644 (file)
@@ -5,6 +5,15 @@ define(['EventHandler', 'StringUtil', 'DOM/Traverse'], function(EventHandler, St
        var _inlineConverter = {};
        var _sourceConverter = [];
        
+       function addSmileyPadding(element, before) {
+               var target = element[(before ? 'previousSibling' : 'nextSibling')];
+               if (target === null || target.nodeType !== Node.TEXT_NODE || !/\s$/.test(target.textContent)) {
+                       return true;
+               }
+               
+               return false;
+       }
+       
        var BBCodeFromHtml = {
                convert: function(message) {
                        if (message.length) this._setup();
@@ -177,7 +186,7 @@ define(['EventHandler', 'StringUtil', 'DOM/Traverse'], function(EventHandler, St
                _convertImage: function(element) {
                        if (element.classList.contains('smiley')) {
                                // smiley
-                               element.outerHTML = ' ' + element.getAttribute('alt') + ' ';
+                               element.outerHTML = (addSmileyPadding(element, true) ? ' ' : '') + element.getAttribute('alt') + (addSmileyPadding(element, false) ? ' ' : '');
                        }
                        else if (element.classList.contains('redactorEmbeddedAttachment')) {
                                // TODO: handle attachments
@@ -333,7 +342,7 @@ define(['EventHandler', 'StringUtil', 'DOM/Traverse'], function(EventHandler, St
                },
                
                _convertUrl: function(element) {
-                       var content = element.textContent.trim(), href = element.href.trim();
+                       var content = element.textContent.trim(), href = element.href.trim(), tagName = 'url';
                        
                        if (href === '' || content === '') {
                                // empty href or content
@@ -342,13 +351,15 @@ define(['EventHandler', 'StringUtil', 'DOM/Traverse'], function(EventHandler, St
                        }
                        
                        if (href.indexOf('mailto:') === 0) {
-                               element.outerHTML = '[email=' + href.substr(6) + ']' + element.innerHTML + '[/email]';
+                               href = href.substr(7);
+                               tagName = 'email';
                        }
-                       else if (href === content) {
-                               element.outerHTML = '[url]' + href + '[/url]';
+                       
+                       if (href === content) {
+                               element.outerHTML = '[' + tagName + ']' + href + '[/' + tagName + ']';
                        }
                        else {
-                               element.outerHTML = "[url='" + href + "']" + element.innerHTML + "[/url]";
+                               element.outerHTML = "[" + tagName + "='" + href + "']" + element.innerHTML + "[/" + tagName + "]";
                        }
                },
                
index 8fb7e5d2def69b23f818c6a868dde34ae86d5d52..0eb669e99606036c171983bb0fa3effd9d4a3701 100644 (file)
@@ -63,6 +63,7 @@ define(['EventHandler', 'Language', 'StringUtil', 'WoltLab/WCF/BBCode/Parser'],
                                // callback replacement
                                color: this._replaceColor.bind(this),
                                code: this._replaceCode.bind(this),
+                               email: this._replaceEmail.bind(this),
                                list: this._replaceList.bind(this),
                                quote: this._replaceQuote.bind(this),
                                url: this._replaceUrl.bind(this),
@@ -117,6 +118,9 @@ define(['EventHandler', 'Language', 'StringUtil', 'WoltLab/WCF/BBCode/Parser'],
                                }
                        }
                        
+                       // replace smilies
+                       this._replaceSmilies(stack);
+                       
                        if (typeof replace === 'string') {
                                stack[item.pair] = '</' + replace + '>';
                                
@@ -221,6 +225,38 @@ define(['EventHandler', 'Language', 'StringUtil', 'WoltLab/WCF/BBCode/Parser'],
                        return '<span style="color: ' + StringUtil.escapeHTML(item.attributes[0]) + '">';
                },
                
+               _replaceEmail: function(stack, item, index) {
+                       var email = '';
+                       if (item.attributes.length) {
+                               email = item.attributes[0];
+                       }
+                       else {
+                               var element;
+                               for (var i = index + 1; i < item.pair; i++) {
+                                       element = stack[i];
+                                       
+                                       if (typeof element === 'object') {
+                                               email = '';
+                                               break;
+                                       }
+                                       else {
+                                               email += element;
+                                       }
+                               }
+                               
+                               // no attribute present and element is empty, handle as plain text
+                               if (email.trim() === '') {
+                                       stack[item.pair] = stack[item.pair].source;
+                                       
+                                       return item.source;
+                               }
+                       }
+                       
+                       stack[item.pair] = '</a>';
+                       
+                       return '<a href="mailto:' + StringUtil.escapeHTML(email) + '">';
+               },
+               
                _replaceImage: function(stack, item, index) {
                        stack[item.pair] = '';
                        
@@ -266,7 +302,7 @@ define(['EventHandler', 'Language', 'StringUtil', 'WoltLab/WCF/BBCode/Parser'],
                                styles.push('margin: ' + (float === 'left' ? '0 15px 7px 0' : '0 0 7px 15px'));
                        }
                        
-                       return '<img src="' + source + '"' + (styles.length ? ' style="' + styles.join(';') + '"' : '') + '>';
+                       return '<img src="' + StringUtil.escapeHTML(source) + '"' + (styles.length ? ' style="' + styles.join(';') + '"' : '') + '>';
                },
                
                _replaceList: function(stack, item, index) {
@@ -333,6 +369,29 @@ define(['EventHandler', 'Language', 'StringUtil', 'WoltLab/WCF/BBCode/Parser'],
                                        + '<div>\u200b';
                },
                
+               _replaceSmilies: function(stack) {
+                       var altValue, item, regexp;
+                       for (var i = 0, length = stack.length; i < length; i++) {
+                               item = stack[i];
+                               
+                               if (typeof item === 'string') {
+                                       for (var smileyCode in __REDACTOR_SMILIES) {
+                                               if (__REDACTOR_SMILIES.hasOwnProperty(smileyCode)) {
+                                                       altValue = smileyCode.replace(/</g, '&lt;').replace(/>/g, '&gt;');
+                                                       regexp = new RegExp('(\\s|^)' + StringUtil.escapeRegExp(smileyCode) + '(?=\\s|$)', 'gi');
+                                                       item = item.replace(regexp, '$1<img src="' + __REDACTOR_SMILIES[smileyCode] + '" class="smiley" alt="' + altValue + '">');
+                                               }
+                                       }
+                                       
+                                       stack[i] = item;
+                               }
+                               else if (__REDACTOR_SOURCE_BBCODES.indexOf(item.name) !== -1) {
+                                       // skip processing content
+                                       i = item.pair;
+                               }
+                       }
+               },
+               
                _replaceUrl: function(stack, item, index) {
                        // ignore url bbcode without arguments
                        if (!item.attributes.length) {