Javascript | General | scripts

Installing A Greasemonkey Script


January 29, 2008 16:35 by joel

My last post was written as an introduction to the Greasemonkey API from Gmail. Its intent was to introduce wouldbe greasemonkey scripters to the various methods that are available in the API. It has recently come to my attention, however, that not everybody is interested in writing their own scripts. Perhaps, in fact, I am a member of the minority.  *gasp*

So. This post will be a simple rundown on how to install my Ad-Removing script, for those that aren't interested in how it works:

1- Get Firefox.

2- Install the Greasemonkey Add-On.

3- If you are using Gmail, install this script.  If you are using Google Apps, install this script.

4- Refresh Gmail/Google Apps.

And that's all there is to it. Lately there have been periodic changes in the way Gmail sets up their pages. I'm usually pretty quick to update the script, so if something starts looking weird, come back here, or head over to userscripts.org (links to follow) and re-install the script.

As a sidenote, while you're at userscripts.org check out some of the other scripts that are available from other users. There is a huge quantity of scripts there that do a lot of helpful things, and once you have Greasemonkey installed, it is a simple thing to add new scripts. Just do a search for the page that you're interested in modifying, or the action you want it to do (ie: remove facebook ads), and likely somebody has written a script for that purpose. Just be careful, as the big red banner at the top of every script page says, if you're installing a script that is new. I would go as far as to say that if you're not familiar with scripting, you shouldn't install a script if less than a couple hundred people have installed it. Also check out the comments to see what other users have said about it. And that's a wrap, as they say. Enjoy my script, and check out some others while you are at it. 

My pages on userscripts.org:

The Gmail Script

The Google Apps Script 



Javascript

The Gmail Greasemonkey API


January 18, 2008 09:42 by joel

My last post provided an introduction to Greasemonkey. This one will show you the main components of a Greasemonkey script, as well as introduce you to the Gmail Greasemonkey API.

Purpose

The script I'll be working with today is one that I wrote for Gmail to get rid of the annoying ads that always take up a good portion of the window when i'm trying to read my email. I very cleverly named it 'Gmail and Google Apps Sidebar Remover'. If you haven't yet installed it, you can do so by clicking that link, or you can simply download the source and follow along. 

Planning

BeforeThere are two main things that I needed to take into consideration when I started this script. The first is that although I strictly use Google Apps, if I wanted my script to target a larger user base, I would need to make sure it was compatible with all versions of Gmail. The second issue is that just above the advertisements, there are a few links that add functionality to the current open conversation. Because of those links, if I had simply removed the Ads, the email would have stayed the same width. The only change would have been a giant white space to the right. To accomplish this task, I decided first to determine which Gmail implementation was currently being used, and then move those links over to the left hand side, just below the navigation menu. Once they were out of the way, it was just a matter of removing the ads and adjusting the width of the conversation element.

The Script

The first thing you'll notice when looking at the script is the metadata at the top:

// ==UserScript==
// @name           Gmail and Google Apps Sidebar Remover
// @description	   Removes the ads from the right side of the screen in the conversation view...
// @namespace      http://www.jtulloch.com
// @include        http://mail.google.com/*
// @include        https://mail.google.com/*
// ==/UserScript==

Check out the wiki for information on how to set up that part of the script.

After the metadata comes the actual script. The first thing I did is attach an EventListener to the window object so that my script runs once the page has loaded. (Since the script will only be running under Firefox, there is no need to implement any kind of browser check)

Now that the document is properly formatted as a Greasemonkey script, and it's set up to run when the page loads, we can start looking at what actually happens in the script. The first thing you will discover is an IF statement that uses the presence of an unsafewindow.gmonkey object as its condition. This object is only present in the new version of Gmail, so if it doesn't exist, we will jump down to the ELSE block where we have provided backwards compatibility for older Gmail implementations.

The process for each version of Gmail is basically the same. The main difference with the new version is that instead of traversing the DOM or using XPath to find and manipulate elements (as you will need to do with most Greasemonkey scripts), you can acces them through the API.

The Gmail Greasemonkey API

