Firefox 3.0で、タブを閉じたとき左のタブをアクティブにする。

以前からFirefoxで現在見ているタブを閉じたときに、カレントタブが右隣のタブになることに違和感を感じていた。最近ConQueryがらみの事で少しjavascriptの知識が増えたので、タブを閉じたときに左のタブをアクティブにするコードを考えてみた。

まずはDom Inspectorでタブを閉じるボタンを探し("Show Annonymouse Content"にチェックを入れ、id=contentで検索、その下を調べる。)、右側のペインで"Objects - XBL Bindings"を選ぶと、 hrome://browser/content/tabbrowser.xml#tabbrowser-close-tab-buttonが表示された。
そこでファイル名「tabbrowser.xml」でmozillaソースコードを検索すると、「mozilla/browser/base/content/tabbrowser.xml」を見つけた。
この中で"tabbrowser-close-tab-button"を探すと、1368行目

<method name="removeCurrentTab">
  <body>
    <![CDATA[
      return this.removeTab(this.mCurrentTab);
    ]]>
  </body>
</method>

と、removeTabを呼び出していた。「name="removeTab"」で検索すると、1390行目

<method name="removeTab">
  <parameter name="aTab"/>
  <body>
    <![CDATA[
      this._browsers = null; // invalidate cache
...以下コードが続く...

となっていた。これはたぶん

this.removeTab: function(aTab) = {
...省略...

ということなのだろう。
1519行以下でcurrentIndexは現在表示しているタブの位置、indexは閉じるタブの位置、newIndexは新たに表示するタブの位置になる。

    // Find the tab to select
     var newIndex = -1;
    if (currentIndex > index)
      newIndex = currentIndex-1;
    else if (currentIndex < index)
      newIndex = currentIndex;
    else {
      if ("owner" in oldTab && oldTab.owner &&
          this.mPrefs.getBoolPref("browser.tabs.selectOwnerOnClose")) {
        for (i = 0; i < this.mTabContainer.childNodes.length; ++i) {
          tab = this.mTabContainer.childNodes[i];
          if (tab == oldTab.owner) {
            newIndex = i;
            break;
          }
        }
      }
      if (newIndex == -1)
        newIndex = (index == l - 1) ? index - 1 : index;

カレントのタブを閉じるときに時に、左隣のタブをカレントにしたいので、1526行目に以下のように「newIndex = index - 1 ;」を挿入すれば良さそうだ。

    else if (currentIndex < index)
      newIndex = currentIndex;
    else {
+     newIndex = index -1;
      if ("owner" in oldTab && oldTab.owner &&
          this.mPrefs.getBoolPref("browser.tabs.selectOwnerOnClose")) {
        for (i = 0; i < this.mTabContainer.childNodes.length; ++i) {

SCRAPBLOGに書いてある.toString()とevalを使うなら、以下のような関数を作って、

function tksBaseMoveLeftAfterRemoveCurrentTab() {
  var tmpString = 'if ("owner" in oldTab && oldTab.owner &&';
  eval(
    "gBrowser.removeTab = "
    + gBrowser.removeTab.toString().replace(tmpString, 'newIndex = index - 1;\n' + tmpString);
  );
}

window.setEventListener("load",tksBaseMoveLeftAfterRemoveCurrentTab,false);
でwindowロード時に実行すれば良い。
同様の機能を持つ拡張を検索して見るとTab Controlが既にあった。

続き