Large

IMDb Boards markup & hotkeys

By Chicago_gangster Last update May 7, 2011 — Installed 940 times.

There are 41 previous versions of this script.

// ==UserScript==
// @name           IMDb Boards markup & hotkeys
// @namespace      http://userscripts.org/users/67626
// @description    Adds markup buttons above the Body text area. Enables hotkeys for previewing/posting. Fixes the "space problem" in long URLs.
// @icon           http://s3.amazonaws.com/uso_ss/icon/42255/large.png
// @author         Chicago_gangster (http://userscripts.org/users/67626)
// @copyright      2009-2011 Chicago_gangster (http://userscripts.org/users/67626)
// @license        Creative Commons BY-NC-ND 3.0, http://creativecommons.org/licenses/by-nc-nd/3.0/
// @include        http://*.imdb.com/*/reply/*
// @include        http://*.imdb.com/*/edit/*
// @include        http://*.imdb.com/*/post/*
// @include        http://*.imdb.com/*/sendpm/*
// @version        2011.05.07
// ==/UserScript==

(function() {

IMDb_design = false;

// List of emoticons. If you add new emoticons, instant preview may not work for them. (It doesn't work in Opera anyway.)
var I = "bigeek biggrin cheers confused giveup laugh no razz sad sigh smile uhoh wink winkgrin yes".split(" ");

// List of colours. You may remove the ones you don't need.
var C = "Red Blue Green Purple Orange Yellow White Black".split(" ");

// List of special characters. Editable. Format: "code|tooltip" or just "code" (tooltips don't pop up in Opera anyway).
var S = new Array("–|en dash", "—|em dash", "±|plus-minus", "•|bullet", "«|left double angle quote", "»|right double angle quote", "£|pound");




function $$(x) {return document.getElementsByTagName(x)}
function $N(x) {return document.getElementsByName(x)[0]}

// The reason not to use "GM_addStyle()" and/or E4X below is increasing cross-browser & cross-version compatibility.
with (CSS = document.createElement("STYLE")) {
	type = "text/css";
	innerHTML = '.markup {vertical-align: middle; margin: auto auto 2px 2px; font-size: 14px; border: 1px solid; background-color: #EEE}\
	             .markup:hover {background-color: #DDD}\
	             .markup:active {background-color: #EEE}\
	             OPTION.list {background-color: white}\
	             OPTION.color {background-color: white; font-weight: bold}';
}
with (CSS_IMDb = document.createElement("STYLE")) {
	type = "text/css";
	innerHTML = '.markup {vertical-align: middle; margin: auto auto 2px 2px; font-size: 14px}\
	             .markup {border-bottom: 1px solid #AAA; border-left: 1px solid #BBB; border-right: 1px solid #AAA; border-top: 1px solid #BBB}\
	             .markup {background: #ECE2C6 url(http://i.media-imdb.com/images/wheel/button-bg.gif) 0 -150px repeat-x}\
	             .markup:hover {background-image: none; border: 1px solid #E6B800}\
	             .markup:active {background-color: #EEE5CC}\
	             OPTION.list {background-color: white}\
	             OPTION.color {background-color: white; font-weight: bold}';
}


var Firefox = (typeof GM_registerMenuCommand == "function");
if (Firefox) {
	function design() {
		GM_setValue("IMDb-ish", !GM_getValue("IMDb-ish"));
		alert("The markup bar design has been set to \"" + ((GM_getValue("IMDb-ish")) ? "IMDb" : "Grey") + "\".\n\n(The change will take effect when the page is reloaded.)");
	}
	GM_registerMenuCommand("IMDb Boards: markup bar design", design);
	with ($$("head")[0]) {(GM_getValue("IMDb-ish")) ? appendChild(CSS_IMDb) : appendChild(CSS)}
}
else {
	with ($$("head")[0]) {(IMDb_design) ? appendChild(CSS_IMDb) : appendChild(CSS)}
}


// The reason not to use "addEventListener()" or E4X below is increasing cross-browser & cross-version compatibility.
with (JS = document.createElement("SCRIPT")) {
	type = "text/javascript";
	innerHTML = 'var Body = document.getElementsByName("body")[0];\
		function readValues() {\
			s = Body.scrollTop;\
			a = Body.selectionStart;\
			b = Body.selectionEnd;\
		}\
		function more(X) {\
			window.open(X);\
			document.getElementById("Special").selected = true;\
		}\
		function special(sChar) {\
			readValues();\
			with (Body) {\
				value = value.substring(0, a) + sChar + value.substring(b, textLength);\
				p = a + sChar.length;\
				setSelectionRange(p,p);\
				scrollTop = s;\
				focus();\
			}\
			document.getElementById("Special").selected = true;\
		}\
		function icon(iconName) {\
			readValues();\
			with (Body) {\
				value = value.substring(0, a) + "[" + iconName + "]" + value.substring(b, textLength);\
				p = a + iconName.length + 2;\
				setSelectionRange(p,p);\
				scrollTop = s;\
				focus();\
			}\
			document.getElementById("Emoticons").selected = true;\
		}\
		function tag(tagName) {\
			Open = "[" + tagName + "]";\
			Close = "[/" + tagName + "]";\
			readValues();\
			with (Body) {\
				if (a < b && value.substring(b-1, b) == " ") {b--}\
				Sel = value.substring(a, b);\
				value = value.substring(0, a) + Open + Sel + Close + value.substring(b, textLength);\
				p = (Sel) ? b + (Open+Close).length : a + Open.length;\
				setSelectionRange(p,p);\
				scrollTop = s;\
				focus();\
			}\
			document.getElementById("Colors").selected = true;\
		}\
		function quote() {\
			Sel = window.getSelection().toString();\
			if (Sel == "") {tag("quote")}\
			else {\
				readValues();\
				with (Body) {\
					while (Sel.match(/^\\s|\\s$/)) {Sel = Sel.replace(/^\\s|\\s$/,"")}\
					value = value.substring(0, a) + "[quote]" + Sel + "[/quote]" + value.substring(b, textLength);\
					p = value.indexOf("[/quote]", a + 8) + 8;\
					setSelectionRange(p,p);\
					scrollTop = s;\
					focus();\
				}\
			}\
		}\
		function url() {\
			readValues();\
			with (Body) {\
				Sel = trim(value.substring(a, b));\
				if (!Sel) {setAttribute("onKeyUp", "trap()")}\
				value = value.substring(0, a) + "[url]" + Sel + "[/url]" + value.substring(b, textLength);\
				p = (Sel) ? a + Sel.length + 11 : a + 5;\
				setSelectionRange(p,p);\
				scrollTop = s;\
				focus();\
			}\
		}\
		function trim(X) {\
			while (X.match(/^\\s|\\s$/)) {X = X.replace(/^\\s|\\s$/,"")}\
			X = X.replace(/ *((\\r\\n)+|\\n+) */g, "[/url]$1[url]");\
			var Junk = new Array(/http:\\/\\/www\\./gi, /http:\\/\\//gi, /(index|default)\\.(html|htm|shtml|php|aspx|asp|jspx|jsp)/gi);\
			if (X.match("p=") && X.match("imdb.com") && X.match("/board/")) {Junk.splice(3, 0, /&p=\\d\\d?|p=\\d\\d?&/g)}\
			if (X.match("web.archive.org")) {Junk.splice(2, 2); Junk.splice(0, 1);}\
			for (i in Junk) {X = X.replace(Junk[i], "")}\
			if (!X.match(/\\n/) && !X.match(/\\/\\S+/) && X.match(/\\/$/)) {X = X.replace(/\\/$/, "")}\
			return X;\
		}\
		function trap() {\
			Body.removeAttribute("onKeyUp");\
			readValues();\
			with (Body) {\
				if (value.substring(b, b+6) == "[/url]") {\
					c = value.substring(0, b).lastIndexOf("[url]") + 5;\
					Sel = trim(value.substring(c, b));\
					value = value.substring(0, c) + Sel + value.substring(b, textLength);\
					p = c + Sel.length + 6;\
					setSelectionRange(p,p);\
					scrollTop = s;\
					focus();\
				}\
			}\
		}\
		function search(X) {\
			Sel = window.getSelection().toString();\
			if (Sel != "") {\
				while (Sel.match(/^\\s|\\s$/)) {Sel = Sel.replace(/^\\s|\\s$/,"")}\
				var Query = Sel.replace(/\\s*(\\r\\n|\\n)\\s*/g, "$1").split(/\\r\\n|\\n/);\
				for (i in Query) {if (!Query[i].match(/\\[\\[/)) {window.open("/" + X + "?" + encodeURIComponent(Query[i]))}}\
			}\
			document.getElementById("List").selected = true;\
		}\
		function link(X) {\
			Open = "[url]" + window.location.hostname.replace("www.","") + "/" + X + "?";\
			readValues();\
			Sel = window.getSelection().toString();\
			if (Sel == "") {\
				with (Body) {\
					Sel = trimList(value.substring(a, b));\
					value = value.substring(0, a) + Open + Sel + "[/url]" + value.substring(b, textLength);\
					p = (Sel) ? a + (Open+Sel).length + 6 : a + Open.length;\
					setSelectionRange(p,p);\
					scrollTop = s;\
					focus();\
				}\
			}\
			else {\
				Sel = trimList(Sel);\
				with (Body) {\
					value = value.substring(0, a) + Open + Sel + "[/url]" + value.substring(b, textLength);\
					p = a + (Open+Sel).length - Sel.split("\\n").length + 7;\
					setSelectionRange(p,p);\
					scrollTop = s;\
					focus();\
				}\
			}\
			document.getElementById("List").selected = true;\
		}\
		function trimList(X) {\
			while (X.match(/^\\s|\\s$/)) {X = X.replace(/^\\s|\\s$/,"")}\
			X = X.replace(/\\?/g, "%3F").replace(/&/g, "%26").replace(/ *((\\r\\n)+|\\n+) */g, "$1").replace(/ *((\\r\\n)+|\\n+) */g, "[/url]$1" + Open);\
			return X;\
		}\
';}

$$("head")[0].appendChild(JS);

var M = '<INPUT type="button" class="markup" value="Quote"   onClick="quote()"          title="Block quote: [quote]...[/quote]" style="margin-left: 10px">\
         <INPUT type="button" class="markup" value="URL"     onClick="url()"            title="URL link: [url]...[/url]">\
         <INPUT type="button" class="markup" value="B"       onClick="tag(\'b\')"       title="Bold text: [b]...[/b]"    style="font-weight: bold">\
         <INPUT type="button" class="markup" value="I"       onClick="tag(\'i\')"       title="Italic text: [i]...[/i]"  style="font-style: italic; font-family: \'Courier New\'">\
         <INPUT type="button" class="markup" value="Spoiler" onClick="tag(\'spoiler\')" title="Spoiler warning: [spoiler]...[/spoiler]">\
         <INPUT type="button" class="markup" value="Pre"     onClick="tag(\'pre\')"     title="Preformatted text: [pre]...[/pre]" style="font-family: \'Courier New\', monospace">\
         <SELECT class="markup"><OPTION id="Colors">Colors</OPTION>';
for (i in C) {M += '<OPTION class="color" style="color:' + C[i] + '" onClick="tag(\'' + C[i].toLowerCase() + '\')">' + C[i] + '</OPTION>';}
M += '</SELECT> <SELECT class="markup" title="Title/name lists processing"><OPTION id="List">List</OPTION>\
      <OPTION class="list" onClick="link(\'Title\')" title="Generate title search links">L tt</OPTION>\
      <OPTION class="list" onClick="link(\'Name\')" title="Generate name search links">L nm</OPTION>\
      <OPTION class="list" onClick="search(\'Title\')" title="Search titles in new windows">S tt</OPTION>\
      <OPTION class="list" onClick="search(\'Name\')" title="Search names in new windows">S nm</OPTION>\
      </SELECT> <SELECT class="markup" title="Special characters"><OPTION id="Special">Special</OPTION>';
for (i in S) {M += '<OPTION class="list" onClick="special(this.innerHTML)" title="' + ((S[i].split("|")[1]) ? S[i].split("|")[1] : '') + '">' + S[i].split("|")[0] + '</OPTION>';}
M += '<OPTION class="list" onClick="more(\'/updates/guide/iso\')" title="at IMDb">more &raquo;</OPTION>\
      <OPTION class="list" onClick="more(\'http://chami.com/tips/internet/050798i.html\')" title=" ">all &raquo;</OPTION>\
      </SELECT> <SELECT class="markup" title="Emotion icons"><OPTION id="Emoticons">Emoticons</OPTION>';
var Help_icon = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA8AAAAPCAYAAAA71pVKAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAJlSURBVHjabFJNbxJhEF52F5BdUDTRAIokphBaEqUebIIl5WgTziVNjD3US+UiCQf7IwiXevDCAXuRXvnQJigevEk0lIBBNBIQECiQ7iIsUNYZwiaITvJk9513nvl43pERC+bZ2lpiWfYOSZIX8czzfEkUxQ+vIhFhMVY2R2I0Gs1DvV5/ZcPluqDVaqf+TCYzfptMysA+vjw8TPxDBqJcpVI9fbC5yXg8HtliBUEQiEAgIHzJ508gQfQv8uPd3W2n07n0aGeHqlarylAodKvZbDJ4Z7FYOl6v9/toNCKe7O2NyuXyizfHxy28o6CqDlp0PdvfV6AjHA6bGo0G4/f7c2azuZtMJm8MBgPRZrPxRqORyudyxs9gECrSMMvKvbU1hdQKVplMJgTHcXSlUmFAMHm9XlfB7GqKoohOp3MTirHdbpejGYa5DCKREhku6Xa7LY/H4/p0Oq2H6qcOh6MFik9HVCqVhMFguAbk3/RwOOR7PD8l1mo1BcyqwEAkmkymrtvt/jkvHswug7EwEY3kcjabvXt/fV0NTqUU5PP5Mouqt1otYNAD+J7DkSQjR0f5QqEwBtDzgcFg8HY0Gr0+73udSIygsxL8TlAwnFX8WixGnh8cDKX2/2exWEz8USqdvkulsvj0gLG0EIqV5WWz1WrdttvtSvvqKqnT6Yher0eA4sT7VEqAVn/B+37q9/sNlAfASWTsgFGr1foNMJZhroIwLMw3Bjs7yWa/FYtFJHGAJj4KYDi/ihQmAOBSX8JXmSUVsUVAD9AFnCER/Yt7jMG4MKoZmZ6RMbgPGADOZz7ijwADAAg4HZxxyNPuAAAAAElFTkSuQmCC";
for (i in I) {M += '<OPTION class="list" onMouseOver="with (document.getElementById(\'help\')) {style.top = \'\'; src = (this.innerHTML == \'[giveup]\') ? \'http://i.imdb.com/Photos/CMSIcons/emoticons/confused/giveup.gif\' : \'http://i.imdb.com/Photos/CMSIcons/emoticons/basic2/' + I[i] + '.gif\'}" onMouseOut="with (document.getElementById(\'help\')) {style.top = \'-13px\'; src = \'' + Help_icon + '\'}" onClick="icon(\'' + I[i] + '\')" title=" ">[' + I[i] + ']</OPTION>';}
M += '</SELECT> <A target="_blank" href="http://userscripts.org/scripts/show/42255" style="position: relative"><IMG src="' + Help_icon + '" id="help" title="Markup bar help" border="0" style="' + ((Firefox) ? 'position: absolute; left: 5px; top: -13px; bottom: 20px' : 'vertical-align: middle') + '"></A>';

var Preview = false;
var Pro = (window.location.hostname == "pro.imdb.com");
var WLP = window.location.pathname;
if (WLP.match("/reply/") || WLP.match("/edit/")) {if ($$("font")[((Pro)?1:2)].innerHTML.match("preview")) {Preview = true}}
else if (WLP.match("/post/")) {if ($$("u")[0]) {Preview = true}}
else {if ($$("b")[((Pro)?5:1)].innerHTML == "Preview:") {Preview = true}}

with (Markup = document.createElement("SPAN")) {innerHTML = M}
with ($N("body")) {
	with (parentNode) {
		insertBefore(Markup, getElementsByTagName("br")[0]);
		with (getElementsByTagName("a")[0]) {
			innerHTML = "markup";
			target = "_blank";
		}
	}
	setSelectionRange(0,0);
	if (!Preview) {
		focus();
		if (WLP.match("/edit/")) {
			value = value.replace(/& ?a ?m ?p ?;(?=[^\[]*\[\/url\])/g, "&").replace(/&(?=[^\[]*\[\/url\])/g, "&amp;").replace(/(\[url\][^\[]{70}) /g, "$1").replace(/&amp;(?=[^\[]*\[\/url\])/g, "&");
			setSelectionRange(0,0);
		}
	}
}

if (typeof addEventListener == "function") {
	function hotkey(event) {
		if (event.ctrlKey && event.which == 13) {
			if (event.shiftKey) {
				var Post = new Array($N("act_Reply"), $N("act_Edit"), $N("act_Post"));
				for (i in Post) {if (Post[i]) {Post[i].click(); break}}
				event.preventDefault();
			}
			else {
				$N("act_Preview").click();
			}
		}
		event.stopPropagation();
	}
	$N("body").addEventListener("keydown", hotkey, false);
	document.getElementsByName("title")[document.getElementsByName("title").length-1].addEventListener("keydown", hotkey, false);
	document.addEventListener("keydown", function(event) {
		if (event.ctrlKey && event.shiftKey) {
			$N("body").focus();
		}
	}, false);
}

})();