Once we have ensured that the gmonkey object is present, we can load the module and begin accessing the different elements of the page. The first method loads the API module:

    unsafeWindow.gmonkey.load('1.0', function(gmail) { // ... the code ... }):

It accepts two arguments, the first of which is a string representing the version you are targeting (currently 1.0 is the only version). The second is the function that is called once the module is loaded. This function accepts one argument which is used to pass the GmailAPI object into the function. The GmailAPI object (which we have aptly named gmail) contains all of the methods that we will use to access the page. A full list of the methods supported by the GmailAPI object can be found here.

After the variable declarations, we will define a callback function, hideRight(), which will be called whenever the active view changes (ie. from your inbox to a message). Logically, the first thing we want to do when the view has changed is discover which view we are currently in. The gmail.getActiveViewType() method returns a string representation of the current view (the only one we are interested in right now is "cv" for conversation view). Regardless of the current view we're going to check the navTest variable to determine whether or not we've already created the toolbox on the left hand side. If we have done so, we will remove it and reset the navTest variable. This ensures that we don't create multiple instances of the toolbox:

if (navTest){
threadLinksBox.setContent("");
threadLinksBox.getElement().parentNode.removeChild(threadLinksBox.getElement());
navTest = false;
}

The next step is to grab the elements that we're going to be working with. We will accomplish this using the getConvRhsElement() and getNavPaneElement() methods (we're also going to isolate the gmail chat box so we can insert our new toolbox above it):

sideBar = gmail.getConvRhsElement();
threadLinks = sideBar.firstChild.firstChild;
navPane = gmail.getNavPaneElement().firstChild;
chatPane = navPane.childNodes[4];

The addNavModule() method creates a collapsible box on the left hand side, similar to the chat or the labels box. It accepts 3 arguments, but only the first one, the title, is required. The next step is to initialize that box, add the links that we are moving from the right, add a margin to the bottom of it, so it looks good, and insert it into the DOM, just above the chat box. 

// Initialbox to the left navigation pane.
threadLinksBox = gmail.addNavModule("Thread Toolbox");
// Make the links look a bit better, and insert them into the new tool box
threadLinks.style.padding = '10px';
threadLinksBox.appendChild(threadLinks);
threadLinksBox.getElement().style.marginBottom = '10px';
// Insert the new toolbox before the chat box.					 
navPane.insertBefore(threadLinksBox.getElement(), chatPane);

Now that we've moved the links, we can get rid of the ads. Once we have removed the sidebar containing the ads, we need to adjust the width of the parent element containing the conversation thread to 100%. Finally we set navTest to true, so we know that the toolbox has been created:

// Remove the right side bar.
sideBar.parentNode.parentNode.removeChild(sideBar.parentNode);
gmail.getActiveViewElement().parentNode.style.width="100%";
// Set test variable to true, so we know that the toolbox has been created.
navTest = true;

That is the function that will be called whenever the active view changes. The last thing that we must do in our script is register hideRight() as a callback function using the registerViewChangeCallback() method:

gmail.registerViewChangeCallback(hideRight);

We now have a functioning Greasemonkey script utilizing the Gmail Greasemonkey API. If you read the security links that were in my last post you will recognize that using the unsafeWindow object is a potential risk in any Greasemonkey script. The best way to ensure your scripts are safe is to use the @include part of the metadata to register the sites that your script will run on. And finally, a screenshot of what you should see after you have installed the script:

After



An Intro to Greasemonkey


January 17, 2008 17:31 by joel

One of the cooler toys that I've been playing with lately is Greasemonkey. Greasemonkey is an add-on for Firefox that allows you to install custom scripts (written in JavaScript) that can manipulate or add functionality to web pages. There is an entire repository of scripts to check out at userscripts.org that do everything from removing annoying ads to adding incredibly beneficial functionality. User scripting allows you to customize any (and every, if you have the time) web page in pretty much any way that you want.

To get started in the world of Greasemonkey, you first need to install the Add-On. If all you're planning on doing is using scripts that other people have written, then that's all you need. However, if you're gonna get busy and make your own, you'll need a few more components. For anybody that is doing any kind of Javascript developing for the Web, there really is no tool more powerful than Firebug, and writing Greasemonkey scripts is no exception. It offers an easy way to debug your scripts, and also allows you to gather a lot of information about a page in a very intuitive way. 

The other tool that you're going to need is a text editor. Personally, I like Notepad++, but you can really use anything. I won't go into all the details of why I like that particular program. I'll save that for another post. Suffice it to say, if you're going to be editing much code, it's nice to have the features of a text editor that is geared towards that purpose. 

Now you're all set up for writing your own Greasemonkey scripts. The combination of a good text editor and Firebug allows you to develop Javascript with almost as much ease as if you were using a full IDE. One thing to remember before I sign off is that because of the way Greasemonkey accesses the page, scripts are afforded a lot more trust than regular embedded Javascript. What this boils down to is that if you are using other people's scripts, you need to be more careful about where they are coming from. Look for scripts with lots of comments and lots of downloads, signifying that there has been plenty of time for anything subversive to have been discovered. If you are writing your own scripts, even if you have loads of experience with Javascript, you need to pay extra attention to a few details about the Greasemonkey environment. Check out this post for an example, and then the security information on the Greasemonkey wiki (also, just in case you missed it at the top of the wiki, this page should be required reading for anyone writing Greasemonkey scripts). 

I'll include a few links here to some resources, and in my next post I'll introduce you to a script that I wrote, and talk a bit about the Gmail Greasemonkey API



General

Behind the Code


January 8, 2008 13:37 by joel

This is the first post on my new blog. It won't be long, as my intention is simply to give you a bit of an introduction.

Many people have written more eloquently than I am capable of doing on the subject of the people behind the software. However, I think as an introduction to my 'web outlet', I would like to reiterate that there is much more to who I am than just a guy that writes software. Because of that, there is a certain flavour to the way that I work, and also the way that I envision the entire software development process. I may subscribe to certain theories, and have people that I look up to, but there is always going to be a bit of my past and my personality that shines through. Because of this, a blog, or journal that I use to convey information about the things I am learning or working on is going to contain a certain amount of bias, or "personality". If it wasn't for this fact, technical blogs would be atrocious reading, and learning from peers would be a mind-numbing chore. I enjoy reading the blogs of certain people, and I think a lot of the reason for that is because they include pieces of themselves in the things that they write.

So, if you do take the time to read my blog, I hope that you are able to learn from me, but I also hope that you can enjoy the "personal rabbit trails" that will no doubt emerge as my journey with this blog progresses. Feel free to leave your thoughts in the form of comments, and I look forward to hearing what you have to say, whether it be criticism, affirmation, or another piece of the puzzle.