Hatena::Groupmoz-addon

hogezilla RSSフィード

当ページに書かれているコードは、修正BSDライセンスのもと、再頒布して頂いて構いません。

 | 

2011-04-27

Firefox4 のタブグループとタブ

23:22 | はてなブックマーク - Firefox4 のタブグループとタブ - hogezilla

昨日のエントリが思いの外ブックマークされて、少しいい気になっているのである。

ということで、パノラマ(タブグループ)関連で少し書こうと思う。

Firefox4 からタブ・グループの概念が導入されたわけだが、扱いが少し面倒。

タブの種類とグループ

グループ的なもので考えるとタブは3つに大別できる。

普通のタブ
一つのグループに属す。アクティブなグループ内のタブのみが、タブバーに表示される。
アプリタブ
ピン止めされたタブ。グループに属さない。アイコンだけのタブとなり常にタブバーに表示される。
孤立タブ
グループに属さない孤立したタブ。(パノラマビューからタブをドラッグ&ドロップでグループ外へドロップすると作れる)

JavaScriptコードからタブ・リストを得る

アプリタブ

アプリタブのリストを得るコードはFirefox内には存在しない。大変困ったことに。なので、自分で定義する必要がある。

function getAppTabs () {
  var appTabs = [];
  for (let [, tab] in Iterator(Array.slice(gBrowser.mTabs))) {
    if (!tab.pinned)
      return appTabs;

    appTabs.push(tab);
  }
  return appTabs;
}

タブがピン止めされているかどうかは、tab.pinnedで判定できる。また、アプリタブは必ずタブノードリストの先頭にあるので上記コードで得られる。

タブバーに表示されているタブ

これは簡単。

gBrowser.visibleTabs

でOK.ただし、アプリタブも取ってくるので、不要なら排除する必要がある。

他のグループのタブ

面倒。

まず第一に、パノラマのビューがロードされている必要がある。Firefox起動時にはパノラマのビューはロードされていないのでグループへのアクセスができない。

ユーザがパノラマを表示すればロードされ、DOMイベントが発行されるので、それを拾ってからでも遅くない拡張機能ならともかく、あらかじめリストを取っておきたいなどの場合は大変困ったことに、まずロードさせることから始めなければならない。別にビューを表示させたいわけではないのにロードしなければならいないというこの設計には何とも腹立たしい限りなのである。

幸い、コールバック関数を引数にロードさせるコードは存在するので、これを仕方なく使用する。

TabView._initFrame(function (){
  var win = TabView._window;
  for (let [, group] in Iterator(win.GroupItems.groupItems) {
    let title = group.getTitle(); // グループのタイトルを得る
    let tabItems = group.getChildren(); // グループに属するタブアイテムオブジェクト(要素じゃないよ)の配列を得る
    for (let [, tabItem] in Iterator(tabItems)) {
      tabItem.tab; // tab要素
      tabItem.tab.linkedBrowser; // browser要素
      tabItem.url; // タブのURL
      tabItem.tab.image; // アイコンURL
      tabItem.parent; // グループのオブジェクトへの参照
    }
  }
});

TabView._initFrame()はパノラマのウィンドウがロードされていなkれば、ロードし、引数のコールバック関数を実行する。また、既にロードされていれば、コーロバック関数を実行するのみとなる。タブグループにアクセスしたい場合は常にこれを使うと良いと思う。

また、ロードすると、アプリタブでなければ、tab要素にtab._tabViewTabItemプロパティが付加され、tabItemを参照できるようになる。

孤立タブ

上記と同様に、パノラマのロードが必要

TabView._initFrame(function() {
  var win = TabView._window;
  for (let [, tabItem] in Iterator(win.GroupItems.getOrphanedTabs()) {
      tabItem.tab; // tab要素
      tabItem.url; // タブのURL
      tabItem.tab.image; // アイコンURL
      tabItem.parent; // => null グループに属していないからnull
  }
});

追記

id:tuto0621 さんがブクマコメントで

グループ番号が取れなくてかなり不便しているので期待。

と書いているので捕捉をば。

「他のグループのタブ」の項のコードでgroupを取得しているが、group.idでグループのIDを得ることができる。これの事を言っているのかな?

tuto0621tuto06212011/05/02 08:21それです!ありがとうございます。
後はAdd-on SDK からアクセスする方法を調べます。

 |