2013年1月8日火曜日

firefoxアドオン : インスタンスがどのインターフェースを実装しているか調べる

firefox上のjavascriptで使用されるfirefox特有のオブジェクトは名前が「nsI」で始まるインターフェースを実装している事があります。 でも、「どのオブジェクトがどのインターフェースを実装しているか?」っていう情報はあまり見かけません。 ってことでコード上で調べる方法を試してみました。

とはいえ、javascriptの知識が浅いのでリフレクションとか継承階層の調べ方とか全くわかりません。 そもそもXPCOMオブジェクトってjavascriptからそういうのを調べられるんですかね?

まぁそういう事は、アドオンに関する興味が続いたらそのうち分かってくるかな? 今は場当たり的なtry&errorで済ませましょう。

とりあえずfor文で、あるイベントで渡されたインスタンスが持つメソッドを調べてみたら、

for(let item in aInstance)
    log(item); // logメソッドは適当に用意

QueryInterfaceしか出てきませんね。 手当たり次第にQueryInterfaceしてインスタンスが返ってきたら実装ありっていう調べ方にでもしましょうか。

const Ci = Components.interfaces;

function printInterfaces(aInstance)
{
    let r = new RegExp("^nsI");
    for(let item in Ci)
    {
        let itemName = item.toString();
        if(itemName.match(r) )
        {
            try
            {
                if(aInstance.QueryInterface(Ci[itemName]) )
                {
                    log("printInterfaces - " + itemName);
                }
            }
            catch(e){}
        }
    }
}

このコードを試してみたら、これでちゃんと実装されたインターフェースの一覧は見れるようです。 Components.interfacesに登録されたインターフェース全てについてイチイチ試しているのでリリースコードにこういうのを入れるのはまずそうですけど、開発中の調べ物には使えそうですね。