Greasemonkey Hijack setInterval
I'm trying to build a greasemonkey script for adding sm开发者_开发技巧ilies to a chatbox.
I need to detect the refresh of the chatbox and replace the smilies: The chatbox refreshes with a setInterval on the page:
setInterval(refreshChat, 7000);
Normaly I would hijack this in this way
var refreshChat = unsafeWindow.refreshChat; unsafeWindow.refreshChat = function() { doSmileyReplace(); return refreshChat(); };
But for some reason this doesn't register? I tried setting my own interval in the greasemonkey to run 5 miliseconds later then the setinterval on the page itself, it works, but doesnt look right.
the refreshChat function is nothing special
function refreshChat() { var randomnumber=Math.floor(Math.random()*500000); $('#chat').load('chat.php?cachebuster='+randomnumber+'&method=chat'); }
So how do I catch the setInterval?
$('#chat').load(
makes an ajax call. You are replacing the smilies prior to the AJAX call returning. If it is acceptable to just replace refreshChat
all together than you can just add a complete function on the load
:
$('#chat').load('chat.php?cachebuster='+randomnumber+'&method=chat',doSmileyReplace);
why dont you use this:
var script = refreshChat.toString();
script.replace('&method=chat');','&method=chat');mycoolhijecfunc();')
refreshChat = eval('('+script+')')
where mycoolhijecfunc
is the function that adds the smilies.
got this from messing in the source of TWpro , I was stunned to see it work, I modified it it normally is:
var modify_function = function (obj, method, options) {
try {
//if (console && console.log) console.log("TW Pro: Modifying method " + method);
if (!obj || !obj[method]) return;
var func = obj[method].toString();
for (var i=3; i<arguments.length; i++) {
if (arguments[i] && arguments[i].length > 1) {
var replacement = arguments[i][1],
arg_opts = arguments[i][2] || {};
if (typeof replacement == "function") {
replacement = "(" + replacement.toString() + ")()";
}
if (arg_opts.catch_errors) {
replacement = ";try{" + replacement + "}catch(twpro_exception){window.twpro_debug.log(twpro_exception,'method " + method + "')}";
}
if (arg_opts.escape) {
replacement = replacement.replace(/\$/g, "$$$$");
}
switch (arg_opts.pos) {
case "L":
replacement += "$&";
break;
case "R":
replacement = "$&" + replacement;
break;
}
func = func.replace(arguments[i][0], replacement);
}
}
//self.fncs.push('"'+method+'"', func);
obj[method] = eval("(" + func + ")");
if (options && options.bind) {
obj[method] = obj[method].bind(options.bind);
}
} catch (e) {
twpro_debug.log("TW Pro failed to modify function " + method + ": " + e);
}
};
Replacing refreshChat
won't work well, since the new messages are loaded asynchronously by AJAX.
Fortunately, the page uses jQuery, so triggering off that AJAX is easy. You could do something like this:
/*--- Evesdrop on the page's AJAX calls and rewrite smilies after
a short delay.
*/
unsafeWindow.$('body').ajaxSuccess (
function (event, requestData) {
setTimeout (function() { doSmileyReplace (); }, 111);
}
);
Note that the delay is probably not necessary, I put it there just in case.
精彩评论