This is a good little bit of grooviness. We've had it over at the 1.1.x den of iniquity for ages and it works very well. Does screw up in older versions of IE (haven't tried it on the latest) but who cares?*
What it does is split BBC tags for you. If you quote a post and want it split into smaller quotes, you just put your cursor where you want it to split and hit Ctrl+left-click. Instant split quotes, with the right starting and end tags.
Also works on code tags or any others. Not sure how it will play with SCE (haven't tried it yet). The bloke who wrote the code is long gone, but license is http://opensource.org/licenses/Zlib so it shouldn't present problems.
Code is this:// Code by author: Aziz
// License: zlib/libpng
/* Functions for the "Split Quotes" feature: */
function COEM_enableSplitting(checkbox)
{
if (!window.$) return;
var textarea = $('#postmodify textarea.editor');
var handleEvent = COEM_enableSplitting.handler;
var un_bind = checkbox.checked?'bind':'unbind';
textarea[un_bind]('keyup', handleEvent)
[un_bind]('click', handleEvent);
}
COEM_enableSplitting.handler = function handleEvent(e) {
e = e || window.event;
if (e.keyCode == 13 && e.shiftKey || e.ctrlKey && e.button == 0)
COEM_splitTags();
}
function COEM_parseTags(text, endPos)
{ // [ name attrs | /name ]
var rx = /\[(?:([a-z]+)([^\]]*)|(\/[a-z]+))\]/gi;
var tagStack = [];
text = text.slice(0, endPos); // "m.index < endPos" doesn't seem to work.
while ((m = rx.exec(text)) /*&& m.index < endPos*/)
if (m[3]) // [/tagName]
tagStack.pop()
else
tagStack.push({"name":m[1], "attributes":m[2]}); // [tagName]
return tagStack;
}
function COEM_splitTags()
{ // Splits tags at the current cursor position.
var form = document.getElementById("postmodify");
var textarea = form.elements.namedItem("message");
var string = textarea.value;
var endPos = Math.min(textarea.selectionStart, string.length)
var tagStack = COEM_parseTags(string, endPos);
if (tagStack.length == 0)
return;
var tagText = "";
// Traverse in reverse and append closing tags.
for (var i = tagStack.length-1; i >= 0; i--)
tagText += '[/' + tagStack[i].name + "]\n";
var newCaretPos = tagText.length + tagStack.length;
for (var i = 0; i < tagStack.length; i++)
if (tag = tagStack[i])
tagText += '\n[' + tag.name + tag.attributes + "]";
COEM_replaceText(tagText, newCaretPos, textarea);
return false;
}
function COEM_replaceText(text, textCaretPos, textarea)
{
function setCaretToPos(input, pos) {
input.setSelectionRange(pos, pos);
}
function getSelectionStart(o) {
if (o.createTextRange) {
var r = document.selection.createRange().duplicate()
r.moveEnd('character', o.value.length)
return (r.text == '') ? o.value.length : o.value.lastIndexOf(r.text);
}
return o.selectionStart
}
// Attempt to create a text range (IE).
if (typeof(textarea.caretPos) != "undefined" && textarea.createTextRange)
{
var caretPos = textarea.caretPos;
var selStart = getSelectionStart(textarea); //textarea.selectionStart;
caretPos.text = caretPos.text.slice(-1) == ' ' ? text + ' ' : text;
setCaretToPos(textarea, selStart + textCaretPos);
}
// Mozilla text range replace.
else if (typeof(textarea.selectionStart) != "undefined")
{
var selStart = textarea.selectionStart;
var begin = textarea.value.substr(0, selStart);
var end = textarea.value.substr(textarea.selectionEnd);
var scrollPos = textarea.scrollTop;
textarea.value = begin + text + end;
if (textarea.setSelectionRange)
{
textarea.focus();
var newCaretPos = begin.length + textCaretPos - 1;
textarea.setSelectionRange(newCaretPos, newCaretPos);
}
textarea.scrollTop = scrollPos;
}
// Just put it on the end.
else
{
textarea.value += text;
textarea.focus(textarea.value.length - 1);
}
}
/* End of functions for the "Split Quotes" feature: */
PS: There's also another handy little one for embdding videos on the page. The good thing about that one is that it starts with just a preview image, so there's no Flash overload if people embed a stack of vids on the one page. The Flash is only loaded for the videos you actually click to play.
*Just tested it in IE9. Doesn't work. Aziz hated IE and couldn't be bothered debugging for it.
Could be made to work in IE, if someone was up for it.