2013-06-21 23:36:33 +08:00
module ( "Discourse.Markdown" , {
setup : function ( ) {
Discourse . SiteSettings . traditional _markdown _linebreaks = false ;
}
} ) ;
2013-06-19 06:03:36 +08:00
var cooked = function ( input , expected , text ) {
2014-04-15 04:51:18 +08:00
var result = Discourse . Markdown . cook ( input , { sanitize : true } ) ;
2014-07-04 04:54:56 +08:00
expected = expected . replace ( /\/>/g , ">" ) ;
// result = result.replace("/>", ">");
2013-08-09 06:14:12 +08:00
equal ( result , expected , text ) ;
2013-06-19 06:03:36 +08:00
} ;
var cookedOptions = function ( input , opts , expected , text ) {
equal ( Discourse . Markdown . cook ( input , opts ) , expected , text ) ;
2013-06-22 02:06:20 +08:00
} ;
2013-06-19 06:03:36 +08:00
test ( "basic cooking" , function ( ) {
cooked ( "hello" , "<p>hello</p>" , "surrounds text with paragraphs" ) ;
2013-08-28 00:24:17 +08:00
cooked ( "**evil**" , "<p><strong>evil</strong></p>" , "it bolds text." ) ;
2013-08-28 23:14:06 +08:00
cooked ( "__bold__" , "<p><strong>bold</strong></p>" , "it bolds text." ) ;
2013-08-28 00:24:17 +08:00
cooked ( "*trout*" , "<p><em>trout</em></p>" , "it italicizes text." ) ;
cooked ( "_trout_" , "<p><em>trout</em></p>" , "it italicizes text." ) ;
2014-06-10 05:46:17 +08:00
cooked ( "*this is italic **with some bold** inside*" , "<p><em>this is italic <strong>with some bold</strong> inside</em></p>" , "it handles nested bold in italics" ) ;
2013-08-25 01:06:07 +08:00
cooked ( "***hello***" , "<p><strong><em>hello</em></strong></p>" , "it can do bold and italics at once." ) ;
2013-08-28 00:24:17 +08:00
cooked ( "word_with_underscores" , "<p>word_with_underscores</p>" , "it doesn't do intraword italics" ) ;
2013-08-30 22:56:41 +08:00
cooked ( "common/_special_font_face.html.erb" , "<p>common/_special_font_face.html.erb</p>" , "it doesn't intraword with a slash" ) ;
2013-08-28 00:24:17 +08:00
cooked ( "hello \\*evil\\*" , "<p>hello *evil*</p>" , "it supports escaping of asterisks" ) ;
cooked ( "hello \\_evil\\_" , "<p>hello _evil_</p>" , "it supports escaping of italics" ) ;
2013-08-28 23:14:06 +08:00
cooked ( "brussel sproutes are *awful*." , "<p>brussel sproutes are <em>awful</em>.</p>" , "it doesn't swallow periods." ) ;
2013-06-21 23:36:33 +08:00
} ) ;
2013-12-14 04:31:25 +08:00
test ( "Auto quoting" , function ( ) {
cooked ( '"My fake plants died because I did not pretend to water them."' ,
"<p><blockquote>My fake plants died because I did not pretend to water them.</blockquote></p>" ,
"it converts single line quotes to blockquotes" ) ;
cooked ( '"hello\nworld"' , "<p>\"hello<br/>world\"</p>" , "It doesn't convert multi line quotes" ) ;
cooked ( '"hello "evil" trout"' , '<p>"hello "evil" trout"</p>' , "it doesn't format quotes in the middle of a line" ) ;
} ) ;
2013-08-27 03:21:23 +08:00
test ( "Traditional Line Breaks" , function ( ) {
2013-06-21 23:36:33 +08:00
var input = "1\n2\n3" ;
2013-09-12 03:52:37 +08:00
cooked ( input , "<p>1<br/>2<br/>3</p>" , "automatically handles trivial newlines" ) ;
2013-06-21 23:36:33 +08:00
var traditionalOutput = "<p>1\n2\n3</p>" ;
cookedOptions ( input ,
{ traditional _markdown _linebreaks : true } ,
traditionalOutput ,
2013-06-22 02:06:20 +08:00
"It supports traditional markdown via an option" ) ;
2013-06-21 23:36:33 +08:00
Discourse . SiteSettings . traditional _markdown _linebreaks = true ;
2013-06-22 02:06:20 +08:00
cooked ( input , traditionalOutput , "It supports traditional markdown via a Site Setting" ) ;
2013-08-27 03:21:23 +08:00
} ) ;
2013-06-21 23:36:33 +08:00
2013-11-21 00:53:06 +08:00
test ( "Unbalanced underscores" , function ( ) {
cooked ( "[evil_trout][1] hello_\n\n[1]: http://eviltrout.com" , "<p><a href=\"http://eviltrout.com\">evil_trout</a> hello_</p>" ) ;
} ) ;
2013-08-27 03:21:23 +08:00
test ( "Line Breaks" , function ( ) {
cooked ( "[] first choice\n[] second choice" ,
2013-09-12 03:52:37 +08:00
"<p>[] first choice<br/>[] second choice</p>" ,
2013-08-27 03:21:23 +08:00
"it handles new lines correctly with [] options" ) ;
2013-10-19 03:20:27 +08:00
cooked ( "<blockquote>evil</blockquote>\ntrout" ,
"<blockquote>evil</blockquote>\n\n<p>trout</p>" ,
"it doesn't insert <br> after blockquotes" ) ;
cooked ( "leading<blockquote>evil</blockquote>\ntrout" ,
"leading<blockquote>evil</blockquote>\n\n<p>trout</p>" ,
"it doesn't insert <br> after blockquotes with leading text" ) ;
2013-06-19 06:03:36 +08:00
} ) ;
2013-10-19 03:20:27 +08:00
test ( "Paragraphs for HTML" , function ( ) {
cooked ( "<div>hello world</div>" , "<div>hello world</div>" , "it doesn't surround <div> with paragraphs" ) ;
cooked ( "<p>hello world</p>" , "<p>hello world</p>" , "it doesn't surround <p> with paragraphs" ) ;
cooked ( "<i>hello world</i>" , "<p><i>hello world</i></p>" , "it surrounds inline <i> html tags with paragraphs" ) ;
cooked ( "<b>hello world</b>" , "<p><b>hello world</b></p>" , "it surrounds inline <b> html tags with paragraphs" ) ;
} ) ;
2013-06-19 06:03:36 +08:00
test ( "Links" , function ( ) {
2013-08-09 06:14:12 +08:00
2013-08-23 06:03:01 +08:00
cooked ( "EvilTrout: http://eviltrout.com" ,
'<p>EvilTrout: <a href="http://eviltrout.com">http://eviltrout.com</a></p>' ,
"autolinks a URL" ) ;
2013-06-19 06:03:36 +08:00
cooked ( "Youtube: http://www.youtube.com/watch?v=1MrpeBRkM5A" ,
'<p>Youtube: <a href="http://www.youtube.com/watch?v=1MrpeBRkM5A">http://www.youtube.com/watch?v=1MrpeBRkM5A</a></p>' ,
"allows links to contain query params" ) ;
cooked ( "Derpy: http://derp.com?__test=1" ,
2013-08-09 06:14:12 +08:00
'<p>Derpy: <a href="http://derp.com?__test=1">http://derp.com?__test=1</a></p>' ,
"works with double underscores in urls" ) ;
cooked ( "Derpy: http://derp.com?_test_=1" ,
'<p>Derpy: <a href="http://derp.com?_test_=1">http://derp.com?_test_=1</a></p>' ,
"works with underscores in urls" ) ;
2013-06-19 06:03:36 +08:00
cooked ( "Atwood: www.codinghorror.com" ,
'<p>Atwood: <a href="http://www.codinghorror.com">www.codinghorror.com</a></p>' ,
"autolinks something that begins with www" ) ;
cooked ( "Atwood: http://www.codinghorror.com" ,
'<p>Atwood: <a href="http://www.codinghorror.com">http://www.codinghorror.com</a></p>' ,
"autolinks a URL with http://www" ) ;
2013-08-22 10:49:55 +08:00
cooked ( "EvilTrout: http://eviltrout.com hello" ,
'<p>EvilTrout: <a href="http://eviltrout.com">http://eviltrout.com</a> hello</p>' ,
"autolinks with trailing text" ) ;
2013-06-19 06:03:36 +08:00
cooked ( "here is [an example](http://twitter.com)" ,
'<p>here is <a href="http://twitter.com">an example</a></p>' ,
"supports markdown style links" ) ;
cooked ( "Batman: http://en.wikipedia.org/wiki/The_Dark_Knight_(film)" ,
'<p>Batman: <a href="http://en.wikipedia.org/wiki/The_Dark_Knight_(film)">http://en.wikipedia.org/wiki/The_Dark_Knight_(film)</a></p>' ,
"autolinks a URL with parentheses (like Wikipedia)" ) ;
2013-08-09 06:14:12 +08:00
cooked ( "Here's a tweet:\nhttps://twitter.com/evil_trout/status/345954894420787200" ,
2013-09-12 03:52:37 +08:00
"<p>Here's a tweet:<br/><a href=\"https://twitter.com/evil_trout/status/345954894420787200\" class=\"onebox\" target=\"_blank\">https://twitter.com/evil_trout/status/345954894420787200</a></p>" ,
2013-08-09 06:14:12 +08:00
"It doesn't strip the new line." ) ;
2013-09-12 03:52:37 +08:00
cooked ( "1. View @eviltrout's profile here: http://meta.discourse.org/users/eviltrout/activity<br/>next line." ,
2013-08-23 06:03:01 +08:00
"<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." ) ;
2013-08-09 06:14:12 +08:00
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" ,
"<p><a href=\"http://discourse.org\">http://discourse.org</a> and " +
"<a href=\"http://discourse.org/another_url\">http://discourse.org/another_url</a> and " +
"<a href=\"http://www.imdb.com/name/nm2225369\">http://www.imdb.com/name/nm2225369</a></p>" ,
'allows multiple links on one line' ) ;
2013-08-29 01:06:41 +08:00
cooked ( "* [Evil Trout][1]\n [1]: http://eviltrout.com" ,
2013-09-12 03:52:37 +08:00
"<ul><li><a href=\"http://eviltrout.com\">Evil Trout</a></li></ul>" ,
2013-08-29 01:06:41 +08:00
"allows markdown link references in a list" ) ;
2013-10-22 02:16:23 +08:00
cooked ( "User [MOD]: Hello!" ,
"<p>User [MOD]: Hello!</p>" ,
"It does not consider references that are obviously not URLs" ) ;
2014-07-04 04:54:56 +08:00
cooked ( "<small>http://eviltrout.com</small>" , "<p><small><a href=\"http://eviltrout.com\">http://eviltrout.com</a></small></p>" , "Links within HTML tags" ) ;
2014-07-15 02:26:48 +08:00
cooked ( "[http://google.com ... wat](http://discourse.org)" ,
"<p><a href=\"http://discourse.org\">http://google.com ... wat</a></p>" ,
"it supports linkins within links" ) ;
2013-06-19 06:03:36 +08:00
} ) ;
2013-08-30 03:18:27 +08:00
test ( "simple quotes" , function ( ) {
cooked ( "> nice!" , "<blockquote><p>nice!</p></blockquote>" , "it supports simple quotes" ) ;
cooked ( " > nice!" , "<blockquote><p>nice!</p></blockquote>" , "it allows quotes with preceeding spaces" ) ;
cooked ( "> level 1\n> > level 2" ,
"<blockquote><p>level 1</p><blockquote><p>level 2</p></blockquote></blockquote>" ,
"it allows nesting of blockquotes" ) ;
cooked ( "> level 1\n> > level 2" ,
"<blockquote><p>level 1</p><blockquote><p>level 2</p></blockquote></blockquote>" ,
"it allows nesting of blockquotes with spaces" ) ;
2013-09-06 05:03:35 +08:00
cooked ( "- hello\n\n > world\n > eviltrout" ,
2013-09-12 03:52:37 +08:00
"<ul><li>hello</li></ul>\n\n<blockquote><p>world<br/>eviltrout</p></blockquote>" ,
2013-09-06 05:03:35 +08:00
"it allows quotes within a list." ) ;
2014-07-16 04:41:53 +08:00
cooked ( "- <p>eviltrout</p>" ,
"<ul><li><p>eviltrout</p></li></ul>" ,
"it allows paragraphs within a list." ) ;
2013-09-12 03:52:37 +08:00
cooked ( " > indent 1\n > indent 2" , "<blockquote><p>indent 1<br/>indent 2</p></blockquote>" , "allow multiple spaces to indent" ) ;
2013-09-06 05:03:35 +08:00
2013-08-30 03:18:27 +08:00
} ) ;
2013-06-19 06:03:36 +08:00
test ( "Quotes" , function ( ) {
2013-08-22 10:36:02 +08:00
2013-09-28 03:08:30 +08:00
cookedOptions ( "[quote=\"eviltrout, post: 1\"]\na quote\n\nsecond line\n\nthird line[/quote]" ,
2013-08-22 10:36:02 +08:00
{ topicId : 2 } ,
2014-07-01 06:10:46 +08:00
"<aside class=\"quote\" data-post=\"1\"><div class=\"title\"><div class=\"quote-controls\"></div>eviltrout said:</div><blockquote>" +
"<p>a quote</p><p>second line</p><p>third line</p></blockquote></aside>" ,
2013-08-22 10:36:02 +08:00
"works with multiple lines" ) ;
2013-06-19 06:03:36 +08:00
cookedOptions ( "1[quote=\"bob, post:1\"]my quote[/quote]2" ,
2013-09-12 03:52:37 +08:00
{ topicId : 2 , lookupAvatar : function ( name ) { return "" + name ; } , sanitize : true } ,
2014-07-01 06:10:46 +08:00
"<p>1</p>\n\n<aside class=\"quote\" data-post=\"1\"><div class=\"title\"><div class=\"quote-controls\"></div>bob" +
"bob said:</div><blockquote><p>my quote</p></blockquote></aside>\n\n<p>2</p>" ,
2013-06-19 06:03:36 +08:00
"handles quotes properly" ) ;
cookedOptions ( "1[quote=\"bob, post:1\"]my quote[/quote]2" ,
2013-12-31 02:29:52 +08:00
{ topicId : 2 , lookupAvatar : function ( ) { } } ,
2014-07-01 06:10:46 +08:00
"<p>1</p>\n\n<aside class=\"quote\" data-post=\"1\"><div class=\"title\"><div class=\"quote-controls\"></div>bob said:" +
"</div><blockquote><p>my quote</p></blockquote></aside>\n\n<p>2</p>" ,
2013-06-19 06:03:36 +08:00
"includes no avatar if none is found" ) ;
2013-06-27 06:41:48 +08:00
} ) ;
2013-06-19 06:03:36 +08:00
test ( "Mentions" , function ( ) {
2013-08-25 03:00:18 +08:00
var alwaysTrue = { mentionLookup : ( function ( ) { return true ; } ) } ;
cookedOptions ( "Hello @sam" , alwaysTrue ,
2013-08-09 06:14:12 +08:00
"<p>Hello <a class=\"mention\" href=\"/users/sam\">@sam</a></p>" ,
2013-06-19 06:03:36 +08:00
"translates mentions to links" ) ;
2014-05-07 05:48:11 +08:00
cooked ( "[@codinghorror](https://twitter.com/codinghorror)" ,
"<p><a href=\"https://twitter.com/codinghorror\">@codinghorror</a></p>" ,
"it doesn't do mentions within links" ) ;
cookedOptions ( "[@codinghorror](https://twitter.com/codinghorror)" , alwaysTrue ,
"<p><a href=\"https://twitter.com/codinghorror\">@codinghorror</a></p>" ,
"it doesn't do link mentions within links" ) ;
2013-08-09 06:14:12 +08:00
cooked ( "Hello @EvilTrout" , "<p>Hello <span class=\"mention\">@EvilTrout</span></p>" , "adds a mention class" ) ;
2013-06-19 06:03:36 +08:00
cooked ( "robin@email.host" , "<p>robin@email.host</p>" , "won't add mention class to an email address" ) ;
cooked ( "hanzo55@yahoo.com" , "<p>hanzo55@yahoo.com</p>" , "won't be affected by email addresses that have a number before the @ symbol" ) ;
2013-08-09 06:14:12 +08:00
cooked ( "@EvilTrout yo" , "<p><span class=\"mention\">@EvilTrout</span> yo</p>" , "it handles mentions at the beginning of a string" ) ;
2013-09-12 03:52:37 +08:00
cooked ( "yo\n@EvilTrout" , "<p>yo<br/><span class=\"mention\">@EvilTrout</span></p>" , "it handles mentions at the beginning of a new line" ) ;
2013-06-19 06:03:36 +08:00
cooked ( "`evil` @EvilTrout `trout`" ,
2013-08-09 06:14:12 +08:00
"<p><code>evil</code> <span class=\"mention\">@EvilTrout</span> <code>trout</code></p>" ,
2013-06-19 06:03:36 +08:00
"deals correctly with multiple <code> blocks" ) ;
2013-08-09 06:14:12 +08:00
cooked ( "```\na @test\n```" , "<p><pre><code class=\"lang-auto\">a @test</code></pre></p>" , "should not do mentions within a code block." ) ;
2013-06-19 06:03:36 +08:00
2013-08-22 04:10:16 +08:00
cooked ( "> foo bar baz @eviltrout" ,
"<blockquote><p>foo bar baz <span class=\"mention\">@eviltrout</span></p></blockquote>" ,
"handles mentions in simple quotes" ) ;
cooked ( "> foo bar baz @eviltrout ohmagerd\nlook at this" ,
2013-09-12 03:52:37 +08:00
"<blockquote><p>foo bar baz <span class=\"mention\">@eviltrout</span> ohmagerd<br/>look at this</p></blockquote>" ,
2013-08-22 04:10:16 +08:00
"does mentions properly with trailing text within a simple quote" ) ;
2013-08-23 00:18:03 +08:00
cooked ( "`code` is okay before @mention" ,
"<p><code>code</code> is okay before <span class=\"mention\">@mention</span></p>" ,
"Does not mention in an inline code block" ) ;
cooked ( "@mention is okay before `code`" ,
"<p><span class=\"mention\">@mention</span> is okay before <code>code</code></p>" ,
"Does not mention in an inline code block" ) ;
cooked ( "don't `@mention`" ,
"<p>don't <code>@mention</code></p>" ,
"Does not mention in an inline code block" ) ;
2013-08-23 03:54:41 +08:00
cooked ( "Yes `@this` should be code @eviltrout" ,
"<p>Yes <code>@this</code> should be code <span class=\"mention\">@eviltrout</span></p>" ,
"Does not mention in an inline code block" ) ;
2013-08-23 04:13:02 +08:00
cooked ( "@eviltrout and `@eviltrout`" ,
"<p><span class=\"mention\">@eviltrout</span> and <code>@eviltrout</code></p>" ,
"you can have a mention in an inline code block following a real mention." ) ;
2013-08-23 05:50:07 +08:00
cooked ( "1. this is a list\n\n2. this is an @eviltrout mention\n" ,
2013-08-27 03:21:23 +08:00
"<ol><li><p>this is a list</p></li><li><p>this is an <span class=\"mention\">@eviltrout</span> mention</p></li></ol>" ,
2013-08-23 05:50:07 +08:00
"it mentions properly in a list." ) ;
2013-08-25 03:00:18 +08:00
cookedOptions ( "@eviltrout" , alwaysTrue ,
"<p><a class=\"mention\" href=\"/users/eviltrout\">@eviltrout</a></p>" ,
"it doesn't onebox mentions" ) ;
2014-07-04 04:54:56 +08:00
cookedOptions ( "<small>a @sam c</small>" , alwaysTrue ,
"<p><small>a <a class=\"mention\" href=\"/users/sam\">@sam</a> c</small></p>" ,
"it allows mentions within HTML tags" ) ;
2013-06-19 06:03:36 +08:00
} ) ;
2013-10-16 22:39:06 +08:00
test ( "Heading" , function ( ) {
cooked ( "**Bold**\n----------" ,
"<h2><strong>Bold</strong></h2>" ,
"It will bold the heading" ) ;
} ) ;
2013-06-19 06:03:36 +08:00
test ( "Oneboxing" , function ( ) {
var matches = function ( input , regexp ) {
2014-04-15 04:51:18 +08:00
return Discourse . Markdown . cook ( input ) . match ( regexp ) ;
2013-06-19 06:03:36 +08:00
} ;
ok ( ! matches ( "- http://www.textfiles.com/bbs/MINDVOX/FORUMS/ethics\n\n- http://drupal.org" , /onebox/ ) ,
2013-08-09 06:14:12 +08:00
"doesn't onebox a link within a list" ) ;
2013-06-19 06:03:36 +08:00
ok ( matches ( "http://test.com" , /onebox/ ) , "adds a onebox class to a link on its own line" ) ;
ok ( matches ( "http://test.com\nhttp://test2.com" , /onebox[\s\S]+onebox/m ) , "supports multiple links" ) ;
ok ( ! matches ( "http://test.com bob" , /onebox/ ) , "doesn't onebox links that have trailing text" ) ;
2013-09-07 04:46:55 +08:00
ok ( ! matches ( "[Tom Cruise](http://www.tomcruise.com/)" , "onebox" ) , "Markdown links with labels are not oneboxed" ) ;
ok ( matches ( "[http://www.tomcruise.com/](http://www.tomcruise.com/)" ,
"onebox" ) ,
"Markdown links where the label is the same as the url are oneboxed" ) ;
2013-06-19 06:03:36 +08:00
cooked ( "http://en.wikipedia.org/wiki/Homicide:_Life_on_the_Street" ,
2013-08-09 06:14:12 +08:00
"<p><a href=\"http://en.wikipedia.org/wiki/Homicide:_Life_on_the_Street\" class=\"onebox\"" +
2013-09-12 03:52:37 +08:00
" target=\"_blank\">http://en.wikipedia.org/wiki/Homicide:_Life_on_the_Street</a></p>" ,
2013-06-19 06:03:36 +08:00
"works with links that have underscores in them" ) ;
} ) ;
2013-11-05 03:24:40 +08:00
test ( "links with full urls" , function ( ) {
cooked ( "[http://eviltrout.com][1] is a url\n\n[1]: http://eviltrout.com" ,
"<p><a href=\"http://eviltrout.com\">http://eviltrout.com</a> is a url</p>" ,
"it supports links that are full URLs" ) ;
} ) ;
2013-08-09 06:14:12 +08:00
test ( "Code Blocks" , function ( ) {
2014-06-24 03:21:07 +08:00
cooked ( "<pre>\nhello\n</pre>\n" ,
"<p><pre>\nhello</pre></p>" ,
"pre blocks don't include extra lines" ) ;
2013-08-23 01:46:51 +08:00
cooked ( "```\na\nb\nc\n\nd\n```" ,
"<p><pre><code class=\"lang-auto\">a\nb\nc\n\nd</code></pre></p>" ,
"it treats new lines properly" ) ;
2013-08-09 06:14:12 +08:00
cooked ( "```\ntest\n```" ,
"<p><pre><code class=\"lang-auto\">test</code></pre></p>" ,
"it supports basic code blocks" ) ;
cooked ( "```json\n{hello: 'world'}\n```\ntrailing" ,
2013-08-27 03:21:23 +08:00
"<p><pre><code class=\"json\">{hello: 'world'}</code></pre></p>\n\n<p>trailing</p>" ,
2013-08-09 06:14:12 +08:00
"It does not truncate text after a code block." ) ;
cooked ( "```json\nline 1\n\nline 2\n\n\nline3\n```" ,
"<p><pre><code class=\"json\">line 1\n\nline 2\n\n\nline3</code></pre></p>" ,
"it maintains new lines inside a code block." ) ;
cooked ( "hello\nworld\n```json\nline 1\n\nline 2\n\n\nline3\n```" ,
2013-09-12 03:52:37 +08:00
"<p>hello<br/>world<br/></p>\n\n<p><pre><code class=\"json\">line 1\n\nline 2\n\n\nline3</code></pre></p>" ,
2013-08-09 06:14:12 +08:00
"it maintains new lines inside a code block with leading content." ) ;
cooked ( "```text\n<header>hello</header>\n```" ,
"<p><pre><code class=\"text\"><header>hello</header></code></pre></p>" ,
"it escapes code in the code block" ) ;
cooked ( "```ruby\n# cool\n```" ,
"<p><pre><code class=\"ruby\"># cool</code></pre></p>" ,
"it supports changing the language" ) ;
cooked ( " ```\n hello\n ```" ,
"<pre><code>```\nhello\n```</code></pre>" ,
"only detect ``` at the begining of lines" ) ;
2013-08-25 01:24:27 +08:00
cooked ( "```ruby\ndef self.parse(text)\n\n text\nend\n```" ,
"<p><pre><code class=\"ruby\">def self.parse(text)\n\n text\nend</code></pre></p>" ,
"it allows leading spaces on lines in a code block." ) ;
2013-08-27 04:53:10 +08:00
cooked ( "```ruby\nhello `eviltrout`\n```" ,
"<p><pre><code class=\"ruby\">hello `eviltrout`</code></pre></p>" ,
"it allows code with backticks in it" ) ;
2013-08-30 02:42:31 +08:00
2013-10-22 01:10:19 +08:00
cooked ( "```eviltrout\nhello\n```" ,
"<p><pre><code class=\"lang-auto\">hello</code></pre></p>" ,
"it doesn't not whitelist all classes" ) ;
2013-08-30 02:42:31 +08:00
cooked ( "```[quote=\"sam, post:1, topic:9441, full:true\"]This is `<not>` a bug.[/quote]```" ,
"<p><pre><code class=\"lang-auto\">[quote="sam, post:1, topic:9441, full:true"]This is `<not>` a bug.[/quote]</code></pre></p>" ,
"it allows code with backticks in it" ) ;
2014-01-22 05:18:20 +08:00
cooked ( " hello\n<blockquote>test</blockquote>" ,
"<pre><code>hello</code></pre>\n\n<blockquote>test</blockquote>" ,
"it allows an indented code block to by followed by a `<blockquote>`" ) ;
2013-08-09 06:14:12 +08:00
} ) ;
2013-10-12 04:24:27 +08:00
test ( "sanitize" , function ( ) {
var sanitize = Discourse . Markdown . sanitize ;
2013-06-20 03:06:23 +08:00
2013-12-10 05:27:49 +08:00
equal ( sanitize ( "<i class=\"fa-bug fa-spin\">bug</i>" ) , "<i>bug</i>" ) ;
2013-10-12 04:24:27 +08:00
equal ( sanitize ( "<div><script>alert('hi');</script></div>" ) , "<div></div>" ) ;
equal ( sanitize ( "<div><p class=\"funky\" wrong='1'>hello</p></div>" ) , "<div><p>hello</p></div>" ) ;
2014-01-26 21:08:47 +08:00
equal ( sanitize ( "<3 <3" ) , "<3 <3" ) ;
equal ( sanitize ( "<_<" ) , "<_<" ) ;
2013-08-09 06:14:12 +08:00
cooked ( "hello<script>alert(42)</script>" , "<p>hello</p>" , "it sanitizes while cooking" ) ;
cooked ( "<a href='http://disneyland.disney.go.com/'>disney</a> <a href='http://reddit.com'>reddit</a>" ,
2013-10-19 03:20:27 +08:00
"<p><a href=\"http://disneyland.disney.go.com/\">disney</a> <a href=\"http://reddit.com\">reddit</a></p>" ,
2013-08-09 06:14:12 +08:00
"we can embed proper links" ) ;
2013-06-20 03:06:23 +08:00
2013-12-05 00:43:20 +08:00
cooked ( "<center>hello</center>" , "<p>hello</p>" , "it does not allow centering" ) ;
2013-10-22 01:32:15 +08:00
cooked ( "<table><tr><td>hello</td></tr></table>\nafter" , "<p>after</p>" , "it does not allow tables" ) ;
2013-10-19 03:20:27 +08:00
cooked ( "<blockquote>a\n</blockquote>\n" , "<blockquote>a\n\n<br/>\n\n</blockquote>" , "it does not double sanitize" ) ;
2013-11-30 01:08:53 +08:00
cooked ( "<iframe src=\"http://discourse.org\" width=\"100\" height=\"42\"></iframe>" , "" , "it does not allow most iframe" ) ;
cooked ( "<iframe src=\"https://www.google.com/maps/embed?pb=!1m10!1m8!1m3!1d2624.9983685732213!2d2.29432085!3d48.85824149999999!3m2!1i1024!2i768!4f13.1!5e0!3m2!1sen!2s!4v1385737436368\" width=\"100\" height=\"42\"></iframe>" ,
"<iframe src=\"https://www.google.com/maps/embed?pb=!1m10!1m8!1m3!1d2624.9983685732213!2d2.29432085!3d48.85824149999999!3m2!1i1024!2i768!4f13.1!5e0!3m2!1sen!2s!4v1385737436368\" width=\"100\" height=\"42\"></iframe>" ,
"it allows iframe to google maps" ) ;
2014-02-05 01:48:14 +08:00
equal ( sanitize ( "<textarea>hullo</textarea>" ) , "hullo" ) ;
2014-02-05 05:28:34 +08:00
equal ( sanitize ( "<button>press me!</button>" ) , "press me!" ) ;
2014-02-06 01:22:17 +08:00
equal ( sanitize ( "<canvas>draw me!</canvas>" ) , "draw me!" ) ;
2014-06-24 23:03:45 +08:00
equal ( sanitize ( "<progress>hello" ) , "hello" ) ;
equal ( sanitize ( "<mark>highlight</mark>" ) , "highlight" ) ;
2014-03-27 22:34:35 +08:00
cooked ( "[the answer](javascript:alert(42))" , "<p><a>the answer</a></p>" , "it prevents XSS" ) ;
2014-04-29 02:43:49 +08:00
2014-07-04 04:54:56 +08:00
cooked ( "<i class=\"fa fa-bug fa-spin\" style=\"font-size:600%\"></i>\n<!-- -->" , "<p><i></i><br/></p>" , "it doesn't circumvent XSS with comments" ) ;
2013-06-25 04:25:08 +08:00
} ) ;
2013-06-27 06:41:48 +08:00
test ( "URLs in BBCode tags" , function ( ) {
cooked ( "[img]http://eviltrout.com/eviltrout.png[/img][img]http://samsaffron.com/samsaffron.png[/img]" ,
2013-09-12 03:52:37 +08:00
"<p><img src=\"http://eviltrout.com/eviltrout.png\"/><img src=\"http://samsaffron.com/samsaffron.png\"/></p>" ,
2013-06-27 06:41:48 +08:00
"images are properly parsed" ) ;
cooked ( "[url]http://discourse.org[/url]" ,
"<p><a href=\"http://discourse.org\">http://discourse.org</a></p>" ,
"links are properly parsed" ) ;
cooked ( "[url=http://discourse.org]discourse[/url]" ,
"<p><a href=\"http://discourse.org\">discourse</a></p>" ,
"named links are properly parsed" ) ;
} ) ;
2013-10-12 04:24:27 +08:00
test ( "urlAllowed" , function ( ) {
2014-07-15 22:11:37 +08:00
var urlAllowed = Discourse . Markdown . urlAllowed ;
2013-10-12 04:24:27 +08:00
var allowed = function ( url , msg ) {
2014-07-15 22:11:37 +08:00
equal ( urlAllowed ( url ) , url , msg ) ;
2013-10-12 04:24:27 +08:00
} ;
allowed ( "/foo/bar.html" , "allows relative urls" ) ;
allowed ( "http://eviltrout.com/evil/trout" , "allows full urls" ) ;
allowed ( "https://eviltrout.com/evil/trout" , "allows https urls" ) ;
allowed ( "//eviltrout.com/evil/trout" , "allows protocol relative urls" ) ;
2014-07-15 22:11:37 +08:00
equal ( urlAllowed ( "http://google.com/test'onmouseover=alert('XSS!');//.swf" ) ,
"http://google.com/test'onmouseover=alert('XSS!');//.swf" ,
"escape single quotes" ) ;
2014-02-21 04:23:10 +08:00
} ) ;
test ( "images" , function ( ) {
2013-10-12 04:24:27 +08:00
2014-02-21 04:23:10 +08:00
cooked ( "[![folksy logo](http://folksy.com/images/folksy-colour.png)](http://folksy.com/)" ,
"<p><a href=\"http://folksy.com/\"><img src=\"http://folksy.com/images/folksy-colour.png\" alt=\"folksy logo\"/></a></p>" ,
"It allows images with links around them" ) ;
2013-10-12 04:24:27 +08:00
} ) ;