O'Reilly Hacks
oreilly.comO'Reilly NetworkSafari BookshelfConferences Sign In/My Account | View Cart   
Book List Learning Lab PDFs O'Reilly Gear Newsletters Press Room Jobs  


 
Buy the book!
Greasemonkey Hacks
By Mark Pilgrim
November 2005
More Info

HACK
#58
Add Keyboard Shortcuts to Google Search Results
If you search frequently and type as quickly as you think, you'll appreciate this keyboard-only hack
The Code
[Discuss (0) | Link to this hack]

I love Google. I use Google 50 times a day…literally. I actually used Google once to look up my own phone number. I was placing an order over the phone when the customer service representative asked me for my home phone, and I totally drew a blank. Has that ever happened to you? I should really get one of those weblog thingies all the kids are talking about, so I can regurgitate personal anecdotes like this in a virtual medium, instead of wasting all this paper. But I digress.

As I was saying, I search a lot, and I type very quickly. And if I'm looking for very specific things, and Google is so very good at finding them, I usually find what I'm looking for in the first page of search results, which means that this hack is perfect for me, because it numbers the search results and lets me follow them without moving my hands off the keyboard.

Running the Hack

After installing the user script (Tools → Install This User Script), go to http://www.google.com and search for something, such as ipod. Next to each Google search result, you will see a red number, as shown in . Typing that number will redirect you to that linked search result.

Figure 1. Search results with keyboard shortcuts

The Code

This user script runs on all Google pages. It uses an XPath query to find all the search results (they're each wrapped in a <p class="g"> element), and then inserts red numbers beside each search result, from 1 to 9, then 0 for the 10th result. The last line of the script ties it all together by registering a global onkeydown event handler that checks whether you typed a number, and if so, finds the associated search result and follows the link.

Save the following user script as google-searchkeys.user.js:

	// ==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==
	
	// based on code by Adam Langley
	// and included here with his gracious permission
	
	var results = document.evaluate("//p[@class='g']", document, null,
		XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
	var counter = 1;
	var querybox = document.evaluate("//input[@name='q']", document, null,
		XPathResult.ORDERED_NODE_ITERATOR_TYPE, null).iterateNext( );
	var next_nodes = document.evaluate(
		"//a[span[@class='b' and text( )='Next']]",
		document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
	var prev_nodes = document.evaluate(
		"//a[span[@class='b' and text( )='Previous']]",
		document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
	var nextlink = null;
	var prevlink = null;
	if (next_nodes.snapshotLength) {
		nextlink = next_nodes.snapshotItem(0).getAttribute('href');
	}
	if (prev_nodes.snapshotLength) {
		prevlink = prev_nodes.snapshotItem(0).getAttribute('href');
	}
	prev_nodes = next_nodes = null;
	var links = new Array( );
	for (var i = 0; i < results.snapshotLength; ++i) {
		var result = results.snapshotItem(i);
		links.push(result.firstChild.nextSibling.getAttribute("href"));
		var newspan = document.createElement("span");
		newspan.setAttribute("style", "color:red; font-variant: small-caps;");
		newspan.appendChild(document.createTextNode('' + counter++ + ' '));
		result.insertBefore(newspan, result.firstChild);
	}
	results = null;

	function keypress_handler(e) {
		if (e.ctrlKey || e.altKey || e.metaKey) { return true; }
		if (e.target.nodeName == 'INPUT' && e.target.name == 'q') {
			return true;
		}
		var keypressed = String.fromCharCode(e.which);
		if (nextlink && (keypressed == 'l' || keypressed == 'L' ||
				 keypressed == '.')) {
			if (e.shiftKey) {
				window.open(nextlink,'Search Results','');
			} else {
				document.location.href = nextlink;
			}
			return false;
		}
		if (prevlink && (keypressed == 'h' || keypressed == 'H' ||
				 keypressed == ',')) {
			if (e.shiftKey) {
				window.open(prevlink,'Search Results','');
			} else {
				document.location.href = prevlink;
			}
			return false;
		}

		if (keypressed <'0' || keypressed > '9') {
			return true;
		}

		var resnum = e.which - "0".charCodeAt(0);
		if (resnum == 0) {
			resnum = 10;
		}

		if (e.shiftKey) {
			window.open(links[resnum - 1],'Search Results','');
		} else {
			document.location.href = links[resnum - 1];
		}
		return false;
	}

	document.addEventListener('keydown', keypress_handler, false);


O'Reilly Home | Privacy Policy

© 2007 O'Reilly Media, Inc.
Website: | Customer Service: | Book issues:

All trademarks and registered trademarks appearing on oreilly.com are the property of their respective owners.