Тормозит, я полагаю что все дело в частой вставке новых нод, но может более опытные товарищи чтонить подскажут.
// ==UserScript==
// @name test
// @namespace test
// @include http://www.linux.org.ru/*
// ==/UserScript==
// @author radiofun@jabber.org
function Smiles() {
var smilesSrc = {
"personal/angel.gif":"O:-) O:) O+) O=) 0:-) 0:) 0+) 0=) (A) (a)",
"icq/smile.gif":":-) :) +) =) :smile:",
"standart/sad.gif":":-( :( +( =( :-(( :(( +(( =(( :sad:",
"icq/wink.gif":";-) ;) ^_~ :wink:",
"standart/blum3.gif":":-P :P :-p :p +P =P +p =p :-b :b +b =b :tongue:",
"standart/dirol.gif":"8-) 8) B) :COOL: :cool: COOL cool COOL! COOL!! COOL!!!",
"icq/biggrin.gif":":-D :D +D =D :biggrin:",
"standart/blush2.gif":":-[ :[ ;'> ;-. :blush:",
"remake/shok.gif":"=-O =O =-o =0 O_O O_o o_O O_0 o_0 0_O 0_o",
"icq/kiss.gif":":-* :* :-{} :{} +{} ={} ^.^ :kiss: *KISS*",
"standart/cray2.gif":":'( :'-(",
"standart/secret.gif":":-X :-x X: x: :-# :# :secret:",
"standart/aggressive.gif":">:o >:O >+O >:o >+o :-@ :angry:",
"standart/fool.gif":":-| :| =|",
"standart/beee.gif":":-\\ :-/ :\\",
"standart/mosking.gif":"*JOKINGLY* 8P 8p",
"personal/diablo.gif":"]:-> }:-> ]:> }:> >:-] >:] (6) :diablo: *DIABLO*",
"personal/music2.gif":"[:-} [:}",
"standart/air_kiss.gif":"*KISSED*",
"standart/bad.gif":":-! :! :-~ ;-~ :(~ +(~ =(~ :bad:",
"standart/boredom.gif":"*TIRED* |-0 :boredom:",
"standart/stop.gif":"*STOP* STOP STOP! STOP!! STOP!!! :stop:",
"icq/give_rose.gif":"@}->-- @}-:-- @>}--,-`--- (F) (f)",
"standart/good.gif":"*THUMBS_UP* :GOOD: :good: GOOD! *GOOD*",
"standart/drinks.gif":"*DRINK* DRINK :drink:",
"madhouse/man_in_love.gif":"*IN_LOVE* LOVE",
"other/bomb.gif":"@=",
"madhouse/wacko.gif":"%) %-) :-$ :$ :wacko: :WACKO:",
"personal/mamba.gif":"*WASSUP* *SUP* *MAMBA* :MAMBA:",
"standart/clapping.gif":"*BRAVO* :BRAVO: :bravo: :clapping:",
"icq/rofl.gif":"*ROFL* :ROFL: :rofl: ROFL ROFL! rofl :-)))) :-))))) :-)))))) :)))) :))))) :)))))) =)))) =))))) =))))))",
"standart/pardon.gif":"*PARDON* =] :PARDON: :pardon: PARDON",
"standart/nea.gif":"*NO*",
"icq/crazy.gif":"*CRAZY* :crazy:",
"standart/dntknw.gif":"*DONT_KNOW* *UNKNOWN* :HZ: :hz:",
"standart/sorry2.gif":"*SORRY* :sorry:",
"standart/yahoo.gif":"*YAHOO* *YAHOO!* :YAHOO: :yahoo: YAHOO! Yahoo! YAHOO!! Yahoo!! YAHOO!!! Yahoo!!!",
"standart/dance4.gif":"*DANCE* :dance:",
"standart/help.gif":"*HELP*",
"standart/ok.gif":"*OK*",
"personal/new_russian.gif":"\\m/ \\M/"
};
var bor;
function addToBor(smiles, file) {
var node = bor;
var nnode = null;//next node
var s = 0;
for(var i = 0; i < smiles.length; ++i) {
var smile = smiles[i];
for(var j = 0; j < smile.length; ++j) {
var c = smile.charAt(j);
nnode = node[c];
if(!nnode) {
node[c] = nnode = {};
}
node = nnode;
}
node.end = {
file: file,
smile: smile,
len: smile.length
};
node = bor;//возвращаемся к корню
}
}
//добавление переходов "неудачи"
function findAndAddAlternatives(srcNode, stack) {
for(var i = 1; i < stack.length; ++i) {
var c;
var destNode = bor[c = stack[i]];
for(var j = i + 1; destNode && j < stack.length; ++j) {
destNode = destNode[c = stack[j]];
}
if(destNode) {
for(var destC in destNode) {
if(!srcNode[destC]) {
srcNode[destC] = destNode[destC];
}
}
}
}
}
function visitor(node, stack) {
for(var i in node) {
var child = node[i];
if(!child.end) {
var childStack = stack.concat(i);
visitor(child, childStack);
findAndAddAlternatives(child, childStack);
}
}
}
function createBor() {
if(!bor) {
bor = {};
for(var file in smilesSrc) {
var smiles = smilesSrc[file].split(" ");
addToBor(smiles, file);
}
node = bor;
var stack = [];
visitor(node, stack);
}
}
//replacing
this.replace = function(node) {
createBor();
if(node.nodeType == 3 /* Node.TEXT_NODE*/) {
var str = node.nodeValue;
var parsed = [];
var borNode = bor;
var last = null;
for(var i = 0; i < str.length; ++i) {
var c = str.charAt(i);
borNode = borNode[c];
if(!borNode) {
borNode = bor;
if(last) {
parsed.push(last);
last = null;
}
} else if(borNode.end) {
var e = borNode.end;
if(!last || (last.s >= i - e.len && last.e <= i)) {
last = {
s: i - e.len + 1,
e: i,
n: e,
file: e.file
};
}
}
}
//замена
var parent = node.parentNode;
for(var i = parsed.length - 1; i >= 0 ; --i) {
var p = parsed[i];
var text = node.splitText(p.s);
text.deleteData(0, p.n.len + 1);
var img = document.createElement("img");
img.src = "http://www.kolobok.us/smiles/" + p.file;
parent.insertBefore(img, text);
}
}
if(node.childNodes) {
for(var i = 0 ; i < node.childNodes.length; ++i) {
this.replace(node.childNodes[i]);
}
}
}
}
/*
this.createMenu = function(handler) {
var menu = document.createElement("div");
for(var s in smiles) {
var se = document.createElement("img");
se.src = site + smiles[s];
se.addEventListener("click", (function(s){
return function(){handler(s)};
})(s), false);
menu.appendChild(se);
}
return menu;
}*/
//window.onload = function() {
try{
var smiles = new Smiles();
var i = document.evaluate("//div[1]/div[@id='bd']/div[@class='messages']/div[@class='comment']/div/div[3]", document, null, XPathResult.ANY_TYPE, null);
var c;
var comments = []
while(c = i.iterateNext()) {
comments.push(c);
}
for(var j = 0; j < comments.length; ++j) {
var comment = comments[j];
smiles.replace(comment);
}
/*var msg = document.getElementById("msg");
var menu = smiles.createMenu(function(smile) {
var val = msg.value;
var s = msg.selectionStart;
var e = msg.selectionEnd;
msg.value = val.substring(0, s) + smile + val.substring(s, val.length);
});
msg.parentNode.insertBefore(menu, msg);*/
} catch(e) {
// console.error(e);
}
//}