Sticky Notes

By panzi Last update Jul 27, 2010 — Installed 7,612 times.

There are 23 previous versions of this script.

Add Syntax Highlighting (this will take a few seconds, probably freezing your browser while it works)

// ==UserScript==
// @name           Sticky Notes
// @namespace      http://twoday.tuwien.ac.at/pub/
// @description    add sticky notes to websites
// @resource       style https://web.student.tuwien.ac.at/~e0427417/downloads/sticky-note/default_style.v2.css
// @include        *
// ==/UserScript==
//
// contributors:
//   Mathias Panzenböck (panzi)
//   Mihai Ghete (Viper)

const BASE_Z_INDEX = 100000;
const VERSION      = 110;

const STATE_DISPLAY = 0;
const STATE_EDIT    = 1;
const STATE_MOVE    = 2;
const STATE_RESIZE  = 3;
const MIN_SIZE      = 15;

function StickyNote(x,y,width,height,text) {
	var stickyNote = this;

	stickyNote._moveX = 0;
	stickyNote._moveY = 0;
	stickyNote._state = STATE_DISPLAY;

	stickyNote.container = document.createElement("div");
	stickyNote.container.style.position = "absolute";
	stickyNote._width  = width  === undefined || width  < MIN_SIZE ? 250 : width;
	stickyNote._height = height === undefined || height < MIN_SIZE ? 250 : height;
	stickyNote._x = x === undefined ? ((window.innerWidth - stickyNote._width) / 2 + window.pageXOffset) : x;
	stickyNote._y = y === undefined ? ((window.innerHeight - stickyNote._height) / 2 + window.pageYOffset) : y;
	stickyNote.container.style.left = stickyNote._x + "px";
	stickyNote.container.style.top  = stickyNote._y + "px";

	stickyNote.container.className = "at-ac-tuwien-student-e0427417-sticky-note-display-mode at-ac-tuwien-student-e0427417-sticky-note";

	stickyNote.container.style.width=stickyNote._width + "px";

	// hopefully high enough z-index:
	stickyNote.container.style.zIndex=BASE_Z_INDEX;

	var div = document.createElement("div");
	div.className = "at-ac-tuwien-student-e0427417-sticky-note-top";
	div.style.MozUserSelect = "none";

	var a = document.createElement("a");

	stickyNote.remove = function() {
		stickyNote.container.parentNode.removeChild(stickyNote.container);
	};

	a.addEventListener("click", function() {
		stickyNote.remove();
		removeStickyNote(stickyNote);
	}, true);

	a.title = "remove this sticky note";
	a.appendChild(document.createTextNode("\xD7"));
	div.appendChild(a);
	stickyNote.container.appendChild(div);

	var resizeGrabber = document.createElement("div");
	resizeGrabber.className = "at-ac-tuwien-student-e0427417-sticky-note-resize-grabber";
	resizeGrabber.style.MozUserSelect="none";
	stickyNote.container.appendChild(resizeGrabber);

	stickyNote.displayText = document.createElement("div");
	stickyNote.displayText.className = "at-ac-tuwien-student-e0427417-sticky-note-display-text";
	stickyNote.editText    = document.createElement("textarea");
	stickyNote.editText.className = "at-ac-tuwien-student-e0427417-sticky-note-edit-text";

	stickyNote.displayText.style.width  = stickyNote.editText.style.width  = "100%";
	stickyNote.displayText.style.height = stickyNote.editText.style.height = stickyNote._height + "px";
	stickyNote.displayText.style.overflow  = "auto";
	stickyNote.displayText.style.MozUserSelect = "none";
	stickyNote.editText.style.display = "none";
	stickyNote.editText.style.border  = "none";
	stickyNote.editText.style.margin  = "0px";
	stickyNote.editText.style.padding = "0px";
	stickyNote.displayText.title = "double click to edit sticky note";

	stickyNote.container.appendChild(stickyNote.displayText);
	stickyNote.container.appendChild(stickyNote.editText);

	stickyNote.setText = function(text) {
		stickyNote.displayText.innerHTML = text.replace(/\n/g,"<br/>");
		stickyNote.editText.value        = text;
	};

	stickyNote.getText = function() {
		return stickyNote.editText.value;
	};

	var body = document.getElementsByTagName("body")[0];

	resizeGrabber.addEventListener("mousedown", function(e) {
		if (e.button == 0 && stickyNote._state != STATE_EDIT) {
			stickyNote.container.className = "at-ac-tuwien-student-e0427417-sticky-note-resize-mode at-ac-tuwien-student-e0427417-sticky-note";
			body.style.MozUserSelect="none";
			stickyNote._state = STATE_RESIZE;
			stickyNote._moveX = e.pageX;
			stickyNote._moveY = e.pageY;
			return false;
		}
		return true;
	}, true);

	stickyNote.container.addEventListener("mousedown", function(e) {
		moveToTop(stickyNote);
		if (e.button == 0 && stickyNote._state == STATE_DISPLAY) {
			stickyNote.container.className = "at-ac-tuwien-student-e0427417-sticky-note-move-mode at-ac-tuwien-student-e0427417-sticky-note";
			body.style.MozUserSelect="none";
			stickyNote._state = STATE_MOVE;
			stickyNote._moveX = e.pageX;
			stickyNote._moveY = e.pageY;
			return false;
		}
		return true;
	}, true);
	
	window.addEventListener("mouseup", function(e) {
		if (e.button == 0 && (stickyNote._state == STATE_MOVE || stickyNote._state == STATE_RESIZE)) {
			stickyNote.container.className = "at-ac-tuwien-student-e0427417-sticky-note-display-mode at-ac-tuwien-student-e0427417-sticky-note";
			body.style.MozUserSelect="text";
			stickyNote._state = STATE_DISPLAY;
			saveStickyNotes();
		}
	}, true);
	
	window.addEventListener("mousemove", function(e) {
		switch (stickyNote._state) {
		case STATE_MOVE:
			stickyNote._x += e.pageX - stickyNote._moveX;
			stickyNote._y += e.pageY - stickyNote._moveY;

			stickyNote.container.style.left = stickyNote._x + "px";
			stickyNote.container.style.top  = stickyNote._y + "px";
			
			stickyNote._moveX = e.pageX;
			stickyNote._moveY = e.pageY;
			return false;
		case STATE_RESIZE:
			var newWidth  = stickyNote._width  + e.pageX - stickyNote._moveX;
			var newHeight = stickyNote._height + e.pageY - stickyNote._moveY;

			if (newWidth >= MIN_SIZE) {
				stickyNote._width = newWidth;
				stickyNote._moveX = e.pageX;
				stickyNote.container.style.width = stickyNote._width + "px";
			}

			if (newHeight >= MIN_SIZE) {
				stickyNote._height = newHeight;
				stickyNote._moveY  = e.pageY;
				stickyNote.editText.style.height = stickyNote.displayText.style.height = stickyNote._height + "px";
			}

			return false;
		}
		return true;
	}, true);

	stickyNote.container.addEventListener("dblclick", function() {	
		stickyNote.container.className = "at-ac-tuwien-student-e0427417-sticky-note-edit-mode at-ac-tuwien-student-e0427417-sticky-note";
		stickyNote.displayText.style.display="none";
		stickyNote.editText.style.display="block";
		stickyNote._state = STATE_EDIT;
		stickyNote.editText.focus();
	}, true);
	
	function endEdit() {
		stickyNote.container.className = "at-ac-tuwien-student-e0427417-sticky-note-display-mode at-ac-tuwien-student-e0427417-sticky-note";
		stickyNote.displayText.style.display="block";
		stickyNote.editText.style.display="none";
		stickyNote._state = STATE_DISPLAY;
		stickyNote.displayText.innerHTML = stickyNote.editText.value.replace(/\n/g,"<br/>");
		saveStickyNotes();
	};
	
	stickyNote.editText.addEventListener("keyup", function(e) {
		if (e.which == 27) {
			endEdit();
		}
	}, true);

	stickyNote.editText.addEventListener("blur", endEdit, true);

	stickyNote.getX = function() {
		return stickyNote._x;
	}

	stickyNote.getY = function() {
		return stickyNote._y;
	}

	stickyNote.getWidth = function() {
		return stickyNote._width;
	}

	stickyNote.getHeight = function() {
		return stickyNote._height;
	}

	stickyNote.setX = function(x) {
		stickyNote._x = x;
		stickyNote.container.style.left = x + "px";
	}

	stickyNote.setY = function(y) {
		stickyNote._y = y;
		stickyNote.container.style.top = y + "px";
	}


	stickyNote.setWidth = function(width) {
		stickyNote.container.style.width = width + "px";
		stickyNote._width = width;
	}

	stickyNote.setHeight = function(height) {
		stickyNote.editText.style.height = stickyNote.displayText.style.height = height + "px";
		stickyNote._height = height;
	}

	if (text != undefined) {
		stickyNote.setText(text);
	}

	body.appendChild(stickyNote.container);
}

