Gmail Notes Client

By johntray Last update Jul 3, 2009 — Installed 1,004 times. Daily Installs: 2, 3, 6, 2, 3, 4, 2, 2, 3, 5, 2, 4, 3, 3, 8, 3, 4, 3, 2, 7, 6, 6, 2, 4, 2, 4, 3, 4, 2, 3, 5, 6

There are 5 previous versions of this script.

// ==UserScript==
// @name          Gmail Notes Client
// @namespace     http://www.gmailnotes.com
// @description   Browser interface for Gmail Notes server (gmailnotes.appspot.com). Adds menu panel to navigation pane.
// @require       http://gmailnotes.appspot.com/static/common/javascript/messaging2.js
// @require       http://gmailnotes.appspot.com/static/common/javascript/json2.js
// @include       https://mail.google.com/*
// @include       http://mail.google.com/*
// @version       4.0.4
// @homepage      http://www.gmailnotes.com
// @copyright     2009, john Tourtellott
// ==/UserScript==

const SCRIPT_VERSION = 404;
const HOST = "gmailnotes.appspot.com";
const NAVBOX_COLOR = "#00eeee";  // teal
const NAVBOX_HEIGHT = 90;

/*
When page loads:
  - Add message event handler (for quick links)
  - Add callback function for viewtype change
  - Create navigation box 
  - Load menu in iframe
*/
window.addEventListener("load", function() {	
	// Add listener for message events
	// Typical Google message is {"s":"resize_iframe","f":"remote_iframe_0","c":0,"a":[325],"t":"wj52nz-r5sg5i"}
	// Typical Gmail Notes message is {["gmnotes",1,{"threadid","120f9a8281ba67c4"}]
	window.addEventListener("message", function(event) {
		GM_log("Received message " + event.data);
		if (!isMessage(event.data))  {
			GM_log("Ignoring message " + event.data);
			return;
		}
		
		// Parse and apply the message
		var message = JSON.parse(event.data);
		var message_type = messageType(message);
		var args = messageArguments(message);
		switch (message_type)  {
			case msg_menu_ready:
				// Not used
				//var appVersion = args["version"];
			break;

			case msg_set_gmail_thread:
				// Deprecated
				GM_log("msg_set_gmail_thread is deprecated");
			break;
			
			case msg_set_gmail_hash:
				// Hash argument must be encoded in Gmail format
				hash = args["hash"];
				GM_log("Setting Gmail hash to " + hash);
				window.top.focus();  // does this bring Gmail to front?
				window.top.location.hash = hash;
			break;

			default:
				GM_log("Unrecognized message " + event.data);
				return;
			break;
		}

	}, false);

	// Load Gmail functions
	if (unsafeWindow.gmonkey) {
		unsafeWindow.gmonkey.load('1.0', function(gmail) {
			// Timing workaround per http://eric.biven.us/2008/11/25/using-the-gmail-greasemonkey-api-and-succeeding-my-workaround/
			window.setTimeout(main,400);
			function main()  {
				var MyFrame = null;
		
				// Internal function - updates navbox uri based on current view type
				function updateNavboxForViewType()  {
					if (!MyFrame)  // safety first
						return;
						
					var viewType = gmail.getActiveViewType();
					var fragment = "";
					// NOTE: Get fragment from location.href because location.hash decodes %2B to plus sign,
					// and since plus sign is used for space, there's no way to distinguish the two (sheesh)
					var url = window.top.location.href;
					var index = url.lastIndexOf("#");
					if (index > 0)
						fragment = url.substr(index+1)
					
					// For reasons unknown, Firefox 3.5 throws a "Security Manager vetoed action" exception
					// when calling sendMessage(); so instead do the equivalent logic here. Just because it seems to work....
					//
					//sendMessage(MyFrame.contentWindow, msg_viewtype_change,
					//	{"viewtype":viewType,"fragment":fragment});
					var checkpoint = 100;  // for error checking
					var s = "";
					var dd = "*";  // per note at https://developer.mozilla.org/en/DOM/window.postMessage
					try  {
						destination = MyFrame.contentWindow;
						checkpoint = 200;
						
						var arr = new Array();
						checkpoint = 220;
						arr[0] = msg_identifier;
						checkpoint = 240;
						arr[1] = msg_viewtype_change;
						checkpoint = 260;
						arr[2] = {"viewtype":viewType,"fragment":fragment};
						checkpoint = 280;
						
						s = JSON.stringify(arr);
						checkpoint = 300;
						//GM_log("Before postMessage(" + s + ")");
						destination.postMessage(s,dd);
						//GM_log("After postMessage()");
						checkpoint = 400;
					}
					catch (ex)  {
						var text = "Exception in updateNavboxForViewType(): \n";
						text += "Checkpoint " + checkpoint + "\n";
						text += "s: " + s + ", dd: " + dd + ". \n";						
						alert(text + ex.message);
					}
				}; // end function updateNavboxForViewType()

				// Create navigation panel with <iframe> for menu
				try  {
					if (MyFrame == null)  {  // added "if" because sometimes 2 nav boxes are displayed (for some reason)
						var title = "<strong><em>Gmail Notes</em></strong>";
						// Add icon for good looks, with thanks to http://www.greywyvern.com/code/php/binary2base64:
						title += "&nbsp;";
						title += "<img alt='[icon]' src='data:image/ico;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAPAKAADwCgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIEEwACBjwAAAALAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABghFkWrwb6Iw87sH2p9sgANFmIAAAAkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACeFnpHH////7P///9T///92yNvzOW56wwcwOnsAAAIyAAAACgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAoNCKV6/bx0/r7/4XG2f+r2+f/4f///+b////C+P//SKi/4gYyP5gAAwZQAAAADgAAAAAAAAAAAAAAAAAAAAAqiKCTx////9H///++8fb/otvo/43K3P+X0N//uOLs/97///+/9f//kcjU7S14i7sGISlwAAUGJwAAAAAAGSQOf93t463p8P+L0uH/su3z/9L////O/f7/uOvy/5/Y5f+Kx9r/m8/g/8Tr8//r////ds7j9QAVHTwAAAAABV12WqL///+t8fX/idTi/37K3P+Iz9//pOHr/73z9//S////yvf6/5zW5P+VzN3/yfz//y93iZMAAAAAAAAAADKTqaKz/v7/t////77////A////ru/0/4jR4f9yvtT/e8TY/6Pf6v/O/P3/4f///16zxtIAAAMPAAAAAAAWIARnzd7NnvD2/2u7y/93w9D/jNnk/7H4+v+/////uvr8/6vs8v+N0+L/quTu/6Xs9fkDLz1WAAAAAAAAAAABXHwgeuf086f7+v91uLr/dLq4/4je4f950uH/dcnb/4LR4f+d5e7/wP7+/8f///8yjKG4AAAAAwAAAAAAAAAABV56V4f+//+Azs//WoSI/0tzqP9hj8n/muXx/5nq8P9+0+L/ccXZ/5vj7f994/H4ACk4WAAAAAAAAAAAAAAAAA6Lso2U////fbSw/y44mv8ACcr/AACN/z9isP+s+fz/sP///7L///+2/v//NoSUvQAAAA4AAAAAAAAAAAAAAAAmsti7nf///574+f8wYPX/DTb0/wAQvP8ABaH/GjCj/2rE2f9+2OX/ofn8/xRET3oAAAAAAAAAAAAAAAAAAAAAC5/NTSyjvIM+w+TDK2/w/ytc//8ROe3/AAi9/xEgsf+M6PD/luzy/23b6/8BGCFEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGGBAgA1uUsKJ9uSCy7c3gAT2f8eU7zig/D18Zz///9Hv9j2AAIIKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWsiwAClhiAAsUDwWKvBcIirNbBIOoZwAICgUAAAAAAAAAAAAAAAAAAAAA//8AAPH/AADgfwAA4A8AAMADAADAAQAAwAEAAIADAACABwAAgAcAAIAPAAAADwAAAB8AAIAfAADwHwAA//8AAA==' />";

						var navbox = gmail.addNavModule(title);
						GM_log("Created navbox");
						navbox.setColor(NAVBOX_COLOR);
						var html = "";
						
						// If browser supports message events, set up menu in inframe
						if (browserSupportsMessages())  {
							html += "<iframe";
							html += " id='navframe'";
							
							html += " src='" + window.top.location.protocol + "//" + HOST + "/menu" 
								+ "/scriptversion=" + SCRIPT_VERSION + "'";
							
							html += " width='100%'";
							html += " scrolling='no'";
							html += " style='border:none; height:" + NAVBOX_HEIGHT + "px;'";
							html += " />";
						}
						// If browser doesn't support message events, say so
						else {
							html += "<textarea"
							html += " style='border:none; height:" + NAVBOX_HEIGHT + "px;";
							html += " width:95%; font-size:small; color:red;'";
							html += ">";
							html += "Browser doesn't support message events."
							html += " You must use Firefox 3.0.0+."
							html += "</textarea>";
						}
						navbox.setContent(html);

						// Move new panel to 3rd position in navigation pane, after "Compose" & "Inbox",
						var navboxElem = navbox.getElement();
						var navPane = gmail.getNavPaneElement().firstChild;
						navPane.insertBefore(navboxElem, navPane.childNodes[2]);

						// Punt here if browser doesn't support message events
						if (!browserSupportsMessages())
							return;

						// Get dom element for iframe
						var nodeList = navboxElem.getElementsByTagName("iframe");
						for (var i=0; i<nodeList.length; i++)  {
							var node = nodeList[i];
							if (node.id && (node.id == "navframe"))  {
								MyFrame = node;
								break;
							}
						}
					}  // end if (MyFrame == null)

					// Register callback for viewtype change 
					gmail.registerViewChangeCallback(updateNavboxForViewType);
					// Initialize menu, after some delay for it to (hopefully) load
					window.setTimeout(updateNavboxForViewType,2000);
				}
				catch (ex)  {
					GM_log('Exception in main script: ' + ex.message);
					return -1;  // no point in going on...
				}
				
			}  // end function main()
		});  // end function  gmonkey.load()
	}  // end if (gmonkey)
},true);  // end function window.addEventListener()