When I was developing the reddit media: intelligent fun online website, I needed to embed reddit's up/down voting buttons to allow users to cast votes on media links directly from the site.
I remembered that reddit had decided not to display posts with a submission time less than two hours ago.
This left me thinking, if the scores are not displayed for new posts, what's the point of having vote boxes on a just posted article page? I thought, it wouldn't make sense if it wasn't available. Quickly did I find a link on reddit's new page which seemed to have received a few votes and added a reddit's button to an empty HTML document.
A reddit voting button/widget can be embedded on a site by putting the following JavaScript code fragment anywhere in the HTML source:
<script>reddit_url='[URL]'</script> <script>reddit_title='[TITLE]'</script> <script language="javascript" src="http://reddit.com/button.js?t=2"></script>
where the URL is the URL to the article and TITLE is the title of the article.
Voila! I now know something nobody else did - how many votes had the post received!
And now, let's create something cool for general public to use so that anyone could reveal the scores for all recently posted links.
Let's use the FireFox browser and its excellent GreaseMonkey add-on/extension.
What is GreaseMonkey you might wonder?
Greasemonkey is a Firefox extension that allows you to write scripts that alter the web pages you visit. You can use it to make a web site more readable or more usable. You can fix rendering bugs that the site owner can't be bothered to fix themselves. You can alter pages so they work better with assistive technologies that speak a web page out loud or convert it to Braille. You can even automatically retrieve data from other sites to make two sites more interconnected. Greasemonkey by itself does none of these things. In fact, after you install it, you won't notice any change at all... until you start installing what are called "user scripts". A user script is just a chunk of Javascript code, with some additional information that tells Greasemonkey where and when it should be run. Each user script can target a specific page, a specific site, or a group of sites. A user script can do anything you can do in Javascript. In fact, it can do even more than that, because Greasemonkey provides special functions that are only available to user scripts.
Do you see where I am aiming? I will write a "user script" in JavaScript programming language which I just learned in more details to find the "just posted" links on a reddit page and replace the original up/down vote box with the vote box widget which reveals the current count of votes!
There is a great free book available on GreaseMonkey which explains it through code examples. It's called "Dive into GreaseMonkey." It's only 99 pages long and can be read in an hour if you know JavaScript already!
Writing the User Script
The basic idea of the script is to parse the DOM of reddit's page, extracting all the posted links and find the links which do not have score displayed (which are newer than 2 hours), then replace the HTML of original up/down vote box with the widget's HTML.
First we need to understand how reddit's entries are layed out on the page. To do this we could view the HTML source of the page, but this method requires too much effort for us because we'd have to prase HTML in our heads. Let's use something more visual. There is an extension to FireFox called FireBug which allows to explore the HTML of a page in a much nicer manner.
We see that each entry on the page is wrapped in two <tr> elements, where each of them have a class name "oddRow" or "evenRow". Our GreaseMonkey user script will have to find these rows and extract the title information from the first row, and date information from the second row.
To do this we use the DOM's getElementsByTagName function to retrieve all <tr> elements on the page, next we loop over these elements matching those having a class name "oddRow" or "evenRow" and maintain a state whether we are matching the first or the second row and call extraction functions for each row accordingly.
Look at find_entries function in the final script to see how it extracts all the entries from the page.
Once we have extracted the entries, all we have to do is replace the HTML of the original up/down vote box with HTML of a up/down vote widget. (See the display_votes function in the final script)
And we are done!
Here is how the reddit page looks like when the GreaseMonkey script has run:
Reddit Score Revealer GreaseMonkey Script
Download link: reddit.score.revealer.user.js
Notes: this script works only with the FireFox browser. To run it you will also need GreaseMonkey extension.
Once you click the link, FireFox will automatically ask you if you want to install this script. Select Install and visit reddit.com/new to have infinite power over the regular users!
Here is a screenshot of how the GreaseMonkey user script Installation dialog looks like:
Btw, has anyone successfully debugged GreaseMonkey scripts? I could not find a way to set breakpoints or even load the user script in any of the debuggers which come with FireFox. Any ideas?
Also the current implementation of the script replaces the original up/down vote box with an iframe. This is kind of ugly. I'll leave it as an exercise to a curious reader to change the script to retrieve the score via XMLHttpRequest interface and change the "published NN minutes/hours ago" status line to one with the score in it.
See ya!