Super iGoogle

By stinkinrich88 Last update Sep 26, 2009 — Installed 9,736 times. Daily Installs: 33, 24, 49, 25, 43, 38, 47, 32, 36, 32, 43, 44, 31, 37, 33, 34, 34, 37, 28, 24, 18, 15, 30, 53, 54, 49, 33, 29, 34, 24, 30, 30

There are 13 previous versions of this script.

// ==UserScript==
// @name		Super iGoogle
// @autho		Richard Coombs (stinkinrich88)
// @namespace	
// @description	Toggle all waste-of-space elements & install mini search form
// @include		http://google.*
// @include		http://www.google.*
// ==/UserScript==

// Abort if not signed-in
if (document.getElementById('new_user_demo')) {
	var miniInput; 	// Reference to mini search box

	// [element]		[is displayed?]		[setting cookie name]	[actual element ID]
	var header 		= {show:true, 		cookie:'showHeader', 	element:'nhdrwrapinner'	};
	var sidebarr 		= {show:true, 		cookie:'showSidebar', 	element:'col1'			}; 
	var footer 		= {show:true, 		cookie:'showFooter', 	element:'footerwrap'	}; 
	var miniSearch 	= {show:true, 		cookie:'showMiniSearch', element:'q'			};

	modifyTopBar();	// Remove all links from top bar & replace with search bar & menu
	
	// If no cookies have been set yet, set default values (no header, sidebar, footer)
	if (readCookie(miniSearch.cookie)==null) setDefaultCookies();

	// Toggle all waste-of-space elements if cookie setting says so
	if (readCookie(header.cookie)	== 'false') {toggleElement(header);}
	if (readCookie(sidebarr.cookie)	== 'false') {toggleElement(sidebarr);}
	if (readCookie(footer.cookie)		== 'false') {toggleElement(footer);}
	if (readCookie(miniSearch.cookie)	== 'false') {toggleElement(miniSearch);}
	else miniInput.focus();

	// Shorten amount of space at bottom of page
	var elm = document.getElementById('modules');
	if (elm) elm.style.marginBottom = '-2em' ;

	initKeyboardShortcuts();
}

// Set default settings (mini-search on; header, footer, sidebar off)
function setDefaultCookies() {
	createCookie(header.cookie,('false'),99999);
	createCookie(sidebarr.cookie,('false'),99999);
	createCookie(footer.cookie,('false'),99999);
	createCookie(miniSearch.cookie,('true'),99999);
}

/* 
 * Remove "@gmail.com" from email address in top-right corner
 * and make email address a compose-email link
 * and add mini form (mini search and menu) to top-right corner
*/
function modifyTopBar() {
	// Find top-right links (sign out, my account etc) and email address and "classic home" link
	var guser = document.getElementById('guser');
	guser.setAttribute("style", "padding-top: 0px ! important;"); // No padding above form
	if (guser) var toprightlinks = guser.firstChild;

	if (toprightlinks) {
		// Get rid of everything after @ in email address and make email address a hyperlink to compose an email
		var email = toprightlinks.firstChild; 
		var gc = email.innerHTML;
		gc = gc.substring(0, gc.indexOf('@'));
		email.innerHTML = '<a href="http://mail.google.com/mail/­?view=cm&fs=1&tf=1"><font color="#000000">' + gc + '</font></a>  ' ;
	
		// Remove all top-right links...
		guser.removeChild(guser.firstChild);
		
		// ... and replace them with just the (modified) email address
		var nobr = document.createElement('nobr');
		nobr.appendChild(email);
		nobr.appendChild(getMiniForm());	// Add mini search and menu
		guser.appendChild(nobr);
	}
}

/*
 * Toggle any element on the page. Parameter must be an object with
 * a 'show' boolean (is displayed?), a 'cookie' string (name of settings cookie)
 * and an 'element' string (actual element ID to toggle). 
 */
function toggleElement(obj) {
	obj.show = !obj.show;
	createCookie(obj.cookie,(obj.show ? 'true' : 'false'),99999);
	var elm = document.getElementById(obj.element);
	if (elm) elm.style.display = (obj.show ? '' : 'none');
}

