mirror of
https://github.com/twisterarmy/twister-html.git
synced 2025-01-27 07:04:24 +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.
|
||||
|
||||
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
|
||||
// kind = "original"/"ancestor"/"descendant"
|
||||
@ -198,7 +211,10 @@ function dmDataToConversationItem(dmData, localUser, remoteUser) {
|
||||
|
||||
// convert message text to html, featuring @users and links formating.
|
||||
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--) {
|
||||
if (stopChars.indexOf(str[i]) > -1)
|
||||
break;
|
||||
@ -215,7 +231,7 @@ function htmlFormatMsg(msg, mentions) {
|
||||
return i;
|
||||
}
|
||||
|
||||
function getStrEnd(str, startPoint, stopChars, isStopCharMustExist, stopCharsTrailing) {
|
||||
function getSubStrEnd(str, startPoint, stopChars, isStopCharMustExist, stopCharsTrailing) {
|
||||
for (var i = startPoint; i < str.length; i++) {
|
||||
if (stopChars.indexOf(str[i]) > -1)
|
||||
break;
|
||||
@ -232,8 +248,8 @@ function htmlFormatMsg(msg, mentions) {
|
||||
return i;
|
||||
}
|
||||
|
||||
function markdown(str, chr, tag) {
|
||||
function whiteSpace(i, j) {
|
||||
function markout(msg, chr, tag) {
|
||||
function isWhiteSpacesBetween(i, j) {
|
||||
j++;
|
||||
for (i += 1; i < j; i++) {
|
||||
if (p[i].w)
|
||||
@ -243,50 +259,50 @@ function htmlFormatMsg(msg, mentions) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var i, j, t, l, r, strEncoded;
|
||||
var i, j, t, l, r, htmlEntityEncoded;
|
||||
var w = false;
|
||||
var p = [];
|
||||
|
||||
// collecting chars position data
|
||||
for (i = 0; i < str.length; i++) {
|
||||
if (str[i] === chr) {
|
||||
for (j = i + 1; j < str.length; j++) {
|
||||
if (str[j] !== chr)
|
||||
for (i = 0; i < msg.str.length; i++) {
|
||||
if (msg.str[i] === chr) {
|
||||
for (j = i + 1; j < msg.str.length; j++) {
|
||||
if (msg.str[j] !== chr)
|
||||
break;
|
||||
}
|
||||
if (i === 0) {
|
||||
p.push({i: i, k: j - i, t: -1, w: w, a: -1, p: -1});
|
||||
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});
|
||||
w = false;
|
||||
} else {
|
||||
if (stopCharsMarkDown.indexOf(str[i - 1]) > -1) {
|
||||
if (stopCharsMarkout.indexOf(msg.str[i - 1]) > -1) {
|
||||
l = 1;
|
||||
for (t = i - 2; t > -1; t--) {
|
||||
if (str[t] === chr) {
|
||||
if (msg.str[t] === chr) {
|
||||
l = -1;
|
||||
break;
|
||||
} else if (stopCharsMarkDown.indexOf(str[t]) === -1) {
|
||||
l = whiteSpaces.indexOf(str[t]);
|
||||
} else if (stopCharsMarkout.indexOf(msg.str[t]) === -1) {
|
||||
l = whiteSpaces.indexOf(msg.str[t]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else
|
||||
l = whiteSpaces.indexOf(str[i - 1]);
|
||||
if (stopCharsMarkDown.indexOf(str[j]) > -1) {
|
||||
l = whiteSpaces.indexOf(msg.str[i - 1]);
|
||||
if (stopCharsMarkout.indexOf(msg.str[j]) > -1) {
|
||||
r = 1;
|
||||
for (t = j + 1; t < str.length; t++) {
|
||||
if (str[t] === chr) {
|
||||
for (t = j + 1; t < msg.str.length; t++) {
|
||||
if (msg.str[t] === chr) {
|
||||
r = -1;
|
||||
break;
|
||||
} else if (stopCharsMarkDown.indexOf(str[t]) === -1) {
|
||||
r = whiteSpaces.indexOf(str[t]);
|
||||
} else if (stopCharsMarkout.indexOf(msg.str[t]) === -1) {
|
||||
r = whiteSpaces.indexOf(msg.str[t]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else
|
||||
r = whiteSpaces.indexOf(str[j]);
|
||||
r = whiteSpaces.indexOf(msg.str[j]);
|
||||
if (l > -1) {
|
||||
if (r > -1) {
|
||||
if (j - i > 2) {
|
||||
@ -307,7 +323,7 @@ function htmlFormatMsg(msg, mentions) {
|
||||
w = false;
|
||||
}
|
||||
i = j - 1;
|
||||
} else if (!w && whiteSpaces.indexOf(str[i]) > -1) {
|
||||
} else if (!w && whiteSpaces.indexOf(msg.str[i]) > -1) {
|
||||
w = true;
|
||||
}
|
||||
}
|
||||
@ -317,7 +333,7 @@ function htmlFormatMsg(msg, mentions) {
|
||||
if (p[i].t < 1 && p[i].a === -1) {
|
||||
t = i;
|
||||
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;
|
||||
break;
|
||||
} 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++) {
|
||||
if (p[i].t === -1 && p[i].a === -1) {
|
||||
for (j = p[i].p; j > -1; j = p[j].p) {
|
||||
if (whiteSpace(i, j)) {
|
||||
if (isWhiteSpacesBetween(i, j)) {
|
||||
i = j - 1;
|
||||
break;
|
||||
} 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[i].a = j;
|
||||
i = j;
|
||||
@ -359,15 +375,15 @@ function htmlFormatMsg(msg, mentions) {
|
||||
else
|
||||
t = '<' + tag + '>';
|
||||
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)
|
||||
t = t + Array(p[i].k).join(chr) + '</' + tag + '>';
|
||||
else
|
||||
t = t + '</' + tag + '>';
|
||||
html.push(t.replace(/&(?!lt;|gt;)/g, '&'));
|
||||
strEncoded = '>' + (html.length - 1).toString() + '<';
|
||||
str = str.slice(0, p[i].i) + strEncoded + str.slice(p[j].i + p[j].k);
|
||||
l = strEncoded.length - p[j].i - p[j].k + p[i].i;
|
||||
msg.htmlEntities.push(t.replace(/&(?!lt;|gt;)/g, '&'));
|
||||
htmlEntityEncoded = '>' + (msg.htmlEntities.length - 1).toString() + '<';
|
||||
msg.str = msg.str.slice(0, p[i].i) + htmlEntityEncoded + msg.str.slice(p[j].i + p[j].k);
|
||||
l = htmlEntityEncoded.length - p[j].i - p[j].k + p[i].i;
|
||||
i = j;
|
||||
for (j += 1; j < p.length; j++)
|
||||
p[j].i += l;
|
||||
@ -379,49 +395,59 @@ function htmlFormatMsg(msg, mentions) {
|
||||
if (p[i].a > -1) {
|
||||
if (p[i].t === -1 || (p[i].t === 0 && p[i].a > i)) {
|
||||
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
|
||||
html.push('<' + tag + '>');
|
||||
msg.htmlEntities.push('<' + tag + '>');
|
||||
} else if (p[i].t === 1 || (p[i].t === 0 && p[i].a < i)) {
|
||||
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
|
||||
html.push('</' + tag + '>');
|
||||
msg.htmlEntities.push('</' + tag + '>');
|
||||
}
|
||||
strEncoded = '>' + (html.length - 1).toString() + '<';
|
||||
str = str.slice(0, p[i].i) + strEncoded + str.slice(p[i].i + p[i].k);
|
||||
l = strEncoded.length - p[i].k;
|
||||
htmlEntityEncoded = '>' + (msg.htmlEntities.length - 1).toString() + '<';
|
||||
msg.str = msg.str.slice(0, p[i].i) + htmlEntityEncoded + msg.str.slice(p[i].i + p[i].k);
|
||||
l = htmlEntityEncoded.length - p[i].k;
|
||||
for (j = i + 1; j < p.length; j++)
|
||||
p[j].i += l;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return str;
|
||||
return msg;
|
||||
}
|
||||
|
||||
function htmlSplitCounter(str) {
|
||||
html.push('<span class="splited-post-counter">' + str + '</span>');
|
||||
function newHtmlEntityLink(template, urlTarget, urlName) {
|
||||
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;
|
||||
|
||||
for (var i = 0; i < str.length - 2; i++) {
|
||||
if (str[i] === '>') {
|
||||
for (var j = i + 2; j < str.length; j++) {
|
||||
if (str[j] === '<')
|
||||
for (var i = 0; i < msg.str.length - 2; i++) {
|
||||
if (msg.str[i] === '>') {
|
||||
for (var j = i + 2; j < msg.str.length; j++) {
|
||||
if (msg.str[j] === '<')
|
||||
break;
|
||||
}
|
||||
t = html[parseInt(str.slice(i + 1, j))];
|
||||
str = str.slice(0, i) + t + str.slice(j + 1);
|
||||
t = msg.htmlEntities[parseInt(msg.str.slice(i + 1, j))];
|
||||
msg.str = msg.str.slice(0, i) + t + msg.str.slice(j + 1);
|
||||
i = i + t.length - 1;
|
||||
}
|
||||
}
|
||||
|
||||
return str;
|
||||
return msg.str;
|
||||
}
|
||||
|
||||
var mentionsChars = 'abcdefghijklmnopqrstuvwxyz_0123456789';
|
||||
@ -433,178 +459,164 @@ function htmlFormatMsg(msg, mentions) {
|
||||
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 '>'
|
||||
+ whiteSpaces;
|
||||
var stopCharsMarkDown = '/\\*~_-`.,:;?!%+=&\'"[](){}^|«»…\u201C\u201D\u2026\u2014\u4E00\u3002\uFF0C\uFF1A\uFF1F\uFF01\u3010\u3011\u2047\u2048\u2049';
|
||||
var i, j, k, str, strEncoded;
|
||||
var html = [];
|
||||
var stopCharsMarkout = '/\\*~_-`.,:;?!%+=&\'"[](){}^|«»…\u201C\u201D\u2026\u2014\u4E00\u3002\uFF0C\uFF1A\uFF1F\uFF01\u3010\u3011\u2047\u2048\u2049';
|
||||
var i, j, k, str;
|
||||
|
||||
msg = markdown(escapeHtmlEntities(msg),
|
||||
'`', 'samp'); // kind of monospace, sequence of chars inside will be escaped from markup
|
||||
msg = {str: escapeHtmlEntities(msg), htmlEntities: []};
|
||||
|
||||
for (i = 0; i < msg.length - 7; i++) {
|
||||
if (msg.slice(i, i + 2) === '](') {
|
||||
// FIXME there can be text with [] inside [] or links with () wee need to handle it too
|
||||
j = getStrStart(msg, i - 2, '[', true, '');
|
||||
msg = markout(msg, '`', 'samp'); // <samp> tag is kind of monospace, here sequence of chars inside it will be escaped from markup
|
||||
|
||||
// handling links
|
||||
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) {
|
||||
k = getStrEnd(msg, i + 3, ')', true, whiteSpaces);
|
||||
k = getSubStrEnd(msg.str, i + 3, ')', true, whiteSpaces);
|
||||
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++) {
|
||||
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;
|
||||
}
|
||||
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
|
||||
if (msg[i] === '#' || msg.slice(i, i + 10).toLowerCase() === 'javascript'
|
||||
|| msg.slice(i, i + 4).toLowerCase() === 'data') {
|
||||
html.push('…<br><b><i>' + polyglot.t('busted_oh') + '</i> '
|
||||
var x = getSubStrEnd(msg.str, i, ':', false, '') + 1;
|
||||
// following check is NOT for real protection (we have blocking CSP rule instead), it's just to aware people
|
||||
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
|
||||
|| 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>'
|
||||
+ msg.slice(i, k + 1)
|
||||
+ msg.str.slice(i, k + 1)
|
||||
.replace(/&(?!lt;|gt;)/g, '&')
|
||||
.replace(/"/g, '"')
|
||||
.replace(/'/g, ''')
|
||||
+ '</samp><br>'
|
||||
);
|
||||
} else {
|
||||
if (getStrEnd(msg, i + 1, whiteSpacesUrl, false, '') < k) // use only first word as href target, others drop silently
|
||||
k = getStrEnd(msg, i + 1, whiteSpacesUrl, false, '');
|
||||
html.push($('#external-page-link-template')[0].outerHTML
|
||||
.replace(/\bid\s*=\s*"[^]*?"+/ig, '') // $().removeAttr('id')
|
||||
//.replace(/\bhref\s*=\s*"[^]*?"+/ig, '') // $().removeAttr('href')
|
||||
.replace(/<a\s+/ig, '<a href="' + proxyURL(msg.slice(i, k + 1)) + '" ') // $().closest('a').attr('href', proxyURL(url))
|
||||
.replace(/(<a\s+[^]*?>)[^]*?(<\/a>)/ig, '$1'
|
||||
+ unpackHtml(
|
||||
markdown(markdown(markdown(markdown(strEncoded, // name of link, see above
|
||||
'*', 'b'), // bold
|
||||
'~', 'i'), // italic
|
||||
'_', 'u'), // underlined
|
||||
'-', 's') // striketrough
|
||||
.replace(/&(?!lt;|gt;)/g, '&')
|
||||
.replace(/"/g, '"')
|
||||
.replace(/'/g, ''')
|
||||
if (getSubStrEnd(msg.str, i + 1, whiteSpacesUrl, false, '') < k) // use only first word as href target, others drop silently
|
||||
k = getSubStrEnd(msg.str, i + 1, whiteSpacesUrl, false, '');
|
||||
msg = msgAddHtmlEntity(msg, j - 1, getSubStrEnd(msg.str, k + 1, ')', true, '') + 2,
|
||||
newHtmlEntityLink(_htmlFormatMsgLinkTemplateExternal,
|
||||
proxyURL(msg.str.slice(i, k + 1)),
|
||||
applyHtml( // we're trying markup inside [] of []()
|
||||
markout(markout(markout(markout(
|
||||
{str: linkName, htmlEntities: msg.htmlEntities},
|
||||
'*', 'b'), // bold
|
||||
'~', 'i'), // italic
|
||||
'_', 'u'), // underlined
|
||||
'-', 's') // striketrough
|
||||
)
|
||||
+ '$2') // $().closest('a').text(url)
|
||||
.replace(/&(?!lt;|gt;)/g, '&')
|
||||
)
|
||||
);
|
||||
}
|
||||
strEncoded = '>' + (html.length - 1).toString() + '<';
|
||||
msg = msg.slice(0, j - 1) + strEncoded + msg.slice(getStrEnd(msg, k + 1, ')', true, '') + 2);
|
||||
i = j + strEncoded.length - 1;
|
||||
} // else
|
||||
// i = just no
|
||||
i = msg.i + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (msg.slice(i, i + 4).toLowerCase() === 'http') {
|
||||
if (msg.slice(i + 4, i + 7) === '://' && stopCharsRight.indexOf(msg[i + 7]) === -1) {
|
||||
j = getStrEnd(msg, i + 7, stopCharsRight, false, stopCharsTrailingUrl);
|
||||
} else if (msg.str.slice(i, i + 4).toLowerCase() === 'http') {
|
||||
if (msg.str.slice(i + 4, i + 7) === '://' && stopCharsRight.indexOf(msg.str[i + 7]) === -1) {
|
||||
j = getSubStrEnd(msg.str, i + 7, stopCharsRight, false, stopCharsTrailingUrl);
|
||||
if (j > i + 6) {
|
||||
str = msg.slice(i, j + 1);
|
||||
// FIXME we're trying to not interact with DOM, coz' we want to run really fast [to hell of RegExps]
|
||||
// FIXME actually we should avoid it by dropping a template idea and construct html right here
|
||||
html.push($('#external-page-link-template')[0].outerHTML
|
||||
.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)
|
||||
str = msg.str.slice(i, j + 1);
|
||||
msg = msgAddHtmlEntity(msg, i, i + str.length,
|
||||
newHtmlEntityLink(_htmlFormatMsgLinkTemplateExternal,
|
||||
proxyURL(str), str)
|
||||
);
|
||||
strEncoded = '>' + (html.length - 1).toString() + '<';
|
||||
msg = msg.slice(0, i) + strEncoded + msg.slice(i + str.length);
|
||||
i = i + strEncoded.length - 1;
|
||||
i = msg.i;
|
||||
}
|
||||
} else if (msg.slice(i + 4, i + 8).toLowerCase() === 's://' && stopCharsRight.indexOf(msg[i + 8]) === -1) {
|
||||
j = getStrEnd(msg, i + 8, stopCharsRight, false, stopCharsTrailingUrl);
|
||||
} else if (msg.str.slice(i + 4, i + 8).toLowerCase() === 's://' && stopCharsRight.indexOf(msg.str[i + 8]) === -1) {
|
||||
j = getSubStrEnd(msg.str, i + 8, stopCharsRight, false, stopCharsTrailingUrl);
|
||||
if (j > i + 7) {
|
||||
str = msg.slice(i, j + 1);
|
||||
html.push($('#external-page-link-template')[0].outerHTML
|
||||
.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)
|
||||
str = msg.str.slice(i, j + 1);
|
||||
msg = msgAddHtmlEntity(msg, i, i + str.length,
|
||||
newHtmlEntityLink(_htmlFormatMsgLinkTemplateExternal,
|
||||
proxyURL(str), str)
|
||||
);
|
||||
strEncoded = '>' + (html.length - 1).toString() + '<';
|
||||
msg = msg.slice(0, i) + strEncoded + msg.slice(i + str.length);
|
||||
i = i + strEncoded.length - 1;
|
||||
i = msg.i;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 1; i < msg.length - 1; i++) {
|
||||
if (msg[i] === '@' && stopCharsLeft.indexOf(msg[i - 1]) === -1
|
||||
&& stopCharsTrailing.indexOf(msg[i - 1]) === -1 && stopCharsRight.indexOf(msg[i + 1]) === -1) {
|
||||
j = getStrStart(msg, i - 1, stopCharsLeft, false, stopCharsTrailing);
|
||||
// handling mails
|
||||
for (i = 1; i < msg.str.length - 1; i++) {
|
||||
if (msg.str[i] === '@' && stopCharsLeft.indexOf(msg.str[i - 1]) === -1
|
||||
&& 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) {
|
||||
k = getStrEnd(msg, i + 1, stopCharsRight, false, stopCharsTrailing);
|
||||
k = getSubStrEnd(msg.str, i + 1, stopCharsRight, false, stopCharsTrailing);
|
||||
if (k > i) {
|
||||
str = msg.slice(j, k + 1);
|
||||
html.push($('#external-page-link-template')[0].outerHTML
|
||||
.replace(/\bid\s*=\s*"[^]*?"+/ig, '') // $().removeAttr('id')
|
||||
//.replace(/\bhref\s*=\s*"[^]*?"+/ig, '') // $().removeAttr('href')
|
||||
.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)
|
||||
str = msg.str.slice(j, k + 1);
|
||||
msg = msgAddHtmlEntity(msg, j, j + str.length,
|
||||
newHtmlEntityLink(_htmlFormatMsgLinkTemplateExternal,
|
||||
'mailto:' + str.toLowerCase(), str)
|
||||
);
|
||||
strEncoded = '>' + (html.length - 1).toString() + '<';
|
||||
msg = msg.slice(0, j) + strEncoded + msg.slice(j + str.length);
|
||||
i = j + strEncoded.length - 1;
|
||||
i = msg.i;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < msg.length - 1; i++) {
|
||||
if (msg[i] === '@' && mentionsChars.indexOf(msg[i + 1].toLowerCase()) > -1) {
|
||||
for (j = i + 2; j < msg.length; j++) {
|
||||
if (mentionsChars.indexOf(msg[j].toLowerCase()) === -1)
|
||||
// handling mentions
|
||||
for (i = 0; i < msg.str.length - 1; i++) {
|
||||
if (msg.str[i] === '@' && mentionsChars.indexOf(msg.str[i + 1].toLowerCase()) > -1) {
|
||||
for (j = i + 2; j < msg.str.length; j++) {
|
||||
if (mentionsChars.indexOf(msg.str[j].toLowerCase()) === -1)
|
||||
break;
|
||||
}
|
||||
str = msg.slice(i + 1, j).toLowerCase();
|
||||
str = msg.str.slice(i + 1, j).toLowerCase();
|
||||
mentions.push(str); // FIXME
|
||||
html.push($('#msg-user-link-template')[0].outerHTML
|
||||
.replace(/\bid\s*=\s*"[^]*?"+/ig, '') // $().removeAttr('id')
|
||||
//.replace(/\bhref\s*=\s*"[^]*?"+/ig, '') // $().removeAttr('href')
|
||||
.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)
|
||||
msg = msgAddHtmlEntity(msg, i, i + str.length + 1,
|
||||
newHtmlEntityLink(_htmlFormatMsgLinkTemplateUser,
|
||||
$.MAL.userUrl(str), '@' + str)
|
||||
);
|
||||
strEncoded = '>' + (html.length - 1).toString() + '<';
|
||||
msg = msg.slice(0, i) + strEncoded + msg.slice(i + str.length + 1);
|
||||
i = i + strEncoded.length - 1;
|
||||
i = msg.i;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < msg.length - 1; i++) {
|
||||
if (msg[i] === '#' && msg[i + 1] !== '#' && stopCharsRight.indexOf(msg[i + 1]) === -1) {
|
||||
j = getStrEnd(msg, i + 1, stopCharsRightHashtags, false, stopCharsTrailing);
|
||||
// handling hashtags
|
||||
for (i = 0; i < msg.str.length - 1; i++) {
|
||||
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) {
|
||||
str = msg.slice(i + 1, j + 1);
|
||||
html.push($('#hashtag-link-template')[0].outerHTML
|
||||
.replace(/\bid\s*=\s*"[^]*?"+/ig, '') // $().removeAttr('id')
|
||||
//.replace(/\bhref\s*=\s*"[^]*?"+/ig, '') // $().removeAttr('href')
|
||||
.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)
|
||||
str = msg.str.slice(i + 1, j + 1);
|
||||
msg = msgAddHtmlEntity(msg, i, i + str.length + 1,
|
||||
newHtmlEntityLink(_htmlFormatMsgLinkTemplateHashtag,
|
||||
$.MAL.hashtagUrl(encodeURIComponent(str.toLowerCase())), '#' + str.replace(/&/g, '&'))
|
||||
);
|
||||
strEncoded = '>' + (html.length - 1).toString() + '<';
|
||||
msg = msg.slice(0, i) + strEncoded + msg.slice(i + str.length + 1);
|
||||
i = i + strEncoded.length - 1;
|
||||
i = msg.i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
msg = unpackHtml(
|
||||
markdown(markdown(markdown(markdown(msg,
|
||||
// handling text style markup
|
||||
msg = markout(markout(markout(markout(msg,
|
||||
'*', 'b'), // bold
|
||||
'~', 'i'), // italic
|
||||
'_', 'u'), // underlined
|
||||
'-', '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(/"/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')
|
||||
msg = msg.replace(/\n/g, '<br />');
|
||||
|
||||
// TODO: add options for emotions; msg = $.emotions(msg);
|
||||
// TODO make markdown optionally mutable ?
|
||||
|
||||
return msg;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user