mirror of
				https://github.com/discourse/discourse.git
				synced 2025-02-25 18:55:32 -06:00 
			
		
		
		
	Replace Markdown Linebreak Regexp with node parser.
This commit is contained in:
		@@ -97,17 +97,7 @@ Discourse.Markdown = {
 | 
				
			|||||||
    return {
 | 
					    return {
 | 
				
			||||||
      makeHtml: function(text) {
 | 
					      makeHtml: function(text) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Linebreaks
 | 
					 | 
				
			||||||
        var linebreaks = opts.traditional_markdown_linebreaks || Discourse.SiteSettings.traditional_markdown_linebreaks;
 | 
					 | 
				
			||||||
        if (!linebreaks) {
 | 
					 | 
				
			||||||
          text = text.replace(/(^[\w<][^\n]*\n+)/gim, function(t) {
 | 
					 | 
				
			||||||
            if (t.match(/\n{2}/gim)) return t;
 | 
					 | 
				
			||||||
            return t.replace("\n", "  \n");
 | 
					 | 
				
			||||||
          });
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        text = Discourse.Dialect.cook(text, opts);
 | 
					        text = Discourse.Dialect.cook(text, opts);
 | 
				
			||||||
 | 
					 | 
				
			||||||
        if (!text) return "";
 | 
					        if (!text) return "";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (opts.sanitize) {
 | 
					        if (opts.sanitize) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -174,7 +174,7 @@ Discourse.Dialect.on("register", function(event) {
 | 
				
			|||||||
      result.push(['p', ['aside', params,
 | 
					      result.push(['p', ['aside', params,
 | 
				
			||||||
                   ['div', {'class': 'title'},
 | 
					                   ['div', {'class': 'title'},
 | 
				
			||||||
                     ['div', {'class': 'quote-controls'}],
 | 
					                     ['div', {'class': 'quote-controls'}],
 | 
				
			||||||
                     avatarImg ? avatarImg + "\n" : "",
 | 
					                     avatarImg ? avatarImg : "",
 | 
				
			||||||
                     I18n.t('user.said',{username: username})
 | 
					                     I18n.t('user.said',{username: username})
 | 
				
			||||||
                   ],
 | 
					                   ],
 | 
				
			||||||
                   contents
 | 
					                   contents
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -32,8 +32,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  ```javascript
 | 
					  ```javascript
 | 
				
			||||||
    Discourse.Dialect.on("parseNode", function(event) {
 | 
					    Discourse.Dialect.on("parseNode", function(event) {
 | 
				
			||||||
      var node = event.node,
 | 
					      var node = event.node;
 | 
				
			||||||
          path = event.path;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
      if (node[0] === 'code') {
 | 
					      if (node[0] === 'code') {
 | 
				
			||||||
        node[node.length-1] = "EVIL TROUT HACKED YOUR CODE";
 | 
					        node[node.length-1] = "EVIL TROUT HACKED YOUR CODE";
 | 
				
			||||||
@@ -68,16 +67,22 @@ var parser = window.BetterMarkdown,
 | 
				
			|||||||
      @method parseTree
 | 
					      @method parseTree
 | 
				
			||||||
      @param {Array} tree the JsonML tree to parse
 | 
					      @param {Array} tree the JsonML tree to parse
 | 
				
			||||||
      @param {Array} path the path of ancestors to the current node in the tree. Can be used for matching.
 | 
					      @param {Array} path the path of ancestors to the current node in the tree. Can be used for matching.
 | 
				
			||||||
 | 
					      @param {Object} insideCounts counts what tags we're inside
 | 
				
			||||||
      @returns {Array} the parsed tree
 | 
					      @returns {Array} the parsed tree
 | 
				
			||||||
    **/
 | 
					    **/
 | 
				
			||||||
    parseTree = function parseTree(tree, path) {
 | 
					    parseTree = function parseTree(tree, path, insideCounts) {
 | 
				
			||||||
      if (tree instanceof Array) {
 | 
					      if (tree instanceof Array) {
 | 
				
			||||||
        Discourse.Dialect.trigger('parseNode', {node: tree, path: path});
 | 
					        Discourse.Dialect.trigger('parseNode', {node: tree, path: path, dialect: dialect, insideCounts: insideCounts || {}});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        path = path || [];
 | 
					        path = path || [];
 | 
				
			||||||
 | 
					        insideCounts = insideCounts || {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        path.push(tree);
 | 
					        path.push(tree);
 | 
				
			||||||
        tree.slice(1).forEach(function (n) {
 | 
					        tree.slice(1).forEach(function (n) {
 | 
				
			||||||
          parseTree(n, path);
 | 
					          var tagName = n[0];
 | 
				
			||||||
 | 
					          insideCounts[tagName] = (insideCounts[tagName] || 0) + 1;
 | 
				
			||||||
 | 
					          parseTree(n, path, insideCounts);
 | 
				
			||||||
 | 
					          insideCounts[tagName] = insideCounts[tagName] - 1;
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
        path.pop();
 | 
					        path.pop();
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
@@ -103,7 +108,8 @@ Discourse.Dialect = {
 | 
				
			|||||||
  cook: function(text, opts) {
 | 
					  cook: function(text, opts) {
 | 
				
			||||||
    if (!initialized) { initializeDialects(); }
 | 
					    if (!initialized) { initializeDialects(); }
 | 
				
			||||||
    dialect.options = opts;
 | 
					    dialect.options = opts;
 | 
				
			||||||
    return parser.renderJsonML(parseTree(parser.toHTMLTree(text, 'Discourse')));
 | 
					    var tree = parser.toHTMLTree(text, 'Discourse');
 | 
				
			||||||
 | 
					    return parser.renderJsonML(parseTree(tree));
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -84,10 +84,48 @@ Discourse.Dialect.on("register", function(event) {
 | 
				
			|||||||
  @namespace Discourse.Dialect
 | 
					  @namespace Discourse.Dialect
 | 
				
			||||||
**/
 | 
					**/
 | 
				
			||||||
Discourse.Dialect.on("parseNode", function(event) {
 | 
					Discourse.Dialect.on("parseNode", function(event) {
 | 
				
			||||||
  var node = event.node,
 | 
					  var node = event.node;
 | 
				
			||||||
      path = event.path;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (node[0] === 'code') {
 | 
					  if (node[0] === 'code') {
 | 
				
			||||||
    node[node.length-1] = Handlebars.Utils.escapeExpression(node[node.length-1]);
 | 
					    node[node.length-1] = Handlebars.Utils.escapeExpression(node[node.length-1]);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Discourse.Dialect.on("parseNode", function(event) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  var node = event.node,
 | 
				
			||||||
 | 
					      opts = event.dialect.options,
 | 
				
			||||||
 | 
					      insideCounts = event.insideCounts,
 | 
				
			||||||
 | 
					      linebreaks = opts.traditional_markdown_linebreaks || Discourse.SiteSettings.traditional_markdown_linebreaks;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (!linebreaks) {
 | 
				
			||||||
 | 
					    // We don't add line breaks inside a pre
 | 
				
			||||||
 | 
					    if (insideCounts.pre > 0) { return; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (node.length > 1) {
 | 
				
			||||||
 | 
					      for (var j=1; j<node.length; j++) {
 | 
				
			||||||
 | 
					        var textContent = node[j];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (typeof textContent === "string") {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          if (textContent === "\n") {
 | 
				
			||||||
 | 
					            node[j] = ['br'];
 | 
				
			||||||
 | 
					          } else {
 | 
				
			||||||
 | 
					            var split = textContent.split(/\n+/);
 | 
				
			||||||
 | 
					            if (split.length) {
 | 
				
			||||||
 | 
					              var spliceInstructions = [j, 1];
 | 
				
			||||||
 | 
					              for (var i=0; i<split.length; i++) {
 | 
				
			||||||
 | 
					                if (split[i].length > 0) {
 | 
				
			||||||
 | 
					                  spliceInstructions.push(split[i]);
 | 
				
			||||||
 | 
					                  if (i !== split.length-1) { spliceInstructions.push(['br']); }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					              }
 | 
				
			||||||
 | 
					              node.splice.apply(node, spliceInstructions);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										42
									
								
								app/assets/javascripts/discourse/dialects/newline_dialect.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								app/assets/javascripts/discourse/dialects/newline_dialect.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,42 @@
 | 
				
			|||||||
 | 
					/**
 | 
				
			||||||
 | 
					  Support for the newline behavior in markdown that most expect.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @event parseNode
 | 
				
			||||||
 | 
					  @namespace Discourse.Dialect
 | 
				
			||||||
 | 
					**/
 | 
				
			||||||
 | 
					Discourse.Dialect.on("parseNode", function(event) {
 | 
				
			||||||
 | 
					  var node = event.node,
 | 
				
			||||||
 | 
					      opts = event.dialect.options,
 | 
				
			||||||
 | 
					      insideCounts = event.insideCounts,
 | 
				
			||||||
 | 
					      linebreaks = opts.traditional_markdown_linebreaks || Discourse.SiteSettings.traditional_markdown_linebreaks;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (!linebreaks) {
 | 
				
			||||||
 | 
					    // We don't add line breaks inside a pre
 | 
				
			||||||
 | 
					    if (insideCounts.pre > 0) { return; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (node.length > 1) {
 | 
				
			||||||
 | 
					      for (var j=1; j<node.length; j++) {
 | 
				
			||||||
 | 
					        var textContent = node[j];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (typeof textContent === "string") {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          if (textContent === "\n") {
 | 
				
			||||||
 | 
					            node[j] = ['br'];
 | 
				
			||||||
 | 
					          } else {
 | 
				
			||||||
 | 
					            var split = textContent.split(/\n+/);
 | 
				
			||||||
 | 
					            if (split.length) {
 | 
				
			||||||
 | 
					              var spliceInstructions = [j, 1];
 | 
				
			||||||
 | 
					              for (var i=0; i<split.length; i++) {
 | 
				
			||||||
 | 
					                if (split[i].length > 0) {
 | 
				
			||||||
 | 
					                  spliceInstructions.push(split[i]);
 | 
				
			||||||
 | 
					                  if (i !== split.length-1) { spliceInstructions.push(['br']); }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					              }
 | 
				
			||||||
 | 
					              node.splice.apply(node, spliceInstructions);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
@@ -14,15 +14,15 @@ describe PrettyText do
 | 
				
			|||||||
      end
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      it "produces a quote even with new lines in it" do
 | 
					      it "produces a quote even with new lines in it" do
 | 
				
			||||||
        PrettyText.cook("[quote=\"EvilTrout, post:123, topic:456, full:true\"]ddd\n[/quote]").should match_html "<p><aside class=\"quote\" data-post=\"123\" data-topic=\"456\" data-full=\"true\"><div class=\"title\">\n<div class=\"quote-controls\"></div>\n<img width=\"20\" height=\"20\" src=\"http://test.localhost/uploads/default/avatars/42d/57c/46ce7ee487/40.png\" class=\"avatar\">\nEvilTrout said:</div>\n<blockquote>ddd\n</blockquote></aside></p>"
 | 
					        PrettyText.cook("[quote=\"EvilTrout, post:123, topic:456, full:true\"]ddd\n[/quote]").should match_html "<p><aside class=\"quote\" data-post=\"123\" data-topic=\"456\" data-full=\"true\"><div class=\"title\">\n<div class=\"quote-controls\"></div>\n<img width=\"20\" height=\"20\" src=\"http://test.localhost/uploads/default/avatars/42d/57c/46ce7ee487/40.png\" class=\"avatar\">EvilTrout said:</div>\n<blockquote>ddd<br>\n</blockquote></aside></p>"
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      it "should produce a quote" do
 | 
					      it "should produce a quote" do
 | 
				
			||||||
        PrettyText.cook("[quote=\"EvilTrout, post:123, topic:456, full:true\"]ddd[/quote]").should match_html "<p><aside class=\"quote\" data-post=\"123\" data-topic=\"456\" data-full=\"true\"><div class=\"title\">\n<div class=\"quote-controls\"></div>\n<img width=\"20\" height=\"20\" src=\"http://test.localhost/uploads/default/avatars/42d/57c/46ce7ee487/40.png\" class=\"avatar\">\nEvilTrout said:</div>\n<blockquote>ddd</blockquote></aside></p>"
 | 
					        PrettyText.cook("[quote=\"EvilTrout, post:123, topic:456, full:true\"]ddd[/quote]").should match_html "<p><aside class=\"quote\" data-post=\"123\" data-topic=\"456\" data-full=\"true\"><div class=\"title\">\n<div class=\"quote-controls\"></div>\n<img width=\"20\" height=\"20\" src=\"http://test.localhost/uploads/default/avatars/42d/57c/46ce7ee487/40.png\" class=\"avatar\">EvilTrout said:</div>\n<blockquote>ddd</blockquote></aside></p>"
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      it "trims spaces on quote params" do
 | 
					      it "trims spaces on quote params" do
 | 
				
			||||||
        PrettyText.cook("[quote=\"EvilTrout, post:555, topic: 666\"]ddd[/quote]").should match_html "<p><aside class=\"quote\" data-post=\"555\" data-topic=\"666\"><div class=\"title\">\n<div class=\"quote-controls\"></div>\n<img width=\"20\" height=\"20\" src=\"http://test.localhost/uploads/default/avatars/42d/57c/46ce7ee487/40.png\" class=\"avatar\">\nEvilTrout said:</div>\n<blockquote>ddd</blockquote></aside></p>"
 | 
					        PrettyText.cook("[quote=\"EvilTrout, post:555, topic: 666\"]ddd[/quote]").should match_html "<p><aside class=\"quote\" data-post=\"555\" data-topic=\"666\"><div class=\"title\">\n<div class=\"quote-controls\"></div>\n<img width=\"20\" height=\"20\" src=\"http://test.localhost/uploads/default/avatars/42d/57c/46ce7ee487/40.png\" class=\"avatar\">EvilTrout said:</div>\n<blockquote>ddd</blockquote></aside></p>"
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -88,7 +88,7 @@ test("quote formatting", function() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  format("[quote=\"eviltrout, post:1, topic:1\"]abc[/quote]\nhello",
 | 
					  format("[quote=\"eviltrout, post:1, topic:1\"]abc[/quote]\nhello",
 | 
				
			||||||
         "<aside class=\"quote\" data-post=\"1\" data-topic=\"1\"><div class=\"title\"><div class=\"quote-controls\"></div>eviltrout said:" +
 | 
					         "<aside class=\"quote\" data-post=\"1\" data-topic=\"1\"><div class=\"title\"><div class=\"quote-controls\"></div>eviltrout said:" +
 | 
				
			||||||
         "</div><blockquote>abc</blockquote></aside></p>\n\n<p>\nhello",
 | 
					         "</div><blockquote>abc</blockquote></aside></p>\n\n<p>hello",
 | 
				
			||||||
         "handles new lines properly");
 | 
					         "handles new lines properly");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -20,8 +20,7 @@ test("basic cooking", function() {
 | 
				
			|||||||
  cooked("***hello***", "<p><strong><em>hello</em></strong></p>", "it can do bold and italics at once.");
 | 
					  cooked("***hello***", "<p><strong><em>hello</em></strong></p>", "it can do bold and italics at once.");
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
test("Line Breaks", function() {
 | 
					test("Traditional Line Breaks", function() {
 | 
				
			||||||
 | 
					 | 
				
			||||||
  var input = "1\n2\n3";
 | 
					  var input = "1\n2\n3";
 | 
				
			||||||
  cooked(input, "<p>1<br>2<br>3</p>", "automatically handles trivial newlines");
 | 
					  cooked(input, "<p>1<br>2<br>3</p>", "automatically handles trivial newlines");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -34,7 +33,12 @@ test("Line Breaks", function() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  Discourse.SiteSettings.traditional_markdown_linebreaks = true;
 | 
					  Discourse.SiteSettings.traditional_markdown_linebreaks = true;
 | 
				
			||||||
  cooked(input, traditionalOutput, "It supports traditional markdown via a Site Setting");
 | 
					  cooked(input, traditionalOutput, "It supports traditional markdown via a Site Setting");
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					test("Line Breaks", function() {
 | 
				
			||||||
 | 
					  cooked("[] first choice\n[] second choice",
 | 
				
			||||||
 | 
					         "<p>[] first choice<br>[] second choice</p>",
 | 
				
			||||||
 | 
					         "it handles new lines correctly with [] options");
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
test("Links", function() {
 | 
					test("Links", function() {
 | 
				
			||||||
@@ -79,11 +83,10 @@ test("Links", function() {
 | 
				
			|||||||
         "<p>Here's a tweet:<br><a href=\"https://twitter.com/evil_trout/status/345954894420787200\" class=\"onebox\">https://twitter.com/evil_trout/status/345954894420787200</a></p>",
 | 
					         "<p>Here's a tweet:<br><a href=\"https://twitter.com/evil_trout/status/345954894420787200\" class=\"onebox\">https://twitter.com/evil_trout/status/345954894420787200</a></p>",
 | 
				
			||||||
         "It doesn't strip the new line.");
 | 
					         "It doesn't strip the new line.");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  cooked("1. View @eviltrout's profile here: http://meta.discourse.org/users/eviltrout/activity\nnext line.",
 | 
					  cooked("1. View @eviltrout's profile here: http://meta.discourse.org/users/eviltrout/activity<br>next line.",
 | 
				
			||||||
        "<ol><li>View <span class=\"mention\">@eviltrout</span>'s profile here: <a href=\"http://meta.discourse.org/users/eviltrout/activity\">http://meta.discourse.org/users/eviltrout/activity</a><br>next line.</li></ol>",
 | 
					        "<ol><li>View <span class=\"mention\">@eviltrout</span>'s profile here: <a href=\"http://meta.discourse.org/users/eviltrout/activity\">http://meta.discourse.org/users/eviltrout/activity</a><br>next line.</li></ol>",
 | 
				
			||||||
        "allows autolinking within a list without inserting a paragraph.");
 | 
					        "allows autolinking within a list without inserting a paragraph.");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
  cooked("[3]: http://eviltrout.com", "", "It doesn't autolink markdown link references");
 | 
					  cooked("[3]: http://eviltrout.com", "", "It doesn't autolink markdown link references");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  cooked("http://discourse.org and http://discourse.org/another_url and http://www.imdb.com/name/nm2225369",
 | 
					  cooked("http://discourse.org and http://discourse.org/another_url and http://www.imdb.com/name/nm2225369",
 | 
				
			||||||
@@ -98,13 +101,13 @@ test("Quotes", function() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  cookedOptions("[quote=\"eviltrout, post: 1\"]\na quote\n\nsecond line\n[/quote]",
 | 
					  cookedOptions("[quote=\"eviltrout, post: 1\"]\na quote\n\nsecond line\n[/quote]",
 | 
				
			||||||
                { topicId: 2 },
 | 
					                { topicId: 2 },
 | 
				
			||||||
                "<p><aside class=\"quote\" data-post=\"1\"><div class=\"title\"><div class=\"quote-controls\"></div>eviltrout said:</div><blockquote>\n" +
 | 
					                "<p><aside class=\"quote\" data-post=\"1\"><div class=\"title\"><div class=\"quote-controls\"></div>eviltrout said:</div><blockquote>" +
 | 
				
			||||||
                "a quote<br/><br/>second line<br/></blockquote></aside></p>",
 | 
					                "a quote<br/><br/>second line<br/></blockquote></aside></p>",
 | 
				
			||||||
                "works with multiple lines");
 | 
					                "works with multiple lines");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  cookedOptions("1[quote=\"bob, post:1\"]my quote[/quote]2",
 | 
					  cookedOptions("1[quote=\"bob, post:1\"]my quote[/quote]2",
 | 
				
			||||||
                { topicId: 2, lookupAvatar: function(name) { return "" + name; } },
 | 
					                { topicId: 2, lookupAvatar: function(name) { return "" + name; } },
 | 
				
			||||||
                "<p>1</p>\n\n<p><aside class=\"quote\" data-post=\"1\"><div class=\"title\"><div class=\"quote-controls\"></div>bob\n" +
 | 
					                "<p>1</p>\n\n<p><aside class=\"quote\" data-post=\"1\"><div class=\"title\"><div class=\"quote-controls\"></div>bob" +
 | 
				
			||||||
                "bob said:</div><blockquote>my quote</blockquote></aside></p>\n\n<p>2</p>",
 | 
					                "bob said:</div><blockquote>my quote</blockquote></aside></p>\n\n<p>2</p>",
 | 
				
			||||||
                "handles quotes properly");
 | 
					                "handles quotes properly");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -138,7 +141,7 @@ test("Mentions", function() {
 | 
				
			|||||||
         "handles mentions in simple quotes");
 | 
					         "handles mentions in simple quotes");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  cooked("> foo bar baz @eviltrout ohmagerd\nlook at this",
 | 
					  cooked("> foo bar baz @eviltrout ohmagerd\nlook at this",
 | 
				
			||||||
         "<blockquote><p>foo bar baz <span class=\"mention\">@eviltrout</span> ohmagerd\nlook at this</p></blockquote>",
 | 
					         "<blockquote><p>foo bar baz <span class=\"mention\">@eviltrout</span> ohmagerd<br>look at this</p></blockquote>",
 | 
				
			||||||
         "does mentions properly with trailing text within a simple quote");
 | 
					         "does mentions properly with trailing text within a simple quote");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  cooked("`code` is okay before @mention",
 | 
					  cooked("`code` is okay before @mention",
 | 
				
			||||||
@@ -162,7 +165,7 @@ test("Mentions", function() {
 | 
				
			|||||||
         "you can have a mention in an inline code block following a real mention.");
 | 
					         "you can have a mention in an inline code block following a real mention.");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  cooked("1. this is  a list\n\n2. this is an @eviltrout mention\n",
 | 
					  cooked("1. this is  a list\n\n2. this is an @eviltrout mention\n",
 | 
				
			||||||
         "<ol><li><p>this is  a list</p></li><li><p>this is an <span class=\"mention\">@eviltrout</span> mention  </p></li></ol>",
 | 
					         "<ol><li><p>this is  a list</p></li><li><p>this is an <span class=\"mention\">@eviltrout</span> mention</p></li></ol>",
 | 
				
			||||||
         "it mentions properly in a list.");
 | 
					         "it mentions properly in a list.");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  cookedOptions("@eviltrout", alwaysTrue,
 | 
					  cookedOptions("@eviltrout", alwaysTrue,
 | 
				
			||||||
@@ -202,7 +205,7 @@ test("Code Blocks", function() {
 | 
				
			|||||||
         "it supports basic code blocks");
 | 
					         "it supports basic code blocks");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  cooked("```json\n{hello: 'world'}\n```\ntrailing",
 | 
					  cooked("```json\n{hello: 'world'}\n```\ntrailing",
 | 
				
			||||||
         "<p><pre><code class=\"json\">{hello: 'world'}</code></pre></p>\n\n<p>\ntrailing</p>",
 | 
					         "<p><pre><code class=\"json\">{hello: 'world'}</code></pre></p>\n\n<p>trailing</p>",
 | 
				
			||||||
         "It does not truncate text after a code block.");
 | 
					         "It does not truncate text after a code block.");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  cooked("```json\nline 1\n\nline 2\n\n\nline3\n```",
 | 
					  cooked("```json\nline 1\n\nline 2\n\n\nline3\n```",
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user