Replacing Javascript using Greasemonkey
This information is provided for educational purposes only.
You take all the responsibility for your use of this information.
There is no warranty, no support, no assurances.
There are errors in this information.
If you hurt yourself and/or others, it's your fault.
If you destroy your equipment or invalidate the warranties, it's your fault.
This disclaimer brought to you by one of the best justice systems on Earth.
This web page copyright © 2009 Squak Mountain Consulting, Inc.
I knew it could be done, I just didn't know how:
how to replace the code of a javascript function in a webpage.
I *could* do something fancy (and difficult) by hooking into the IP stack and changing the web page as it flys by. That is sort of a heavyweight solution for this problem, to say the least.
Or, I could use an add-on tool for firefox, but which one?
I looked at a lot of tools, and found 2 that do the job.
One is a debugger. I set a breakpoint on the javascript to force the return value of the javascript function. This is crude, difficult, labor-intensive, but at least it worked. I forgot the name of the debugger, unfortunately.
The other is greasemonkey. At first, this looked to be very difficult. But, like a lot of things, once you know how, it's easy. It turned out to take quite a number of hours to find a technique that would work. I started out by trying to modify 1 character of the script in the DOM. But, I couldn't get the script text to change when I did that. I started digging, and it seems to have to do with security and the context that Greasemonkey is executing in. I'll figure this out eventually. But, for now, I have to get this thing working!
Could I override the entire Javascript function with one of my own?
It turned out I could. The official Greasemonkey documentation didn't mention anything like this. I was confused; isn't this a basic thing someone would want to do with a tool like greasemonkey?
I did a lot of google searching on the web for "greasemonkey replace javascript" and similar phrases. I had to dig through a lot of false positive hits until I found a useful answer. A very nice person in Barcelona had run into a similar problem, and had written some documentation on it!
It was even written in English, woo hoo! Now, I wasn't sure if this would work, since what is does is add a new Javascript function at the end of all the other scripts. I would then have two scripts with the same name. Wouldn't the two scripts conflict somehow, or at least be rejected by the browser?
A little experimentation showed that this technique has the effect of replacing the original script. The later script overrides the earlier script. Is this by design in Firefox, or did i find a bug? I don't know yet and, for the moment (Firefox 3.0.5), it works. Here's how it goes:
First of all, I'm using a function I put on this page for this example, and I put it right near the start of my page, where it's easy for you to find. Here's the function
<script> function getcurrenttime(){ now=new Date; var currenttime = now.getTime(); } </script>
We are going to replace it with
<script> function getcurrenttime(){ now=new Date; var currenttime = now.getTime(); alert("The time is now: " + now ); } </script>
ok, now let's have you run this example on your browser.
you can later take the example and use it as the start of your greasemonkey script
just install greasemonkey, browse to the page you're reading right now, right-click on the monkey head icon (insert picture of monkey head icon), choose "new user script", fill in a name for your script, and paste this code right in there.
by default, the script operates on the page you currently have open, so it is good that you are reading this while creating the script!
var scriptCode = new Array(); // this is where we are going to build our new script // here's the build of the new script, one line at a time scriptCode.push('function getcurrenttime(){' ); scriptCode.push(' now=new Date;' ); scriptCode.push(' var currenttime = now.getTime();'); scriptCode.push(' alert("The time is: " + now );' ); scriptCode.push('}' ); // now, we put the script in a new script element in the DOM var script = document.createElement('script'); // create the script element script.innerHTML = scriptCode.join('\n'); // add the script code to it scriptCode.length = 0; // recover the memory we used to build the script // this is sort of hard to read, because it's doing 2 things: // 1. finds the first <head> tag on the page // 2. adds the new script just before the </head> tag document.getElementsByTagName('head')[0].appendChild(script); |
Now, click this button
and you should get the alert:
If you install firebug and look at the html of this page, you'll see that it now has 2 functions with the same name:
The function we just added is the one that got executed.
That's all for now!
references:
The code I started out with is at: http://luckyshot.es/blog/greasemonkey-user-scripts-quick-guide
at "Inserting Script and CSS Style tags"
Firefox
Greasemonkey