Home > Latest topics

Latest topics > タブキラー復活

宣伝1。日経LinuxにてLinuxの基礎?を紹介する漫画「シス管系女子」を連載させていただいています。 以下の特設サイトにて、単行本まんがでわかるLinux シス管系女子の試し読みが可能! シス管系女子って何!? - 「シス管系女子」特設サイト

宣伝2。Firefox Hacks Rebooted発売中。本書の1/3を使って、再起動不要なアドオンの作り方のテクニックや非同期処理の効率のいい書き方などを解説しています。既刊のFirefox 3 Hacks拡張機能開発チュートリアルと併せてどうぞ。

Firefox Hacks Rebooted ―Mozillaテクノロジ徹底活用テクニック
浅井 智也 池田 譲治 小山田 昌史 五味渕 大賀 下田 洋志 寺田 真 松澤 太郎
オライリージャパン

タブキラー復活 - Mar 28, 2007

Firefoxの主要機能を開発するために投じられた多くの人々の多大な努力をぶち壊しにする悪夢の拡張機能、タブキラーがFirefox 2のために帰ってきましたよ。

Firefox 2正式対応は伊達じゃない。今回のアップデートではなななななんと! Firefox 2の新機能の「最近閉じたタブをもう一度開き直す」機能をいじくり倒して、「最近閉じたウィンドウをもう一度開き直す」という機能に作り替えてみました。ああ激しく無駄な努力。

ソース見ればだいたい分かると思うけど、一応、実装の仕方を以下に説明しておく。

「閉じたタブの復元」機能を「閉じたウィンドウの復元」機能に作り替える上での鍵になるのは、nsISessionStoreのgetWindowStateメソッド(指定したウィンドウのタブの状態をシリアライズして文字列として取得する)とsetWindowStateメソッド(シリアライズされた文字列を元にウィンドウの状態を復元する)という機能だ。

「最近閉じたタブ」メニューには、そのウィンドウ内で閉じたタブの一覧が表示される。nsISessionStoreの実装を見てみたところ、閉じたタブの情報の扱いは以下のようになっていることが分かった。

  • 内部的には、「そのウィンドウ内で閉じたタブの一覧」を、ウィンドウごとに保持している。
  • ウィンドウを閉じた場合、それが最後のウィンドウでない限りは、ウィンドウの情報をすべて破棄してしまう。
  • もちろん、そのウィンドウ内で閉じられたタブの情報も、ウィンドウの情報と一緒に消えてしまう。

ウィンドウごとに履歴が別れてしまっているので、このままでは、あるウィンドウで閉じたタブを他のウィンドウで開き直すということはできない。ではどうすればいいかというということで考えたのが、以下のやり方だ。ここに、2つのウィンドウA, Bがあり、Aは単一のタブXを、Bは単一のタブYを保持していると仮定しよう(タブキラーがインストールされていても、内部的には最低一つのタブを持っていることになる)。

  1. Aを閉じる。
  2. Aを閉じる直前の処理に割り込んで、getWindowStateメソッドでウィンドウの状態を丸ごと取得する。
  3. Bに対してsetWindowStateメソッドを使用して、ABの内容を統合する。BYと、Xの複製であるX'の2つのタブが開かれた状態になる。
  4. BにおいてX'を閉じる。

これで、ウィンドウAのタブXを閉じた履歴をウィンドウBに残すことができる。

「タブを開き直す」処理を「ウィンドウを開き直す」に置き換える時も、これと同じようなことをする。

  1. Bの中で、タブを開き直す処理を実行する。
  2. Bの中で、タブX'が復元される。
  3. タブを開き直した直後の処理に割り込んで、新しいウィンドウCを開く。このウィンドウは空のタブZを保持している。
  4. Bの内容をgetWindowStateで取得する。
  5. Cに対してsetWindowStateメソッドを使用して、BCの内容を統合する。CZと、X'の複製であるX''Yの複製であるY'の3つのタブが開かれた状態になる。
  6. BにおいてX'を閉じる。
  7. CにおいてY'Zを閉じる。

これで、タブXだけを含んだウィンドウを開き直すことができる。

ただ、このままだと6と7のステップでそれぞれのウィンドウに、Y'を閉じたという履歴情報が「最近閉じたタブ」の一覧に残ってしまう。これはちょっとまずい。これらのステップでタブを閉じる時には、nsISessionStoreに履歴が残らないようにしないといけない。

nsISessionStoreを見てみると、どんなタブに対しても「最近閉じたタブ」の履歴を残すというわけではなく、履歴を残さない例外があることが分かった。その条件とは、「セッションヒストリの履歴の数が1つしかなくて、現在のページがabout:blankである」場合。要するに、新しく開かれたばかりの空っぽのタブは、閉じても履歴に残らないということである。

つまり、履歴を残さずにタブを閉じるためには、タブを「開いたばかりの空のタブ」と同じ状態に戻してから閉じればいいわけだ。それには、タブに対応しているbrowserのセッションヒストリにアクセスしてすべての履歴を削除したあと、そのタブで表示しているページをabout:blankに置き換えればよい。


if (tab.linkedBrowser.sessionHistory)
    tab.linkedBrowser.sessionHistory.PurgeHistory(
      tab.linkedBrowser.sessionHistory.count
    );
tab.linkedBrowser.contentWindow.location.replace('about:blank');

タブキラーの場合は各ウィンドウで一つだけタブを残すという前提があるので、上記のような処理は割と簡単に書けた。ウィンドウごとに複数のタブを開ける通常の状態でも、「元々そのウィンドウで開かれていたタブ」と「他のウィンドウで開かれていて、今のウィンドウの中にインポートされたタブ」とをちゃんと区別してやれば、タブをウィンドウからウィンドウへ移動するといったことも可能と思われる。というか、TBEをFirefox 2の機能を使って実装し直す場合はそういうことになりそうな感じだ。

つまり今回の試みは、ジョーク拡張機能を作り込むだけじゃあなくて、TBEのFirefox 2対応に必要な技術の勉強でもあったわけです。……と、強引なこじつけをしてみるテスト。

分類:Mozilla > 拡張機能, , , , , , , 時刻:05:34 | Comments/Trackbacks (1) | Edit

Comments/Trackbacks

no title

Tab Mix Plusでは細かい設定ができなくて困っているので
TBEのFirefox 2対応期待してます。

Commented by Ben at 2007/03/28 (Wed) 08:59:52

TrackBack ping me at


の末尾に2014年1月19日時点の日本の首相のファミリーネーム(ローマ字で回答)を繋げて下さい。例えば「noda」なら、「2007-03-28_tabkiller.trackbacknoda」です。これは機械的なトラックバックスパムを防止するための措置です。

Post a comment

writeback message: Ready to post a comment.

2014年1月19日時点の日本の首相のファミリーネーム(ひらがなで回答)

Powered by blosxom 2.0 + starter kit
Home

カテゴリ一覧

過去の記事

1999.2~2005.8

最近のつぶやき

オススメ

Mozilla Firefox ブラウザ無料ダウンロード