improve behaviour, add more tests
This commit is contained in:
parent
b7b8a11551
commit
c5139c9a71
2 changed files with 44 additions and 14 deletions
|
|
@ -15,18 +15,27 @@
|
||||||
|
|
||||||
// punycode non-ascii chars in urls
|
// punycode non-ascii chars in urls
|
||||||
converter.hooks.chain("preConversion", function(text) {
|
converter.hooks.chain("preConversion", function(text) {
|
||||||
// remove < > around markdown-style urls
|
|
||||||
var mdUrlRegex = /<((https?|ftp):[^'">\s]+)>/gi;
|
// add < > around plain urls, effectively making them "autolinks"
|
||||||
text = text.replace(mdUrlRegex, function(wholematch, m1) {
|
var urlRegex = /(^|\s)\b((?:[a-z][\w-]+:(?:\/{1,3}|[a-z0-9%])|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}\/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:'".,<>?«»“”‘’]))/gi;
|
||||||
return m1;
|
text = text.replace(urlRegex, function(wholematch, space, url) {
|
||||||
|
return space+"<"+url+">";
|
||||||
});
|
});
|
||||||
|
|
||||||
// regex shamelessly copied from http://daringfireball.net/2010/07/improved_regex_for_matching_urls
|
// process links
|
||||||
var urlRegex = /\b((?:[a-z][\w-]+:(?:\/{1,3}|[a-z0-9%])|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}\/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:'".,<>?«»“”‘’]))/g;
|
var linkRegex = /(\[.*\]:\s)?(<|\()((https?|ftp):[^'">\s]+)(>|\))/gi;
|
||||||
return text.replace(urlRegex, function(url){
|
text = text.replace(linkRegex, function() {
|
||||||
var newUrl = "["+url+"]("+punycode.toASCII(url)+")"; // console.log( punycode.toASCII(url) );
|
var unicodeUrl = arguments[3];
|
||||||
return newUrl;
|
var asciiUrl = punycode.toASCII(unicodeUrl);
|
||||||
|
if(arguments[1] == "") { // inline link
|
||||||
|
if(arguments[2] == "<") return "["+unicodeUrl+"]("+asciiUrl+")"; // without link text
|
||||||
|
else return arguments[2]+asciiUrl+arguments[5]; // with link text
|
||||||
|
} else { // reference style link
|
||||||
|
return arguments[1]+asciiUrl;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
return text;
|
||||||
});
|
});
|
||||||
|
|
||||||
converter.hooks.chain("postConversion", function (text) {
|
converter.hooks.chain("postConversion", function (text) {
|
||||||
|
|
|
||||||
|
|
@ -142,14 +142,35 @@ describe("app.views.Post", function(){
|
||||||
})
|
})
|
||||||
|
|
||||||
context("markdown rendering", function() {
|
context("markdown rendering", function() {
|
||||||
it("correctly handles non-ascii characters in urls", function() {
|
beforeEach(function() {
|
||||||
// example from issue #2665
|
// example from issue #2665
|
||||||
var evilUrl = "http://www.bürgerentscheid-krankenhäuser.de";
|
this.evilUrl = "http://www.bürgerentscheid-krankenhäuser.de";
|
||||||
this.statusMessage.set({text: "<"+evilUrl+">"});
|
this.asciiUrl = "http://www.xn--brgerentscheid-krankenhuser-xkc78d.de";
|
||||||
|
});
|
||||||
|
|
||||||
|
it("correctly handles non-ascii characters in urls", function() {
|
||||||
|
this.statusMessage.set({text: "<"+this.evilUrl+">"});
|
||||||
var view = new app.views.Post({model : this.statusMessage}).render();
|
var view = new app.views.Post({model : this.statusMessage}).render();
|
||||||
|
|
||||||
expect($(view.el).html()).toContain("http://www.xn--brgerentscheid-krankenhuser-xkc78d.de");
|
expect($(view.el).html()).toContain(this.asciiUrl);
|
||||||
expect($(view.el).html()).toContain(evilUrl);
|
expect($(view.el).html()).toContain(this.evilUrl);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("doesn't break link texts for non-ascii urls", function() {
|
||||||
|
var linkText = "check out this awesome link!";
|
||||||
|
this.statusMessage.set({text: "["+linkText+"]("+this.evilUrl+")"});
|
||||||
|
var view = new app.views.Post({model: this.statusMessage}).render();
|
||||||
|
|
||||||
|
expect($(view.el).html()).toContain(this.asciiUrl);
|
||||||
|
expect($(view.el).html()).toContain(linkText);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("doesn't break reference style links for non-ascii urls", function() {
|
||||||
|
var postContent = "blabla blab [my special link][1] bla blabla\n\n[1]: "+this.evilUrl+" and an optional title)";
|
||||||
|
this.statusMessage.set({text: postContent});
|
||||||
|
var view = new app.views.Post({model: this.statusMessage}).render();
|
||||||
|
|
||||||
|
expect($(view.el).html()).not.toContain(this.evilUrl);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue