テキストエリアで、選択した部分を、任意のタグで囲むJavaScript +
Firefoxで置換後、スクロールがTOPに戻ってしまう不具合が起こらないようにしたスクリプト。
http://archiva.jp/web/javascript/getRange_in_textarea.htmlここのを元にちょろちょろ変えた。冗長っぽい部分省いてみたり。
var isIE = (navigator.appName.indexOf('Microsoft') > -1) ? 1 : 0;
function insertTag(elementId, tag) {
    var o = document.getElementById(elementId);
    var top = o.scrollTop;
    var val = o.value;
    var pos = getCursorPosition(o);
    if (pos['s'] != pos['e']) {
        o.value =
            val.slice(0, pos['s']) +
            '<'+tag+'>' + val.slice(pos['s'], pos['e']) + '</'+tag+'>' +
            val.slice(pos['e']);
        o.scrollTop = top;
        if (!isIE) { o.setSelectionRange(pos['s'], pos['s']); }
    }
    else {
        o.value =
            val.slice(0, pos['s']) +
            '<'+tag+'>' + '</'+tag+'>' +
            val.slice(pos['e']);
    }
}
function getCursorPosition(o) {
    if (isIE) {
        o.focus();
        var range = document.selection.createRange();
        var dup = range.duplicate();
        dup.moveToElementText(o);
        dup.setEndPoint('EndToEnd', range);
        return {
            s: dup.text.length - range.text.length,
            e: dup.text.length - range.text.length + range.text.length
        }
    }
    else {
        return {
            s: o.selectionStart,
            e: o.selectionEnd
        }
    }
}
insertTag(テキストエリアのエレメントID、囲むタグ)
呼ぶ時は
<button onClick="insertTag('ta', 'pre');">pre</button>
<textarea id="ta" cols="42" rows="16" name="text">hogehoge</textarea>
こんな感じ。
IE6、7、Firefox3、Opera9で試して、きちんと動いているように見える。
デモPR