Arch2Arch Tab BEA.com
Syndicate this blog (XML)

More Mashups: Using Greasemonkey to Weave New Features into Web Sites

Bookmark Blog Post

del.icio.us del.icio.us
Digg Digg
DZone DZone
Furl Furl
Reddit Reddit

Peter Laird's Blog | July 2, 2007   1:08 AM | Comments (3)


With this blog entry I am continuing the theme of demonstrating tools to help you build mashups. In this case, I will show how a tool called Greasemonkey can be a powerful approach for building browser side mashups. Greasemonkey is a plugin to Firefox that allows a script developer to inject useful Javascript into any web page. This capability enables you to add new features to sites that you do not own. I will show in this blog how you can add a new feature to the dev2dev website, without having access to the dev2dev code. Later, a follow-up blog will show how this same technique can create a feature on dev2dev that includes data from a different web site, producing a true mashup.

This is part 1 of a series of blog entries on Greasemonkey mashups.

Client side Code Injection with Greasemonkey

Greasemonkey is just cool - and I have been having a lot of fun playing around with it. It operates on a simple principle, but delivers massive power from that simplicity.

Greasemonkey allows you, a Javascript developer, to write a script that gets included into web pages that a user visits with the Firefox browser. This script can do really anything, but usually it will inject/update HTML elements into the page to create entirely new features for that web site. The targeted web site need not have any idea that this is going on - the Greasemonkey script is executed on the browser after the original page comes back from the web server.

To be useful, a Greasemonkey script generally will be targeted towards a specific web site, though a general purpose script is possible. The developer specifies which URLs (with wildcards) are valid for the script. The Greasemonkey plug-in in Firefox will silently watch the user's URLs as they browser, and will inject a script when appropriate.

To be clear, Greasemonkey is not installed by default, nor are the scripts that you write. It is an opt-in activity for the user to both install Greasemonkey and then each script that they want to have. This means that Greasemonkey is not quite as accesible as other mashup solutions that I have written about - the mashup here is not a URL. The user must be skilled enough to install Greasemonkey and your script.

greasemonkey_arch.png

Greasemonkey Hello World

Installing Greasemonkey is straightforward: you will find the download link at the Greasemonkey Home Page. You will need to use Firefox of course, but otherwise it can't go wrong. After you have it installed, the next step is to install your first Greasemonkey script.

Unlike a lot of cutting edge projects out on the web, Greasemonkey has excellent documentation. Primarily, the best place to go for an introduction, tutorials, and documentation is Mark Pilgrim's online book, Dive Into Greasemonkey. The book is quite comprehensive and is geared towards getting you on your feet quickly.

To that point, the Hello World example for Greasemonkey that I will show is derived directly from Mark's book. The example below has been stripped of comments for brevity, but otherwise is identical to his original found here. This script is offered as a public file named helloworld.user.js. By the file extension, you know that this is nothing but JavaScript. And a closer look will show that it contains some meta-data within the comments, and then a single JavaScript function call to alert().

The meta-data is hopefully self-explanatory: it instructs Greasemonkey to execute it on any (*) site except for a couple of exclusions. If you install Greasemonkey, and then install this script helloworld.user.js by clicking on the link, you will see that it just pops up an alert box for every page view.

// Hello World! example user script
// version 0.1 BETA!
// 2005-04-22
// Copyright (c) 2005, Mark Pilgrim
// Released under the GPL license
// http://www.gnu.org/copyleft/gpl.html
// ==UserScript==
// @name          Hello World
// @namespace     http://diveintogreasemonkey.org/download/
// @description   example script to alert "Hello world!" 
// @include       *
// @exclude       http://diveintogreasemonkey.org/*
// @exclude       http://www.diveintogreasemonkey.org/*
// ==/UserScript==

alert('Hello world!');
greasemonkey_install.png

Mr. Wong and BEA dev2dev

If you visit BEA's dev2dev site, you will notice that Jon has helpfully included links to popular tagging services on all articles and blogs. This allows you to quickly tag the article or blog using del.icio.us, Digg, DZone, Furl or Reddit. See the image below to see how the site works today:

greasemonkey_mrwong_orig.png

However, what if that list is not sufficient for your needs? That is my problem - there is one tagging site that I use that is not listed. As an aside, I have been doing research into the spread of Web 2.0 in China. In doing that work, I have been tagging chinese articles that I find, and some english ones just to be helpful. I am not using an english language tagging site, I am using Mr. Wong, which is a Chinese language tagging site. I would like to have Mr. Wong as one of my tagging options when browsing dev2dev. But since I don't have access to the dev2dev code, I cannot add it.

Weaving Mr. Wong into BEA dev2dev Using Greasemonkey

Enter Greasemonkey.

