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; } } } }, }; })();