TracWiki で手軽に br マクロを入力する

「TracWiki で [[br]] を入力するのがめんどくさい」というのを聞いて、「そういえばあまり Wiki (TracWiki に限らず) であまり物理改行は使わないなぁ…」と思いつつも

Shift+Enter で [[br]] を挿入するような javascript でも仕込んでおけばいいんじゃなかろうか…とか思った。_

ので、実際に javascript を書いてみました。
いろいろ面倒なので trac/htdocs/js/wikitoolbar.js を直接パッチします。

diff --git a/trac/htdocs/js/wikitoolbar.js b/trac/htdocs/js/wikitoolbar.js
index 107e4d2..ceb534e 100644
--- a/trac/htdocs/js/wikitoolbar.js
+++ b/trac/htdocs/js/wikitoolbar.js
@@ -82,6 +82,50 @@
     });

     $(textarea).before(toolbar);
+    $(textarea).keypress(insertBreakOnShiftEnter);
+  }
+
+  function insertBreakOnShiftEnter(event) {
+    if (event.shiftKey === true && event.keyCode === 0x0d /* ENTER */) {
+      var text = "[[br]]";
+      var d = this.ownerDocument;
+      var w = d.defaultView || d.parentWindow;
+      if (w.getSelection) {
+        if (!w.opera) {
+          try {   // Google Chrome, Safari
+            d.execCommand("insertHTML", false, text);
+            return false;
+          }
+          catch (e) { }
+          try {     // Firefox
+            for (var i = 0; i < text.length; i++) {
+              var evt = d.createEvent("KeyboardEvent");
+              evt.initKeyEvent("keypress", true, true, null,
+                false, false, false, false, 0, text.charCodeAt(i));
+              this.dispatchEvent(evt);
+            }
+            return false;
+          }
+          catch (e) { }
+        }
+        else {  // Opera
+          var selection = w.getSelection();
+          var start = this.selectionStart;
+          var end = this.selectionEnd;
+          var value = this.value;
+          this.value = value.substring(0, start) + text + value.substring(end);
+          this.setSelectionRange(start + text.length, start + text.length);
+          return false;
+        }
+      }
+      else if (d.selection) {        // IE
+        var range = d.selection.createRange();
+        range.execCommand("paste", false, text);
+        range.collapse(false);
+        range.select();
+        return false;
+      }
+    }
   }

 })(jQuery);

このパッチを当てて Shift+Enter すれば [[br]] が挿入されるようになります。
また、まともに undo できるようにするために textarea.value を直接変更するのは止めて以下のような処理を行っています。

  • Google Chrome, Safari では document.execCommand("inserthtml") を利用して挿入
  • Firefox では KeyboardEvent イベントを利用して挿入
  • Internet Explorer では TextRange.execCommand("paste") を利用して挿入し、選択領域を調整
  • Opera では undo 可能にする方法が見つからなかったので textarea.value を直接変更した後 textarea.setSelectionRange() で選択領域を調整

これで少しは楽になるのではないでしょうか。