/* Client-side part of StreamGoose */ /* escape HTML entities (for non-server-provided stuff) */ function esc(s) { return s.replace(/&/g,'&').replace(//g,'>') .replace(/"/g,'"').replace(/'/g,''') } /* handle Twitch and YouTube emotes */ function handleEmotes(text) { var url = 'https://static-cdn.jtvnw.net/emoticons/v2/$id/default/dark/1.0' /* Handle Twitch emotes coming from backends */ text = text.replace(/#EMOTE-[^\s]+#/g, a=>'') /* Handle YouTube emotes */ text = text.replace(/:[^\s]+:/g, a => { if(YT_EMOTES.indexOf(a) > -1) /* found in the database */ return '' else return a }) return text } /* detect if there are any overridden styles */ function overrideStyles(text) { var styles = '', re if(messageHighlightRules) { for(re in messageHighlightRules) { if((new RegExp(re, 'iu')).test(text)) styles += 'color:' + messageHighlightRules[re] + ';' } } if(styles.length > 0) styles = ' style="' + esc(styles) + '"' return styles } /* individual message appender */ function gooseAppendMessage(id, type, timestamp, username, text, icon) { var html = "" if(parseInt(id) > 0 && type.length > 0) { var classes = type.split('-'), cl = classes.length, j, colorpref = null for(j=0;j' if(icon.length > 0) html += '' html += '' + timestamp + '' html += '' html += '' + handleEmotes(text) + '' } document.getElementById("msglist").innerHTML += html /* autoscroll to the end */ window.scrollTo(0, document.body.scrollHeight) } /* entry point, set up an event source */ window.addEventListener('DOMContentLoaded', function() { var msgSource = new EventSource('/sse') msgSource.onmessage = e => { var msg = JSON.parse(e.data) gooseAppendMessage(msg.id, msg.type, msg.timestamp, msg.username, msg.text, msg.icon) } }, false)