読者です 読者をやめる 読者になる 読者になる

遥かへのスピードランナー

シリコンバレーでAndroidアプリの開発してます。コンピュータービジョン・3D・アルゴリズム界隈にもたまに出現します。

Firefoxアドオンでちょっとコアにタブを扱う

IT Firefox

Firefoxのアドオンで、ちょっとコアにタブを扱う処理のメモ。

http-on-modify-requestなどのトピック発生時に、HTTPリクエスト発生元のタブを取得するサンプルコード

getTabFromHttpChannelでtry-catchしている部分は、リクエスト元がDOMWindowじゃない場合にExceptionが発生するのでキャッチしているが、あんまり綺麗じゃないので他にうまいやり方はないだろうか。

const Cc = Components.classes;
const Ci = Components.interfaces;
const Cr = Components.results;

//myHTTPListnerはhttp-on-modify-requestなどのトピックのObserverとして登録するオブジェクト
//Observer登録部分のソースは省略
function myHTTPListener() {};
myHTTPListener.prototype = {
  observe : function (subject, topic, data) {
    var httpChannel = subject.QueryInterface(Ci.nsIHttpChannel);
    var tab = getTabFromHttpChannel(httpChannel);
    if (tab) {
      //リクエスト元のタブに対する処理
    }
  }
};

function getTabFromHttpChannel (httpChannel) {
  var tab = null;
  if (httpChannel.notificationCallbacks) {
    var interfaceRequestor = httpChannel.notificationCallbacks
        .QueryInterface(Ci.nsIInterfaceRequestor);
    try {
      var targetDoc = interfaceRequestor.getInterface(Ci.nsIDOMWindow).document;
    } catch (e) {
      return;
    }
    var webNav = httpChannel.notificationCallbacks.getInterface(Ci.nsIWebNavigation);
    var mainWindow = webNav.QueryInterface(Ci.nsIDocShellTreeItem)
        .rootTreeItem.QueryInterface(Ci.nsIInterfaceRequestor)
        .getInterface(Ci.nsIDOMWindow);

    var gBrowser = mainWindow.getBrowser();
    var targetBrowserIndex = gBrowser.getBrowserIndexForDocument(targetDoc);
    if (targetBrowserIndex != -1) {
      tab = gBrowser.tabContainer.childNodes[targetBrowserIndex];
    }
  }
  return tab;
};
タブごとに値を保存・取得するサンプルコード

タブごとに任意の値を保存するには、単に独自プロパティを1つ追加してもよいが、sessionStoreを使うとFireFoxを再起動してタブ復元しても保存される。詳細はこのへん

var tab = gBrowser.selectedTab; 
var ss = Cc["@mozilla.org/browser/sessionstore;1"].getService(Ci.nsISessionStore);

//タブに任意の値を保存
ss.setTabValue(tab, "your-attribute", "your-value");

//タブに保存した値を取得
var yourValue = ss.getTabValue(tab, "your-attribute");