var stickyNotes = [];
const siteId = location.href.split('#')[0];

function listSites() {
	return [name for each (name in GM_listValues()) if (!/^stickynote:/.test(name))];
}

function GM_getObject(name,defaultValue) {
	var s = GM_getValue(name);

	if (s === undefined) {
		return defaultValue;
	}
	else {
		return JSON.parse(s);
	}
}

function GM_setObject(name,value) {
	GM_setValue(name, JSON.stringify(value));
}

function arrayEquals(a1, a2) {
	if (a1.length != a2.length) {
		return false;
	}
	
	for (var i = 0; i < a1.length; ++ i) {
		if (a1[i] !== a2[i]) {
			return false;
		}
	}

	return true;
}

function listStickyNotes(site) {
	var notes = GM_getObject(site);

	if (notes === undefined) {
		return [];
	}
	else {
		return notes;
	}
}

function reloadStickyNotes() {
	for each (note in stickyNotes) {
		note.remove();
	}
	stickyNotes = [];
	loadStickyNotes();
}

function loadStickyNotes() {
	var version = GM_getValue('stickynote:version');

	if (version !== VERSION) {
		GM_setValue('stickynote:version', VERSION);
	}

	if (version < 110) {
		var style = getStylesheet();
		style += '\n\n.at-ac-tuwien-student-e0427417-sticky-note-overlay-extra-buttons {\n  float: left;\n}';
		setStylesheet(style);
		saveStylesheet(style);
	}

	for each ([x,y,width,height,text] in listStickyNotes(siteId)) {
		stickyNotes.push(new StickyNote(x,y,width,height,text));
	}
}

