[userChrome.js] 新しいタブを現在のタブの右隣に開く

リンク先を新しいタブを開いたときに、最後尾ではなく現在のタブの右隣(連続して2つ開く場合はさらにその右隣)に開くための userChrome.js 用ユーザスクリプトである Tabs to the Right では、Firefox 本体で定義された gBrowser.addTab 関数と gBrowser.moveTabTo 関数の改造を以下のような方法で実現させている。

  1. 元の関数(つまり Function オブジェクト)を toString() で文字列化
  2. 関数内の改造したい部分の文字列を置換
  3. evalで文字列から関数を再定義する
eval(
  "gBrowser.moveTabTo = " + 
  gBrowser.moveTabTo.toString().replace(/{/, "$& if (aTab == this.mCurrentTab) this.__uc_addedTabs = 0;")
);

なるほどこれは面白いやり方だ。拡張機能によって Firefox 本体で定義された関数の動作の一部分だけを無理やり変更したいときには苦肉の策として有効である。

同じく Firefox 本体で定義された関数の動作に変更を加えたいケースで、元の関数の前後に何らかの処理を割り込ませたい場合は、以下のような手段が有効である。

  1. 元の関数を新しい関数としてコピー
  2. 元の関数を書き換え、その関数内で割り込ませる処理とともにコピーされた関数を呼び出して実行

たとえばブックマークを削除するときに確認ダイアログを表示させるようにしたければ、 BookmarksCommand.deleteBookmark 関数の前へ確認ダイアログを表示する処理を割り込ませる。

// 関数のコピー
BookmarksCommand.deleteBookmarkOriginal = BookmarksCommand.deleteBookmark;
// 関数の書き換え
BookmarksCommand.deleteBookmark = function(aSelection)
{
    // 確認ダイアログ表示
    if ( !window.confirm("Are you sure you wish to delete bookmarks?") ) return;
    // ブックマークを削除
    this.deleteBookmarksOriginal(aSelection);
};

この方法でいくと、先ほどの、新しいタブを現在のタブの右隣に開くための userChrome.js は、以下のようにも書くことができる。どちらが良いかは好みの問題であろう。

(function()
{
    getBrowser().__uc_addedTabs = 0;
    gBrowser.addTabOriginal    = gBrowser.addTab;
    gBrowser.moveTabToOriginal = gBrowser.moveTabTo;
    gBrowser.addTab = function(aURI, aReferrerURI, aCharset, aPostData, aOwner, aAllowThirdPartyFixup)
    {
        var oldTabPos = this.mCurrentTab._tPos;
        var t = this.addTabOriginal(aURI, aReferrerURI, aCharset, aPostData, aOwner, aAllowThirdPartyFixup);
        if ( aURI != "about:blank" ) {
            this.moveTabTo(t, oldTabPos + 1 + this.__uc_addedTabs++);
        }
        return t;
    };
    gBrowser.moveTabTo = function(aTab, aIndex)
    {
        if ( aTab == this.mCurrentTab ) {
            this.__uc_addedTabs = 0;
        }
        return this.moveTabToOriginal(aTab, aIndex);
    };
    gBrowser.mTabContainer.addEventListener("select", function() { gBrowser.__uc_addedTabs = 0; }, false);
})();

TOP

TOP