ImperialViolet

The wonders of GreaseMonkey (22 Mar 2005)

GreaseMonkey is a Firefox extension which allows you to install Javascript scripts which can manipulate webpages before they're displayed.

You can see a list of GreaseMonkey scripts, but as a demo have a look at the one I cooked up below. It adds result numbers to Google search results and you can then select that result with a single keypress (press '1' for the first result etc).

Type-ahead-find often goes pretty badly on search results because (you would hope) many of the results have all the same keywords in them.

(If you have GreaseMonkey installed, you can install this script by following this link and selecting "Install User Script" from the Tools menu.)

/*
	Add one-press access keys to Google search results. Search results
	are numbered in red and pressing 1..0 selects that search result.
	A Firefox Greasemonkey script,
	Version 0.1
	Adam Langley <agl@imperialviolet.org>

	Public Domain
*/

// ==UserScript==
// @name 			Google Searchkeys
// @namespace 		http://www.imperialviolet.org
// @description 	Adds one-press access keys to Google search results
// @include 		http://www.google.*/search*
// ==/UserScript==

(function() {
	// Search results are in p elements with a class of 'g'
	// This uses XPath to find all such elements and returns a 
	// snapshot. (A snapshot doesnt become invalid after changing
	// the DOM
	
	var results = document.evaluate("//p[@class='g']", document, null, 
			XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
	var counter = 1;
	
	// We store the links in this array which is used by the keypress
	// handler function
	var links = new Array();
	
	for (var i = 0; i < results.snapshotLength; ++i) {
		var result = results.snapshotItem(i);
		// the first child of the paragraph is a comment element
		// this is a little fragile, maybe should be an XPath lookup
		links.push(result.firstChild.nextSibling.getAttribute("href"));

		// We put the result number in a small-caps red span
		var newspan = document.createElement("span");
		newspan.setAttribute("style", "color:red; font-variant: small-caps;");
		newspan.appendChild(document.createTextNode("Result " + counter++ + " "));
		result.insertBefore(newspan, result.firstChild);
	}

	function keypress_handler(e) {
		// e.which contains the ASCII char code of the
		// key which was pressed
		// see: http://web.archive.org/web/20040214161257/devedge.netscape.com/
		// library/manuals/2000/javascript/1.3/reference/
		// handlers.html#1120313
		
		var keypressed = String.fromCharCode(e.which);
		if (keypressed < '0' || keypressed > '9') {
			return true;
		}

		var resnum = e.which - "0".charCodeAt(0);
		if (resnum == 0) {
			resnum = 10;
		}
		document.location = links[resnum - 1];

		return false;
	}

	document.onkeydown = keypress_handler;
})();