function saveStickyNotesFor(site,notes) {
	if (notes.length == 0) {
		GM_deleteValue(site);
	}
	else {
		GM_setObject(site, notes);
	}
}

function saveStickyNotes() {
	saveStickyNotesFor(siteId, [[
		note.getX(), note.getY(),
		note.getWidth(), note.getHeight(),
		note.getText()] for each (note in stickyNotes)]);
}

function removeStickyNote(stickyNote) {
	stickyNotes = [note for each (note in stickyNotes) if (note != stickyNote)];
	saveStickyNotes();
}

function moveToTop(stickyNote) {
	stickyNotes = [note for each (note in stickyNotes) if (note != stickyNote)];
	stickyNotes.push(stickyNote);

	var zIndex = BASE_Z_INDEX;
	for each (note in stickyNotes) {
		note.container.style.zIndex = zIndex;
		++ zIndex;
	}
}

var onOverlayClosed = null;

function showOverlay(element, opts) {
	if (!opts || !opts.buttons) {
		buttons = [];
	}
	else {
		buttons = opts.buttons;
	}

	buttons.push(createButton('Close', function () {
		hideOverlay('close');
	}));

	var buttonDiv = document.createElement('div');
	buttonDiv.className = 'at-ac-tuwien-student-e0427417-sticky-note-overlay-buttons';

	for (var i = 0; i < buttons.length; ++ i) {
		var button = buttons[i];
		buttonDiv.appendChild(button);
	}

	var overlay = document.getElementById("at-ac-tuwien-student-e0427417-sticky-note-overlay");
	var blanket = document.getElementById("at-ac-tuwien-student-e0427417-sticky-note-blanket");

	if (!blanket) {
		blanket = document.createElement("div");
		blanket.id = "at-ac-tuwien-student-e0427417-sticky-note-blanket";
		blanket.style.position = 'fixed';
		blanket.style.left   = '0px';
		blanket.style.top    = '0px';
		blanket.style.width  = '100%';
		blanket.style.height = '100%';
		blanket.style.zIndex = '100101';
		document.body.appendChild(blanket);
	}
	else {
		blanket.style.display = 'block';
	}

	if (!overlay) {
		var overlay = document.createElement("div");
		overlay.id = "at-ac-tuwien-student-e0427417-sticky-note-overlay";
		overlay.style.position = 'fixed';
		overlay.style.margin = 'auto';
		overlay.style.zIndex = '100102';
		document.body.appendChild(overlay);

		window.addEventListener('resize', function () {
			if (overlay.style.display != 'none') {
				overlay.style.left = ((window.innerWidth - overlay.offsetWidth) / 2) + 'px';
				overlay.style.top  = ((window.innerHeight - overlay.offsetHeight) / 2) + 'px';
			}
		}, true);
	}
	else {
		overlay.innerHTML = '';
		overlay.style.display = 'block';
	}

	onOverlayClosed = opts && opts.onClose ? opts.onClose : null;
	overlay.appendChild(element);

	if (opts && opts.extraButtons) {
		var extraButtonDiv = document.createElement('div');
		extraButtonDiv.className = 'at-ac-tuwien-student-e0427417-sticky-note-overlay-extra-buttons';

		for each (button in opts.extraButtons) {
			extraButtonDiv.appendChild(button);
		}
		overlay.appendChild(extraButtonDiv);
	}

	overlay.appendChild(buttonDiv);

	var compStyle = getComputedStyle(overlay,'');
	var overlayWidth  = px(compStyle.width) || overlay.offsetWidth;
	var overlayHeight = px(compStyle.height) || overlay.offsetHeight;

	overlay.style.left = ((window.innerWidth - overlayWidth) / 2) + 'px';
	overlay.style.top  = ((window.innerHeight - overlayHeight) / 2) + 'px';

	compStyle = getComputedStyle(buttonDiv,'');
	var contentWidth = overlayWidth;
	var contentHeight = (overlayHeight -
		(px(compStyle.height) || buttonDiv.offsetHeight) -
		px(compStyle.marginTop) -
		px(compStyle.marginBottom) -
		px(compStyle.paddingTop) -
		px(compStyle.paddingBottom) -
		px(compStyle.borderTopWidth) -
		px(compStyle.borderBottomWidth));

	compStyle = getComputedStyle(element,'');
	var elementWidth = (contentWidth -
		px(compStyle.paddingLeft) -
		px(compStyle.paddingRight) -
		px(compStyle.marginLeft) -
		px(compStyle.marginRight) -
		px(compStyle.borderLeftWidth) -
		px(compStyle.borderRightWidth));
	var elementHeight = (contentHeight -
		px(compStyle.marginTop) -
		px(compStyle.marginBottom) -
		px(compStyle.paddingTop) -
		px(compStyle.paddingBottom) -
		px(compStyle.borderTopWidth) -
		px(compStyle.borderBottomWidth));

	element.style.width  = elementWidth + 'px';
	element.style.height = elementHeight + 'px';
}

