From b19ad1508684990c5008652648b81ad6f56d3453 Mon Sep 17 00:00:00 2001
From: Jens Maier <jens@elberet.de>
Date: Thu, 24 Jul 2014 19:39:16 +0200
Subject: [PATCH] FIX: improve list bbcodes: ignore newlines resulting in
 unnecessary blank lines

---
 .../discourse/dialects/bbcode_dialect.js      | 20 ++++++++++++++++---
 test/javascripts/lib/bbcode_test.js           |  1 +
 2 files changed, 18 insertions(+), 3 deletions(-)

diff --git a/app/assets/javascripts/discourse/dialects/bbcode_dialect.js b/app/assets/javascripts/discourse/dialects/bbcode_dialect.js
index fe27c9c0a..d04f675de 100644
--- a/app/assets/javascripts/discourse/dialects/bbcode_dialect.js
+++ b/app/assets/javascripts/discourse/dialects/bbcode_dialect.js
@@ -55,6 +55,20 @@ function replaceBBCodeParamsRaw(tag, emitter) {
   });
 }
 
+/**
+  Filters an array of JSON-ML nodes, removing nodes that represent empty lines ("\n").
+
+  @method removeEmptyLines
+  @param {Array} [contents] Array of JSON-ML nodes
+**/
+function removeEmptyLines(contents) {
+  var result = [];
+  for (var i=0; i < contents.length; i++) {
+    if (contents[i] !== "\n") { result.push(contents[i]); }
+  }
+  return result;
+}
+
 /**
   Creates a BBCode handler that accepts parameters. Passes them to the emitter.
   Processes the inside recursively so it can be nested.
@@ -75,9 +89,9 @@ replaceBBCode('u', function(contents) { return ['span', {'class': 'bbcode-u'}].c
 replaceBBCode('s', function(contents) { return ['span', {'class': 'bbcode-s'}].concat(contents); });
 Discourse.Markdown.whiteListTag('span', 'class', /^bbcode-[bius]$/);
 
-replaceBBCode('ul', function(contents) { return ['ul'].concat(contents); });
-replaceBBCode('ol', function(contents) { return ['ol'].concat(contents); });
-replaceBBCode('li', function(contents) { return ['li'].concat(contents); });
+replaceBBCode('ul', function(contents) { return ['ul'].concat(removeEmptyLines(contents)); });
+replaceBBCode('ol', function(contents) { return ['ol'].concat(removeEmptyLines(contents)); });
+replaceBBCode('li', function(contents) { return ['li'].concat(removeEmptyLines(contents)); });
 
 rawBBCode('img', function(contents) { return ['img', {href: contents}]; });
 rawBBCode('email', function(contents) { return ['a', {href: "mailto:" + contents, 'data-bbcode': true}, contents]; });
diff --git a/test/javascripts/lib/bbcode_test.js b/test/javascripts/lib/bbcode_test.js
index c269cff45..f07c1274a 100644
--- a/test/javascripts/lib/bbcode_test.js
+++ b/test/javascripts/lib/bbcode_test.js
@@ -45,6 +45,7 @@ test('spoiler', function() {
 test('lists', function() {
   format("[ul][li]option one[/li][/ul]", "<ul><li>option one</li></ul>", "creates an ul");
   format("[ol][li]option one[/li][/ol]", "<ol><li>option one</li></ol>", "creates an ol");
+  format("[ul]\n[li]option one[/li]\n[li]option two[/li]\n[/ul]", "<ul><li>option one</li><li>option two</li></ul>", "suppresses empty lines in lists");
 });
 
 test('tags with arguments', function() {