The process for developing a Mr. Wong feature on dev2dev is as follows:

  • Navigate to dev2dev, and View Source on the HTML for blogs and articles
  • Note that the tagging links box is easily found in both by looking for the last div tag with class box_gray
  • The div tag contains a simple HTML table, all we need to do is add a new row
  • Formulating the link to Mr. Wong is easy: we just need the document title and url. Both are easily available in JavaScript
  • Write the JavaScript!

Before I show the code for the script, here is the result:

greasemonkey_mrwong.png

As you can see, even though I did not have access to dev2dev code, I was able to easily add a brand new feature to it!

The Mr. Wong Script

The script used to add this feature to dev2dev is below. But if you would like to try it out, or view the live version, navigate to my script repository for Greasemonkey (or here if that link does not work). Install the script named dev2dv Mr Wong. The code roughly follows this path:

  • Find the last box_gray div tag on the page, this is the tagging box
  • Find the inner table in that div
  • Add a new row to that table
  • Populate the row with a link and image for Mr. Wong
// ==UserScript==
// @name          dev2dev Mr Wong
// @namespace     http://dev2dev.bea.com
// @description   Injects a link to Mr Wong on each blog/article link
// @include       http://dev2dev.bea.com/blog/*
// @include       http://dev2dev.bea.com/pub/*
// ==/UserScript==

var divTagsWithClass, taggingDiv;
GM_log('Running dev2dev Mr Wong script');

// get the existing tagging div box 
//   by looking for the class (box_gray)
divTagsWithClass = document.evaluate(
    "//div[@class='box_gray']",
    document,
    null,
    XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,
    null);
// the tagging div appears last
taggingDiv = divTagsWithClass.snapshotItem(divTagsWithClass.snapshotLength-1);

if (taggingDiv)
{
	// find the table
	tableTag = taggingDiv.getElementsByTagName('table')[0];
	if (tableTag)
	{
		// create the new row
		var lastIndex = tableTag.rows.length;
		newLinkTR = tableTag.insertRow(lastIndex);
		
		// create the td for image and set styles
		var newLinkTD = newLinkTR.insertCell(0);
		newLinkTD.valign = 'bottom';
		newLinkTD.width = '20';

		// build the HTML	
		newLinkTD.innerHTML = '<img src='+
			'"http://www.mister-wong.cn/favicon.ico"'+
			' alt="Mr. Wong" border="0" height="18" '+
			'hspace="8" width="18">';

		// create the td for the image
		var newLinkTD = newLinkTR.insertCell(1);

		// set the styles
		newLinkTD.nowrap = 'nowrap';
		newLinkTD.valign = 'bottom';

		// build the HTML	
		newLinkTD.innerHTML = 
			'<a href="http://www.mister-wong.cn/index.php?'+
			'action=addurl&v=1&bm_url='+
			window.location+
			'&bm_description='+
			document.title+
			'">'+
			'Mr. Wong</a>';
	}
	else {
		GM_log('  Error: did not find the tagging inner table');
	}
}
else {
	GM_log('  Error: did not find a tagging div');
}

Pros and Cons

Hopefully you can see the power and simplicity of the Greasemonkey plugin. In a follow up blog I will show how you can take this technique further by injecting data from other sites to create a true mashup. Here is what I see as the pros and cons of this tool:

  • Pro: it is easy for a developer to install both the plugin and scripts
  • Pro: a seasoned JavaScript developer can crank out features in little time
  • Pro: you do not need access to the web site's code to add new features
  • Pro: the documentation and developer community around Greasemonkey are superb
  • Con: mashups created with Greasemonkey aren't exactly URL accessible, it requires install steps
  • Con: Greasemonkey is not supported on IE or any browser other than Firefox
  • Con: there is a significant security issue that I will cover in my next blog entry

References

Technorati tags:


Comments

Comments are listed in date ascending order (oldest first) | Post Comment

  • Thanks Nagesh, I agree that Monkeygrease is also interesting. It is limited to web apps hosted by servlet containers, but as a server-side solution avoids some of the issues with Greasemonkey I am about to blog about.

    Have you built something with Monkeygrease? How did it go?

    Posted by: plaird on July 12, 2007 at 10:29 PM

  • Hey Peter, Great entry about greasemonkey. I came across monkeygrease which takes this one step further and makes the plugins available via a servlet filter. (pretty cool idea) - Nagesh

    Posted by: nagesh on July 10, 2007 at 9:40 PM

  • The Greasemonkey script repository appears to be down today. I have uploaded the Mr. Wong script to an alternate location:

    dev2dev Mr. Wong Script

    Posted by: plaird on July 2, 2007 at 12:18 PM



Only logged in users may post comments. Login Here.

Powered by
Movable Type 3.31