私は実際に解決策を見つけました。それは完璧ではなく、Mrchiefが提案したようにコードミラーの統合を検討しています。唯一の問題は、現在のソリューションでは、バックエンドに保存されて後で表示されるマークアップを編集できることです。まさにWYSIWYGです。私のエディターは、いくつかのコードフラグメントを追加したい、より優れたコンテンツ編集可能な記事の一部であることを述べておかなければなりません。
codemirrorのようなエディターを使用するのは素晴らしいことですが、保存する前にそれを取り除く必要があり、コードブロックをtextareaとして表示する必要があります(以前のRSSフレンドリーではありません)。
とにかく、ここに興味がある人は私の解決策/ハックです。
<pre>
を含む要素でラップされている限り、contenteditablesのネストされたタグなどからイベントを委任できますcontenteditable="false"
。したがって、挿入する代わりに:
<pre>some code</pre
私が挿入した:
<code contenteditable="false"><pre>code snippet here</pre></code>
次に、そのような代理人を追加しました。
var getFirstRange = function() {
var sel = rangy.getSelection();
return sel.rangeCount ? sel.getRangeAt(0) : null;
}
contenteditablediv
.delegate('pre', 'keydown', function(event) {
switch(event.keyCode) {
case 13:
var range = getFirstRange(),
added = false,
newline = document.createTextNode('\r\n');
if (range) {
range.insertNode(newline);
range.setEndAfter(newline);
range.setStartAfter(newline);
var sel = rangy.getSelection();
sel.setSingleRange(range)
added = true;
}
if (added) {
event.preventDefault();
}
break;
case 9:
// insert a tab
var range = getFirstRange(),
tab = document.createTextNode('\t');
if (range) {
range.insertNode(tab);
var sel = rangy.getSelection();
range.setEndAfter(tab);
range.setStartAfter(tab);
sel.setSingleRange(range)
}
return false;
}
}).delegate('pre', 'click', function() {
$(this).attr('contenteditable', true);
}).delegate('pre', 'blur', function() {
$(this).removeAttr('contenteditable');
});
このイベントが発生します。クリック/ぼかし削除を追加して、内側のpreタグでcontenteditableを切り替えて、これが後で保存されないようにしましたが、サーバー側で実行できます。これにより、タブキーに\ t文字を挿入し、brの代わりに\ r\nを挿入できます。