mami/src/mami.js/parsing.js

389 lines
14 KiB
JavaScript

#include messages.js
#include settings.js
#include utility.js
#include ui/markup.js
if(!Umi.Parser) Umi.Parser = {};
if(!Umi.Parser.SockChatBBcode) Umi.Parser.SockChatBBcode = {};
Umi.Parsing = (function() {
const bbCodes = [
{
tag: 'b',
replace: '<b>{0}</b>',
button: true,
},
{
tag: 'i',
replace: '<i>{0}</i>',
button: true,
},
{
tag: 'u',
replace: '<u>{0}</u>',
button: true,
},
{
tag: 's',
replace: '<del>{0}</del>',
button: true,
},
{
tag: 'quote',
replace: '<q style="font-variant: small-caps;">{0}</q>',
button: true,
},
{
tag: 'code',
replace: '<span style="white-space: pre-wrap; font-family: monospace;">{0}</span>',
button: true,
},
{
tag: 'sjis',
replace: '<span class="sjis" style="white-space: pre-wrap;">{0}</span>',
},
{
tag: 'color',
hasArg: true,
stripArg: ';:{}<>&|\\/~\'"',
replace: '<span style="color:{0};">{1}</span>',
isToggle: true,
button: true,
},
{
tag: 'img',
stripText: '"\'',
replace: '<span title="{0}"><span title="link"><a class="markup__link" href="{0}" target="_blank" rel="nofollow noreferrer noopener">{0}</a></span>&nbsp;[<a href="#" onclick="Umi.Parser.SockChatBBcode.EmbedImage(this);return false;" class="markup__link">Embed</a>]</span>',
button: true,
},
{
tag: 'url',
stripText: '"\'',
replace: '<a href="{0}" target="_blank" rel="nofollow noreferrer noopener" class="markup__link">{0}</a>',
},
{
tag: 'url',
hasArg: true,
stripArg: '"\'',
replace: '<a href="{0}" target="_blank" rel="nofollow noreferrer noopener" class="markup__link">{1}</a>',
button: true,
},
{
tag: 'video',
stripText: '"\'',
replace: '<span title="{0}"><span title="link"><a class="markup__link" href="{0}" target="_blank" rel="nofollow noreferrer noopener">{0}</a></span>&nbsp;[<a href="#" onclick="Umi.Parser.SockChatBBcode.EmbedVideo(this);return false;" class="markup__link">Embed</a>]</span>',
button: true,
},
{
tag: 'audio',
stripText: '"\'',
replace: '<span title="{0}"><span title="link"><a class="markup__link" href="{0}" target="_blank" rel="nofollow noreferrer noopener">{0}</a></span>&nbsp;[<a href="#" onclick="Umi.Parser.SockChatBBcode.EmbedAudio(this);return false;" class="markup__link">Embed</a>]</span>',
button: true,
},
{
tag: 'spoiler',
stripText: '"\'',
replace: '<span data-shit="{0}"><span>*** HIDDEN ***</span>&nbsp;[<a href="#" onclick="Umi.Parser.SockChatBBcode.ToggleSpoiler(this);return false;" class="markup__link">Reveal</a>]</span>',
button: true,
}
];
const replaceAll = function(haystack, needle, replace, ignore) {
return haystack.replace(
new RegExp(
needle.replace(/([\/\,\!\\\^\$\{\}\[\]\(\)\.\*\+\?\|\<\>\-\&])/g, '\\$&'),
(ignore ? 'gi' : 'g')
),
(typeof (replace) == 'string')
? replace.replace(/\$/g, '$$$$')
: replace
);
}
const stripChars = function(str, chars) {
if(!chars)
return str;
for(let i = 0; i < chars.length; i++)
str = replaceAll(str, chars[i], '');
return str;
}
const extractMotiv = function(elem) {
const msgId = parseInt(elem.parentNode.parentNode.parentNode.parentNode.id.substring(8));
let topText = 'Top Text',
bottomText = 'Bottom Text';
const msg = Umi.Messages.Get(msgId);
if(msg) {
const msgText = msg.getText().replace(/\[(.*?)\](.*?)\[\/(.*?)\]/g, '').trim();
if(msgText.length > 0) {
const msgTextParts = msgText.split(' '),
topTextLength = Math.ceil(msgTextParts.length / 10),
topTextParts = msgTextParts.slice(0, topTextLength);
let bottomTextParts = null;
if(msgTextParts.length === 1 || Math.random() > .7) {
bottomTextParts = msgTextParts;
} else {
bottomTextParts = msgTextParts.slice(topTextLength);
}
topText = topTextParts.join(' ');
bottomText = bottomTextParts.join(' ');
}
}
return {
top: topText,
bottom: bottomText,
};
};
const motivFrame = function(texts, body) {
return $e({
attrs: {
style: {
display: 'inline-block',
textAlign: 'center',
fontFamily: '\'Times New Roman\', serif',
backgroundColor: 'black',
fontVariant: 'small-caps',
fontSize: '1.3em',
lineHeight: '1.4em',
},
},
child: [
{
tag: 'div',
attrs: {
style: {
border: '3px double #fff',
maxWidth: '50vw',
maxHeight: '50vh',
marginTop: '30px',
marginLeft: '50px',
marginRight: '50px',
boxSizing: 'content-box',
display: 'inline-block',
},
},
child: body,
},
{
tag: 'h1',
child: texts.top,
attrs: {
style: {
color: '#fff',
textDecoration: 'none !important',
margin: '10px',
textTransform: 'uppercase',
},
},
},
{
tag: 'p',
child: texts.bottom,
attrs: {
style: {
color: '#fff',
textDecoration: 'none !important',
margin: '10px',
},
},
},
],
});
};
const toggleImage = function(element) {
const url = element.parentElement.title,
container = element.parentElement.getElementsByTagName('span')[0],
anchor = container.getElementsByTagName('a')[0],
isEmbedded = container.title !== 'link';
if(isEmbedded) {
container.title = 'link';
element.textContent = 'Embed';
element.dataset.embed = '0';
anchor.textContent = url;
} else {
container.title = 'image';
element.textContent = 'Remove';
element.dataset.embed = '1';
let html = $e({
tag: 'img',
attrs: {
src: url,
alt: url,
style: {
maxWidth: '50vw',
maxHeight: '50vh',
verticalAlign: 'middle',
},
},
});
if(Umi.Settings.get('motivationalImages'))
html = motivFrame(
extractMotiv(element),
html
);
anchor.textContent = '';
anchor.appendChild(html);
}
};
const toggleAudio = function(element) {
const url = element.parentElement.title,
container = element.parentElement.getElementsByTagName('span')[0],
isEmbedded = container.title !== 'link';
if(isEmbedded) {
container.title = 'link';
element.dataset.embed = '0';
element.textContent = 'Embed';
container.textContent = '';
container.appendChild($e({
tag: 'a',
attrs: {
href: url,
target: '_blank',
rel: 'nofollow noreferrer noopener',
className: 'markup__link',
},
child: url,
}));
} else {
container.title = 'audio';
element.dataset.embed = '1';
element.textContent = 'Remove';
container.textContent = '';
container.appendChild($e({
tag: 'audio',
attrs: {
src: url,
controls: true,
},
}));
}
};
const toggleVideo = function(element) {
const url = element.parentElement.title,
container = element.parentElement.getElementsByTagName('span')[0],
isEmbedded = container.title !== 'link';
if(isEmbedded) {
container.title = 'link';
element.dataset.embed = '0';
element.textContent = 'Embed';
container.textContent = '';
container.appendChild($e({
tag: 'a',
attrs: {
href: url,
target: '_blank',
rel: 'nofollow noreferrer noopener',
className: 'markup__link',
},
child: url,
}));
} else {
container.title = 'video';
element.dataset.embed = '1';
element.textContent = 'Remove';
let html = $e({
tag: 'video',
attrs: {
src: url,
controls: true,
style: {
maxWidth: '800px',
maxHeight: '600px',
},
},
});
if(Umi.Settings.get('motivationalVideos'))
html = motivFrame(
extractMotiv(element),
html
);
container.textContent = '';
container.appendChild(html);
}
};
const toggleSpoiler = function(element) {
const container = element.parentElement,
target = container.querySelector('span');
if(container.dataset.revealed === 'yes') {
container.dataset.revealed = 'no';
target.textContent = '*** HIDDEN ***';
element.textContent = 'Reveal';
} else {
container.dataset.revealed = 'yes';
target.textContent = container.dataset.shit;
element.textContent = 'Hide';
}
};
Umi.Parser.SockChatBBcode.EmbedImage = toggleImage;
Umi.Parser.SockChatBBcode.EmbedAudio = toggleAudio;
Umi.Parser.SockChatBBcode.EmbedVideo = toggleVideo;
Umi.Parser.SockChatBBcode.ToggleSpoiler = toggleSpoiler;
return {
Init: function() {
for (let i = 0; i < bbCodes.length; i++) {
const bbCode = bbCodes[i];
if(!bbCode.button)
continue;
const start = '[{0}]'.replace('{0}', bbCode.tag + (bbCode.arg ? '=' : '')), end = '[/{0}]'.replace('{0}', bbCode.tag);
const text = (bbCode.tag.length > 1 ? bbCode.tag.substring(0, 1).toUpperCase() + bbCode.tag.substring(1) : bbCode.tag).replace('Color', 'Colour');
Umi.UI.Markup.Add(bbCode.tag, text, start, end);
}
},
Parse: function(element, message) {
for(let i = 0; i < bbCodes.length; i++) {
const bbCode = bbCodes[i];
if(!bbCode.hasArg) {
let at = 0;
while((at = element.innerHTML.indexOf('[' + bbCode.tag + ']', at)) != -1) {
let end;
if((end = element.innerHTML.indexOf('[/' + bbCode.tag + ']', at)) != -1) {
const inner = stripChars(element.innerHTML.substring(at + ('[' + bbCode.tag + ']').length, end), bbCode.stripText == undefined ? '' : bbCode.stripText);
const replace = replaceAll(bbCode.replace, '{0}', inner);
element.innerHTML = element.innerHTML.substring(0, at) + replace + element.innerHTML.substring(end + ('[/' + bbCode.tag + ']').length);
at += replace.length;
} else break;
}
} else {
let at = 0;
while((at = element.innerHTML.indexOf('[' + bbCode.tag + '=', at)) != -1) {
let start, end;
if((start = element.innerHTML.indexOf(']', at)) != -1) {
if((end = element.innerHTML.indexOf('[/' + bbCode.tag + ']', start)) != -1) {
const arg = stripChars(element.innerHTML.substring(at + ('[' + bbCode.tag + '=').length, start), '[]' + (bbCode.stripArg == undefined ? '' : bbCode.stripArg));
const inner = stripChars(element.innerHTML.substring(start + 1, end), bbCode.stripText == undefined ? '' : bbCode.stripText);
const replace = replaceAll(replaceAll(bbCode.replace, '{1}', inner), '{0}', arg);
element.innerHTML = element.innerHTML.substring(0, at) + replace + element.innerHTML.substring(end + ('[/' + bbCode.tag + ']').length);
at += replace.length;
} else break;
} else break;
}
}
}
return element;
},
};
})();