From 684150d36dce827a664dc56c6c74f538aae907a4 Mon Sep 17 00:00:00 2001 From: Hannah Wolfe Date: Sun, 1 Sep 2013 16:32:54 +0100 Subject: [PATCH] GFM Auto-linking fixes closes #577 - auto-linking was interfering with things that were already a link - now checks to ensure we are not in a HTML or markdown link already - added tonnes of new tests --- .../vendor/showdown/extensions/github.js | 31 +-- core/test/unit/client_showdown_int_spec.js | 147 ++++++++++++-- core/test/unit/shared_gfm_spec.js | 185 +++++++++++++++++- 3 files changed, 328 insertions(+), 35 deletions(-) diff --git a/core/shared/vendor/showdown/extensions/github.js b/core/shared/vendor/showdown/extensions/github.js index e8d81f564a..6c2ad2dd50 100644 --- a/core/shared/vendor/showdown/extensions/github.js +++ b/core/shared/vendor/showdown/extensions/github.js @@ -63,29 +63,34 @@ } // filter out def urls - text = text.replace(/^ *\[([^\]]+)\]: *]+)>?(?: +["(]([^\n]+)[")])? *(?:\n+|$)/gim, + // from Marked https://github.com/chjj/marked/blob/master/lib/marked.js#L24 + text = text.replace(/^ *\[([^\]]+)\]: *]+)>?(?: +["(]([^\n]+)[")])? *(?:\n+|$)/gmi, function (x) { var hash = hashId(); extractions[hash] = x; return "{gfm-js-extract-ref-url-" + hash + "}"; }); - // taken from https://gist.github.com/jorilallo/1283095#L158 - text = text.replace(/https?\:\/\/[^"\s\<\>]*[^.,;'">\:\s\<\>\)\]\!]/g, function (wholeMatch, matchIndex) { - var left = text.slice(0, matchIndex), right = text.slice(matchIndex), - href; - if (left.match(/<[^>]+$/) && right.match(/^[^>]*>/)) { - return wholeMatch; - } - href = wholeMatch.replace(/^http:\/\/github.com\//, "https://github.com/"); - return "" + wholeMatch + ""; - }); + // match a URL + // adapted from https://gist.github.com/jorilallo/1283095#L158 + // and http://blog.stevenlevithan.com/archives/mimic-lookbehind-javascript + text = text.replace(/(\]\(|\]|\[|]*?\>)?https?\:\/\/[^"\s\<\>]*[^.,;'">\:\s\<\>\)\]\!]/gmi, + function (wholeMatch, lookBehind, matchIndex) { + // Check we are not inside an HTML tag + var left = text.slice(0, matchIndex), right = text.slice(matchIndex); + if ((left.match(/<[^>]+$/) && right.match(/^[^>]*>/)) || lookBehind) { + return wholeMatch; + } + // If we have a matching lookBehind, this is a failure, else wrap the match in tag + return lookBehind ? wholeMatch : "" + wholeMatch + ""; + }); - text = text.replace(/[a-z0-9_\-+=.]+@[a-z0-9\-]+(\.[a-z0-9-]+)+/ig, function (wholeMatch) { + // match emil + text = text.replace(/[a-z0-9_\-+=.]+@[a-z0-9\-]+(\.[a-z0-9-]+)+/gmi, function (wholeMatch) { return "" + wholeMatch + ""; }); - text = text.replace(/\{gfm-js-extract-ref-url-([0-9]+)\}/gm, function (x, y) { + text = text.replace(/\{gfm-js-extract-ref-url-([0-9]+)\}/gi, function (x, y) { return "\n\n" + extractions[y]; }); diff --git a/core/test/unit/client_showdown_int_spec.js b/core/test/unit/client_showdown_int_spec.js index b826514945..ae4cd4773a 100644 --- a/core/test/unit/client_showdown_int_spec.js +++ b/core/test/unit/client_showdown_int_spec.js @@ -136,12 +136,43 @@ describe("Showdown client side converter", function () { }); }); - it("should auto-link URL", function () { + it("should auto-link URL in text with markdown syntax", function () { var testPhrases = [ - {input: "http://google.co.uk", output: /^

http:\/\/google.co.uk<\/a><\/p>$/}, + { + input: "http://google.co.uk", + output: /^

http:\/\/google.co.uk<\/a><\/p>$/ + }, { input: "https://atest.com/fizz/buzz?baz=fizzbuzz", output: /^

https:\/\/atest.com\/fizz\/buzz\?baz=fizzbuzz<\/a><\/p>$/ + }, + { + input: "Some [ text (http://www.google.co.uk) some other text", + output: /^

Some \[ text \(http:\/\/www.google.co.uk<\/a>\) some other text<\/p>$/ + }, + { + input: ">http://google.co.uk", + output: /^

\n

http:\/\/google.co.uk<\/a><\/p>\n<\/blockquote>$/ + }, + { + input: "> http://google.co.uk", + output: /^

\n

http:\/\/google.co.uk<\/a><\/p>\n<\/blockquote>$/ + }, + { + input: "<>>> http://google.co.uk", + output: /^

<>>> http:\/\/google.co.uk<\/a><\/p>$/ + }, + { + input: "http://google.co.uk", + output: /^

http:\/\/google.co.uk<\/a><\/p>$/ + }, + { + input: "# http://google.co.uk", + output: /^

http:\/\/google.co.uk<\/a><\/h1>$/ + }, + { + input: "* http://google.co.uk", + output: /^