function px(x) {
	return parseFloat(x.split('px')[0]);
}

function hideOverlay(reason) {
	var overlay = document.getElementById("at-ac-tuwien-student-e0427417-sticky-note-overlay");
	var blanket = document.getElementById("at-ac-tuwien-student-e0427417-sticky-note-blanket");

	if (overlay) {
		if (onOverlayClosed) {
			onOverlayClosed(reason);
			onOverlayClosed = null;
		}

		overlay.style.display = 'none';
		overlay.innerHTML = '';
	}

	if (blanket) {
		blanket.style.display = 'none';
	}
}

function createButton(label,callback) {
	var btn = document.createElement('input');
	btn.type = 'button';
	btn.value = label;
	if (callback) {
		btn.addEventListener('click', callback, true);
	}
	return btn;
}

function createCheckbox(id,label,callback) {
	id = 'at-ac-tuwien-student-e0427417-sticky-note-overlay-'+id;
	var chk  = document.createElement('input');
	var lbl  = document.createElement('label');
	var span = document.createElement('span');
	chk.type = 'checkbox';
	chk.id = id;
	lbl.htmlFor = id;
	lbl.appendChild(document.createTextNode(label));
	if (callback) {
		chk.addEventListener('change', callback, true);
	}
	span.appendChild(chk);
	span.appendChild(lbl);
	return span;
}

function createTextarea(text) {
	var textarea = document.createElement("textarea");
	if (text != undefined) {
		textarea.value = text;
	}
	return textarea;
}

