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



Related posts

Comments

January 18. 2008 17:00

I just wanted to point out that there is a small difference between the way that Google Aps and regular Gmail are being implemented at the moment. The script in its current incarnation is set up for Google Aps. The only difference you are going to notice if you are using regular Gmail is that instead of being above the chat box, your new toolbox will appear below the chat box. The script is easy to alter, and the place is well commented. So if this is a problem for you, just edit that number yourself. Thanks!

joel

January 18. 2008 18:42

As an update, I've posted a version of this script with the altered code for people that aren't interested in changing it themselves:
http://www.jtulloch.com/files/gmailsideba.user.js

joel

January 29. 2008 15:35

Okay Joel, I'm not afraid to admit it, but I have no idea. I desperately want to use that script, but have no idea where to put it, or how to make it run. Now, believe it or not I did read your whole post and probably should know how to make it work, but I don't have a freaking clue. Want to help me out? Lol

Ian Shorten

Add comment


 

[b][/b] - [i][/i] - [u][/u]- [quote][/quote]



Live preview

November 19. 2008 18:08