// Function to create a new mini search form to be added to the right-end of the tab bar
function getMiniForm() {
	// Rename original form 'f' to 'f2'
	var f2 = document.getElementById('sfrm');	
	f2.name='f2';		// Error caused if two forms are called f
	var q = document.getElementById('q');
	
	// Create new form & input field
	var miniForm = document.createElement("form");
	miniInput = document.createElement("input");
	if (q) miniInput.value = q.value;
	
	miniForm.appendChild(miniInput);
	miniInput.style.width="200px";
	miniForm.appendChild(document.createTextNode(" ")); 	// Spacing
	// Add drop-down menu
	miniForm.appendChild(getDropdownMenu());
	
	// Make google think this is the real form to make it behave as normal
	miniForm.action="/search";	// Need this for submitting queries
	miniForm.name='f';		// Enable predictive text
	miniInput.name='q';		// Need this for submitting queries
	miniInput.id='q';			// Better id it as 'q' again so we can find & toggle it
	miniInput.setAttribute("autocomplete", "off");
	
	return miniForm;
}

// Function returns a menu item to be added to a drop-down menu
function createMenuItem(itemName, onclickFunction) {
	var newElement = document.createElement('option');
	newElement.appendChild(document.createTextNode(itemName));
	if (onclickFunction!=null) newElement.addEventListener("click", onclickFunction, false);
	return newElement;
}

// Function generates and returns the drop-down menu 'select' item
function getDropdownMenu() {
	var select = document.createElement('select');
	select.addEventListener("change", function() {select.options.selectedIndex = 0;}, false); 
	
	select.appendChild(createMenuItem("Menu"));
	select.appendChild(createMenuItem("-------------"));
	select.appendChild(createMenuItem("Toggle Header (Alt+1)", 
		function(){toggleElement(header)}));	
	if(document.getElementById('col1')) {
		select.appendChild(createMenuItem("Toggle Sidebar (Alt+2)", 
			function(){toggleElement(sidebarr)}));}
	select.appendChild(createMenuItem("Toggle Footer (Alt+3)",
		function(){toggleElement(footer)}));
	select.appendChild(createMenuItem("Toggle Mini Search (Alt+4)",
		function(){toggleElement(miniSearch); if (miniSearch.show) miniInput.focus();}));
	select.appendChild(createMenuItem("-------------"));
	select.appendChild(createMenuItem("Advanced Search",
		function() {window.location='http://www.google.com/advanced_search?hl=en';}));
	select.appendChild(createMenuItem("Search Preferences",
		function() {window.location='http://www.google.com/preferences?hl=en';}));
	select.appendChild(createMenuItem("Language Tools",
		function() {window.location='http://www.google.com/language_tools?hl=en';}));	select.appendChild(createMenuItem("-------------"));
	select.appendChild(createMenuItem("iGoogle Settings",
		function() {window.location='http://www.google.com/ig/settings';}));
	select.appendChild(createMenuItem("Change theme",
		function() {window.location='http://www.google.com/ig/directory?type=themes&dpos=themes';}));
	select.appendChild(createMenuItem("Get artist themes",
		function() {window.location='http://www.google.com/help/ig/art/gallery.html';}));
	select.appendChild(createMenuItem("Themes for causes",
		function() {window.location='http://www.google.com/ig/directory?type=themes&cat=causes&dpos=themes';}));
	select.appendChild(createMenuItem("Add Stuff",
		function() {window.location='http://www.google.com/ig/directory?root=/ig&igtab=Super&dpos=top';}));
	select.appendChild(createMenuItem("-------------"));
	select.appendChild(createMenuItem("Classic Home",
		function() {window.location='http://www.google.com/url?sa=p&pref=ig&pval=1&q=/webhp%3Frls%3Dig';}));
	select.appendChild(createMenuItem("My Account",
		function() {window.location='https://www.google.com/accounts/ManageAccount';}));
	select.appendChild(createMenuItem("Sign Out",
		function() {window.location='http://www.google.com/ig/logout?continue=http://www.google.com/ig';}));
	
	return select;
}