function deleteNote(list, li) {
	return function () {
		var origNotes = list.stickyNotes;
		var delIndex = li.stickyNoteIndex;
		var notes = [];

		for (var i = 0; i < origNotes.length; ++ i) {
			if (i != delIndex) {
				notes.push(origNotes[i]);
			}
		}

		var sibling = li.nextSibling;

		while (sibling != null) {
			if (sibling.stickyNoteIndex != undefined) {
				-- stickyNoteIndex.stickyNoteIndex;
			}
			sibling = sibling.nextSibling;
		}

		list.stickyNotes = notes;
		list.removeChild(li);
		saveStickyNotesFor(list.stickyNoteSite, notes);

		if (siteId == list.stickyNoteSite) {
			reloadStickyNotes();
		}
	};
}

function expandNote(div) {
	return function () {
		if (div.style.display == 'none') {
			div.style.display = 'block';
		}
		else {
			div.style.display = 'none';
		}
	};
}

function expandSite(site, list) {
	return function () {
		if (list.style.display == 'none') {
			var notes = listStickyNotes(site);
			for (var index = 0; index < notes.length; ++ index) {
				var [x, y, w, h, text] = notes[index];
				var li = document.createElement('li');
				var titleDiv = document.createElement('div');
				var titleA = document.createElement('a');
				var delA = document.createElement('a');
				var noteDiv = document.createElement('div');
				
				li.stickyNoteIndex = index;

				titleDiv.className = 'at-ac-tuwien-student-e0427417-sticky-note-manage-note';
				titleA.appendChild(document.createTextNode('x: ' + x + ', y: ' + y));

				delA.style.MozUserSelect = 'none';
				
				delA.className = 'at-ac-tuwien-student-e0427417-sticky-note-manage-delete';
				delA.appendChild(document.createTextNode("\xD7"));
				noteDiv.style.display = 'none';
				noteDiv.innerHTML = text;

				titleDiv.addEventListener('click', expandNote(noteDiv), true);
				delA.addEventListener('click', deleteNote(list, li), true);

				titleDiv.appendChild(titleA);
				titleDiv.appendChild(delA);
				li.appendChild(titleDiv);
				li.appendChild(noteDiv);
				list.appendChild(li);
			}

			list.stickyNotes = notes;
			list.style.display = 'block';
		}
		else {
			list.innerHTML = '';
			list.style.display = 'none';
		}
	};
}

function manageStickyNotes() {
	var div = document.createElement('div');
	var list = document.createElement('ul');
	var sites = listSites();
	sites.sort();
	div.id = 'at-ac-tuwien-student-e0427417-sticky-note-manage';

	for each (site in sites) {
		var li = document.createElement('li');
		var siteDiv = document.createElement('div');
		var titleA = document.createElement('a');
		var gotoA = document.createElement('a');
		var siteList = document.createElement('ul');

		siteDiv.className = 'at-ac-tuwien-student-e0427417-sticky-note-manage-site';
		siteList.stickyNoteSite = site;

		titleA.appendChild(document.createTextNode(site));
		siteList.style.display = 'none';

		siteDiv.addEventListener('click', expandSite(site, siteList), true);

		gotoA.className = 'at-ac-tuwien-student-e0427417-sticky-note-manage-link';
		gotoA.href = site;
		gotoA.appendChild(document.createTextNode('[link]'));

		siteDiv.appendChild(titleA);
		siteDiv.appendChild(document.createTextNode(' '));
		siteDiv.appendChild(gotoA);
		li.appendChild(siteDiv);
		li.appendChild(siteList);
		list.appendChild(li);
	}

	div.appendChild(list);
	showOverlay(div);
}

function exportStickyNotes() {
	var text = [
		(JSON.stringify(name) + ':' + GM_getValue(name))
		for each (name in GM_listValues())
		if (!/^stickynote:/.test(name))].join(',');
	showOverlay(createTextarea('{'+text+'}'));
}

