From 908ae7ae3dad487b03054252312d41d049607784 Mon Sep 17 00:00:00 2001 From: Thomas Forgione Date: Sat, 4 Apr 2020 14:30:06 +0200 Subject: [PATCH] Fix HTML chars bug --- static/main.css | 9 +++++ static/main.js | 97 ++++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 97 insertions(+), 9 deletions(-) diff --git a/static/main.css b/static/main.css index bfa15dd..357c776 100644 --- a/static/main.css +++ b/static/main.css @@ -30,6 +30,7 @@ body { .text { padding-right: 0.5rem; + word-wrap: break-word; } .name { @@ -44,6 +45,14 @@ body { width: 2rem; } +.badges { + display: inline-block; +} + +.badges+span+span:after { + display: block; +} + @keyframes slide { from { } to { bottom: 0rem; } diff --git a/static/main.js b/static/main.js index 080838e..ec09b3d 100644 --- a/static/main.js +++ b/static/main.js @@ -14,26 +14,29 @@ class Message { this.element.style.position = "relative"; let badges = document.createElement('span'); + badges.className = 'badges'; for (let key in this.context.badges) { let badge = document.createElement('span'); badge.className = "badge"; badge.innerHTML = ''; badges.appendChild(badge); } - this.element.appendChild(badges); let name = document.createElement('span'); name.className = "text name"; name.style.color = readableColor(this.context.color); name.innerHTML = escapeHtml(this.context["display-name"]); - this.element.appendChild(name); + badges.appendChild(name); - let message = document.createElement('span'); - let text = formatEmotes(this.message, this.context.emotes); + this.element.appendChild(badges); + + let messageSpan = document.createElement('span'); + let {message, emotes} = fixEmotes(this.message, this.context.emotes); + let text = formatEmotes(message, emotes); text = replaceAll(text, "DragonRck", ''); - message.innerHTML = text; - message.className = "text message"; - this.element.appendChild(message); + messageSpan.innerHTML = text; + messageSpan.className = "text message"; + this.element.appendChild(messageSpan); setTimeout(() => this.destroy(), timeout); return this.element; @@ -53,8 +56,79 @@ function escapeHtml(unsafe) { .replace(/'/g, "'"); } +function fixEmotes(message, emotes) { + let offsets = [[0, 0]]; + + let len = message.length; + let newMessage = ''; + + + let currentCharIndex = 0; + let currentOffset = 0; + while (currentCharIndex < len) { + let character = message.charAt(currentCharIndex); + switch (character) { + case '&': + newMessage += '&'; + currentOffset += 4; + offsets.push([currentCharIndex, currentOffset]); + break; + case '<': + newMessage += '<'; + currentOffset += 3; + offsets.push([currentCharIndex, currentOffset]); + break; + case '>': + newMessage += '>'; + currentOffset += 3; + offsets.push([currentCharIndex, currentOffset]); + break; + case '"': + newMessage += '"'; + currentOffset += 5; + offsets.push([currentCharIndex, currentOffset]); + break; + case "'": + newMessage += '''; + currentOffset += 5; + offsets.push([currentCharIndex, currentOffset]); + break; + default: + newMessage += character; + } + + currentCharIndex++; + } + + for (let emoteType in emotes) { + let emoteSet = emotes[emoteType]; + for (let emoteKey in emoteSet) { + let boundaries = emoteSet[emoteKey].split('-').map(x => parseInt(x, 10)); + + for (let i = 0; i < 2; i++) { + // Find floor entry + + let entryIndex = 0; + while (entryIndex + 1 < offsets.length && offsets[entryIndex + 1][0] < boundaries[i]) { + entryIndex++; + } + + boundaries[i] += offsets[entryIndex][1]; + + } + + emoteSet[emoteKey] = boundaries.map(x => x + "").join('-'); + + } + } + + return {message: newMessage, emotes}; + + +} + function formatEmotes(text, emotes) { - var splitText = escapeHtml(text).split(''); + var splitText = text.split(''); for(var i in emotes) { var e = emotes[i]; for(var j in e) { @@ -107,7 +181,12 @@ function addMessage(object) { messages.className = "slide"; }; +function onWindowResize() { + messages.style.width = window.innerWidth + 'px'; +} + let messages = document.getElementById('messages'); let socket = io(); socket.on('message', addMessage); - +window.addEventListener('resize', onWindowResize, false); +onWindowResize();