// Add keyboard shortcut to call 'func' when keys 'keyCombo' are pressed
function addShortcut(keyCombo, func) {
	shortcut = getShortcutVar();
	shortcut.add(keyCombo,func,{'type':'keyup','propagate':true,'target':document});
}

// Function to add keyboard shortcuts to page
function initKeyboardShortcuts(){
	addShortcut("Ctrl+1", function() {toggleElement(header);});
	addShortcut("Ctrl+2", function() {toggleElement(sidebarr);});
	addShortcut("Ctrl+3", function() {toggleElement(footer);});
	addShortcut("Ctrl+4", function() {toggleElement(miniSearch);if (miniSearch.show) miniInput.focus();});
	
	addShortcut("Alt+1", function() {toggleElement(header);});
	addShortcut("Alt+2", function() {toggleElement(sidebarr);});
	addShortcut("Alt+3", function() {toggleElement(footer);});
	addShortcut("Alt+4", function() {toggleElement(miniSearch);if (miniSearch.show) miniInput.focus();});
}

// All code past this line was not written by stinkinrich88
// #################################################
// ########## FOLLOWING CODE NOT WRITTEN BY STINKINRICH88 #########
// The following code is only used to read / save cookies which are used to save settings. 
// Code obtained from http://www.quirksmode.org/js/cookies.html
function createCookie(name,value,days) {
	if (days) {
		var date = new Date();
		date.setTime(date.getTime()+(days*24*60*60*1000));
		var expires = "; expires="+date.toGMTString();
	}
	else var expires = "";
	document.cookie = name+"="+value+expires+"; path=/";
}

function readCookie(name) {
	var nameEQ = name + "=";
	var ca = document.cookie.split(';');
	for(var i=0;i < ca.length;i++) {
		var c = ca[i];
		while (c.charAt(0)==' ') c = c.substring(1,c.length);
		if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
	}
	return null;
}