function importStickyNotes() {
	var textarea = createTextarea();
	var importButton = createButton('Import', function() {
		var newNotes = JSON.parse(textarea.value);

		for (url in newNotes) {
			if (/^stickynote:/.test(url)) {
				continue;
			}

			// ignore invalid notes:
			var notes = [note for each (note in newNotes[url]) if (
				note instanceof Array && note.length == 5 &&
				typeof(note[0]) == 'number' && typeof(note[1]) == 'number' &&
				typeof(note[2]) == 'number' && typeof(note[3]) == 'number' &&
				typeof(note[4]) == 'string')];

			var existingNotes = GM_getObject(url);

			if (existingNotes !== undefined) {
				var merged = [note for each (note in existingNotes)];
				for each (note in notes) {
					var exists = false;
					for each (existingNote in existingNotes) {
						if (arrayEquals(note, existingNote)) {
							exists = true;
							break;
						}
					}
					if (!exists) {
						merged.push(note);
					}
				}
				newNotes[url] = merged;
				GM_setObject(url, merged);
			}
			else {
				newNotes[url] = notes;
				GM_setObject(url, notes);
			}
		}

		for each (note in stickyNotes) {
			note.remove();
		}
		stickyNotes = [];
		for each ([x,y,width,height,text] in newNotes[siteId]) {
			stickyNotes.push(new StickyNote(x,y,width,height,text));
		}
		hideOverlay();
	});
	showOverlay(textarea, { buttons: [importButton] });
}

function saveStylesheet(style) {
	GM_setValue("stickynote:stylesheet", style);
}

function loadStylesheet() {
	var style = GM_getValue("stickynote:stylesheet");

	if (style === undefined) {
		style = GM_getResourceText('style');
	}

	setStylesheet(style);
}

function setStylesheet(style) {
	var styleElem = document.getElementById("at-ac-tuwien-student-e0427417-sticky-note-style");

	if (!styleElem) {
		styleElem = document.createElement("style");
		styleElem.id = "at-ac-tuwien-student-e0427417-sticky-note-style";
		styleElem.type = "text/css";
		var head = document.getElementsByTagName("head")[0];
		head.appendChild(styleElem);
	}
	else {
		styleElem.innerHTML = '';
	}

	styleElem.appendChild(document.createTextNode(style));
}

function getStylesheet() {
	var styleElem = document.getElementById("at-ac-tuwien-student-e0427417-sticky-note-style");

	if (!styleElem) {
		return GM_getResourceText('style');
	}
	else {
		return styleElem.innerHTML;
	}
}

function editStylesheet() {
	var unchangedStyle = getStylesheet();
	var textarea = createTextarea(unchangedStyle);
	var resetButton = createButton("Reset", function () {
		textarea.value = GM_getResourceText('style');
	});
	var saveButton = createButton("Save", function () {
		saveStylesheet(textarea.value);
		setStylesheet(textarea.value);
		hideOverlay('save');
	});
	var onStyleEdited = function () {
		setStylesheet(textarea.value);
	};
	var previewCheckbox = createCheckbox('live-preview', 'Live Preview', function (event) {
		if (event.originalTarget.checked) {
			setStylesheet(textarea.value);
			textarea.addEventListener('keyup', onStyleEdited, true);
		}
		else {
			textarea.removeEventListener('keyup', onStyleEdited, true);
			setStylesheet(unchangedStyle);
		}
	});
	
	textarea.style.fontFamily = 'monospace';
	textarea.addEventListener("keydown", function(e) {
		if (e.ctrlKey && e.which == 13) {
			saveStylesheet(textarea.value);
			setStylesheet(textarea.value);
			hideOverlay('save');
		}
	}, true);

	showOverlay(textarea, {
		buttons: [resetButton, saveButton],
		extraButtons: [previewCheckbox],
		onClose: function (reason) {
			if (reason == 'close') {
				setStylesheet(unchangedStyle);
			}
		}
	});
}

function addStickyNote() {
	stickyNotes.push(new StickyNote());
}

unsafeWindow.addStickyNote = addStickyNote;

// HACK: This should be done by greasemonkey.
window.addEventListener('keydown', function(e) {
	if (e.altKey && e.which == 78) {
		addStickyNote();
	}
}, true);

GM_registerMenuCommand("Add Sticky Note", addStickyNote, "n", "alt", "N");
GM_registerMenuCommand("Manage Sticky Notes...", manageStickyNotes, undefined, undefined, "M");
GM_registerMenuCommand("Export Sticky Notes...", exportStickyNotes, undefined, undefined, "E");
GM_registerMenuCommand("Import Sticky Notes...", importStickyNotes, undefined, undefined, "I");
GM_registerMenuCommand("Edit Sticky Note Stylesheet...", editStylesheet, undefined, undefined, "S");

loadStylesheet();
loadStickyNotes();