Restore Functionality in Google Print

Restore Functionality in Google Print

Google Print goes to extraordinary lengths to keep you from downloading images, but you don't need to go to the same extraordinary lengths to get them anyway.

It's long been stated that if you put your images up on the Web, there's no real way of stopping people from downloading them and using them for their own purposes. That's still basically true, although one of the interesting things about the new Google Print service is the unusual lengths it goes to prevent the average web user from doing exactly that.

This hack is based on an article by Gervase Markham, who has graciously allowed me to include it here. The code is mine, but I couldn't have written it without his excellent and original research. You can read his article at, including comments from many other people who were collaboratively hacking Google Print on the day it was announced.

Google Print allows you to search printed books (although Google obviously has the data in electronic form). To see it in action, search Google for Romeo and Juliet and click the link under Book Results titled "Romeo and Juliet by William Shakespeare." You'll see an image of the first page of the book, but the page is specially crafted to prevent you from printing the image or saving it to your local computer.

The first thing that prevents you from saving the image of the printed page is that the right-click context menu is disabled. Google has used the standard JavaScript trick to disable the context menu for the entire page, by returning false from the oncontextmenu handler. This is no problem for those takingback the Web. Go to Tools Options Web Features Advanced JavaScript and uncheck "Disable or replace context menus." Score one for Firefox.

The next obstacle is that selecting the View Image item in the newly enabled context menu seems to show you a blank page. The <img> element for the image of the printed page is actually a transparent GIF; the real book page is defined as a CSS background image on a container <div>. If you select View Image from the context menu, all you end up with is the transparent GIF, not the background image. And since there's a foreground image overlaying the background image, Firefox suppresses the View Background Image item in the context menu. Score one for Google.

OK, let's change tactics. Open the Page Info dialog under the Tools menu, and go to the Media tab. This lists all the media on the page, and it has a Save As… button next to each media file that allows you to save that file to disk—except that it doesn't work for the one image we're interested in. It works for images inserted using <img>, <input>, and <embed>, but not for background images inserted using a CSS background-image rule. Score: Google 2, hackers 1.

My next idea was to copy and paste the URL out of page source. However, Google likes to serve pages without newlines, and there are a lot of similar URLs in them, so it would seem virtually impossible to find the right URL in the View Source window scrolling two and a half miles to the right. Score: Google 3, hackers 1.

Let's change tactics again. Since the transparent GIF is in our way (literally, it's an <img> element that is obscuring the actual image of the printed page), we can try to delete the GIF altogether using DOM Inspector.

DOM Inspector is not installed by default. If you don't see a DOM Inspector item in your Tools menu, you'll need to reinstall Firefox, select Custom Install Developer Tools. You can safely reinstall over your existing Firefox installation. This will not affect your existing bookmarks, preferences, extensions, or user scripts.

DOM Inspector displays a tree of all the elements on the current page. Changes you make in DOM Inspector are immediately reflected in the original page. So, theoretically, we can locate the GIF in the DOM Inspector tree and just press Delete. Bang! The entire book page image disappears along with it! How did this happen? Well, the transparent GIF <img> element was providing a size for the <div> that contains it. When we removed the transparent GIF, the <div> collapsed and we could no longer see the book page image, since it was now the background image of a 0x0 <div>. Another point for Google.

No problem. In DOM Inspector, we can select the container <div> (the one helpfully declared as class="theimg"), drop down the menu on the right to select CSS Style Rules, and then manually edit the CSS to give the <div> a real width and height. Right-click in the lower pane on the right and select New Property. Enter a property name of width and a value of 400. Repeat and enter a property name of height and a value of 400.

Success! This allows us to see the background image again on the original page, albeit only partially, since the image is larger than 400 x 400. But it's enough, because the transparent GIF is gone, so we can right-click the partial book page image and select View Background Image to display the image in isolation. From there, we can save the image to disk or print it. Final score: Google 4, hackers 8. Game, set, match.

Now that we've suffered through all the gory details of Google's attempts to make your browser less functional, let's automate the process with a 20-line Greasemonkey script.

The Code

This user script runs on Google Print pages. Right out of the gate, it reenables the right-click context menu by setting document.oncontextmenu=null. Then, it uses an XPath query to find all the transparent GIFs named cleardot.gif. These are the GIFs obscuring other images. For each one, it replaces the URL of the transparent GIF with the URL of the obscured image. For bonus points, it makes the image clickable by wrapping it in an <a> element that links to the image URL.

Save the following user script as nrestoregoogleprint.user.js:

	// ==UserScript==
	// @name		  Restore Google Print
	// @namespace
	// @description	  restore normal browser functionality in Google Print
	// @include*
	// ==/UserScript==

	// restore context menu
	unsafeWindow.document.oncontextmenu = null;

	// remove clear GIFs that obscure divs with background images
	var snapDots = document.evaluate("//img[@src='images/cleardot.gif']",
	    document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
	for(var i = snapDots.snapshotLength - 1; i >= 0; i--) {
	    var elmDot = snapDots.snapshotItem(i);
		var elmWrapper = elmDot.parentNode;
		while (elmWrapper.nodeName.toLowerCase() != 'div') {
		    elmWrapper = elmWrapper.parentNode;
		var urlImage = getComputedStyle(elmWrapper, '').backgroundImage;
		urlImage = urlImage.replace(/url\((.*?)\)/g, '$1');
		// make image clickable
		var elmClone = elmDot.cloneNode(true); = 'none';
		elmClone.src = urlImage;
		var elmLink = document.createElement('a');
		elmLink.href = urlImage;
		elmDot.parentNode.insertBefore(elmLink, elmDot);

Running the Hack

After installing the user script (Tools Install This User Script), go to and search for Romeo and Juliet. Click the link under Book Results titled "Romeo and Juliet by William Shakespeare." You will see the first page of Romeo and Juliet. Thanks to this hack, you can right-click the image of the printed page and do all the things you can normally do with an image (such as saving it to disk), as shown in Figure.

Restored context menu on Google Print

There are actually two protected images on each Google Print page: the image of the printed page and the smaller thumbnail image of the book cover. Google uses the same technique for both images, so this hack works on the cover thumbnail image as well.

     Python   SQL   Java   php   Perl 
     game development   web development   internet   *nix   graphics   hardware 
     telecommunications   C++ 
     Flash   Active Directory   Windows