Whirlpool Posting

By Johnny Bravo Last update May 3, 2008 — Installed 144 times.

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

// ==UserScript==
// @name          whirlpoolPosting
// @namespace     jaromanda/GreaseMonkey
// @description   quick reply and whirlcode shortcuts v2.4
// @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 sdb(name,maxlen) {
	this.name=name;
	this.load();
}
sdb.prototype.get=function(key) {
	return (typeof this.data[key] == 'undefined') ? '' : this.data[key];
}
sdb.prototype.$add=function(key, value) {
	this.data[key]=value;
	return;
}
sdb.prototype.del=function(key) {
	if(typeof this.data[key] == 'undefined') return -1;
	delete this.data[key];
	this.save();
	return;
}
sdb.prototype.$mod=function(key, value) {
	this.data[key]=value;
	return;
}
sdb.prototype.set=function(key, value) {
	if(typeof this.data[key] == 'undefined') this.$add(key, value);
	else this.$mod(key, value);
	this.save();
	return;
}
sdb.prototype.load=function() {
	this.data=eval(GM_getValue(this.name, '({})'));
	return;
}
sdb.prototype.save=function() {
	GM_setValue(this.name, uneval(this.data));
}
function $i(id) {
	return document.getElementById(id);
}
function $e(t, a){
	var n = document.createElement(t);
	for (var b in a) if (a.hasOwnProperty(b)){
		n.setAttribute(b, a[b]);
	}
	return n;
}
function $x(p, c) {
	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 $o(p, c) {
	var i, n, r = [], x = document.evaluate(p, c || document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
	for(i = 0; n=x.snapshotItem(i); i++) r.push(n);
	return r;
}
function $a(p, c) {
	return document.evaluate(p, c || document, null, XPathResult.ANY_UNORDERED_NODE_TYPE, null).singleNodeValue;
}
var EventManager= {
	_registry: null,
	Initialise: function() {
		if (this._registry == null) {
		this._registry = [];
		EventManager.Add(window, '_unload', this.CleanUp);
	  }
	},
	Add: function(obj, type, fn, useCapture) {
		this.Initialise();
		var realType=(type=='_unload'?'unload':type);
		if (typeof obj == 'string')
			obj = $i(obj);
		if (obj == null || fn == null)
			return false;
		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 < EventManager._registry.length; i++) {
			with(EventManager._registry[i]) {
				if(type=='unload') fn();
				obj.removeEventListener(type,fn,useCapture);
			}
		}
		EventManager._registry = null;
	}
};
var replyArea=$i('body');
var noQuickQuote=false; //GM_getValue("QuickQuote", "show") == "hide";
var uWin=unsafeWindow?unsafeWindow:window;
var qqRoot=null;
var qQuote=null;
var replyURL='';
var inReply=document.location.href.indexOf('forum-reply.cfm?r=')>-1;
var inEdit=document.location.href.indexOf('forum-reply.cfm?e=')>-1;
var inThread=document.location.href.indexOf('forum-replies.cfm')>-1;
var inWiki=document.location.href.indexOf('index.cfm?a=wiki')>-1;
var inWhim=document.location.href.indexOf('whim/?action=write')>-1;
var replyNumber=0;
var threadId=0;

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' }, // looks like rubbish
	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 threadTexts=new sdb('threadTexts');

function saveText() {
	var txt=qQuote?qQuote.value:'';
	if(threadId) {
		if(txt.length) {
			threadTexts.set(threadId, escape(txt));
		}
		else {
			threadTexts.del(threadId);
			threadTexts.del('fn_'+threadId);
		}
	}
}
var buttonStack=[];
function flushStack() {
    while(buttonStack.length) {
		var xB=buttonStack.pop();
		xB.opened=false;
		if(!xB.hidden) xB.el.className='whirlyCSS';
    }
}
function clearQuote() {
    flushStack();
    qQuote.value = '';
	qQuote.setAttribute('rows', '10');
    qQuote.focus();
}
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);
	}
}
function postReply() {
    var txt=qQuote.value;
    if(txt.length && replyNumber) {
		threadTexts.set(threadId, escape(txt));
		threadTexts.set('fn_'+threadId, 'R');
		//clearQuote();
    }
    document.location = replyURL;
}
function postPreview() {
    var txt=qQuote.value;
    if(txt.length && replyNumber) {
		threadTexts.set(threadId, escape(txt));
		threadTexts.set('fn_'+threadId, 'P');
		//clearQuote();
    }
    document.location = replyURL;
}
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();
}
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') });
	var qqDiv = $e('DIV', { 'align' : 'center' });
	qqDiv = qqContain.appendChild(qqDiv);
	qQuote = $e('TEXTAREA', {
		'name' 		: 'qqText',
		'id'		: 'qqText',
		'class'		: 'textCSS',
		'cols'		: '100',
		'rows'		: '10'
	});
	qQuote.value=unescape(txt);
	qQuote=qqDiv.appendChild(qQuote);
	EventManager.Add(qQuote, "keydown", shortcutKeys, false);
	qqDiv.appendChild($e('BR'));
	var prevBtn = $e('INPUT', {
		'type'		: 'submit',
		'class'		: 'previewCSS'
	});
	prevBtn.value='Show Preview' ;
	prevBtn.accessKey ='v';
	prevBtn.addEventListener('click', postPreview, false);
	qqDiv.appendChild(prevBtn);
	var prevBtn = $e('INPUT', {
		'type'		: 'submit',
		'class'		: 'submitCSS'
	});
	prevBtn.value='Post Reply' ;
	prevBtn.accessKey ='p';
	prevBtn.addEventListener('click', postReply, false);
	qqDiv.appendChild(prevBtn);
	var clearBtn = $e('INPUT', {
		'type'		: 'reset',
		'class'		: 'clearCSS'
	});
	clearBtn.value='Clear' ;
	clearBtn.accessKey ='x';
	clearBtn.addEventListener('click', clearQuote,false);
	qqDiv.appendChild(clearBtn);
	if(inThread) {
		var toggleBtn = $e('INPUT', {
			'type'		: 'button',
			'class'		: 'toggleCSS'
		});
		toggleBtn.value='Float' ;
		toggleBtn.addEventListener('click', toggleQuote,false);
		qqDiv.appendChild(toggleBtn);
	}
    return qqContain; 
}
if(inReply && replyArea) {
    replyNumber=parseInt(document.location.search.substring(3));
	var savedText=unescape(threadTexts.get(replyNumber));
	var savedFn=threadTexts.get('fn_'+replyNumber);
    if(savedText.length) {
		threadTexts.del(replyNumber);
		threadTexts.del('fn_'+replyNumber);
        replyArea.value=savedText;
		document.body.appendChild($ec('DIV', {
			'style'		: 'width:100%;height:100%;margin:0;padding:0;position:fixed;z-index:2000;top:0;left:0;background:black;opacity:0.7;'
		}));
		var inDiv=document.body.appendChild($ec('DIV', {
			'style'		: 'position:fixed;top:0;left:0;z-index:2001;width:100%;margin:200px auto 0;background-color:transparent;'+
						  'text-align:center;fontSize:16pt;fontWeight:bold;fontFamily:verdana,helvetica,sans-serif;color:white;'
		}));
		inDiv.appendChild(document.createTextNode('Please Wait ...'));
		if(savedFn == 'P') uWin.prevbutton.click();
		else if(savedFn == 'R') uWin.postbutton.click();
	}
}
GM_addStyle([
	'.previewCSS {border:0px solid gray;color:black;background:#FFDCBF;width:150px;font:16px Arial;margin-right:2em;}',
	'.submitCSS {border:0px solid gray;color:black;background:#BFDCFF;width:150px;font:16px Arial;margin-right:2em;}',
	'.clearCSS {border:0px solid gray;color:black;background:#DAF2B3;width:150px;font:16px Arial;}',
	'.toggleCSS {border:0px solid gray;color:black;background:#bbb;width:auto;font:16px Arial;margin-left:1em;}',
	'.textCSS {border:0px solid gray; color:black; background:#e5e5e5;}',
	'.whirlyCSSopen, .whirlyCSS {border:1px outset gray;color:black;padding:0;margin:0 1px;color:#018;font-size:1em;cursor:pointer;}',
	'.whirlyCSS {background:#ddddff;}',
	'.whirlyCSS:hover {background:#eeffee;}',
	'.whirlyCSS:focus {background:#ddffdd;border-style:inset;}',
	'.whirlyCSSopen {border-style:inset;background:#eeeeff;}',
	'.whirlyCSSopen:hover {background:#ffeeee;}',
	'.whirlyCSSopen:focus {background:#ffdddd;}',
	'.whirlyCSS SPAN {color:#900;}',
	'.whirlyHiddenCSS {height:0;width:0;border:none;padding:0;margin:0;}',
	'#qqText { padding:5px; -moz-border-radius: 11px; }',
	'.qqInline { padding:0; }',
	'.qqInline #qqText { width:90%; padding: 5px; }',
	'.qqFloat { position:fixed; background:grey; border:solid black 1px; width:auto; max-height:50%; height:auto; bottom:10px;'+ 
	'left: 10%; width:80%; xright:210px; z-index:9999; padding: 10px;}',
	'.qqFloat #qqText { width:95%; margin:0 auto;}'
].join(''));
if(inThread) {
	var reply=$a('//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));
	window.addEventListener('unload', saveText, false);
	var qqloc=$i('breadcrumb_footer');
	var createdQQ=createQuote(savedText);
	if(createdQQ) {
		qqRoot = qqloc.parentNode.appendChild(createdQQ);
		var repDiv=$i('replies');
		var bar=$a('//DIV[@id="replies"]/TABLE[1]/TBODY[1]/TR/TD/DIV/SPAN[@class="bar"]');
		var reps=$o('//DIV[@id="replies"]/TABLE[1]/TBODY[1]/TR/TD[@class="bodytext"]');
		var locs=$o('//DIV[@id="replies"]/TABLE[1]/TBODY[1]/TR/TD/DIV/A[@title="a link to this specific post"]');
		var whos=$o('//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'});
			newLink.appendChild(document.createTextNode('q-quote'));
			newLink=par.appendChild(newLink);
			EventManager.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 = $a('./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);
			anch.parentNode.appendChild(newBar);
			addQuoter(anch.parentNode, anch, reps[i], whos[i]);
		});
	}
}
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 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);
	newLabel.appendChild(document.createTextNode(label));
	where.appendChild(newInput);
	where.appendChild(newLabel);
	where.appendChild($e('BR'));
	return newInput;
}
function clickConfig(event) {
	if(event) {
		event.stopPropagation();
		event.preventDefault();
	}
	var newDiv=$i('wc_config');
	if(newDiv) return;
	newDiv = $e('DIV', { 
		'style'		: 'position:fixed;left:10px;top:10px',
		'id'		: 'wc_config'
	});
	newDiv=document.body.appendChild(newDiv);
	newDiv=newDiv.appendChild($e('DIV', { 'style' : 'background-color:#ddddff;border:ridge 3px;color:#000000;'}));
	for(o in buttons) addConfigCheckbox(newDiv, 'wc_config_'+o, buttons[o].value.replace(/\-/g,''), buttons[o].hidden?false:true);
	//addConfigCheckbox(newDiv, 'wc_config_quickquote', 'Quick Quote/Reply', noQuickQuote?false:true);
	newDiv.appendChild($e('BR'));
	var inClose=newDiv.appendChild($e('INPUT'));
	inClose.type='button';
	inClose.value='CANCEL';
	EventManager.Add(inClose, 'click', function() {
		var div=$i('wc_config');
		document.body.removeChild(div);
	}, false);
	var inSubmit=newDiv.appendChild($e('INPUT'));
	inSubmit.type='button';
	inSubmit.value='ACCEPT';
	EventManager.Add(inSubmit, 'click', function() {
		var div=$i('wc_config');
		var btns=div.getElementsByTagName('INPUT');
		Array.forEach(btns, function(btn) {
			if(btn.type=='checkbox') {
				var nm=btn.id.substr(10);
				//if(nm == 'quickquote') GM_setValue('QuickQuote', btn.checked?"show":"hide"); else 
				buttons[nm].hidden=btn.checked?false:true;
			}
		});
		writeConfig();
		document.body.removeChild(div);
	}, false);
}
function cleanupWhirlcode(s) {
	var tbl=[
		'*','b',
		'/','i',
		"'",'abbr',
		'"','q',
		'^','sup',
		'\\','sub',
		'-','s',
		'#','code',
		'()','small',
		'+','h2',
		'`','h3',
		'[]','h4',
		'~','h5',
		'?','h6'
	];
	for(var i=0; i < tbl.length; i+=2) {
		var x='\\[\\'+tbl[i].substr(0,1);
		var y=new RegExp(x, 'gm');
		s=s.replace(y, "<"+tbl[i+1]+">");
		x='\\'+tbl[i].substr(-1)+'\\]';
		y=new RegExp(x, 'gm');
		s=s.replace(y, "</"+tbl[i+1]+">");
	}
	var div=$e('DIV');
	div.innerHTML=s;
	s=div.innerHTML;
	for(var i=0; i < tbl.length; i+=2) {
		var x='<'+tbl[i+1]+'>';
		var y=new RegExp(x, 'gm');
		s=s.replace(y, "["+tbl[i].substr(0,1));
		x='</'+tbl[i+1]+'>';
		y=new RegExp(x, 'gm');
		s=s.replace(y, tbl[i].substr(-1)+"]");
	}
	delete div;
	return s;
}
function clickClean(event) {
	event.stopPropagation();
	event.preventDefault();
	var tgt=edit.getTarget();
	tgt.value=cleanupWhirlcode(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();
	EventManager.Add(txtDest, 'focus', setButtons, false);
	EventManager.Add(txtDest, 'click', setButtons, false);
	EventManager.Add(txtDest, 'keyup', setButtons, false);
	var btnEl=$e('button');
	btnEl.className="whirlyCSS";
	btnEl.id='wc_config_button';
	btnEl.appendChild(document.createTextNode('\u00a9'));
	btnEl=el.appendChild(btnEl);
	EventManager.Add(btnEl,'click', clickConfig, false);
	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';
		access.appendChild(document.createTextNode(splits[1]));
		btnEl.appendChild(document.createTextNode(splits[0]));
		btnEl.appendChild(access);
		btnEl.appendChild(document.createTextNode(splits[2]));
		if(bn.hidden) {
			btnEl.className="whirlyHiddenCSS";
		}
		btnEl=el.appendChild(btnEl);
		bn.el=btnEl;
		if(o.substr(0,5) == 'whirl') {
			btnEl.title=o.substr(5)+' WhirlCode';
			EventManager.Add(btnEl,'click', clickWhirl, false);
		}
		if(o.substr(0,7) == 'makeUrl') {
			btnEl.title='Add url '+o.substr(7);
			EventManager.Add(btnEl,'click', clickUrl, false);
		}
		if(o == 'cleanupCode') {
			btnEl.title='Cleanup whirlcode';
			EventManager.Add(btnEl,'click', clickClean, false);
		}
	}
}
var textArea=$i('body');
var buttonLocation;
if(textArea) {
	var url=document.location.href;
	if(inReply){
		var p2i=$a('//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) return;//don't have a previous row ... maybe we could add one ... not now
		var tds=targetTr.getElementsByTagName('TD');
		var theIndex=1;
		if(!inReply && tds.length < 2) return;//
		if(inReply) theIndex=0;
		buttonLocation=tds[theIndex];
		buttonLocation.style.fontSize='80%';
		buttonLocation.style.textAlign='center';
	}
	else {
		var tNode=document.getElementsByTagName('BLOCKQUOTE')[0];
		if(tNode) {
			var newDiv=$e('DIV');
			buttonLocation=tNode.parentNode.insertBefore(newDiv, tNode);
			buttonLocation.style.fontSize='80%';
			newDiv.style.textAlign='center';
		}
	}
}
if(!textArea) {
	textArea=$i('f_body');
	if(textArea) {
		var tNode=$i('f_form');
		if(!tNode) return;
		tNode=tNode.parentNode;
		if(!tNode) return;
		var newDiv=$e('DIV');
		buttonLocation=tNode.appendChild(newDiv);
		buttonLocation.style.fontSize='120%';
	}
}
if(!textArea) {
	textArea=qQuote;
	if(textArea) {
		var tNode=textArea.parentNode;
		if(!tNode) return;
		var newDiv=$e('DIV');
		buttonLocation=tNode.insertBefore(newDiv,textArea);
		buttonLocation.style.fontSize='80%';
	}
}
var edit;
if(textArea && buttonLocation) {
	edit=new editObject(textArea);
	addButtons(buttonLocation, textArea);
	qQuote = textArea;
}