Source for "Whirlpool Posting Plus"

By Johnny Bravo
Has 13 other scripts.


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

// ==UserScript==
// @name          Whirlpool Posting Plus
// @namespace     jaromanda/GreaseMonkey
// @description   quick reply and whirlcode shortcuts v2.10
// @include       http://forums.whirlpool.net.au/forum-reply*
// @include       http://forums.whirlpool.net.au/forum-replies*
// @include       http://forums.whirlpool.net.au/index.cfm?a=wiki*
// @include       http://forums.whirlpool.net.au/whim/?action=write*
// @include       http://whirlpool.net.au/forum-reply*
// @include       http://whirlpool.net.au/forum-replies*
// @include       http://whirlpool.net.au/index.cfm?a=wiki*
// @include       http://whirlpool.net.au/whim/?action=write*
// ==/UserScript==

function $i(id) { // getById
	return document.getElementById(id);
}
function $x(p, c) { // xpath unordered nodes
	var i, r = [], x = document.evaluate(p, c || document, null, XPathResult.UNORDERED_NODE_ITERATOR_TYPE, null);
	while(i=x.iterateNext()) r.push(i);
	return r;
}
function $xo(p, c) { // xpath ordered nodes
	var i, r = [], x = document.evaluate(p, c || document, null, XPathResult.ORDERED_NODE_ITERATOR_TYPE, null);
	while(i=x.iterateNext()) r.push(i);
	return r;
}
function $xf(p, c) { // xpath single first node
	return document.evaluate(p, c || document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
}
function $xa(p, c) { // xpath single any node
	return document.evaluate(p, c || document, null, XPathResult.ANY_UNORDERED_NODE_TYPE, null).singleNodeValue;
}
function $t(s) { // text node
	return document.createTextNode(s);
}
function $e(type, attributes) { // create Element
	var node = document.createElement(type);
	for (var attr in attributes) if (attributes.hasOwnProperty(attr)){
		node.setAttribute(attr, attributes[attr]);
	}
	return node;
}
function $ed(element) { // delete Element
	element.parentNode.removeChild(element);
}
function $ea(newNode, node) { // insert element after
	return node.parentNode.insertBefore(newNode, node.nextSibling);
}
function $eb(newNode, node) { // insert element before
	return node.parentNode.insertBefore(newNode, node);
}
function $ef(newNode, par) { // make element first child of par
	return par.insertBefore(newNode, par.firstChild);
}
function $el(newNode, par) { // make element last child of par
	return par.appendChild(newNode);
}
var $ev= {
	_registry: null,
	Initialise: function() {
		if (this._registry == null) {
			this._registry = [];
			$ev.Add(window, "_unload", this.CleanUp);
		}
	},
	Add: function(obj, type, fn, useCapture) {
		this.Initialise();
		var realType=(type=="_unload"?"unload":type);
		if (typeof obj == "string") obj = document.getElementById(obj);
		if (obj == null || fn == null) return false;
		if(obj.addEventListener) obj.addEventListener(realType, fn, useCapture);
		this._registry.push({obj:obj, type:type, fn:fn, useCapture:useCapture});
		return true;
	},
	CleanUp: function() {
		for (var i = 0; i < $ev._registry.length; i++) {
			with($ev._registry[i]) {
				if(type=="unload") fn();
				if(obj.removeEventListener) obj.removeEventListener(type,fn,useCapture);
			}
		}
		$ev._registry = null;
	}
};
// -- start common config --
function __config() {
	var xx=$i('__back__');
	var yy=$i('__config_back__');
	xx.style.display=xx.style.display == 'block' ? 'none' : 'block';
	yy.style.display=xx.style.display;
}
if(! $i('__config__') ) {
	$el($e('DIV', { 
		'id'		: '__back__',
		'style'		: 'position: fixed; top: 0; left: 0; z-index: 9998; width:100%; height:100%; background: black; opacity: 0.7; display:none;'
	}),document.body);
	$el($e('DIV', { 
		'id'		: '__config_back__',
		'style'		: 'position: fixed; top: 0; left: 0; z-index: 9999; width:100%; height:100%;'+
					  'background: transparent;font-size:16px; display:none;'
	}),document.body);
	$el($e('DIV', { 
		'id'		: '__config_header__',
		'style'		: 'width: 100%; text-align:center; font-size:2.6em; font-weight:bold;color: white;'
	}),$i('__config_back__'));
	$el($e('DIV', { 
		'id'		: '__config__',
		'style'		: 'width: 100%; position:fixed; z-index:10000; background: transparent;top:3em;bottom:0;'
	}), $i('__config_back__'));
	$el($e('DIV', { 'style' : 'clear:both;' }), $i('__config__'));
	$el($e('DIV', { 
		'style' : 'font-size: 0.6em; position:fixed; z-index:10000; top:5px; right: 5px; color:white: font-weight:bold; background:red;'+
				  '-moz-border-radius:8px; padding: 0 6px; cursor:pointer;',
		'id' : '__config_close__'
	}),$i('__config_header__'));
	$el($t('Greasemonkey Scripts Setup'), $i('__config_header__'));
	$el($t('X'), $i('__config_close__'));
	$ev.Add($i('__config_close__'), 'click', __config, false);
}
function _config_addBlock(s) {
	var r = $eb($e('DIV', { 
		'style' : 'width:22%; margin:0 0 10px 10px; padding: 10px 8px; border: inset 2px yellow;background:#8888dd;-moz-border-radius:9px;' +
		'float:left;'
	}),$i('__config__').lastChild);
	$el($t(s), $el($e('H2', { 'style' : 'text-align:center; margin:0 0 0.4em;' }), r));
	return r;
}
// -- end common config --
// -- start WP config common --
if(! $i('__GMWP__')) {
	var tDL=$xa('//div[@id="footer"]/DL[@class="wikilist"]');
	if(tDL) {
		var tDT=$i('gm_config');
		if(! tDT ) {
			tDT=$el($e('DT', { 'id' : 'gm_config'} ),tDL);
			$el($t('Greasemonkey'), tDT);
		}
		var tDD = $el($e('DD', { 'style': 'cursor: pointer;', id: '__GMWP__'}),tDL);
		$el($t('Configuration'),tDD);
		$ev.Add(tDD, "click", __config, false);
	}
}
// -- end WP config common --
function db(name,maxlen) {
	this.maxlen=maxlen;
	this.name=name;
	this.count=0;
	this.load();
}
db.prototype = {
	get: function(key) {
		if(this.maxlen && this.data[key]) {
			var t=this.data[key];
			delete this.data[key];
			this.data[key]=t;
		}
	  	return (typeof this.data[key] == 'undefined') ? '' : this.data[key];
	},
	$kill: function() {
		for(var o in this.data) return this.del(o);
		return -1;
	},
	$prune: function() {
		if(this.maxlen) while(this.count>=this.maxlen) this.$kill();
		this.save();
	},
	$add: function(key, value) {
		this.data[key]=value;
		this.count++;
		this.$prune();
		return;
	},
	del: function(key) {
		if(typeof this.data[key] == 'undefined') return -1;
		delete this.data[key];
		this.count--;
		this.save();
		return;
	},
	$mod: function(key, value) {
		if(this.maxlen) {
			var t=this.data[key];
			delete this.data[key];
		}
		this.data[key]=value;
		return;
	},
	set: function(key, value) {
		if(typeof this.data[key] == 'undefined') this.$add(key, value);
		else this.$mod(key, value);
		this.save();
		return;
	},
	load: function() {
		this.data=eval(GM_getValue(this.name, '({})'));
		this.count=0;
		for(o in this.data) this.count++;
		this.$prune();
		return;
	},
	save: function() {
		GM_setValue(this.name, uneval(this.data));
	}
};
var canPost = typeof $i('si_user') == 'undefined' && typeof $xa('//P[contains(@class, "binned")]') == 'undefined';
canPost = true;
var replyArea=$i('body');
var noQuickQuote=GM_getValue("QuickQuote", "show") == "hide";
var qPreview=GM_getValue('quickPreview', 'false') == 'true';
var uWin=unsafeWindow?unsafeWindow:window;
var qqRoot=null;
var qQuote=null;
var replyURL='';
var inReply=/forum-reply\.cfm\?r=/i.test(document.location.href);
var inEdit=/forum-reply\.cfm\?e=/i.test(document.location.href);
var inThread=canPost && /forum-replies\.cfm/i.test(document.location.href);
var inWiki=/index\.cfm\?a=wiki/i.test(document.location.href);
var inWhim=/whim\/\?action=write/i.test(document.location.href);
var replyNumber=0;
var threadId=0;
var cfgConcurrent = parseInt(GM_getValue('concurrent', '10'));
if(cfgConcurrent < 1) cfgConcurrent = 1;

var buttons={
	whirlBold        :{ value:'-b-old',     whirl:'*',  key:'b' },
	whirlItalic      :{ value:'-i-talic',   whirl:'/',  key:'i' },
	whirlSingleQuote :{ value:"'quo-t-e'",  whirl:"'",  key:'t' },
	whirlDoubleQuote :{ value:'"-q-uote"',  whirl:'"',  key:'q' },
	whirlQuote       :{ value:'w-h-o',      whirl:'+',  key:'h' },
	whirlSuperscript :{ value:'su-p-er',    whirl:'^',  key:'p' },
	whirlSubscript   :{ value:'sub-\\-',    whirl:'\\', key:'\\' },
	whirlStrike      :{ value:'stri-k-e',   whirl:'-',  key:'k' },
	whirlCourier     :{ value:'-c-ourier',  whirl:'#',  key:'c' },
	whirlSmall       :{ value:'s-m-all',    whirl:'()', key:'m' },
	whirlGrey        :{ value:'g-r-ey',     whirl:'`',  key:'r' },
	whirlSerif       :{ value:'-s-erif',    whirl:'~',  key:'s' },
	whirlGoogle      :{ value:'-g-oogle',   whirl:'?',  key:'g' },
	whirlEscape      :{ value:'-e-sc',      whirl:'.',  key:'e' },
	whirlWiki        :{ value:'-w-iki',     whirl:'[]', key:'w', re:/_/g, replace:' ' },
	makeUrlText      :{ value:'-l-ink',                 key:'l' },
	makeUrlHref      :{ value:'-u-rl',                  key:'u' },
	cleanupCode      :{ value:'cle-a-n',                key:'a' }
};
var whirlcode = {
	tbl:[
		'*','b',
		'/','i',
		'^','sup',
		'\\','sub',
		'-','strike',
		'#','tt',

		"'",'wcrep2',
		'"','wcrep1',
		'()','wcsml',
		'+','wcauth',
		'`','wcgrey',
		'~','wcserif',
		'?','xxgoogle',
		'[]','xxwiki'
	],
	toFakeHtml: function(s) {
		for(var i=0; i < this.tbl.length; i+=2) {
			var x='\\[\\'+this.tbl[i].substr(0,1);
			var y=new RegExp(x, 'gm');
			s=s.replace(y, "<"+this.tbl[i+1]+">");
			x='\\'+this.tbl[i].substr(-1)+'\\]';
			y=new RegExp(x, 'gm');
			s=s.replace(y, "</"+this.tbl[i+1]+">");
		}
		return s;
	},
	toWhirl: function(s) {
		for(var i=0; i < this.tbl.length; i+=2) {
			var x='<'+this.tbl[i+1]+'>';
			var y=new RegExp(x, 'gm');
			s=s.replace(y, "["+this.tbl[i].substr(0,1));
			x='</'+this.tbl[i+1]+'>';
			y=new RegExp(x, 'gm');
			s=s.replace(y, this.tbl[i].substr(-1)+"]");
		}
		return s;
	},
	clean: function(s) {
		var div=$e('DIV');
		div.innerHTML=this.toFakeHtml(s);
		var cont=false;
		do {
			cont=false;
			$xo('.//*', div).forEach(function(el) {
				if(!el.childNodes.length) {
					$ed(el);
					cont=true;
				}
				else if (el.nodeName == 'XXWIKI' && !(el.getAttribute('title'))) {
					cont=true;
					var blah=el.innerHTML.split('|');
					el.setAttribute('title', blah[0]);
					if(blah.length > 1) {
						blah.shift();
						el.innerHTML=blah.join('|');
					}
				}
			});
		} while(cont);
		s=div.innerHTML;
		delete div;
		return this.toWhirl(s);
	},
	toPreview: function(s) {
		if($i('modeht') && !$i('modeht').checked) s=s.replace(/</gim, '&lt;').replace(/>/gim, '&gt;');
		if($i('modewc') && $i('modewc').checked) {
			s=this.toFakeHtml(this.clean(s));
			s=s.replace(/<wcauth>(\d+)( .*?)<\/wcauth>/gim, '<p class="wcauth"><a href="#$1">$2</a></p>')
				.replace(/<(wc.*?)>/gim, '<span class="$1">')
				.replace(/<\/wc.*?>/gim, '</span>')
				.replace(/<xxgoogle>(.*?)<\/xxgoogle>/gim, '<a href="javascript:return false;">$1</a>')
				.replace(/<xxwiki *(title=".*?")>(.*?)<\/xxwiki>/gim, '<a href="javascript:return false;" class="wiki" $1>$2</a>');
		}
		if($i('modebr') && $i('modebr').checked) s=s.replace(/\n/gim, '<br />');
		return s;
	}
};
var threadTexts=new db('threadTexts', cfgConcurrent);

function $get(url, cb) {
  GM_xmlhttpRequest({ method: "GET", url: url, onload: function(xhr) { cb(xhr.responseText); } });
}
function saveText() {
	var txt=qQuote?qQuote.value:'';
	if(threadId) {
		if(txt.length) threadTexts.set(threadId, escape(txt));
		else threadTexts.del(threadId);
	}
}
var buttonStack=[];
function flushStack() {
    while(buttonStack.length) {
		var xB=buttonStack.pop();
		xB.opened=false;
		if(!xB.hidden) xB.el.className='whirlyCSS';
    }
}
function disableQuote() {
	qQuote.disabled = true;
	qQuote.style.backgroundColor = '#dddddd';
	qQuote.style.backgroundImage = 'url('+loaderimgsrc+')';
}
function enableQuote() {
	qQuote.disabled = false;
	qQuote.style.backgroundColor = '';
	qQuote.style.backgroundImage = 'none';
    qQuote.focus();
}
function clearQuote() {
    flushStack();
	enableQuote();
    qQuote.value = '';
	qQuote.setAttribute('rows', '10');
	threadTexts.del(threadId);
	if($i('__preview__')) setPreviewText();
}
var loaderimgsrc = [
	"data:image/gif;base64,",
	"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",
	"AAA=="
].join('');
function shortcutKeys(e){
    if (e.ctrlKey==1 && e.keyCode==13 )
		postReply();
    else if (e.ctrlKey==1 && e.keyCode==92 )
		postPreview();
    else if (e.ctrlKey==1 && e.keyCode==32)
		clearQuote();
}
function doExpand() {
	if(qQuote.scrollHeight > qQuote.clientHeight) {
		qQuote.setAttribute('rows', parseInt(qQuote.getAttribute('rows')) + 1);
		window.setTimeout(doExpand, 0);
	}
}
var replyPreview='';
function doReply(s) {
	if (s.indexOf('<div id="alert">') > -1) {
		if(s.indexOf('Penalty box') > -1) alert("You are in the Penalty box and can not post");
		else if(s.indexOf('Only registered users') > -1) alert("You need to log in to post");
		else if(s.indexOf('Permissions Error') > -1) alert("You don't have permission to post here");
		else alert("You can't post for some reason - could be temporary");
	}
	else {
		var ins=s.match(/<input .*?name=.*?>/gim).join('').match(/<input .*?hidden.*?>/gim).join('');
		var tDiv=$e('DIV', { 'style': 'display:none', 'id' : 'qqTempDiv'});
		tDiv.innerHTML=ins.replace(/id="(.*?)"/gim, 'id="xxx_$1"');
		$x('.//INPUT', tDiv).forEach(function(el) {
			if(!el.id && $i('x'+el.name)) $i('x'+el.name).value=el.value;
		});
		threadTexts.set(threadId, '[*[--]*]'); // bit of a "hack" ... means clear me out dude!
		enableQuote();
		$i('xpost2').value = (replyPreview == 'post') ? 'post' : '';
		$i('qq'+replyPreview).click();
	}
	postPreview='';
	enableQuote();
}
function postReply() {
    var txt=qQuote.value;
	disableQuote();
	replyPreview='post';
	$get(replyURL, doReply);
}
function postPreview() {
	var txt=qQuote.value;
	disableQuote();
	replyPreview='prev';
	$get(replyURL, doReply);
}
function setPreviewText() {
	$i('__preview__').innerHTML='<TD class="bodyuser">Quick Preview</TD><TD class="bodytext">'+whirlcode.toPreview(qQuote.value)+'</TD>';
}
function quickPreview() {
	var div=$i('__preview__');
	if(qPreview) {
		if(!div) div=$el($e('TR', { id: '__preview__' }), $xf('./TABLE/TBODY', $i('replies')));
		setPreviewText();
	}
	else if(div) $ed(div);
}
function setButtons(e) {
    var ta=e.currentTarget;
    var selEnd=ta.selectionEnd;
    var txt=ta.value.substring(0,selEnd);
    for(o in buttons) {
		var btn=buttons[o];
		if(btn.whirl) {
			var op='['+btn.whirl.substr(0,1);
			var cl=btn.whirl.substr(-1)+']';
			btn.opened=(txt).split(op).length>(txt).split(cl).length;
			if(!btn.hidden) btn.el.className=btn.opened?'whirlyCSSopen':'whirlyCSS';
		}
    }
	if($i('qqCnt').className != 'qqFloat') doExpand();
	if($i('__preview__')) setPreviewText();
}
function toggleQuote() {
	var qqCnt = $i('qqCnt');
	qqCnt.className = (qqCnt.className == 'qqInline') ? 'qqFloat' : 'qqInline';
	GM_setValue('qqState', qqCnt.className);
	if (qqCnt.className == 'qqFloat') { 
		qQuote.setAttribute('rows', '10');
	}
	else {
		doExpand();
	}
}
function createQuote(txt) {
	if(noQuickQuote) return null;
	var qqContain = $e('DIV', { 'id': 'qqCnt', 'class' : GM_getValue('qqState', 'qqInline') });
	$el($e('INPUT', { 'type' : 'checkbox', 'id' : 'local_qpreview' }), qqContain);
	var lab=$e('LABEL', { 'for': 'local_qpreview' });
	$el($t(' Quick preview'), lab);
	$el(lab, qqContain);

	var qqForm = $el($e('FORM', {
		'action'	: replyURL.replace(/forum-replies/, 'forum-reply'),
		'method'	: 'post',
		'name'		: 'fm',
		'id'		: 'fm'
	}), qqContain);
	var qqDiv = $el($e('DIV', { 'align' : 'center' }), qqForm);
	qQuote = $e('TEXTAREA', {
		'name' 		: 'body',
		'id'		: 'qqText',
		'class'		: 'textCSS',
		'cols'		: '100',
		'rows'		: '10'
	});
	if(txt == '[*[--]*]') txt = '';
	qQuote.value=unescape(txt);
	qQuote=$el(qQuote,qqDiv);
	$ev.Add(qQuote, "keydown", shortcutKeys, false);
	$el($e('BR'),qqDiv);
	function addSpanInput(p, n, c) {
		var span=$e('SPAN');
		$el($t(p+':'), span);
		var inp = $el($e('INPUT', 
			{ 'type' : 'checkbox', 'name' : n, 'id' : n, 'value' : 'true', 'style' : 'cursor:pointer;' }
		), span);
		if(c) inp.checked = 'checked';
		return span;
	}
	var qqFunc=$el($e('DIV', { 'id' : 'qqFunc'}), qqDiv);
	var tdiv=$e('DIV', { 'style' : 'display:none;' } );
	$el($e('INPUT', { 'type' : 'hidden', 'name' : 'post2',            'id' : 'xpost2',            'value' : '' }), tdiv);
	$el($e('INPUT', { 'type' : 'hidden', 'name' : 'form',             'id' : 'xform',             'value' : '' }), tdiv);
	$el($e('INPUT', { 'type' : 'hidden', 'name' : 'tinkle',           'id' : 'xtinkle',           'value' : '' }), tdiv);
	$el($e('INPUT', { 'type' : 'hidden', 'name' : 'poll_enabled',     'id' : 'xpoll_enabled',     'value' : '' }), tdiv);
	$el($e('INPUT', { 'type' : 'hidden', 'name' : 'poll_choice_size', 'id' : 'xpoll_choice_size', 'value' : '' }), tdiv);
	$el($e('INPUT', { 'type' : 'hidden', 'name' : 'timestart',        'id' : 'xtimestart',        'value' : '' }), tdiv);
	$el($e('INPUT', { 'type' : 'submit', 'name' : 'prev',             'id' : 'qqprev'                          }), tdiv);
	$el($e('INPUT', { 'type' : 'submit', 'name' : 'post',             'id' : 'qqpost'                          }), tdiv);
	$el(tdiv, qqFunc);
	$el(addSpanInput('Whirlcode',        'modewc', true), qqFunc);
	$el(addSpanInput('HTML',             'modeht', true), qqFunc);
	$el(addSpanInput('AutoBR',           'modebr', true), qqFunc);
	$el(addSpanInput('Preserve Spacing', 'modemo', false), qqFunc);
	$el(addSpanInput('Clickable Links',  'modewl', true), qqFunc);
	$el(addSpanInput('Auto Entities',    'modest', false), qqFunc);
	$el(addSpanInput('Spell Check',      'modesp', true), qqFunc);
	$el(addSpanInput('Watch Thread',     'modesu', false), qqFunc);
	var tBtn = $el($e('INPUT', 
		{'type' : 'button', 'class' : 'previewCSS', 'value' : 'Show Preview', 'accessKey' : 'v'}),qqDiv);
	$ev.Add(tBtn, 'click', postPreview, false);
	tBtn = $el($e('INPUT', 
		{'type' : 'button', 'class' : 'submitCSS', 'value' : 'Post Reply', 'accessKey' : 'p'}),qqDiv);
	$ev.Add(tBtn, 'click', postReply, false);
	tBtn = $el($e('INPUT', 
		{'type' : 'button', 'class' : 'clearCSS', 'value' : 'Clear', 'accessKey' : 'x'}), qqDiv);
	$ev.Add(tBtn, 'click', clearQuote, false);
	if(inThread) {
		tBtn = $el($e('INPUT', 
			{'type' : 'button', 'class' : 'toggleCSS', 'value' : 'Float', 'accessKey' : 'f'}), qqDiv);
		$ev.Add(tBtn, 'click', toggleQuote, false);
	}
    return qqContain; 
}
GM_addStyle([
	'.qpreviewCSS {width:9em;color:#000000;font:16px Arial;margin-right:2em;}',
	'.previewCSS {width:9em;color:#df5C3F;font:16px Arial;margin-right:2em;}',
	'.submitCSS {width:9em;color:#3F5CdF;font:16px Arial;margin-right:2em;}',
	'.clearCSS {width:9em;color:#5Aa233;font:16px Arial;}',
	'.toggleCSS {width:9em;font:16px Arial;margin-left:1em;}',
	'.textCSS {border:0px solid gray; color:black; background:#e5e5e5 none 50% 50% no-repeat;}',
	'.whirlyCSSopen {color:#080; outline: solid #0C0 1px;}',
	'.whirlyCSS SPAN, .whirlyCSSopen SPAN {color:#900;font-weight:bold;}',
	'.whirlyHiddenCSS {height:0;width:0;border:none;padding:0;margin:0;}',
	'.whirlyCSSopen, .whirlyCSS { padding: 1px 3px;font-size:1em;cursor:pointer; }',
	'.qqEnabled {}',
	'.qqDisabled { background-color: threedface; }',
	'#qqText { padding:5px; -moz-border-radius: 11px; }',
	'.qqInline { padding:0; }',
	'.qqInline #qqText { width:90%; padding: 5px; }',
	'.qqFloat { position:fixed; background:#cccccc; height:auto; border:solid black 1px; bottom:18px;',
		'left: 10%; width:80%; z-index:999; padding: 10px; -moz-border-radius: 11px;}',
	'.qqFloat #qqText { width:95%; margin:0 auto;}',
	'#qqFunc span { margin-left:1.3em; }'
].join(''));
if(inThread) {
	var reply=$xa('//div[@class = "foot_reply"]/a');
	if(!reply) return;
	replyURL=reply.href;
	var x=replyURL.indexOf('r=');
	if(x>-1) replyNumber=replyURL.substring(x+2);
	x=document.location.search.indexOf('t=');
	if(x>-1) threadId=parseInt(document.location.search.substring(x+2)); 
	var savedText=unescape(threadTexts.get(threadId));
	$ev.Add(window, 'unload', saveText, false);
	var qqloc=$i('breadcrumb_footer');
	var createdQQ=createQuote(savedText);
	if(createdQQ) {
		qqRoot = $el(createdQQ,qqloc.parentNode);
		var repDiv=$i('replies');
		var bar=$xa('//DIV[@id="replies"]/TABLE[1]/TBODY[1]/TR/TD/DIV/SPAN[@class="bar"]');
		var reps=$xo('//DIV[@id="replies"]/TABLE[1]/TBODY[1]/TR/TD[@class="bodytext"]');
		var locs=$xo('//DIV[@id="replies"]/TABLE[1]/TBODY[1]/TR/TD/DIV/A[@title="a link to this specific post"]');
		var whos=$xo('//DIV[@id="replies"]/TABLE[1]/TBODY[1]/TR/TD/DIV/A/SPAN[@class="bu_name"]');
		function addQuoter(par, lnk, post, who) {
			var newLink=$e('BUTTON', {'style': 'color:#777; font-size:inherit; font-family:inherit; ' +
										'background-color: inherit; border:none; cursor:pointer'});
			$el($t('q-quote'), newLink);
			newLink=$el(newLink, par);
			$ev.Add(newLink, 'click', function() {
				var e=arguments[0];
				e.preventDefault();
				e.stopPropagation();
				var sel=window.getSelection();
				var txt=sel.toString();
				if(txt.length == 0) {
				sel.selectAllChildren(post);
				}
				txt=sel.toString();

				var wName=who.firstChild.nodeValue;
				var wLink=who.parentNode.getAttribute('href');
				var pLink=lnk.getAttribute('href');

				var ttxt = $xa('./TD[1]/A[2]',post.parentNode).name.substr(1);

				var qt=[
					'[+'+ttxt+' '+wName+' writes...+]',
					'["'+txt+'"]',
					''
				].join('\n');
				qQuote.value+=qt;
				qQuote.focus();
			}, false);
		}
		locs.forEach(function(anch, i) {
			var newBar=bar.cloneNode(bar, true);
			$el(newBar, anch.parentNode);
			addQuoter(anch.parentNode, anch, reps[i], whos[i]);
		});
		$i('local_qpreview').checked = qPreview;
		$ev.Add($i('local_qpreview'), 'click', 
			function() { qPreview=$i('local_qpreview').checked; quickPreview();}, false);
		$ev.Add($i('modewc'), 'click', quickPreview, false);
		$ev.Add($i('modeht'), 'click', quickPreview, false);
		$ev.Add($i('modebr'), 'click', quickPreview, false);
		$ev.Add($i('modemo'), 'click', quickPreview, false);
		$ev.Add($i('modewl'), 'click', quickPreview, false);
		quickPreview();
	}
}
var DefaultUrlPrompt='Click here ...';

function editObject(tgt) {
	this.tgt=tgt;
	this.text=null;
	this.obj=null;
}
editObject.prototype.getTarget=function() {
	return this.tgt;
}
editObject.prototype.getSelectedText=function() {
	this.text=null;
	this.obj=null;
	if (window.getSelection) {
		this.text=(window.getSelection()).toString();
	}
	else if (document.getSelection) {
		this.text=(document.getSelection()).toString();
	}
	if(this.text.length==0) {
		var text=null;
		var obj=null;
		try {
			$x('.//textarea | .//input[@type="text" or not(@type)]').forEach(function(el) {
				if(el.ownerDocument === document || el.id=='qqText' || el.id == 'body') {
					if(!(el.form && el.form.style && el.form.style.display == 'none')) {
						if(0<(el.selectionEnd-el.selectionStart)) {
							obj=el;
							text=el.value.substring(el.selectionStart,el.selectionEnd);
							throw('ok');
						}
					}
				}
			});
		}
		catch(err) { this.obj = obj; this.text=text;}
	}	
	return this.text;
}
editObject.prototype.addReplaceSelectedText=function(s) {
	var scrollTop=this.tgt.scrollTop;
	var scrollLeft=this.tgt.scrollLeft;
	var before;
	var after;
	var caretStart;
	var caretEnd;
	if(this.obj == this.tgt) { // src and destination element are the same - we replace
		caretStart=this.tgt.selectionStart;
		caretEnd=caretStart+s.length;
	} else {
		caretEnd=this.tgt.selectionEnd+s.length;
		caretStart=caretEnd;
	}
	before=(this.tgt.value).substring(0,this.tgt.selectionStart);
	after=(this.tgt.value).substring(this.tgt.selectionEnd);
	this.tgt.value=before+s+after;
	this.tgt.setSelectionRange(caretStart, caretEnd);
	this.tgt.focus();
	this.tgt.scrollTop=scrollTop;
	this.tgt.scrollLeft=scrollLeft;
}
function clickClean(event) {
	event.stopPropagation();
	event.preventDefault();
	var tgt=edit.getTarget();
	tgt.value=whirlcode.clean(tgt.value);
	flushStack();
	tgt.focus();
}
function clickWhirl(event) {
	var bId;
	event.stopPropagation();
	event.preventDefault();
	bId=event.currentTarget.id.substr(3);
	if(event.which==3)
	  return(clickConfig(event));
	var bObj=buttons[bId];
	var text=edit.getSelectedText();
	var pre='['+bObj.whirl.substr(0,1);
	var post=bObj.whirl.substr(-1)+']';
	if(text.length) {
		if(bObj.re && bObj.replace) {
			var tt=text.split('|');
			tt[0]=tt[0].replace(bObj.re, bObj.replace);
			text=tt.join('|');
		}
		edit.addReplaceSelectedText(pre+text+post);
	} else {
		if(!bObj.opened) {
			buttonStack.push(bObj);
		}
		else if(bObj.opened && buttonStack.length>1) {
			var prePost='';
			var xB=buttonStack.pop();
			while(xB && xB != bObj) {
				prePost+=xB.whirl.substr(-1)+']';
				xB.opened=false;
				xB=buttonStack.pop();
			}
			post=prePost+post;
		}
		else buttonStack.pop();
		edit.addReplaceSelectedText(bObj.opened?post:pre);
	}
}
function clickUrl(event) {
	var bId;
	event.stopPropagation();
	event.preventDefault();
	bId=event.currentTarget.id.substr(3);
	if(event.which==3)
		return(clickConfig(event));
	var bObj=buttons[bId];
	var promptText=bId.substr(7);
	var url=edit.getSelectedText();
	var pre='<a href="';
	var mid='">';
	var post='</a>';
	var cutPos=-1;
	if(!url) {
		var textArea=$i('body');
		if(!textArea)textArea=$i('f_body');
		if(!textArea)textArea=qQuote;
		if(textArea && textArea.setSelectionRange) {
			textArea.focus();
			var caret=textArea.selectionStart;
			var txt=textArea.value;
			var c=txt.substr(caret, 1);
			if(c>' ') {
				var start=caret;
				var end=caret;
				while(start>-1 && txt.substr(--start,1)>' ');
				start++;
				while(end<txt.length && txt.substr(++end,1)>' ');
				url=txt.substring(start,end);
				textArea.setSelectionRange(start, end+1);
			}
		}
	}
	if(!url) {
		var clean=textArea.value.replace(/\n/gm,' ');
		var sp=clean.split(' ');
		if(sp.length) {
			var indx=sp.length-1;
			var check=sp[indx].toLowerCase();
			if(!check.length)
			check=sp[--indx].toLowerCase();
			if(check.indexOf('http://') == 0 || check.indexOf('https://') == 0 || check.indexOf('ftp://') == 0) {
				url=sp[indx];
				cutPos=textArea.value.lastIndexOf(url);
			}
		}
	}
	if(url.length) {
		var text;
		if(promptText=='Text')
		text=window.prompt('Enter desription for this link', DefaultUrlPrompt);
		else if(promptText=='Href') {
			text=url;
			url='';
			url=window.prompt('Enter url', 'http://');
		}
		if(text.length && url.length) {
			if(cutPos >= 0) textArea.value=textArea.value.substr(0, cutPos);
			edit.addReplaceSelectedText(pre+url+mid+text+post);
		}
	}
}
function readConfig() {
	var config=GM_getValue('hiddenButtons', '');
	if(config.length) {
		var configArray=config.split(':');
		configArray.forEach(function(x) { if(buttons[x]) buttons[x].hidden=true; });
	}
}
function addButtons(el, txtDest) {
	readConfig();
	$ev.Add(txtDest, 'focus', setButtons, false);
	$ev.Add(txtDest, 'click', setButtons, false);
	$ev.Add(txtDest, 'keyup', setButtons, false);
	var btnEl;
	for(var o in buttons) {
		var bn=buttons[o];
		bn.opened=false; // flag for when no text selected
		btnEl=$e('button');
		btnEl.id='wc_'+o;
		btnEl.accessKey=bn.key;
		btnEl.className="whirlyCSS";
		var splits=bn.value.split('-');
		var access=$e('SPAN');
		access.style.color='#aa3333';
		$el($t(splits[1]), access);
		$el($t(splits[0]), btnEl);
		$el(access, btnEl);
		$el($t(splits[2]), btnEl);
		if(bn.hidden) {
			btnEl.className="whirlyHiddenCSS";
		}
		btnEl=$el(btnEl, el);
		bn.el=btnEl;
		if(o.substr(0,5) == 'whirl') {
			btnEl.title=o.substr(5)+' WhirlCode';
			$ev.Add(btnEl,'click', clickWhirl, false);
		}
		else if(o.substr(0,7) == 'makeUrl') {
			btnEl.title='Add url '+o.substr(7);
			$ev.Add(btnEl,'click', clickUrl, false);
		}
		else if(o == 'cleanupCode') {
			btnEl.title='Cleanup whirlcode';
			$ev.Add(btnEl,'click', clickClean, false);
		}
	}
}
var textArea=$i('body');
var buttonLocation;
if(textArea) {
	if(inReply || inEdit){
		var p2i=$xa('//input[@name="post2"]');
		if(p2i) {
			if(window.post2input) {
				window.post2input=p2i;
				p2i.id='post2';
			}
		}
	}
	if(!inWhim){
		var targetTr=textArea.parentNode.parentNode.previousSibling;
		while(targetTr && targetTr.nodeName!='TR') targetTr=targetTr.previousSibling;
		if(targetTr) {
			if(inReply || inEdit) buttonLocation = $xf('.//TD', targetTr);
			else buttonLocation = $xo('.//TD[2]', targetTr);
		}
	}
	else {
		var tNode=$xf('//BLOCKQUOTE');
		if(tNode) {
			var newDiv=$e('DIV');
			buttonLocation=$eb(newDiv, tNode);
		}
	}
	if(buttonLocation) {
		buttonLocation.style.fontSize='80%';
		buttonLocation.style.textAlign='center';
	}
}
if(!textArea) {
	textArea=$i('f_body');
	if(textArea) {
		var tNode=$i('f_form');
		if(tNode) {
			tNode=tNode.parentNode;
			if(tNode) {
				var newDiv=$e('DIV');
				buttonLocation=$el(newDiv, tNode);
				buttonLocation.style.fontSize='120%';
			}
		}
	}
}
if(!textArea) {
	textArea=qQuote;
	if(textArea) {
		var tNode=textArea.parentNode;
		if(tNode) {
			var newDiv=$e('DIV');
			buttonLocation=$eb(newDiv,textArea);
			buttonLocation.style.fontSize='80%';
		}
	}
}
var edit;
if(textArea && buttonLocation) {
	edit=new editObject(textArea);
	addButtons(buttonLocation, textArea);
	qQuote = textArea;
}
{
	function writeConfig() {
		var config='';
		for(o in buttons) {
			var btn=$i('wc_'+o);
			if(btn) btn.className='whirlyCSS';
			if(buttons[o].hidden) {
				if(btn) btn.className='whirlyHiddenCSS';
				config+=(config.length?':':'')+o;
			}
		}
		GM_setValue('hiddenButtons', config);
	}
	function addConfigCheckbox(where, id, label, state) {
		var newInput=$e('INPUT', {'id':id,'type':'checkbox'});
		newInput.checked=state;
		var newLabel=$e('LABEL');
		newLabel.setAttribute('for',id);
		$el($t(label), newLabel);
		$el(newInput, where);
		$el(newLabel, where);
		$el($e('BR'), where);
		if(id.substr(10) == 'quickquote')
			$ev.Add(newInput, 'click', function() { GM_setValue('QuickQuote', newInput.checked?"show":"hide"); }, false);
		else
			$ev.Add(newInput, 'click', function() { buttons[id.substr(10)].hidden=newInput.checked?false:true; writeConfig();}, false);
		return newInput;
	}
	var tCfg=_config_addBlock('Whirlpool Posting (Whirlcodes)');
	for(o in buttons) addConfigCheckbox(tCfg, 'wc_config_'+o, buttons[o].value.replace(/\-/g,''), buttons[o].hidden?false:true);
	addConfigCheckbox(tCfg, 'wc_config_quickquote', 'Quick Quote/Reply', noQuickQuote?false:true);

	tCfg=_config_addBlock('Whirlpool Posting (General)');
	$el($e("BR"), tCfg);
	$el($e("BR"), tCfg);
	$el($e('INPUT', { 'type' : 'checkbox', 'id' : 'wpost_qpreview' }), tCfg);
	$i('wpost_qpreview').checked = qPreview;
	var lab=$e('LABEL', { 'for': 'wpost_qpreview' });
	$el($t(' Quick preview'), lab);
	$el(lab, tCfg);
	$el($e("BR"), tCfg);
	$el($e("BR"), tCfg);
	$el($e('INPUT', { 'type' : 'text', 'id' : 'wpost_con', 'value' : cfgConcurrent.toString() }), tCfg);
	lab=$e('LABEL', { 'for': 'wpost_con' });
	$el($t(' Concurrent threads'), lab);
	$el(lab, tCfg);
	$el($e("BR"), tCfg);
	$el($e("BR"), tCfg);
	$el($e('INPUT', { 'type' : 'button', 'id' : 'wpost_clrall', 'value' : 'Clear ALL Saved Text' }), tCfg);
	$el($e("BR"), tCfg);
	$ev.Add($i('wpost_con'), 'blur', 
		function() { GM_setValue('concurrent', parseInt($i('wpost_con').value).toString()); }, false);
	$ev.Add($i('wpost_clrall'), 'click', 
		function() { GM_setValue('threadTexts', '({})'); threadTexts.load(); }, false);
	$ev.Add($i('wpost_qpreview'), 'click', 
		function() { qPreview=$i('wpost_qpreview').checked; GM_setValue('quickPreview', qPreview.toString()); quickPreview();}, false);
}