403 lines
14 KiB
JavaScript
403 lines
14 KiB
JavaScript
if(!Umi.Parser) Umi.Parser = {};
|
|
if(!Umi.Parser.SockChatBBcode) Umi.Parser.SockChatBBcode = {};
|
|
|
|
const UmiBBCodes = [
|
|
{
|
|
tag: 'b',
|
|
text: 'B',
|
|
style: 'font-weight: 700',
|
|
replace: '<b>{0}</b>',
|
|
},
|
|
{
|
|
tag: 'i',
|
|
text: 'I',
|
|
style: 'font-style: italic',
|
|
replace: '<i>{0}</i>',
|
|
},
|
|
{
|
|
tag: 'u',
|
|
text: 'U',
|
|
style: 'text-decoration: underline',
|
|
replace: '<u>{0}</u>',
|
|
},
|
|
{
|
|
tag: 's',
|
|
text: 'S',
|
|
style: 'text-decoration: line-through',
|
|
replace: '<del>{0}</del>',
|
|
},
|
|
{
|
|
tag: 'quote',
|
|
text: 'Quote',
|
|
replace: '<q style="font-variant: small-caps;">{0}</q>',
|
|
},
|
|
{
|
|
tag: 'code',
|
|
text: 'Code',
|
|
replace: '<span style="white-space: pre-wrap; font-family: monospace;">{0}</span>',
|
|
},
|
|
{
|
|
tag: 'sjis',
|
|
replace: '<span class="sjis" style="white-space: pre-wrap;">{0}</span>',
|
|
},
|
|
{
|
|
tag: 'color',
|
|
text: 'Colour',
|
|
hasArg: true,
|
|
stripArg: ';:{}<>&|\\/~\'"',
|
|
replace: '<span style="color:{0};">{1}</span>',
|
|
},
|
|
{
|
|
tag: 'bgcolor',
|
|
hasArg: true,
|
|
stripArg: ';:{}<>&|\\/~\'"',
|
|
replace: '<span style="background-color:{0};">{1}</span>',
|
|
},
|
|
{
|
|
tag: 'img',
|
|
text: 'Image',
|
|
stripText: '"\'',
|
|
replace: '<span title="{0}"><span title="link"><a class="markup__link" href="{0}" target="_blank" rel="nofollow noreferrer noopener">{0}</a></span> [<a href="#" onclick="Umi.Parser.SockChatBBcode.EmbedImage(this);return false;" class="markup__link">Embed</a>]</span>',
|
|
},
|
|
{
|
|
tag: 'url',
|
|
stripText: '"\'',
|
|
replace: '<a href="{0}" target="_blank" rel="nofollow noreferrer noopener" class="markup__link">{0}</a>',
|
|
},
|
|
{
|
|
tag: 'url',
|
|
text: 'URL',
|
|
hasArg: true,
|
|
stripArg: '"\'',
|
|
replace: '<a href="{0}" target="_blank" rel="nofollow noreferrer noopener" class="markup__link">{1}</a>',
|
|
},
|
|
{
|
|
tag: 'video',
|
|
text: 'Video',
|
|
stripText: '"\'',
|
|
replace: '<span title="{0}"><span title="link"><a class="markup__link" href="{0}" target="_blank" rel="nofollow noreferrer noopener">{0}</a></span> [<a href="#" onclick="Umi.Parser.SockChatBBcode.EmbedVideo(this);return false;" class="markup__link">Embed</a>]</span>',
|
|
},
|
|
{
|
|
tag: 'audio',
|
|
text: 'Audio',
|
|
stripText: '"\'',
|
|
replace: '<span title="{0}"><span title="link"><a class="markup__link" href="{0}" target="_blank" rel="nofollow noreferrer noopener">{0}</a></span> [<a href="#" onclick="Umi.Parser.SockChatBBcode.EmbedAudio(this);return false;" class="markup__link">Embed</a>]</span>',
|
|
},
|
|
{
|
|
tag: 'spoiler',
|
|
text: 'Spoiler',
|
|
stripText: '"\'',
|
|
replace: '<span data-shit="{0}"><span>*** HIDDEN ***</span> [<a href="#" onclick="Umi.Parser.SockChatBBcode.ToggleSpoiler(this);return false;" class="markup__link">Reveal</a>]</span>',
|
|
},
|
|
];
|
|
|
|
Umi.Parsing = (function() {
|
|
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) {
|
|
let topText = 'Top Text';
|
|
let bottomText = 'Bottom Text';
|
|
|
|
const root = elem.closest('.message');
|
|
if(root instanceof Element && 'body' in root.dataset) {
|
|
const msgText = root.dataset.body.replace(/\[(.*?)\](.*?)\[\/(.*?)\]/g, '').trim();
|
|
|
|
if(msgText.length > 0) {
|
|
const msgTextParts = msgText.split(' ');
|
|
const topTextLength = Math.ceil(msgTextParts.length / 10);
|
|
const 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 $element(
|
|
'div',
|
|
{
|
|
style: {
|
|
display: 'inline-block',
|
|
textAlign: 'center',
|
|
fontFamily: '\'Times New Roman\', serif',
|
|
backgroundColor: 'black',
|
|
fontVariant: 'small-caps',
|
|
fontSize: '1.3em',
|
|
lineHeight: '1.4em',
|
|
},
|
|
},
|
|
$element(
|
|
'div',
|
|
{
|
|
style: {
|
|
border: '3px double #fff',
|
|
maxWidth: '50vw',
|
|
maxHeight: '50vh',
|
|
marginTop: '30px',
|
|
marginLeft: '50px',
|
|
marginRight: '50px',
|
|
boxSizing: 'content-box',
|
|
display: 'inline-block',
|
|
},
|
|
},
|
|
body
|
|
),
|
|
$element(
|
|
'h1',
|
|
{
|
|
style: {
|
|
color: '#fff',
|
|
textDecoration: 'none !important',
|
|
margin: '10px',
|
|
textTransform: 'uppercase',
|
|
},
|
|
},
|
|
texts.top
|
|
),
|
|
$element(
|
|
'p',
|
|
{
|
|
style: {
|
|
color: '#fff',
|
|
textDecoration: 'none !important',
|
|
margin: '10px',
|
|
},
|
|
},
|
|
texts.bottom
|
|
),
|
|
);
|
|
};
|
|
|
|
const toggleImage = function(element) {
|
|
const url = element.parentElement.title;
|
|
const container = element.parentElement.getElementsByTagName('span')[0];
|
|
const anchor = container.getElementsByTagName('a')[0];
|
|
const 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';
|
|
element.classList.add('markup__link--visited');
|
|
|
|
let html = $element(
|
|
'img',
|
|
{
|
|
src: url,
|
|
alt: url,
|
|
style: {
|
|
maxWidth: '50vw',
|
|
maxHeight: '50vh',
|
|
verticalAlign: 'middle',
|
|
},
|
|
onload: () => {
|
|
if(mami.settings.get('autoScroll'))
|
|
container.scrollIntoView({ inline: 'end' });
|
|
},
|
|
},
|
|
);
|
|
|
|
if(mami.settings.get('motivationalImages'))
|
|
html = motivFrame(
|
|
extractMotiv(element),
|
|
html
|
|
);
|
|
|
|
anchor.textContent = '';
|
|
anchor.appendChild(html);
|
|
}
|
|
};
|
|
const toggleAudio = function(element) {
|
|
const url = element.parentElement.title;
|
|
const container = element.parentElement.getElementsByTagName('span')[0];
|
|
const isEmbedded = container.title !== 'link';
|
|
|
|
if(isEmbedded) {
|
|
container.title = 'link';
|
|
element.dataset.embed = '0';
|
|
element.textContent = 'Embed';
|
|
container.textContent = '';
|
|
container.appendChild($element(
|
|
'a',
|
|
{
|
|
href: url,
|
|
target: '_blank',
|
|
rel: 'nofollow noreferrer noopener',
|
|
className: 'markup__link',
|
|
},
|
|
url,
|
|
));
|
|
} else {
|
|
container.title = 'audio';
|
|
element.dataset.embed = '1';
|
|
element.textContent = 'Remove';
|
|
container.textContent = '';
|
|
element.classList.add('markup__link--visited');
|
|
|
|
let media = $element(
|
|
'audio',
|
|
{
|
|
src: url,
|
|
controls: true,
|
|
onloadedmetadata: () => {
|
|
if(mami.settings.get('autoScroll'))
|
|
container.scrollIntoView({ inline: 'end' });
|
|
if(mami.settings.get('autoEmbedPlay'))
|
|
media.play();
|
|
},
|
|
},
|
|
);
|
|
|
|
container.appendChild(media);
|
|
}
|
|
};
|
|
const toggleVideo = function(element) {
|
|
const url = element.parentElement.title;
|
|
const container = element.parentElement.getElementsByTagName('span')[0];
|
|
const isEmbedded = container.title !== 'link';
|
|
|
|
if(isEmbedded) {
|
|
container.title = 'link';
|
|
element.dataset.embed = '0';
|
|
element.textContent = 'Embed';
|
|
container.textContent = '';
|
|
container.appendChild($element(
|
|
'a',
|
|
{
|
|
href: url,
|
|
target: '_blank',
|
|
rel: 'nofollow noreferrer noopener',
|
|
className: 'markup__link',
|
|
},
|
|
url,
|
|
));
|
|
} else {
|
|
container.title = 'video';
|
|
element.dataset.embed = '1';
|
|
element.textContent = 'Remove';
|
|
element.classList.add('markup__link--visited');
|
|
|
|
let media = $element(
|
|
'video',
|
|
{
|
|
src: url,
|
|
controls: true,
|
|
style: {
|
|
maxWidth: '800px',
|
|
maxHeight: '600px',
|
|
},
|
|
onloadedmetadata: () => {
|
|
if(mami.settings.get('autoScroll'))
|
|
container.scrollIntoView({ inline: 'end' });
|
|
if(mami.settings.get('autoEmbedPlay'))
|
|
media.play();
|
|
},
|
|
},
|
|
);
|
|
|
|
let html = media;
|
|
|
|
if(mami.settings.get('motivationalVideos'))
|
|
html = motivFrame(
|
|
extractMotiv(element),
|
|
html
|
|
);
|
|
|
|
container.textContent = '';
|
|
container.appendChild(html);
|
|
}
|
|
};
|
|
const toggleSpoiler = function(element) {
|
|
const container = element.parentElement;
|
|
const target = container.querySelector('span');
|
|
|
|
if(container.dataset.revealed === 'yes') {
|
|
container.dataset.revealed = 'no';
|
|
target.textContent = '*** HIDDEN ***';
|
|
element.dataset.embed = '0';
|
|
element.textContent = 'Reveal';
|
|
} else {
|
|
container.dataset.revealed = 'yes';
|
|
target.textContent = container.dataset.shit;
|
|
element.dataset.embed = '1';
|
|
element.textContent = 'Hide';
|
|
element.classList.add('markup__link--visited');
|
|
}
|
|
};
|
|
|
|
Umi.Parser.SockChatBBcode.EmbedImage = toggleImage;
|
|
Umi.Parser.SockChatBBcode.EmbedAudio = toggleAudio;
|
|
Umi.Parser.SockChatBBcode.EmbedVideo = toggleVideo;
|
|
Umi.Parser.SockChatBBcode.ToggleSpoiler = toggleSpoiler;
|
|
|
|
return {
|
|
Parse: function(element, message) {
|
|
for(let i = 0; i < UmiBBCodes.length; i++) {
|
|
const bbCode = UmiBBCodes[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;
|
|
}
|
|
}
|
|
}
|
|
},
|
|
};
|
|
})();
|