After fiddling around with GM scripts for a bit now, I’ve got a pretty good handle on how to write them and what’s possible. I wanted to start a multipurpose thread to encourage other people to play around with GM scripts. I’ll give a quick overview of what you need to get started along with some tips/tricks that make it pretty simple to write your scripts. Then, it can just turn into a general GM thread if you have questions or get stuck or whatever… there are no stupid questions here.

Getting Started
There are a couple of things you’ll need in addition to FireFox and the GreaseMonkey plugin. The most important tool is the DOM Inspector addon. Another handy one is the Web Developeraddon, though to a lesser extent. Oh… and to embed images (e.g. icons), here’s a good page: It will convert an image into a string, as seen in many of the scripts I’ve written.

Webpages like TG are built with a Document Object Model – You can think of the page as being built of nested containers. A practical example might be a “table” container, which might contain several “row” containers. Inside each “row” container you have a number of “cells”. Inside each cell you can have links or images or even another table. 

The two hardest things when I first started were A) I didn’t know how to access any of these objects and B) I didn’t know ANY javascript. The first problem is solved by the DOM Inspector. It’s incredibly simple and powerful tool because it gives you a graphical view of all the page’s content:

You can either start at the top and mine your way down until the element you’re looking for blinks; or you can simply click an element in the web-page and DOMi will warp you to that container.This page has a couple really good videos (under a minute each) on how to inspect elements in a webpage using DOMi.

Javascript 101
Here’s somethings google learned me good:


  1. Semicolons appear to be optional.
  2. Variables don’t need to be declared.
  3. ‘+myVar+’ – use the ‘+ +’ syntax when you want to insert the value of a variable rather than just the variable name itself.

Built-in Functions:

Text manipulation:

  • obj.indexOf(‘someString’) – searches obj for the text in quotes. Returns -1 if it’s not found. Returns where in obj the string was found [a number].
  • obj.lastIndexOf(‘someString’) – same as indexOf() except it searches through obj backwards.
  • obj.replace(‘string1′,’string2’) – replaces string1 with string2
  • myString = obj.substring(start, end) – extracts part of a string out of a larger string.

Page navigation and searching:

  • obj.getElementsByTagName(‘tr’) – return a list of elements of that type. Here, I’m looking for all table rows in obj.
  • obj.getElementById(‘user_table’) – return a single elements with the unique ID specified. Oh.. and watchout that you don’t have “getElementsById”… that ‘s’ in there makes it not work.

GreaseMonkey parameter saving:

  • GM_setValue(key, value) – Save a parameter on a user’s machine. This lets you set a value on one page and access that value when the script runs at some later point in time (it’s kinda like a browser cookie).Details.
  • GM_getValue(key, value) – Read a previously saved parameter.Details.

Debugging Tips and Tricks

Finding syntax errors:

Debugging a script can be difficult because if you make a mistake somewhere, there’s no error message to tell you what the problem is… the script will just stop running half way through. You can use this to your advantage: First, on the page your operating on, find an element in that page and change it’s border:

debugDiv = document.getElementById('vbwrapper3')
if(debugDiv){ = '5px solid red'

Once you have that working, you can change the color of that border to different colors throughout the code. For example, the syntax error in this code would cause the script to stop working:

    allCells = document.getElementByTagName('td');
    if(allCells.length > 2){
        myCell = allCells[2]

I can find the problem by inserting a few debug lines:

Code: = '5px solid blue'
    allCells = document.getElementByTagName('td'); = '5px solid green'
    if(allCells.length > 2){ = '5px solid yellow'
        myCell = allCells[2]

When I refresh the target page and see a blue border around that cell, I know the script stopped working right after that… I’d look and see “getElementByTagName” should be “getElementsByTagName”.

Inspecting variables/parameters:

To inspect a variable, assign it’s value to the title of a link or image. Then when you mouseover, you can see the value of the parameter. If you mouse over the [ ReplyAll >> ] button, it currently shows the nameList variable – which is the list of names to be added to the original sender’s name in the reply’s TO: field.

                buttonsCell = replyAnchor.parentNode;
                replyAllAnchor= document.createElement('a')
                replyAllAnchor.innerHTML = '\<img src\=\"data\:image\/png\;base64\,'+base64_all+'\"\>'
                replyAllAnchor.title = nameList; //"Reply All"

ok.. that’s enough for now… let me know if you’ve got any questions or requests for scripts. Here’s a few ideas I’ve had – If you’re bored feel free to give them a try. They shouldn’t be too hard given the other scripts you can use as examples:

1) I’d like to see someone try tweaking the PM reply page so that the quoted text gets put at the bottom of the reply-field rather than the top. (Likewise the cursor would have to be moved to the top of that entry form.)

2) Add date-stamp to PM-replies. I suspect that this would require a script similar to my Reply-All script, where the date stamp would be found and saved (GM_setValue) on the “reading the PM” page, and then fetched and inserted on the reply page.