mirror of
https://github.com/twisterarmy/twister-html.git
synced 2025-02-05 03:24:17 +00:00
fix of post formatting: optimizing
This commit is contained in:
parent
2f4e91ff63
commit
fb67d7a04d
@ -3,6 +3,19 @@
|
|||||||
//
|
//
|
||||||
// Format JSON posts and DMs to HTML.
|
// Format JSON posts and DMs to HTML.
|
||||||
|
|
||||||
|
var _htmlFormatMsgLinkTemplateExternal;
|
||||||
|
var _htmlFormatMsgLinkTemplateUser;
|
||||||
|
var _htmlFormatMsgLinkTemplateHashtag;
|
||||||
|
|
||||||
|
$(document).ready(function() {
|
||||||
|
// we're setting it here for perfomance improvement purpose // to not search and prepare it for for every post
|
||||||
|
_htmlFormatMsgLinkTemplateExternal = $('#external-page-link-template')[0].cloneNode();
|
||||||
|
_htmlFormatMsgLinkTemplateExternal.removeAttribute('id');
|
||||||
|
_htmlFormatMsgLinkTemplateUser = $('#msg-user-link-template')[0].cloneNode();
|
||||||
|
_htmlFormatMsgLinkTemplateUser.removeAttribute('id');
|
||||||
|
_htmlFormatMsgLinkTemplateHashtag = $('#hashtag-link-template')[0].cloneNode();
|
||||||
|
_htmlFormatMsgLinkTemplateHashtag.removeAttribute('id');
|
||||||
|
});
|
||||||
|
|
||||||
// format "userpost" to html element
|
// format "userpost" to html element
|
||||||
// kind = "original"/"ancestor"/"descendant"
|
// kind = "original"/"ancestor"/"descendant"
|
||||||
@ -198,7 +211,10 @@ function dmDataToConversationItem(dmData, localUser, remoteUser) {
|
|||||||
|
|
||||||
// convert message text to html, featuring @users and links formating.
|
// convert message text to html, featuring @users and links formating.
|
||||||
function htmlFormatMsg(msg, mentions) {
|
function htmlFormatMsg(msg, mentions) {
|
||||||
function getStrStart(str, startPoint, stopChars, isStopCharMustExist, stopCharsTrailing) {
|
// TODO: add options for emotions; msg = $.emotions(msg);
|
||||||
|
// TODO make markup optionally mutable ?
|
||||||
|
|
||||||
|
function getSubStrStart(str, startPoint, stopChars, isStopCharMustExist, stopCharsTrailing) {
|
||||||
for (var i = startPoint; i > -1; i--) {
|
for (var i = startPoint; i > -1; i--) {
|
||||||
if (stopChars.indexOf(str[i]) > -1)
|
if (stopChars.indexOf(str[i]) > -1)
|
||||||
break;
|
break;
|
||||||
@ -215,7 +231,7 @@ function htmlFormatMsg(msg, mentions) {
|
|||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getStrEnd(str, startPoint, stopChars, isStopCharMustExist, stopCharsTrailing) {
|
function getSubStrEnd(str, startPoint, stopChars, isStopCharMustExist, stopCharsTrailing) {
|
||||||
for (var i = startPoint; i < str.length; i++) {
|
for (var i = startPoint; i < str.length; i++) {
|
||||||
if (stopChars.indexOf(str[i]) > -1)
|
if (stopChars.indexOf(str[i]) > -1)
|
||||||
break;
|
break;
|
||||||
@ -232,8 +248,8 @@ function htmlFormatMsg(msg, mentions) {
|
|||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
function markdown(str, chr, tag) {
|
function markout(msg, chr, tag) {
|
||||||
function whiteSpace(i, j) {
|
function isWhiteSpacesBetween(i, j) {
|
||||||
j++;
|
j++;
|
||||||
for (i += 1; i < j; i++) {
|
for (i += 1; i < j; i++) {
|
||||||
if (p[i].w)
|
if (p[i].w)
|
||||||
@ -243,50 +259,50 @@ function htmlFormatMsg(msg, mentions) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
var i, j, t, l, r, strEncoded;
|
var i, j, t, l, r, htmlEntityEncoded;
|
||||||
var w = false;
|
var w = false;
|
||||||
var p = [];
|
var p = [];
|
||||||
|
|
||||||
// collecting chars position data
|
// collecting chars position data
|
||||||
for (i = 0; i < str.length; i++) {
|
for (i = 0; i < msg.str.length; i++) {
|
||||||
if (str[i] === chr) {
|
if (msg.str[i] === chr) {
|
||||||
for (j = i + 1; j < str.length; j++) {
|
for (j = i + 1; j < msg.str.length; j++) {
|
||||||
if (str[j] !== chr)
|
if (msg.str[j] !== chr)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (i === 0) {
|
if (i === 0) {
|
||||||
p.push({i: i, k: j - i, t: -1, w: w, a: -1, p: -1});
|
p.push({i: i, k: j - i, t: -1, w: w, a: -1, p: -1});
|
||||||
w = false;
|
w = false;
|
||||||
} else if (j === str.length) {
|
} else if (j === msg.str.length) {
|
||||||
p.push({i: i, k: j - i, t: 1, w: w, a: -1, p: -1});
|
p.push({i: i, k: j - i, t: 1, w: w, a: -1, p: -1});
|
||||||
w = false;
|
w = false;
|
||||||
} else {
|
} else {
|
||||||
if (stopCharsMarkDown.indexOf(str[i - 1]) > -1) {
|
if (stopCharsMarkout.indexOf(msg.str[i - 1]) > -1) {
|
||||||
l = 1;
|
l = 1;
|
||||||
for (t = i - 2; t > -1; t--) {
|
for (t = i - 2; t > -1; t--) {
|
||||||
if (str[t] === chr) {
|
if (msg.str[t] === chr) {
|
||||||
l = -1;
|
l = -1;
|
||||||
break;
|
break;
|
||||||
} else if (stopCharsMarkDown.indexOf(str[t]) === -1) {
|
} else if (stopCharsMarkout.indexOf(msg.str[t]) === -1) {
|
||||||
l = whiteSpaces.indexOf(str[t]);
|
l = whiteSpaces.indexOf(msg.str[t]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
l = whiteSpaces.indexOf(str[i - 1]);
|
l = whiteSpaces.indexOf(msg.str[i - 1]);
|
||||||
if (stopCharsMarkDown.indexOf(str[j]) > -1) {
|
if (stopCharsMarkout.indexOf(msg.str[j]) > -1) {
|
||||||
r = 1;
|
r = 1;
|
||||||
for (t = j + 1; t < str.length; t++) {
|
for (t = j + 1; t < msg.str.length; t++) {
|
||||||
if (str[t] === chr) {
|
if (msg.str[t] === chr) {
|
||||||
r = -1;
|
r = -1;
|
||||||
break;
|
break;
|
||||||
} else if (stopCharsMarkDown.indexOf(str[t]) === -1) {
|
} else if (stopCharsMarkout.indexOf(msg.str[t]) === -1) {
|
||||||
r = whiteSpaces.indexOf(str[t]);
|
r = whiteSpaces.indexOf(msg.str[t]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
r = whiteSpaces.indexOf(str[j]);
|
r = whiteSpaces.indexOf(msg.str[j]);
|
||||||
if (l > -1) {
|
if (l > -1) {
|
||||||
if (r > -1) {
|
if (r > -1) {
|
||||||
if (j - i > 2) {
|
if (j - i > 2) {
|
||||||
@ -307,7 +323,7 @@ function htmlFormatMsg(msg, mentions) {
|
|||||||
w = false;
|
w = false;
|
||||||
}
|
}
|
||||||
i = j - 1;
|
i = j - 1;
|
||||||
} else if (!w && whiteSpaces.indexOf(str[i]) > -1) {
|
} else if (!w && whiteSpaces.indexOf(msg.str[i]) > -1) {
|
||||||
w = true;
|
w = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -317,7 +333,7 @@ function htmlFormatMsg(msg, mentions) {
|
|||||||
if (p[i].t < 1 && p[i].a === -1) {
|
if (p[i].t < 1 && p[i].a === -1) {
|
||||||
t = i;
|
t = i;
|
||||||
for (j = i + 1; j < p.length; j++) {
|
for (j = i + 1; j < p.length; j++) {
|
||||||
if (p[i].t === 0 && whiteSpace(i, j)) {
|
if (p[i].t === 0 && isWhiteSpacesBetween(i, j)) {
|
||||||
i = j - 1;
|
i = j - 1;
|
||||||
break;
|
break;
|
||||||
} else if (p[j].t < 1 && p[j].a === -1) {
|
} else if (p[j].t < 1 && p[j].a === -1) {
|
||||||
@ -335,11 +351,11 @@ function htmlFormatMsg(msg, mentions) {
|
|||||||
for (i = 0; i < p.length; i++) {
|
for (i = 0; i < p.length; i++) {
|
||||||
if (p[i].t === -1 && p[i].a === -1) {
|
if (p[i].t === -1 && p[i].a === -1) {
|
||||||
for (j = p[i].p; j > -1; j = p[j].p) {
|
for (j = p[i].p; j > -1; j = p[j].p) {
|
||||||
if (whiteSpace(i, j)) {
|
if (isWhiteSpacesBetween(i, j)) {
|
||||||
i = j - 1;
|
i = j - 1;
|
||||||
break;
|
break;
|
||||||
} else if (p[j].t === 0
|
} else if (p[j].t === 0
|
||||||
&& !(p[j].p > -1 && p[p[j].p].t === 0 && !whiteSpace(j, p[j].p))) {
|
&& !(p[j].p > -1 && p[p[j].p].t === 0 && !isWhiteSpacesBetween(j, p[j].p))) {
|
||||||
p[j].a = i;
|
p[j].a = i;
|
||||||
p[i].a = j;
|
p[i].a = j;
|
||||||
i = j;
|
i = j;
|
||||||
@ -359,15 +375,15 @@ function htmlFormatMsg(msg, mentions) {
|
|||||||
else
|
else
|
||||||
t = '<' + tag + '>';
|
t = '<' + tag + '>';
|
||||||
j = p[i].a;
|
j = p[i].a;
|
||||||
t = t + str.slice(p[i].i + p[i].k, p[j].i);
|
t = t + msg.str.slice(p[i].i + p[i].k, p[j].i);
|
||||||
if (p[j].k > 1)
|
if (p[j].k > 1)
|
||||||
t = t + Array(p[i].k).join(chr) + '</' + tag + '>';
|
t = t + Array(p[i].k).join(chr) + '</' + tag + '>';
|
||||||
else
|
else
|
||||||
t = t + '</' + tag + '>';
|
t = t + '</' + tag + '>';
|
||||||
html.push(t.replace(/&(?!lt;|gt;)/g, '&'));
|
msg.htmlEntities.push(t.replace(/&(?!lt;|gt;)/g, '&'));
|
||||||
strEncoded = '>' + (html.length - 1).toString() + '<';
|
htmlEntityEncoded = '>' + (msg.htmlEntities.length - 1).toString() + '<';
|
||||||
str = str.slice(0, p[i].i) + strEncoded + str.slice(p[j].i + p[j].k);
|
msg.str = msg.str.slice(0, p[i].i) + htmlEntityEncoded + msg.str.slice(p[j].i + p[j].k);
|
||||||
l = strEncoded.length - p[j].i - p[j].k + p[i].i;
|
l = htmlEntityEncoded.length - p[j].i - p[j].k + p[i].i;
|
||||||
i = j;
|
i = j;
|
||||||
for (j += 1; j < p.length; j++)
|
for (j += 1; j < p.length; j++)
|
||||||
p[j].i += l;
|
p[j].i += l;
|
||||||
@ -379,49 +395,59 @@ function htmlFormatMsg(msg, mentions) {
|
|||||||
if (p[i].a > -1) {
|
if (p[i].a > -1) {
|
||||||
if (p[i].t === -1 || (p[i].t === 0 && p[i].a > i)) {
|
if (p[i].t === -1 || (p[i].t === 0 && p[i].a > i)) {
|
||||||
if (p[i].k > 1)
|
if (p[i].k > 1)
|
||||||
html.push('<' + tag + '>' + Array(p[i].k).join(chr));
|
msg.htmlEntities.push('<' + tag + '>' + Array(p[i].k).join(chr));
|
||||||
else
|
else
|
||||||
html.push('<' + tag + '>');
|
msg.htmlEntities.push('<' + tag + '>');
|
||||||
} else if (p[i].t === 1 || (p[i].t === 0 && p[i].a < i)) {
|
} else if (p[i].t === 1 || (p[i].t === 0 && p[i].a < i)) {
|
||||||
if (p[i].k > 1)
|
if (p[i].k > 1)
|
||||||
html.push(Array(p[i].k).join(chr) + '</' + tag + '>');
|
msg.htmlEntities.push(Array(p[i].k).join(chr) + '</' + tag + '>');
|
||||||
else
|
else
|
||||||
html.push('</' + tag + '>');
|
msg.htmlEntities.push('</' + tag + '>');
|
||||||
}
|
}
|
||||||
strEncoded = '>' + (html.length - 1).toString() + '<';
|
htmlEntityEncoded = '>' + (msg.htmlEntities.length - 1).toString() + '<';
|
||||||
str = str.slice(0, p[i].i) + strEncoded + str.slice(p[i].i + p[i].k);
|
msg.str = msg.str.slice(0, p[i].i) + htmlEntityEncoded + msg.str.slice(p[i].i + p[i].k);
|
||||||
l = strEncoded.length - p[i].k;
|
l = htmlEntityEncoded.length - p[i].k;
|
||||||
for (j = i + 1; j < p.length; j++)
|
for (j = i + 1; j < p.length; j++)
|
||||||
p[j].i += l;
|
p[j].i += l;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return str;
|
return msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
function htmlSplitCounter(str) {
|
function newHtmlEntityLink(template, urlTarget, urlName) {
|
||||||
html.push('<span class="splited-post-counter">' + str + '</span>');
|
template.href = urlTarget;
|
||||||
|
template.innerHTML = urlName; // .innerHTML instead .text to allow markup inside [] of [url name](target)
|
||||||
|
|
||||||
return '>' + (html.length - 1).toString() + '<';
|
return template.outerHTML;
|
||||||
}
|
}
|
||||||
|
|
||||||
function unpackHtml(str) {
|
function msgAddHtmlEntity(msg, strSliceLeft, strSliceRigth, htmlEntity) {
|
||||||
|
msg.htmlEntities.push(htmlEntity);
|
||||||
|
var htmlEntityEncoded = '>' + (msg.htmlEntities.length - 1).toString() + '<';
|
||||||
|
msg.str = msg.str.slice(0, strSliceLeft) + htmlEntityEncoded + msg.str.slice(strSliceRigth);
|
||||||
|
msg.i = strSliceLeft + htmlEntityEncoded.length - 1;
|
||||||
|
|
||||||
|
return msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
function applyHtml(msg) {
|
||||||
var t;
|
var t;
|
||||||
|
|
||||||
for (var i = 0; i < str.length - 2; i++) {
|
for (var i = 0; i < msg.str.length - 2; i++) {
|
||||||
if (str[i] === '>') {
|
if (msg.str[i] === '>') {
|
||||||
for (var j = i + 2; j < str.length; j++) {
|
for (var j = i + 2; j < msg.str.length; j++) {
|
||||||
if (str[j] === '<')
|
if (msg.str[j] === '<')
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
t = html[parseInt(str.slice(i + 1, j))];
|
t = msg.htmlEntities[parseInt(msg.str.slice(i + 1, j))];
|
||||||
str = str.slice(0, i) + t + str.slice(j + 1);
|
msg.str = msg.str.slice(0, i) + t + msg.str.slice(j + 1);
|
||||||
i = i + t.length - 1;
|
i = i + t.length - 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return str;
|
return msg.str;
|
||||||
}
|
}
|
||||||
|
|
||||||
var mentionsChars = 'abcdefghijklmnopqrstuvwxyz_0123456789';
|
var mentionsChars = 'abcdefghijklmnopqrstuvwxyz_0123456789';
|
||||||
@ -433,178 +459,164 @@ function htmlFormatMsg(msg, mentions) {
|
|||||||
var stopCharsRight = '>' + whiteSpaces;
|
var stopCharsRight = '>' + whiteSpaces;
|
||||||
var stopCharsRightHashtags = '>/\\.,:;?!%\'"[](){}^|«»…\u201C\u201D\u2026\u2014\u4E00\u3002\uFF0C\uFF1A\uFF1F\uFF01\u3010\u3011\u2047\u2048\u2049' // same as stopCharsTrailing but without '*~_-`' plus '>'
|
var stopCharsRightHashtags = '>/\\.,:;?!%\'"[](){}^|«»…\u201C\u201D\u2026\u2014\u4E00\u3002\uFF0C\uFF1A\uFF1F\uFF01\u3010\u3011\u2047\u2048\u2049' // same as stopCharsTrailing but without '*~_-`' plus '>'
|
||||||
+ whiteSpaces;
|
+ whiteSpaces;
|
||||||
var stopCharsMarkDown = '/\\*~_-`.,:;?!%+=&\'"[](){}^|«»…\u201C\u201D\u2026\u2014\u4E00\u3002\uFF0C\uFF1A\uFF1F\uFF01\u3010\u3011\u2047\u2048\u2049';
|
var stopCharsMarkout = '/\\*~_-`.,:;?!%+=&\'"[](){}^|«»…\u201C\u201D\u2026\u2014\u4E00\u3002\uFF0C\uFF1A\uFF1F\uFF01\u3010\u3011\u2047\u2048\u2049';
|
||||||
var i, j, k, str, strEncoded;
|
var i, j, k, str;
|
||||||
var html = [];
|
|
||||||
|
|
||||||
msg = markdown(escapeHtmlEntities(msg),
|
msg = {str: escapeHtmlEntities(msg), htmlEntities: []};
|
||||||
'`', 'samp'); // kind of monospace, sequence of chars inside will be escaped from markup
|
|
||||||
|
|
||||||
for (i = 0; i < msg.length - 7; i++) {
|
msg = markout(msg, '`', 'samp'); // <samp> tag is kind of monospace, here sequence of chars inside it will be escaped from markup
|
||||||
if (msg.slice(i, i + 2) === '](') {
|
|
||||||
// FIXME there can be text with [] inside [] or links with () wee need to handle it too
|
// handling links
|
||||||
j = getStrStart(msg, i - 2, '[', true, '');
|
for (i = 0; i < msg.str.length - 7; i++) {
|
||||||
|
if (msg.str.slice(i, i + 2) === '](') {
|
||||||
|
// FIXME there can be text with [] inside [] or links with () we need to handle it too
|
||||||
|
j = getSubStrStart(msg.str, i - 2, '[', true, '');
|
||||||
if (j < i - 1) {
|
if (j < i - 1) {
|
||||||
k = getStrEnd(msg, i + 3, ')', true, whiteSpaces);
|
k = getSubStrEnd(msg.str, i + 3, ')', true, whiteSpaces);
|
||||||
if (k > i + 2) {
|
if (k > i + 2) {
|
||||||
strEncoded = msg.slice(j, i); // just temporary storage for name of possiible link
|
var linkName = msg.str.slice(j, i); // name of possiible link
|
||||||
for (i += 2; i < k; i++) {
|
for (i += 2; i < k; i++) {
|
||||||
if (whiteSpacesUrl.indexOf(msg[i]) === -1) // drop whitespaces and ' and " // apostrophes and quotes to prevent injection of js events
|
if (whiteSpacesUrl.indexOf(msg.str[i]) === -1) // drop whitespaces and ' and " // apostrophes and quotes to prevent injection of js events
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (i < k) {
|
if (i < k) {
|
||||||
// check for injections like [href=(' or ")]('#' or 'javascript' or 'data')[:] // () and [] here just to explain somehow an idea, it's not about markup syntax
|
var x = getSubStrEnd(msg.str, i, ':', false, '') + 1;
|
||||||
if (msg[i] === '#' || msg.slice(i, i + 10).toLowerCase() === 'javascript'
|
// following check is NOT for real protection (we have blocking CSP rule instead), it's just to aware people
|
||||||
|| msg.slice(i, i + 4).toLowerCase() === 'data') {
|
if (x > i && x < k && (msg.str.slice(x - 6, x).toLowerCase() === 'script' // other things would be added when W3C and all the people invent it
|
||||||
html.push('…<br><b><i>' + polyglot.t('busted_oh') + '</i> '
|
|| msg.str.slice(x - 4, x).toLowerCase() === 'data')) {
|
||||||
|
msg = msgAddHtmlEntity(msg, j - 1, getSubStrEnd(msg.str, k + 1, ')', true, '') + 2,
|
||||||
|
'…<br><b><i>' + polyglot.t('busted_oh') + '</i> '
|
||||||
+ polyglot.t('busted_avowal') + ':</b><br><samp>'
|
+ polyglot.t('busted_avowal') + ':</b><br><samp>'
|
||||||
+ msg.slice(i, k + 1)
|
+ msg.str.slice(i, k + 1)
|
||||||
.replace(/&(?!lt;|gt;)/g, '&')
|
.replace(/&(?!lt;|gt;)/g, '&')
|
||||||
.replace(/"/g, '"')
|
.replace(/"/g, '"')
|
||||||
.replace(/'/g, ''')
|
.replace(/'/g, ''')
|
||||||
+ '</samp><br>'
|
+ '</samp><br>'
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
if (getStrEnd(msg, i + 1, whiteSpacesUrl, false, '') < k) // use only first word as href target, others drop silently
|
if (getSubStrEnd(msg.str, i + 1, whiteSpacesUrl, false, '') < k) // use only first word as href target, others drop silently
|
||||||
k = getStrEnd(msg, i + 1, whiteSpacesUrl, false, '');
|
k = getSubStrEnd(msg.str, i + 1, whiteSpacesUrl, false, '');
|
||||||
html.push($('#external-page-link-template')[0].outerHTML
|
msg = msgAddHtmlEntity(msg, j - 1, getSubStrEnd(msg.str, k + 1, ')', true, '') + 2,
|
||||||
.replace(/\bid\s*=\s*"[^]*?"+/ig, '') // $().removeAttr('id')
|
newHtmlEntityLink(_htmlFormatMsgLinkTemplateExternal,
|
||||||
//.replace(/\bhref\s*=\s*"[^]*?"+/ig, '') // $().removeAttr('href')
|
proxyURL(msg.str.slice(i, k + 1)),
|
||||||
.replace(/<a\s+/ig, '<a href="' + proxyURL(msg.slice(i, k + 1)) + '" ') // $().closest('a').attr('href', proxyURL(url))
|
applyHtml( // we're trying markup inside [] of []()
|
||||||
.replace(/(<a\s+[^]*?>)[^]*?(<\/a>)/ig, '$1'
|
markout(markout(markout(markout(
|
||||||
+ unpackHtml(
|
{str: linkName, htmlEntities: msg.htmlEntities},
|
||||||
markdown(markdown(markdown(markdown(strEncoded, // name of link, see above
|
'*', 'b'), // bold
|
||||||
'*', 'b'), // bold
|
'~', 'i'), // italic
|
||||||
'~', 'i'), // italic
|
'_', 'u'), // underlined
|
||||||
'_', 'u'), // underlined
|
'-', 's') // striketrough
|
||||||
'-', 's') // striketrough
|
|
||||||
.replace(/&(?!lt;|gt;)/g, '&')
|
|
||||||
.replace(/"/g, '"')
|
|
||||||
.replace(/'/g, ''')
|
|
||||||
)
|
)
|
||||||
+ '$2') // $().closest('a').text(url)
|
.replace(/&(?!lt;|gt;)/g, '&')
|
||||||
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
strEncoded = '>' + (html.length - 1).toString() + '<';
|
i = msg.i + 1;
|
||||||
msg = msg.slice(0, j - 1) + strEncoded + msg.slice(getStrEnd(msg, k + 1, ')', true, '') + 2);
|
}
|
||||||
i = j + strEncoded.length - 1;
|
|
||||||
} // else
|
|
||||||
// i = just no
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (msg.slice(i, i + 4).toLowerCase() === 'http') {
|
} else if (msg.str.slice(i, i + 4).toLowerCase() === 'http') {
|
||||||
if (msg.slice(i + 4, i + 7) === '://' && stopCharsRight.indexOf(msg[i + 7]) === -1) {
|
if (msg.str.slice(i + 4, i + 7) === '://' && stopCharsRight.indexOf(msg.str[i + 7]) === -1) {
|
||||||
j = getStrEnd(msg, i + 7, stopCharsRight, false, stopCharsTrailingUrl);
|
j = getSubStrEnd(msg.str, i + 7, stopCharsRight, false, stopCharsTrailingUrl);
|
||||||
if (j > i + 6) {
|
if (j > i + 6) {
|
||||||
str = msg.slice(i, j + 1);
|
str = msg.str.slice(i, j + 1);
|
||||||
// FIXME we're trying to not interact with DOM, coz' we want to run really fast [to hell of RegExps]
|
msg = msgAddHtmlEntity(msg, i, i + str.length,
|
||||||
// FIXME actually we should avoid it by dropping a template idea and construct html right here
|
newHtmlEntityLink(_htmlFormatMsgLinkTemplateExternal,
|
||||||
html.push($('#external-page-link-template')[0].outerHTML
|
proxyURL(str), str)
|
||||||
.replace(/\bid\s*=\s*"[^]*?"+/ig, '') // $().removeAttr('id')
|
|
||||||
//.replace(/\bhref\s*=\s*"[^]*?"+/ig, '') // $().removeAttr('href')
|
|
||||||
.replace(/<a\s+/ig, '<a href="' + proxyURL(str) + '" ') // $().closest('a').attr('href', proxyURL(url))
|
|
||||||
.replace(/(<a\s+[^]*?>)[^]*?(<\/a>)/ig, '$1' + str + '$2') // $().closest('a').text(url)
|
|
||||||
);
|
);
|
||||||
strEncoded = '>' + (html.length - 1).toString() + '<';
|
i = msg.i;
|
||||||
msg = msg.slice(0, i) + strEncoded + msg.slice(i + str.length);
|
|
||||||
i = i + strEncoded.length - 1;
|
|
||||||
}
|
}
|
||||||
} else if (msg.slice(i + 4, i + 8).toLowerCase() === 's://' && stopCharsRight.indexOf(msg[i + 8]) === -1) {
|
} else if (msg.str.slice(i + 4, i + 8).toLowerCase() === 's://' && stopCharsRight.indexOf(msg.str[i + 8]) === -1) {
|
||||||
j = getStrEnd(msg, i + 8, stopCharsRight, false, stopCharsTrailingUrl);
|
j = getSubStrEnd(msg.str, i + 8, stopCharsRight, false, stopCharsTrailingUrl);
|
||||||
if (j > i + 7) {
|
if (j > i + 7) {
|
||||||
str = msg.slice(i, j + 1);
|
str = msg.str.slice(i, j + 1);
|
||||||
html.push($('#external-page-link-template')[0].outerHTML
|
msg = msgAddHtmlEntity(msg, i, i + str.length,
|
||||||
.replace(/\bid\s*=\s*"[^]*?"+/ig, '') // $().removeAttr('id')
|
newHtmlEntityLink(_htmlFormatMsgLinkTemplateExternal,
|
||||||
//.replace(/\bhref\s*=\s*"[^]*?"+/ig, '') // $().removeAttr('href')
|
proxyURL(str), str)
|
||||||
.replace(/<a\s+/ig, '<a href="' + proxyURL(str) + '" ') // $().closest('a').attr('href', proxyURL(url))
|
|
||||||
.replace(/(<a\s+[^]*?>)[^]*?(<\/a>)/ig, '$1' + str + '$2') // $().closest('a').text(url)
|
|
||||||
);
|
);
|
||||||
strEncoded = '>' + (html.length - 1).toString() + '<';
|
i = msg.i;
|
||||||
msg = msg.slice(0, i) + strEncoded + msg.slice(i + str.length);
|
|
||||||
i = i + strEncoded.length - 1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 1; i < msg.length - 1; i++) {
|
// handling mails
|
||||||
if (msg[i] === '@' && stopCharsLeft.indexOf(msg[i - 1]) === -1
|
for (i = 1; i < msg.str.length - 1; i++) {
|
||||||
&& stopCharsTrailing.indexOf(msg[i - 1]) === -1 && stopCharsRight.indexOf(msg[i + 1]) === -1) {
|
if (msg.str[i] === '@' && stopCharsLeft.indexOf(msg.str[i - 1]) === -1
|
||||||
j = getStrStart(msg, i - 1, stopCharsLeft, false, stopCharsTrailing);
|
&& stopCharsTrailing.indexOf(msg.str[i - 1]) === -1 && stopCharsRight.indexOf(msg.str[i + 1]) === -1) {
|
||||||
|
j = getSubStrStart(msg.str, i - 1, stopCharsLeft, false, stopCharsTrailing);
|
||||||
if (j < i) {
|
if (j < i) {
|
||||||
k = getStrEnd(msg, i + 1, stopCharsRight, false, stopCharsTrailing);
|
k = getSubStrEnd(msg.str, i + 1, stopCharsRight, false, stopCharsTrailing);
|
||||||
if (k > i) {
|
if (k > i) {
|
||||||
str = msg.slice(j, k + 1);
|
str = msg.str.slice(j, k + 1);
|
||||||
html.push($('#external-page-link-template')[0].outerHTML
|
msg = msgAddHtmlEntity(msg, j, j + str.length,
|
||||||
.replace(/\bid\s*=\s*"[^]*?"+/ig, '') // $().removeAttr('id')
|
newHtmlEntityLink(_htmlFormatMsgLinkTemplateExternal,
|
||||||
//.replace(/\bhref\s*=\s*"[^]*?"+/ig, '') // $().removeAttr('href')
|
'mailto:' + str.toLowerCase(), str)
|
||||||
.replace(/<a\s+/ig, '<a href="mailto:' + str.toLowerCase() + '" ') // $().closest('a').attr('href', 'mailto:'+url)
|
|
||||||
.replace(/(<a\s+[^]*?>)[^]*?(<\/a>)/ig, '$1' + str + '$2') // $().closest('a').text(url)
|
|
||||||
);
|
);
|
||||||
strEncoded = '>' + (html.length - 1).toString() + '<';
|
i = msg.i;
|
||||||
msg = msg.slice(0, j) + strEncoded + msg.slice(j + str.length);
|
|
||||||
i = j + strEncoded.length - 1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < msg.length - 1; i++) {
|
// handling mentions
|
||||||
if (msg[i] === '@' && mentionsChars.indexOf(msg[i + 1].toLowerCase()) > -1) {
|
for (i = 0; i < msg.str.length - 1; i++) {
|
||||||
for (j = i + 2; j < msg.length; j++) {
|
if (msg.str[i] === '@' && mentionsChars.indexOf(msg.str[i + 1].toLowerCase()) > -1) {
|
||||||
if (mentionsChars.indexOf(msg[j].toLowerCase()) === -1)
|
for (j = i + 2; j < msg.str.length; j++) {
|
||||||
|
if (mentionsChars.indexOf(msg.str[j].toLowerCase()) === -1)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
str = msg.slice(i + 1, j).toLowerCase();
|
str = msg.str.slice(i + 1, j).toLowerCase();
|
||||||
mentions.push(str); // FIXME
|
mentions.push(str); // FIXME
|
||||||
html.push($('#msg-user-link-template')[0].outerHTML
|
msg = msgAddHtmlEntity(msg, i, i + str.length + 1,
|
||||||
.replace(/\bid\s*=\s*"[^]*?"+/ig, '') // $().removeAttr('id')
|
newHtmlEntityLink(_htmlFormatMsgLinkTemplateUser,
|
||||||
//.replace(/\bhref\s*=\s*"[^]*?"+/ig, '') // $().removeAttr('href')
|
$.MAL.userUrl(str), '@' + str)
|
||||||
.replace(/<a\s+(?=[^>]*?\bclass\s*=\s*"(?=[^"]*?\bopen-profile-modal\b))/ig, '<a href="' + $.MAL.userUrl(str) + '" ') // $().closest('a.open-profile-modal').attr('href', $.MAL.userUrl(username))
|
|
||||||
.replace(/(<a\s+(?=[^>]*?\bclass\s*=\s*"(?=[^"]*?\bopen-profile-modal\b))[^]*?>)[^]*?(<\/a>)/ig, '$1@' + str + '$2') // $().closest('a.open-profile-modal').text('@'+username)
|
|
||||||
);
|
);
|
||||||
strEncoded = '>' + (html.length - 1).toString() + '<';
|
i = msg.i;
|
||||||
msg = msg.slice(0, i) + strEncoded + msg.slice(i + str.length + 1);
|
|
||||||
i = i + strEncoded.length - 1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < msg.length - 1; i++) {
|
// handling hashtags
|
||||||
if (msg[i] === '#' && msg[i + 1] !== '#' && stopCharsRight.indexOf(msg[i + 1]) === -1) {
|
for (i = 0; i < msg.str.length - 1; i++) {
|
||||||
j = getStrEnd(msg, i + 1, stopCharsRightHashtags, false, stopCharsTrailing);
|
if (msg.str[i] === '#' && msg.str[i + 1] !== '#' && stopCharsRight.indexOf(msg.str[i + 1]) === -1) {
|
||||||
|
j = getSubStrEnd(msg.str, i + 1, stopCharsRightHashtags, false, stopCharsTrailing);
|
||||||
if (j > i) {
|
if (j > i) {
|
||||||
str = msg.slice(i + 1, j + 1);
|
str = msg.str.slice(i + 1, j + 1);
|
||||||
html.push($('#hashtag-link-template')[0].outerHTML
|
msg = msgAddHtmlEntity(msg, i, i + str.length + 1,
|
||||||
.replace(/\bid\s*=\s*"[^]*?"+/ig, '') // $().removeAttr('id')
|
newHtmlEntityLink(_htmlFormatMsgLinkTemplateHashtag,
|
||||||
//.replace(/\bhref\s*=\s*"[^]*?"+/ig, '') // $().removeAttr('href')
|
$.MAL.hashtagUrl(encodeURIComponent(str.toLowerCase())), '#' + str.replace(/&/g, '&'))
|
||||||
.replace(/<a\s+(?=[^>]*?\bclass\s*=\s*"(?=[^"]*?\bopen-hashtag-modal\b))/ig, '<a href="' + $.MAL.hashtagUrl(encodeURIComponent(str.toLowerCase())) + '" ') // $().closest('a.open-profile-modal').attr('href', $.MAL.hashtagUrl(hashtag))
|
|
||||||
.replace(/(<a\s+(?=[^>]*?\bclass\s*=\s*"(?=[^"]*?\bopen-hashtag-modal\b))[^]*?>)[^]*?(<\/a>)/ig, '$1#' + str.replace(/&/g, '&') + '$2') // $().closest('a.open-profile-modal').text('#'+hashtag)
|
|
||||||
);
|
);
|
||||||
strEncoded = '>' + (html.length - 1).toString() + '<';
|
i = msg.i;
|
||||||
msg = msg.slice(0, i) + strEncoded + msg.slice(i + str.length + 1);
|
|
||||||
i = i + strEncoded.length - 1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
msg = unpackHtml(
|
// handling text style markup
|
||||||
markdown(markdown(markdown(markdown(msg,
|
msg = markout(markout(markout(markout(msg,
|
||||||
'*', 'b'), // bold
|
'*', 'b'), // bold
|
||||||
'~', 'i'), // italic
|
'~', 'i'), // italic
|
||||||
'_', 'u'), // underlined
|
'_', 'u'), // underlined
|
||||||
'-', 's') // striketrough
|
'-', 's') // striketrough
|
||||||
.replace(/\(\d{1,2}\/\d{1,2}\)$/, htmlSplitCounter)
|
;
|
||||||
|
|
||||||
|
// handling splitted posts numbering and escaping ampersands, qoutes and apostrophes
|
||||||
|
msg.str = msg.str
|
||||||
|
.replace(/\(\d{1,2}\/\d{1,2}\)$/, function (str) {
|
||||||
|
msg.htmlEntities.push('<span class="splited-post-counter">' + str + '</span>'); // FIXME
|
||||||
|
|
||||||
|
return '>' + (msg.htmlEntities.length - 1).toString() + '<';
|
||||||
|
})
|
||||||
.replace(/&(?!lt;|gt;)/g, '&') // FIXME in many cases there is no need to escape ampersand in HTML 5
|
.replace(/&(?!lt;|gt;)/g, '&') // FIXME in many cases there is no need to escape ampersand in HTML 5
|
||||||
.replace(/"/g, '"')
|
.replace(/"/g, '"')
|
||||||
.replace(/'/g, ''')
|
.replace(/'/g, ''')
|
||||||
);
|
|
||||||
|
|
||||||
|
// applying html entities to msg.str and converting msg to string back
|
||||||
|
msg = applyHtml(msg);
|
||||||
|
|
||||||
|
// handling linebreaks
|
||||||
if ($.Options.displayLineFeeds.val === 'enable')
|
if ($.Options.displayLineFeeds.val === 'enable')
|
||||||
msg = msg.replace(/\n/g, '<br />');
|
msg = msg.replace(/\n/g, '<br />');
|
||||||
|
|
||||||
// TODO: add options for emotions; msg = $.emotions(msg);
|
|
||||||
// TODO make markdown optionally mutable ?
|
|
||||||
|
|
||||||
return msg;
|
return msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user