userChrome.jsが面白い

以前、このはてなダイアリーじゃないところで、Firefoxで「コンテンツエリアでミドルクリックしたら今見てるタブを閉じる」とかいう、かなり誰も支持しないような操作法を実現するためのTipsを書いたりしてたけど、エクステンションを作るような知識もなく、browser.js内のcontentAreaClickを直接いじって…という感じでどうにかしていた。けどFirefoxをアップデートしたらそのいじった箇所も上書きされてしまうわけで、また書いて.jarファイルに圧縮して、とかいうのがウザくてやめた。

でも実際、Livedoor Readerとかでピン立て→一気に開く、とかやってると、凄い勢いでタブを閉じまくりたい時がある。「タブ上でミドルクリック」はデフォだけど、タブのところまでマウスを持っていくのが面倒くさい。ミドルクリックでのスクロールやジェスチャなんかを使う人はこの方法は論外だけど、使わない人は「コンテンツエリアでミドルクリックでタブを閉じる」って、いいと思うんだけどなぁ。

とか思っていたら、userChrome.jsなんて物があったのか。Firefoxの挙動自体をかなり自由に決めれる感じだ。早速これで再チャレンジしてみた。

最初は、window.contentAreaClickをオーバーライドして拡張して…なんて思っていて、こちらを参考にしたり、applyとかcallとかやってみたけど、どうもネイティブのwindow.contentAreaClickでの条件分岐を生かす書き方がわからなかった。targetがlinkNodeなのかとか、そういう判定を生かしつつ、“linkNodeとかじゃない場合”の処理を追加する方法がわからない。

なので、window.middleMousePasteを悪用することにした。middleMousePasteは、ミドルクリックをするとクリップボード内の文字列をURLとして開く機能なのだけど、はっきり言ってマジ要らないので普段はOFFにしてある。だけどこれをabout:configでmiddlemouse.contentLoadURL=trueにして、わざわざONにしておき、middleMousePasteをタブ閉じのための処理にごっそり書き換えてみた。

(function MouseEvents(){
window.middleMousePaste = function(event){
  if(event.target.nodeName=="xul:tab" || event.target.localName=="tab"){
    gBrowser.removeTab(event.target);
  }else{
    gBrowser.removeTab(gBrowser.selectedTab);
  }
  event.stopPropagation();
  return false;
}
})();

return falseが要るのかどうかはよくわからないけど、これで理想の動作になった!Tab Mix Plusを愛用しているけど、この拡張はmiddlemouse.contentLoadURL=trueの場合はタブ上での「ミドルクリックで閉じる」の処理を行わない。だからタブ上での動作も自前で書く必要がある。今回はシンプルにと思ってこの程度にしたけど、閉じた後に右のタブに移るのか左のタブに移るのか?みたいなこと書くならまた大変そうだな…。