// #################################################
// ########## FOLLOWING CODE NOT WRITTEN BY STINKINRICH88 #########
// The following code is only used to add keyboard shortcuts. To change the keyboard
// shortcuts look at the initKeyboardShortcuts function
function getShortcutVar() {
/**
 * http://www.openjs.com/scripts/events/keyboard_shortcuts/
 * Version : 2.01.B
 * By Binny V A
 * License : BSD
 */
	return {
		'all_shortcuts':{},//All the shortcuts are stored in this array
		'add': function(shortcut_combination,callback,opt) {
			//Provide a set of default options
			var default_options = {
				'type':'keydown',
				'propagate':false,
				'disable_in_input':false,
				'target':document,
				'keycode':false
			}
			if(!opt) opt = default_options;
			else {
				for(var dfo in default_options) {
					if(typeof opt[dfo] == 'undefined') opt[dfo] = default_options[dfo];
				}
			}
			var ele = opt.target;
			if(typeof opt.target == 'string') ele = document.getElementById(opt.target);
			var ths = this;
			shortcut_combination = shortcut_combination.toLowerCase();
			//The function to be called at keypress
			var func = function(e) {
				e = e || window.event;
			
				if(opt['disable_in_input']) { //Don't enable shortcut keys in Input, Textarea fields
					var element;
					if(e.target) element=e.target;
					else if(e.srcElement) element=e.srcElement;
					if(element.nodeType==3) element=element.parentNode;

					if(element.tagName == 'INPUT' || element.tagName == 'TEXTAREA') return;
				}
				//Find Which key is pressed
				if (e.keyCode) code = e.keyCode;
				else if (e.which) code = e.which;
				var character = String.fromCharCode(code);
				if(code == 188) character=","; //If the user presses , when the type is onkeydown
				if(code == 190) character="."; //If the user presses , when the type is onkeydown
				var keys = shortcut_combination.split("+");
				//Key Pressed - counts the number of valid keypresses - if it is same as the number of keys, the shortcut function is invoked
				var kp = 0;
				//Work around for stupid Shift key bug created by using lowercase - as a result the shift+num combination was broken
				var shift_nums = {"`":"~","1":"!","2":"@","3":"#","4":"$","5":"%","6":"^",
					"7":"&","8":"*","9":"(","0":")","-":"_","=":"+",";":":","'":"\"",",":"<",
					".":">","/":"?","\\":"|"}
				//Special Keys - and their codes
				var special_keys ={
					'esc':27,'escape':27,'tab':9,'space':32,'return':13,'enter':13,
					'backspace':8,'scrolllock':145,'scroll_lock':145,'scroll':145,
					'capslock':20,'caps_lock':20,'caps':20,'numlock':144,'num_lock':144,
					'num':144,'pause':19,'break':19,'insert':45,'home':36,'delete':46,
					'end':35,'pageup':33,'page_up':33,'pu':33,'pagedown':34,'page_down':34,
					'pd':34,'left':37,'up':38,'right':39,'down':40,'f1':112,'f2':113,'f3':114,'f4':115,
					'f5':116,'f6':117,'f7':118,'f8':119,'f9':120,'f10':121,'f11':122,'f12':123}
				var modifiers = { 
					shift: { wanted:false, pressed:false},
					ctrl : { wanted:false, pressed:false},
					alt  : { wanted:false, pressed:false},
					meta : { wanted:false, pressed:false}	//Meta is Mac specific
				};
				if(e.ctrlKey)	modifiers.ctrl.pressed = true;
				if(e.shiftKey)	modifiers.shift.pressed = true;
				if(e.altKey)	modifiers.alt.pressed = true;
				if(e.metaKey)   modifiers.meta.pressed = true;
				for(var i=0; k=keys[i],i<keys.length; i++) {
					//Modifiers
					if(k == 'ctrl' || k == 'control') {
						kp++;
						modifiers.ctrl.wanted = true;
					} else if(k == 'shift') {
						kp++;
						modifiers.shift.wanted = true;
					} else if(k == 'alt') {
						kp++;
						modifiers.alt.wanted = true;
					} else if(k == 'meta') {
						kp++;
						modifiers.meta.wanted = true;
					} else if(k.length > 1) { //If it is a special key
						if(special_keys[k] == code) kp++;
					} else if(opt['keycode']) {
						if(opt['keycode'] == code) kp++;
					} else { //The special keys did not match
						if(character == k) kp++;
						else {
							if(shift_nums[character] && e.shiftKey) { //Stupid Shift key bug created by using lowercase
								character = shift_nums[character]; 
								if(character == k) kp++;}}}}
				if(kp == keys.length && 
							modifiers.ctrl.pressed == modifiers.ctrl.wanted &&
							modifiers.shift.pressed == modifiers.shift.wanted &&
							modifiers.alt.pressed == modifiers.alt.wanted &&
							modifiers.meta.pressed == modifiers.meta.wanted) {
					callback(e);
					if(!opt['propagate']) { //Stop the event
						//e.cancelBubble is supported by IE - this will kill the bubbling process.
						e.cancelBubble = true;
						e.returnValue = false;
						//e.stopPropagation works in Firefox.
						if (e.stopPropagation) {
							e.stopPropagation();
							e.preventDefault();
						}return false;}}}
			this.all_shortcuts[shortcut_combination] = {
				'callback':func, 'target':ele, 'event': opt['type']};
			//Attach the function with the event
			if(ele.addEventListener) ele.addEventListener(opt['type'], func, false);
			else if(ele.attachEvent) ele.attachEvent('on'+opt['type'], func);
			else ele['on'+opt['type']] = func;
		},
		//Remove the shortcut - just specify the shortcut and I will remove the binding
		'remove':function(shortcut_combination) {
			shortcut_combination = shortcut_combination.toLowerCase();
			var binding = this.all_shortcuts[shortcut_combination];
			delete(this.all_shortcuts[shortcut_combination])
			if(!binding) return;
			var type = binding['event'];
			var ele = binding['target'];
			var callback = binding['callback'];
			if(ele.detachEvent) ele.detachEvent('on'+type, callback);
			else if(ele.removeEventListener) ele.removeEventListener(type, callback, false);
			else ele['on'+type] = false;
		}}}