FIX: Autolinking within a list
This commit is contained in:
parent
513f941f50
commit
612c0ccccb
|
@ -14,51 +14,32 @@ Discourse.Dialect.on("register", function(event) {
|
||||||
Parses out links from HTML.
|
Parses out links from HTML.
|
||||||
|
|
||||||
@method autoLink
|
@method autoLink
|
||||||
@param {Markdown.Block} block the block to examine
|
@param {String} text the text match
|
||||||
@param {Array} next the next blocks in the sequence
|
@param {Array} match the match found
|
||||||
@return {Array} the JsonML containing the markup or undefined if nothing changed.
|
@param {Array} prev the previous jsonML
|
||||||
|
@return {Array} an array containing how many chars we've replaced and the jsonML content for it.
|
||||||
@namespace Discourse.Dialect
|
@namespace Discourse.Dialect
|
||||||
**/
|
**/
|
||||||
dialect.block['autolink'] = function autoLink(block, next) {
|
dialect.inline['http'] = dialect.inline['www'] = function autoLink(text, match, prev) {
|
||||||
|
|
||||||
|
// We only care about links on boundaries
|
||||||
|
if (prev && (prev.length > 0)) {
|
||||||
|
var last = prev[prev.length - 1];
|
||||||
|
if (typeof last === "string" && (!last.match(/\s$/))) { return; }
|
||||||
|
}
|
||||||
|
|
||||||
var pattern = /(^|\s)((?:https?:(?:\/{1,3}|[a-z0-9%])|www\d{0,3}[.])(?:[^\s()<>]+|\([^\s()<>]+\))+(?:\([^\s()<>]+\)|[^`!()\[\]{};:'".,<>?«»“”‘’\s]))/gm,
|
var pattern = /(^|\s)((?:https?:(?:\/{1,3}|[a-z0-9%])|www\d{0,3}[.])(?:[^\s()<>]+|\([^\s()<>]+\))+(?:\([^\s()<>]+\)|[^`!()\[\]{};:'".,<>?«»“”‘’\s]))/gm,
|
||||||
result,
|
m = pattern.exec(text);
|
||||||
remaining = block,
|
|
||||||
m;
|
|
||||||
|
|
||||||
var pushIt = function(p) { result.push(p) };
|
|
||||||
|
|
||||||
while (m = pattern.exec(remaining)) {
|
|
||||||
result = result || ['p'];
|
|
||||||
|
|
||||||
|
if (m) {
|
||||||
var url = m[2],
|
var url = m[2],
|
||||||
urlIndex = remaining.indexOf(url),
|
displayUrl = m[2];
|
||||||
before = remaining.slice(0, urlIndex);
|
|
||||||
|
|
||||||
if (before.match(/\[\d+\]/)) { return; }
|
|
||||||
|
|
||||||
pattern.lastIndex = 0;
|
|
||||||
remaining = remaining.slice(urlIndex + url.length);
|
|
||||||
|
|
||||||
if (before) {
|
|
||||||
this.processInline(before).forEach(pushIt);
|
|
||||||
}
|
|
||||||
|
|
||||||
var displayUrl = url;
|
|
||||||
if (url.match(/^www/)) { url = "http://" + url; }
|
if (url.match(/^www/)) { url = "http://" + url; }
|
||||||
result.push(['a', {href: url}, displayUrl]);
|
return [m[0].length, ['a', {href: url}, displayUrl]];
|
||||||
|
|
||||||
if (remaining && remaining.match(/\n/)) {
|
|
||||||
next.unshift(MD.mk_block(remaining));
|
|
||||||
remaining = [];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result) {
|
|
||||||
if (remaining.length) {
|
|
||||||
this.processInline(remaining).forEach(pushIt);
|
|
||||||
}
|
|
||||||
return [result];
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
});
|
});
|
|
@ -11,8 +11,17 @@ Discourse.Dialect.on("register", function(event) {
|
||||||
var dialect = event.dialect,
|
var dialect = event.dialect,
|
||||||
MD = event.MD;
|
MD = event.MD;
|
||||||
|
|
||||||
dialect.inline['@'] = function(text, match, prev) {
|
/**
|
||||||
var args = Array.prototype.slice.call(arguments);
|
Parses out @username mentions.
|
||||||
|
|
||||||
|
@method parseMentions
|
||||||
|
@param {String} text the text match
|
||||||
|
@param {Array} match the match found
|
||||||
|
@param {Array} prev the previous jsonML
|
||||||
|
@return {Array} an array containing how many chars we've replaced and the jsonML content for it.
|
||||||
|
@namespace Discourse.Dialect
|
||||||
|
**/
|
||||||
|
dialect.inline['@'] = function parseMentions(text, match, prev) {
|
||||||
|
|
||||||
// We only care about mentions on word boundaries
|
// We only care about mentions on word boundaries
|
||||||
if (prev && (prev.length > 0)) {
|
if (prev && (prev.length > 0)) {
|
||||||
|
@ -25,8 +34,7 @@ Discourse.Dialect.on("register", function(event) {
|
||||||
|
|
||||||
if (m) {
|
if (m) {
|
||||||
var username = m[1],
|
var username = m[1],
|
||||||
mentionLookup = dialect.options.mentionLookup || Discourse.Mention.lookupCache,
|
mentionLookup = dialect.options.mentionLookup || Discourse.Mention.lookupCache;
|
||||||
index = prev.indexOf(username);
|
|
||||||
|
|
||||||
if (mentionLookup(username.substr(1))) {
|
if (mentionLookup(username.substr(1))) {
|
||||||
return [username.length, ['a', {'class': 'mention', href: Discourse.getURL("/users/") + username.substr(1).toLowerCase()}, username]];
|
return [username.length, ['a', {'class': 'mention', href: Discourse.getURL("/users/") + username.substr(1).toLowerCase()}, username]];
|
||||||
|
|
|
@ -38,6 +38,10 @@ test("Line Breaks", function() {
|
||||||
|
|
||||||
test("Links", function() {
|
test("Links", function() {
|
||||||
|
|
||||||
|
cooked("EvilTrout: http://eviltrout.com",
|
||||||
|
'<p>EvilTrout: <a href="http://eviltrout.com">http://eviltrout.com</a></p>',
|
||||||
|
"autolinks a URL");
|
||||||
|
|
||||||
cooked("Youtube: http://www.youtube.com/watch?v=1MrpeBRkM5A",
|
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>',
|
'<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");
|
"allows links to contain query params");
|
||||||
|
@ -58,10 +62,6 @@ test("Links", function() {
|
||||||
'<p>Atwood: <a href="http://www.codinghorror.com">http://www.codinghorror.com</a></p>',
|
'<p>Atwood: <a href="http://www.codinghorror.com">http://www.codinghorror.com</a></p>',
|
||||||
"autolinks a URL with http://www");
|
"autolinks a URL with http://www");
|
||||||
|
|
||||||
cooked("EvilTrout: http://eviltrout.com",
|
|
||||||
'<p>EvilTrout: <a href="http://eviltrout.com">http://eviltrout.com</a></p>',
|
|
||||||
"autolinks a URL");
|
|
||||||
|
|
||||||
cooked("EvilTrout: http://eviltrout.com hello",
|
cooked("EvilTrout: http://eviltrout.com hello",
|
||||||
'<p>EvilTrout: <a href="http://eviltrout.com">http://eviltrout.com</a> hello</p>',
|
'<p>EvilTrout: <a href="http://eviltrout.com">http://eviltrout.com</a> hello</p>',
|
||||||
"autolinks with trailing text");
|
"autolinks with trailing text");
|
||||||
|
@ -78,6 +78,11 @@ 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.",
|
||||||
|
"<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.");
|
||||||
|
|
||||||
|
|
||||||
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",
|
||||||
|
|
Loading…
Reference in New Issue