Fixed quote nesting by applying black magic
authorAlexander Ebert <ebert@woltlab.com>
Mon, 27 Oct 2014 01:32:26 +0000 (02:32 +0100)
committerAlexander Ebert <ebert@woltlab.com>
Mon, 27 Oct 2014 01:32:26 +0000 (02:32 +0100)
wcfsetup/install/files/js/3rdParty/redactor/plugins/wbbcode.js
wcfsetup/install/files/js/3rdParty/redactor/plugins/wmonkeypatch.js

index b73374d442f56ab7bea2b223d4167032eaa873a4..2991899fa4c7f3d9f667a8d493479593ec45ad35 100644 (file)
@@ -606,7 +606,7 @@ RedactorPlugins.wbbcode = function() {
                        data = data.replace(/\[list=1\]/gi, '<ul style="list-style-type: decimal">');
                        data = data.replace(/\[list=a\]/gi, '<ul style="list-style-type: lower-latin">');
                        data = data.replace(/\[list=(none|circle|square|disc|decimal|lower-roman|upper-roman|decimal-leading-zero|lower-greek|lower-latin|upper-latin|armenian|georgian)\]/gi, '<ul style="list-style-type: $1">');
-                       data = data.replace(/\[\/list]/gi, '</ul>');
+                       data = data.replace(/\[\/list]\n?/gi, '</ul>\n');
                        
                        // trim whitespaces within [table]
                        data = data.replace(/\[table\]([\S\s]*?)\[\/table\]/gi, function(match, p1) {
@@ -673,31 +673,59 @@ RedactorPlugins.wbbcode = function() {
                        // extract [quote] bbcodes to prevent line break handling below
                        var $cachedQuotes = [ ];
                        var $knownQuotes = [ ];
-                       for (var $i = 0; $i < 5; $i++) {
-                               var $foundQuotes = false;
-                               
-                               data = data.replace(/\[quote.*?\]((?!\[quote)[\s\S])*?\[\/quote\]/gi, function(match) {
-                                       var $key = match.hashCode();
-                                       $cachedQuotes.push({
-                                               hashCode: $key,
-                                               content: match.replace(/\$/g, '$$$$')
-                                       });
-                                       $knownQuotes.push($key.toString());
-                                       
-                                       $foundQuotes = true;
-                                       
-                                       return '@@' + $key + '@@';
-                               });
+                       
+                       var $parts = data.split(/(\[(?:\/quote|quote|quote='[^']*?'(?:,'[^']*?')?|quote="[^"]*?"(?:,"[^"]*?")?)\])/);
+                       var $lostQuote = WCF.getUUID();
+                       while (true) {
+                               var $foundClosingTag = false;
+                               for (var $i = 0; $i < $parts.length; $i++) {
+                                       var $part = $parts[$i];
+                                       if ($part === '[/quote]') {
+                                               $foundClosingTag = true;
+                                               
+                                               var $content = '';
+                                               var $previous = $parts.slice(0, $i);
+                                               var $foundOpenTag = false;
+                                               while ($previous.length) {
+                                                       var $prev = $previous.pop();
+                                                       $content = $prev + $content;
+                                                       if ($prev.match(/^\[quote/)) {
+                                                               $part = $content + $part;
+                                                               
+                                                               var $key = WCF.getUUID();
+                                                               $cachedQuotes.push({
+                                                                       hashCode: $key,
+                                                                       content: $part.replace(/\$/g, '$$$$')
+                                                               });
+                                                               $knownQuotes.push($key);
+                                                               
+                                                               $part = '@@' + $key + '@@';
+                                                               $foundOpenTag = true;
+                                                               break;
+                                                       }
+                                               }
+                                               
+                                               if (!$foundOpenTag) {
+                                                       $previous = $parts.slice(0, $i);
+                                                       $part = $lostQuote;
+                                               }
+                                               
+                                               // rebuild the array
+                                               $parts = $previous.concat($part, $parts.slice($i + 1));
+                                               console.debug($parts);
+                                               break;
+                                       }
+                               }
                                
-                               // we found no more quotes
-                               if (!$foundQuotes) {
+                               if (!$foundClosingTag) {
                                        break;
                                }
                        }
                        
-                       // add newlines before and after [quote] tags
-                       data = data.replace(/(\[quote.*?\])/gi, '$1\n');
-                       data = data.replace(/(\[\/quote\])/gi, '\n$1');
+                       data = $parts.join('');
+                       
+                       // restore unmatched closing quote tags
+                       data = data.replace(new RegExp($lostQuote, 'g'), '[/quote]');
                        
                        // drop trailing line breaks
                        data = data.replace(/\n*$/, '');
@@ -826,7 +854,7 @@ RedactorPlugins.wbbcode = function() {
                                        data = data.replace($regex, $transformQuote($cachedQuote.content));
                                }
                        }
-                       
+                       console.debug(data);
                        WCF.System.Event.fireEvent('com.woltlab.wcf.redactor', 'afterConvertToHtml', { data: data });
                        
                        return data;
index 9540ca7ef009efdd810e94c5b4e892d32bfa84aa..b61700cc7d6e62593a6260439089daabdbda5910 100644 (file)
@@ -118,6 +118,7 @@ RedactorPlugins.wmonkeypatch = function() {
                        }).bind(this);
                        
                        // clean.setVerified
+                       // TODO: remove this once the escape bug has been fixed by Imperavi
                        this.clean.setVerified = (function(html) {
                                if (this.utils.browser('msie')) return html;