FirefoxのセッションストアAPIから、開いているタブのタイトルを得る


Firefoxって、特に古いAPIまわりは、かなりドキュメント雑ですね。嫌になりますね。

Firefoxアドオン作ってます

大量のタブやらウィンドウを開くのが趣味な人には便利かもしれないアドオン作ってます。
もともと、小さいディスプレイでもタブを別のウィンドウに移動する動作をやりやすくするために作ったのですが。いろいろ開きすぎて「あれ? あのタブどこだっけ?」って時にも便利です。
https://addons.mozilla.org/ja/firefox/addon/move-to-window/
https://github.com/gyu-don/move-to-window

で。このアドオンのために、各タブのタイトルを得る必要があるのですが。起動時に前回のセッションを復元する設定にしている場合、起動した後は、前回のセッションが残ってはいるものの、ページ自体の読み込みはまだされていません。タブを切り替えた時点で、読み込みが始まります。
(たしか、大昔のFirefoxは、起動時に全タブ再読み込みがかかったけれど、それじゃ重いよねってなったのか、いつの間にか、そういう挙動になりました)

そうすると、それっぽく、タブのAPIを叩いてみても、ページのタイトルを取得できません。(まだ読み込みを初めてすらいないわけですから)
けれど、タブバーにはタイトルが表示されているので、タイトルを得る方法はあるはずだ、と調べてたら、セッションストアに行き着きました。

古臭いAPI叩く準備

昔のドキュメントではComponents.Class[...]とかComponents.Interfaceとか出てきますけど。最近のは、それ使えません。次のように書いて、Components.ClassCcに、Components.InterfaceCiに読み替えます。

CcとCiを使う
var { Cc, Ci } = require('chrome');

SessionStoreのAPIを得る

SessionStoreのAPIを得る
var sessionstore = Cc["@mozilla.org/browser/sessionstore;1"]
                      .getService(Ci.nsISessionStore);

で、使い方のドキュメントがこちら
https://developer.mozilla.org/ja/docs/XPCOM_Interface_Reference/nsISessionStore

うわ、めっちゃ雑。どんな引数渡したらどんなデータが返ってくるか、全然イメージつかへん・・・・

どんなデータが返ってくるのか

プロファイルのディレクトリを開いて下さい。
そこに、sessionstore-backupsってディレクトリがあると思います。
そこに、previous.jsがあると思います。
このJSON形式が、セッションストアの全貌のようです。

このJSONをgetBrowserState(), getWindowState(aWindow), getTabState(aTab)で拾えます。JSON.parseなどに食わせましょう。
getBrowserState()だけ知ってれば、いいっちゃいいんですが。指定したウィンドウだけ、あるいは指定したタブだけのJSONが欲しい場合、getWindowState(aWindow), getTabState(aTab)が必要になります。

ちなみに、引数に指定するウィンドウやタブは、例えば次のようにして得られます。

ウィンドウやタブを得る
// 低レベルAPI。高レベルAPIと比べて互換性のない変更が将来起こりやすいとされている。
var Window = require("sdk/window/utils");
var Tabs = require("sdk/tabs/utils");

var idomactivewindow = Window.getMostRecentBrowserWindow();  // アクティブなウィンドウ
var idomwindows = Window.windows("navigator:browser");  // ウィンドウ全部
idomwindows.forEach(function(win){
  // winがウィンドウ
  var activetab = Tabs.getActiveTab(win);  // ウィンドウ内のアクティブなタブ
  var tabs = Tabs.getTabs(win);  // ウィンドウ内のタブ全部
}

タブのタイトルを得る

JSONを変数jsonに読み込んだ、と仮定して話を進めます。
json.windows[windowIdx].tabs[tabIdx].entries のリストには、各タブの履歴(戻る・進む)が保持されています。json.windows[windowIdx].tabs[tabIdx].index が、履歴の中のどこにいるかを示すようですが、どういう経緯かしらないですが、このindexは1はじまりになっています。なので、現在のページは
json.windows[windowIdx].tabs[tabIdx].entries[json.windows[windowIdx].tabs[tabIdx].index - 1]
となります。
タイトルは、後ろに.titleとつけるだけです。すなわち
json.windows[windowIdx].tabs[tabIdx].entries[json.windows[windowIdx].tabs[tabIdx].index - 1].title
やっと、タイトルが得られました。

まとめ

Firefoxアドオン作りは、Mozilla公式のよくわからないドキュメントとグーグル検索とトライアンドエラーでなんとかやりたいことをやる方法を見つける苦行の連続です。
みなさん、よいFirefoxライフを!