* added handlebars helper for markdown formatting * finished port of profile sidebar view to handlebars template * people_controller refactoring
144 lines
5.1 KiB
JavaScript
144 lines
5.1 KiB
JavaScript
|
|
// cache url regex globally, for direct acces when testing
|
|
$(function() {
|
|
Diaspora.url_regex = /(^|\s)\b((?:(?:https?|ftp):(?:\/{1,3})|www\.)(?:[^"<>\)\s]|\(([^\s()<>]+|(\([^\s()<>]+\)))\))+)(?=\s|$)/gi;
|
|
});
|
|
|
|
(function(){
|
|
//make it so I take text and mentions rather than the modelapp.helpers.textFormatter(
|
|
var textFormatter = function textFormatter(text, model) {
|
|
var mentions = model ? model.get("mentioned_people") : [];
|
|
|
|
return textFormatter.mentionify(
|
|
textFormatter.hashtagify(
|
|
textFormatter.markdownify(text)
|
|
), mentions
|
|
)
|
|
};
|
|
|
|
textFormatter.markdownify = function markdownify(text){
|
|
var converter = Markdown.getSanitizingConverter();
|
|
|
|
// punycode non-ascii chars in urls
|
|
converter.hooks.chain("preConversion", function(text) {
|
|
|
|
// add < > around plain urls, effectively making them "autolinks"
|
|
text = text.replace(Diaspora.url_regex, function() {
|
|
var url = arguments[2];
|
|
if( url.match(/^[^\w]/) ) return url; // evil witchcraft, noop
|
|
return arguments[1]+"<"+url+">";
|
|
});
|
|
|
|
// process links
|
|
// regex copied from: https://code.google.com/p/pagedown/source/browse/Markdown.Converter.js#1198 (and slightly expanded)
|
|
var linkRegex = /(\[.*\]:\s)?(<|\()((?:(https?|ftp):\/\/[^\/'">\s]|www)[^'">\s]+?)([>\)]{1,2})/gi;
|
|
text = text.replace(linkRegex, function() {
|
|
var unicodeUrl = arguments[3];
|
|
var urlSuffix = arguments[5];
|
|
|
|
unicodeUrl = ( unicodeUrl.match(/^www/) ) ? ('http://' + unicodeUrl) : unicodeUrl;
|
|
|
|
// handle parentheses, especially in case the link ends with ')'
|
|
if( urlSuffix.indexOf(')') != -1 && urlSuffix.indexOf('>') != -1 ) {
|
|
unicodeUrl += ')';
|
|
urlSuffix = '>';
|
|
}
|
|
|
|
// url*DE*code as much as possible
|
|
try {
|
|
while( unicodeUrl.indexOf("%") !== -1 && unicodeUrl != decodeURI(unicodeUrl) ) {
|
|
unicodeUrl = decodeURI(unicodeUrl);
|
|
}
|
|
}
|
|
catch(e){}
|
|
|
|
// markdown doesn't like '(' or ')' anywhere, except where it wants
|
|
var workingUrl = unicodeUrl.replace(/\(/, "%28").replace(/\)/, "%29");
|
|
|
|
var addr = parse_url(unicodeUrl);
|
|
if( !addr.host ) addr.host = ""; // must not be 'undefined'
|
|
|
|
var asciiUrl = // rebuild the url
|
|
(!addr.scheme ? '' : addr.scheme +
|
|
( (addr.scheme.toLowerCase()=="mailto") ? ':' : '://')) +
|
|
(!addr.user ? '' : addr.user +
|
|
(!addr.pass ? '' : ':'+addr.pass) + '@') +
|
|
punycode.toASCII(addr.host) +
|
|
(!addr.port ? '' : ':' + addr.port) +
|
|
(!addr.path ? '' : encodeURI(addr.path) ) +
|
|
(!addr.query ? '' : '?' + encodeURI(addr.query) ) +
|
|
(!addr.fragment ? '' : '#' + encodeURI(addr.fragment) );
|
|
if( !arguments[1] || arguments[1] == "") { // inline link
|
|
if(arguments[2] == "<") return "["+workingUrl+"]("+asciiUrl+")"; // without link text
|
|
else return arguments[2]+asciiUrl+urlSuffix; // with link text
|
|
} else { // reference style link
|
|
return arguments[1]+asciiUrl;
|
|
}
|
|
});
|
|
|
|
return text;
|
|
});
|
|
|
|
// make nice little utf-8 symbols
|
|
converter.hooks.chain("preConversion", function(text) {
|
|
var input_strings = [
|
|
"<->", "->", "<-",
|
|
"(c)", "(r)", "(tm)",
|
|
"<3"
|
|
];
|
|
var output_symbols = [
|
|
"↔", "→", "←",
|
|
"©", "®", "™",
|
|
"♥"
|
|
];
|
|
// quote function from: http://stackoverflow.com/a/494122
|
|
var quote = function(str) {
|
|
return str.replace(/([.?*+^$[\]\\(){}|-])/g, "\\$1");
|
|
};
|
|
|
|
_.each(input_strings, function(str, idx) {
|
|
var r = new RegExp(quote(str), "gi");
|
|
text = text.replace(r, output_symbols[idx]);
|
|
});
|
|
return text;
|
|
});
|
|
|
|
converter.hooks.chain("postConversion", function (text) {
|
|
return text.replace(/(\"(?:(?:http|https):\/\/)?[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,3}(?:\/\S*)?\")(\>)/g, '$1 target="_blank">')
|
|
});
|
|
|
|
return converter.makeHtml(text)
|
|
};
|
|
|
|
textFormatter.hashtagify = function hashtagify(text){
|
|
var utf8WordCharcters =/(<a[^>]*>.*?<\/a>)|(\s|^|>)#([\u0080-\uFFFF|\w|-]+|<3)/g;
|
|
|
|
return text.replace(utf8WordCharcters, function(result, linkTag, preceeder, tagText) {
|
|
if(linkTag)
|
|
return linkTag;
|
|
else
|
|
return preceeder + "<a href='/tags/" + tagText.toLowerCase() +
|
|
"' class='tag'>#" + tagText + "</a>";
|
|
});
|
|
};
|
|
|
|
textFormatter.mentionify = function mentionify(text, mentions) {
|
|
var mentionRegex = /@\{([^;]+); ([^\}]+)\}/g
|
|
return text.replace(mentionRegex, function(mentionText, fullName, diasporaId) {
|
|
var person = _.find(mentions, function(person){
|
|
return (diasporaId == person.diaspora_id || person.handle) //jquery.mentionsInput gives us person.handle
|
|
})
|
|
if(person) {
|
|
var url = person.url || "/people/" + person.guid //jquery.mentionsInput gives us person.url
|
|
, personText = "<a href='" + url + "' class='mention'>" + fullName + "</a>"
|
|
} else {
|
|
personText = fullName;
|
|
}
|
|
|
|
return personText
|
|
})
|
|
}
|
|
|
|
app.helpers.textFormatter = textFormatter;
|
|
})();
|
|
|