I just wrote my first GreaseMonkey user script. It’s a script that puts a random Benjamin Franklin quote above the stories on reddit to remind me to be dutiful and not spend too much time looking at online news. I found the quotes through (you guessed it) reddit.

Here’s what it looks like:


And here’s the code:

// ==UserScript==
// @name           Reddit Quotes
// @namespace      com.benatkin
// @description    Shows Quotes in front of Reddit
// @include        http://reddit.com/
// ==/UserScript==

function franklinQuote() {
  var quotes = [
    'Early to bed, and early to rise, makes a man healthy, wealthy and wise',
    'Diligence is the mother of good luck',
    'God helps them that help themselves',
    'Sloth, like rust, consumes faster than labor wears, while the used key is always bright',
    'Dost thou love life, then do not squander time, for that’s the stuff life is made of',
    'Lost time is never found again',
    'He that riseth late, must trot all day, and shall scarce overtake his business at night',
    'Drive thy business, let not that drive thee',
    'Industry need not wish',
    'He that lives upon hope will die fasting',
    'There are no gains, without pains',
    'Plough deep, while sluggards sleep, and you shall have corn to sell and to keep',
    'One today is worth two tomorrows',
    'Have you somewhat to do tomorrow, do it today',
    'Be ashamed to catch yourself idle',
    'Let not the sun look down and say, inglorious here he lies',
    'He that hath a trade hath an estate',
    'He that hath a calling hath an office of profit and honor',
    'At the working man’s house hunger looks in, but dares not enter',
    'For industry pays debts, while despair encreaseth them',
    'Constant dropping wears away stones',
    'By diligence and patience the mouse ate in two the cable',
    'Little strokes fell great oaks',
    'Employ thy time well if thou meanest to gain leisure',
    'Since thou art not sure of a minute, throw not away an hour',
    'A life of leisure and a life of laziness are two things. Do you imagine that sloth will afford you more comfort than labor?',
    'Trouble springs from idleness, and grievous toil from needless ease.',
    'Many without labor would live by their wits only, but they break for want of stock',
    'Industry gives comfort, and plenty, and respect: fly pleasures, and they’ll follow you',
    'Keep the shop, and thy shop will keep thee',
    'If you would have your business done, go; if not, send',
    'He that by the plough would thrive, Himself must either hold or drive.',
    'The eye of a master will do more work than both his hands',
    'Want of care does us more damage than want of knowledge',
    'Not to oversee workmen is to leave them your purse open',
    'In the affairs of this world men are saved not by faith, but by the want of it',
    'Learning is to the studious, and riches to the careful, as well as power to the bold, and Heaven to the virtuous',
    'If you would have a faithful servant, and one that you like, serve yourself',
    'For want of a nail the shoe was lost; for want of a shoe the horse was lost, and for want of a horse the rider was lost'
  return quotes[Math.floor(Math.random()*(quotes.length))];

function addFranklinQuote() {
  var tbl = document.getElementById('siteTable');
  if (tbl) {
    var quoteBox = document.createElement('div');
    quoteBox.innerHTML = franklinQuote();
    quoteBox.style.fontSize = "16pt";
    quoteBox.style.backgroundColor = "#f9f7ed";
    quoteBox.style.padding = "1.5em";
    quoteBox.style.position = "relative";
    quoteBox.style.width = '500pt';
    tbl.parentNode.insertBefore(quoteBox, tbl);

    var quoteName = document.createElement('div');
    quoteName.innerHTML = "-- Benjamin Franklin";
    quoteName.style.fontSize = "10pt";
    quoteName.style.position = "absolute";
    quoteName.style.bottom = "0";
    quoteName.style.right = "0";


Greasemonkey really is as simple to use as it sounds. You give it a script and the URL’s to which it applies. When you browse to a page that matches the URL, the script is executed. For this one, it was a simple matter of adding a DOM element in the right place.

Some scripts are meant to be loaded on all pages, such as a script that makes it possible to use shift to quickly check or uncheck a bunch of checkboxes. If you’ve heard people complain about the Greasemonkey overhead, it’s probably because they’ve run a bunch of these utility scripts that run on all pages. A script or two that are browser-wide, with the rest of the scripts only running on a single site shouldn’t slow things down much.

To install, first install greasemonkey. Then, find the greasemonkey folder (gm_scripts) in your profile directory and save the above code into a file called “redditquotes.user.js”.

UPDATE (2007-07-17): After searching for ‘sliding doors css “dead space”‘ I found that someone already solved the problem without using JavaScript.

About a year ago I read Sliding Doors of CSS on A List Apart. While I admired the elegance of the design, I found the dead space on the left side of the tabs to be annoying.

The problem comes down to not being able to wrap an individual anchor tag around a list item tag and have it work. The anchor tag had to be put inside the list item tag, and try as I and the author might, it couldn’t be made to include the entire tab. The left side of the tabs were unclickable, as can be seen in the example.

The other day, I got the idea to fix the problem with JavaScript. I could make the list item trigger an onclick event. I could also make it show a hand cursor when hovering over the list item. The hand cursor thing could be done with CSS, but I like doing it in the JavaScript better, because if somehow the JavaScript code doesn’t execute properly, it won’t show a hand cursor in an area that’s not actually clickable.

I use the following JavaScript code, which relies on the JQuery library, to make the dead space clickable. On the first try I had the whole page flicker in Firefox when part of the anchor was clicked (the part that wasn’t dead space before). I tested it on the old page and it didn’t have the whole page flicker issue. So I figured out that it was probably a result of both the link and the javascript being triggered, and I added an event for the anchor to tell it not to trigger the dead-space event if the user clicked on the anchor.

clickedAnchor = false;

function fixDeadSpace(headerDiv) {
  var items = $('li', headerDiv);
  items.css('cursor', 'pointer');
  items.click(function(arg) {
    if (! clickedAnchor) {
      window.location.href = $('a', arg.target).attr('href');
  $('a', headerDiv).click(function() { clickedAnchor = true; });

$(function() {

To use, make sure the JQuery library is available, and add the above in a script tag. Here is the example with my code added, and different query strings in the links.

It behaves just about the same as if the left part of the tab were part of the link. The only difference that might be noticeable to a very small number of users is that when you hover over the area outside the anchor tag, the location isn’t shown in the status bar.