Fix inline colour filter by applying to text nodes only
this requires traversing the line's DOM and manipulating things there
This commit is contained in:
parent
dbdd0523f9
commit
d95abdd0df
|
@ -269,7 +269,7 @@ $ openssl req -nodes -newkey rsa:4096 -keyout relay.pem -x509 -days 365 -out rel
|
|||
<td class="prefix"><a ng-click="addMention(bufferline.prefix)"><span ng-repeat="part in ::bufferline.prefix" ng-class="::part.classes" ng-bind="::part.text"></span></a></td><!--
|
||||
--><td class="message"><!--
|
||||
--><div ng-repeat="metadata in ::bufferline.metadata" plugin data="::metadata"></div><!--
|
||||
--><span ng-repeat="part in ::bufferline.content" class="text" ng-class="::part.classes" ng-bind-html="::part.text | irclinky:'_blank' | inlinecolour"></span>
|
||||
--><span ng-repeat="part in ::bufferline.content" class="text" ng-class="::part.classes" ng-bind-html="::part.text | irclinky:'_blank' | DOMfilter:'inlinecolour'"></span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="readmarker" ng-if="activeBuffer().lastSeen==$index">
|
||||
|
|
|
@ -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 <div class="colourbox" style="background-color:#$2"></div> $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);
|
||||
};
|
||||
}]);
|
||||
})();
|
||||
|
|
Loading…
Reference in New Issue