Firefox拡張入門第3回(全てのタブからはてダのリンクを作る)

それでは実際にFirefox拡張を作ってみましょう。
全てのタブの、アドレスとタイトルを取得して、はてなダイアリーのリンクにするサイドバー拡張を作ります。

http://eva-lu-ator.net/~gemma/geocities/matchfox/Clipboard11.png

タブの情報は、メインウィンドウのwindow.gBrowser変数に入っています。タブブラウザ用コード - MDC
さて、サイドバーとメインウィンドウとではwindowが違います。

  • 要素
    • サイドバーの要素 <- いまここ
    • 要素
      • Webページを表示する要素
        • ...

サイドバーのwindowからメインウィンドウのwindowを取得するには、3種類の方法があります。

var mainWindow = window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
                   .getInterface(Components.interfaces.nsIWebNavigation)
                   .QueryInterface(Components.interfaces.nsIDocShellTreeItem)
                   .rootTreeItem
                   .QueryInterface(Components.interfaces.nsIInterfaceRequestor)
                   .getInterface(Components.interfaces.nsIDOMWindow); 
var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
                   .getService(Components.interfaces.nsIWindowMediator);
var mainWindow = wm.getMostRecentWindow("navigator:browser");
var mainWindow = getTopWin();

getTopWinは chrome://browser/content/utilityOverlay.js が定義しています。他にも便利な関数が入っているので一読おすすめ。

では実装しましょう。
http://eva-lu-ator.net/~gemma/geocities/matchfox/Clipboard10.png

  • まず、拙作のMatchfox拡張で、骨組みを作ります。urllistと名付けましょう。
  • 骨組みのsidebar.xulにこのようにbuttonと、出力先のtextboxを作ります。
これはxmlですうんちゃらなんちゃら...
<page ほげほげ...>
  <button oncommand="urllist.sidebarFoobar0();" label="&urllist.sidebar.test;"/>
  <textbox id="output" multiline="true" rows="20"></textbox>
</page>

buttonを押すとchrome/content/sidebar/00-foobar0.jsのsidebarFoobar0関数を呼ぶようになっているので、
このあたりに以下のコードを書きます。

const EXPORT = ['sidebarFoobar0'];

function sidebarFoobar0() {
  document.getElementById("output").value = getURLs().map(function(x) {
    return "[" + x.url + ":title=" + x.title + "]";
  }).join("\n");
}

function getMainWindow() {
  return getTopWin();
}

function getURLs() {
  var mw = getMainWindow();
  var num = mw.gBrowser.browsers.length;
  var arr = [];
  for (var i = 0; i < num; i++) {
    var b = mw.gBrowser.getBrowserAtIndex(i);
    if (b.currentURI.spec != "about:blank") {
      arr.push({
        url:   b.contentDocument.documentURI,
        title: b.contentDocument.title
      });
    }
  }
  return arr;
}

完成です。
ここに置いときますね。http://eva-lu-ator.net/~gemma/geocities/matchfox/urllist.xpi

開発のヒント

  • サイドバーのプログラムはサイドバーをパカパカでリロードできます。
  • エラーコンソールへの出力は Application.console.log 関数です。
  • 先にMozReplで偵察しておくとスムーズです。
    • MozReplでサイドバーのwindowに潜るにはこうします。
 repl.enter(document.getElementById("sidebar").contentWindow)