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