diff --git a/code/modules/goonchat/browserassets/js/browserOutput.js b/code/modules/goonchat/browserassets/js/browserOutput.js index 8f7194917c80..a7a2a1118189 100644 --- a/code/modules/goonchat/browserassets/js/browserOutput.js +++ b/code/modules/goonchat/browserassets/js/browserOutput.js @@ -78,6 +78,12 @@ function clamp(val, min, max) { return Math.max(min, Math.min(val, max)) } +function outerHTML(el) { + var wrap = document.createElement('div'); + wrap.appendChild(el.cloneNode(true)); + return wrap.innerHTML; +} + //Polyfill for fucking date now because of course IE8 and below don't support it if (!Date.now) { Date.now = function now() { @@ -167,62 +173,58 @@ function byondDecode(message) { return message; } -//Get a highlight markup span -function createHighlightMarkup() { +//Actually turns the highlight term match into appropriate html +function addHighlightMarkup(match) { var extra = ''; if (opts.highlightColor) { - extra += ' style="background-color: ' + opts.highlightColor + '"'; + extra += ' style="background-color: '+opts.highlightColor+'"'; } - return ''; + return ''+match+''; } -// Get all child text nodes that match a regex pattern -function getTextNodes(elem, pattern) { - var result = $([]); - $(elem).contents().each(function(idx, child) { - if (child.nodeType === 3 && /\S/.test(child.nodeValue) && pattern.test(child.nodeValue)) { - result = result.add(child); - } - else { - result = result.add(getTextNodes(child, pattern)); +//Highlights words based on user settings +function highlightTerms(el) { + if (el.children.length > 0) { + for(var h = 0; h < el.children.length; h++){ + highlightTerms(el.children[h]); } - }); - return result; -} + } -// Highlight all text terms matching the registered regex patterns -function highlightTerms(el) { - var pattern = new RegExp("(" + opts.highlightTerms.join('|') + ")", 'gi'); - var nodes = getTextNodes(el, pattern); - - nodes.each(function (idx, node) { - var content = $(node).text(); - var parent = $(node).parent(); - var pre = $(node.previousSibling); - $(node).remove(); - content.split(pattern).forEach(function (chunk) { - // Get our highlighted span/text node - var toInsert = null; - if (pattern.test(chunk)) { - var tmpElem = $(createHighlightMarkup()); - tmpElem.text(chunk); - toInsert = tmpElem; - } - else { - toInsert = document.createTextNode(chunk); - } + var hasTextNode = false; + for (var node = 0; node < el.childNodes.length; node++) + { + if (el.childNodes[node].nodeType === 3) + { + hasTextNode = true; + break; + } + } - // Insert back into our element - if (pre.length == 0) { - var result = parent.prepend(toInsert); - pre = $(result[0].firstChild); - } - else { - pre.after(toInsert); - pre = $(pre[0].nextSibling); + if (hasTextNode) { //If element actually has text + var newText = ''; + for (var c = 0; c < el.childNodes.length; c++) { //Each child element + if (el.childNodes[c].nodeType === 3) { //Is it text only? + var words = el.childNodes[c].data.split(' '); + for (var w = 0; w < words.length; w++) { //Each word in the text + var newWord = null; + for (var i = 0; i < opts.highlightTerms.length; i++) { //Each highlight term + if (opts.highlightTerms[i] && words[w].toLowerCase().indexOf(opts.highlightTerms[i].toLowerCase()) > -1) { //If a match is found + newWord = words[w].replace("<", "<").replace(new RegExp(opts.highlightTerms[i], 'gi'), addHighlightMarkup); + break; + } + if (window.console) + console.log(newWord) + } + newText += newWord || words[w].replace("<", "<"); + newText += w >= words.length ? '' : ' '; + } + } else { //Every other type of element + newText += outerHTML(el.childNodes[c]); } - }); - }); + } + el.innerHTML = newText; + } +} function iconError(E) { var that = this; @@ -406,7 +408,7 @@ function output(message, flag) { //Actually do the snap //Stuff we can do after the message shows can go here, in the interests of responsiveness if (opts.highlightTerms && opts.highlightTerms.length > 0) { - highlightTerms($(entry)); + highlightTerms(entry); } } @@ -749,11 +751,15 @@ $(function() { internalOutput('Loaded ping display of: '+(opts.pingDisabled ? 'hidden' : 'visible')+'', 'internal'); } if (savedConfig.shighlightTerms) { - var savedTerms = $.parseJSON(savedConfig.shighlightTerms).filter(function (entry) { - return entry !== null && /\S/.test(entry); - }); - var actualTerms = savedTerms.length != 0 ? savedTerms.join(', ') : null; + var savedTerms = $.parseJSON(savedConfig.shighlightTerms); + var actualTerms = ''; + for (var i = 0; i < savedTerms.length; i++) { + if (savedTerms[i]) { + actualTerms += savedTerms[i] + ', '; + } + } if (actualTerms) { + actualTerms = actualTerms.substring(0, actualTerms.length - 2); internalOutput('Loaded highlight strings of: ' + actualTerms+'', 'internal'); opts.highlightTerms = savedTerms; } @@ -1067,12 +1073,20 @@ $(function() { $('body').on('submit', '#highlightTermForm', function(e) { e.preventDefault(); - opts.highlightTerms = []; - for (var count = 0; count < opts.highlightLimit; count++) { + var count = 0; + while (count < opts.highlightLimit) { var term = $('#highlightTermInput'+count).val(); - if (term !== null && /\S/.test(term)) { - opts.highlightTerms.push(term.trim().toLowerCase()); + if (term) { + term = term.trim(); + if (term === '') { + opts.highlightTerms[count] = null; + } else { + opts.highlightTerms[count] = term.toLowerCase(); + } + } else { + opts.highlightTerms[count] = null; } + count++; } var color = $('#highlightColor').val();