diff --git a/index.html b/index.html
index 0d6d5d8..0e69a41 100644
--- a/index.html
+++ b/index.html
@@ -269,7 +269,7 @@ $ openssl req -nodes -newkey rsa:4096 -keyout relay.pem -x509 -days 365 -out rel
|
+ -->
|
diff --git a/js/filters.js b/js/filters.js
index 42335bd..b39a307 100644
--- a/js/filters.js
+++ b/js/filters.js
@@ -36,7 +36,7 @@ weechat.filter('irclinky', ['$filter', function($filter) {
};
}]);
-weechat.filter('inlinecolour', ['$sce', function($sce) {
+weechat.filter('inlinecolour', function() {
return function(text) {
if (!text) {
return text;
@@ -46,7 +46,53 @@ weechat.filter('inlinecolour', ['$sce', function($sce) {
var hexColourRegex = /(^|[^&])\#([0-9a-f]{6})($|[^\w'"])/gmi;
var substitute = '$1#$2 $3';
- return $sce.trustAsHtml(text.replace(hexColourRegex, substitute));
+ return text.replace(hexColourRegex, substitute);
+ };
+});
+
+// apply a filter to an HTML string's text nodes, and do so with not exceedingly terrible performance
+weechat.filter('DOMfilter', ['$filter', '$sce', function($filter, $sce) {
+ return function(text, filter) {
+ if (!text || !filter) {
+ return text;
+ }
+
+ var filterFunction = $filter(filter);
+ var el = document.createElement('div');
+ el.innerHTML = text;
+
+ // Recursive DOM-walking function applying the filter to the text nodes
+ var process = function(node) {
+ if (node.nodeType === 3) { // text node
+ var value = filterFunction(node.nodeValue);
+ if (value !== node.nodeValue) {
+ // we changed something. create a new node to replace the current one
+ // we could also only add its children but that would probably incur
+ // more overhead than it would gain us
+ var newNode = document.createElement('span');
+ newNode.innerHTML = value;
+
+ var parent = node.parentNode;
+ var sibling = node.nextSibling;
+ parent.removeChild(node);
+ if (sibling) {
+ parent.insertBefore(newNode, sibling);
+ } else {
+ parent.appendChild(newNode);
+ }
+ }
+ }
+ // recurse
+ node = node.firstChild;
+ while (node) {
+ process(node);
+ node = node.nextSibling;
+ }
+ };
+
+ process(el);
+
+ return $sce.trustAsHtml(el.innerHTML);
};
}]);
})();