From b3b75419a9b0e37cb8e2130f541f3afc7c67d14e Mon Sep 17 00:00:00 2001 From: Alexander Ebert Date: Sun, 14 Sep 2014 19:24:28 +0200 Subject: [PATCH] Improved handling of nested quotes --- .../js/3rdParty/redactor/plugins/wbbcode.js | 93 +++++++++++++------ 1 file changed, 67 insertions(+), 26 deletions(-) diff --git a/wcfsetup/install/files/js/3rdParty/redactor/plugins/wbbcode.js b/wcfsetup/install/files/js/3rdParty/redactor/plugins/wbbcode.js index 91c7268c5d..58c2de3163 100644 --- a/wcfsetup/install/files/js/3rdParty/redactor/plugins/wbbcode.js +++ b/wcfsetup/install/files/js/3rdParty/redactor/plugins/wbbcode.js @@ -230,6 +230,9 @@ RedactorPlugins.wbbcode = { html = html.replace(/
\n?]+>\n?
[\s\S]*?<\/header>/gi, function(match, link, author, innerContent) { var $quote; + author = WCF.String.unescapeHTML(author); + link = WCF.String.unescapeHTML(link); + if (link) { $quote = "[quote='" + author + "','" + link + "']"; } @@ -242,7 +245,7 @@ RedactorPlugins.wbbcode = { return $quote; }); - html = html.replace(/(?:\n*)<\/blockquote>/gi, '[/quote]\n'); + html = html.replace(/(?:\n*)<\/blockquote>\n?/gi, '[/quote]\n'); // [email] html = html.replace(/]*?href=(["'])mailto:(.+?)\1.*?>([\s\S]+?)<\/a>/gi, '[email=$2]$3[/email]'); @@ -609,12 +612,29 @@ RedactorPlugins.wbbcode = { data = data.replace(/(\r|\r\n)/g, "\n"); // extract [quote] bbcodes to prevent line break handling below - var $cachedQuotes = { }; - data = data.replace(/\[quote.*?\][\S\s]*?\[\/quote\]/gi, function(match) { - var $key = match.hashCode(); - $cachedQuotes[$key] = match.replace(/\$/g, '$$$$'); - return '@@' + $key + '@@'; - }); + 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 + '@@'; + }); + + // we found no more quotes + if (!$foundQuotes) { + break; + } + } // add newlines before and after [quote] tags data = data.replace(/(\[quote.*?\])/gi, '$1\n'); @@ -660,7 +680,7 @@ RedactorPlugins.wbbcode = { data = data.replace(/\[code\][\S\s]*?\[\/code\]/, '
$&
'); // insert quotes - if ($.getLength($cachedQuotes)) { + if ($cachedQuotes.length) { // [quote] var $unquoteString = function(quotedString) { return quotedString.replace(/^['"]/, '').replace(/['"]$/, ''); @@ -710,6 +730,13 @@ RedactorPlugins.wbbcode = { if ($line.length === 0) { $line = self.opts.invisibleSpace; } + else if ($line.match(/^@@([0-9\-]+)@@$/)) { + if (WCF.inArray(RegExp.$1, $knownQuotes)) { + // prevent quote being nested inside a
block + $tmp += $line; + continue; + } + } $tmp += '
' + $line + '
'; } @@ -725,9 +752,11 @@ RedactorPlugins.wbbcode = { }, this)); }; - for (var $key in $cachedQuotes) { - var $regex = new RegExp('@@' + $key + '@@', 'g'); - data = data.replace($regex, $transformQuote($cachedQuotes[$key])); + // reinsert quotes in reverse order, adding the most outer quotes first + for (var $i = $cachedQuotes.length - 1; $i >= 0; $i--) { + var $cachedQuote = $cachedQuotes[$i]; + var $regex = new RegExp('@@' + $cachedQuote.hashCode + '@@', 'g'); + data = data.replace($regex, $transformQuote($cachedQuote.content)); } } @@ -873,25 +902,31 @@ RedactorPlugins.wbbcode = { switch (data.event.which) { // arrow down case $.ui.keyCode.DOWN: - if ($parent) { - if ($quote.length) { + if ($current.next('blockquote.quoteBox').length) { + this.selectionStart($current.next().find('> div > div:first')); + + data.cancel = true; + } + else if ($parent) { + if ($parent.next('blockquote.quoteBox').length) { + this.selectionStart($parent.next().find('> div > div:first')); + + data.cancel = true; + } + else if ($quote.length) { var $container = $current.closest('div', $quote[0]); if (!$container.next().length) { - this.insertingAfterLastElement($quote); + // check if there is an element after the quote + if ($quote.next().length) { + this.setSelectionStart($quote.next()); + } + else { + this.insertingAfterLastElement($quote); + } data.cancel = true; } - } - else if ($parent.next('blockquote.quoteBox').length) { - this.selectionStart($parent.next().find('> div > div:first')); - - data.cancel = true; - } - } - else if ($current.next('blockquote.quoteBox').length) { - this.selectionStart($current.next().find('> div > div:first')); - - data.cancel = true; + } } break; @@ -902,8 +937,14 @@ RedactorPlugins.wbbcode = { } var $container = $current.closest('div', $quote[0]); - if ($container.prev('div').length) { + var $prev = $container.prev(); + if ($prev[0].tagName === 'DIV') { + return; + } + else if ($prev[0].tagName === 'BLOCKQUOTE') { + // set focus to quote text rather than the element itself return; + //this.selectionEnd($prev.find('> div > div:last')); } var $previousElement = $quote.prev(); -- 2.20.1