XULで動的にスタイルシートを読み込む方法が分かった

ここまでのあらすじ

Firefox拡張機能を作ろうとしていました。でも、XULで動的にスタイルシートを読み込む方法が分からずに困っていました(そのときのエントリ)。そうすると、id:teramako さんがはてなブックマークのコメントで「stylechanger.js を読むと良いかも」と教えてくれました。なので、さっそく試してみることにしました。

試したこと

そのstylechanger.jsで(僕にとって)大事なところは、81行目あたりの以下の関数です。

var manager = {
    load: function(css){
        /* 途中省略 */
        if (sss.sheetRegistered(uri, sss.USER_SHEET))
            sss.unregisterSheet(uri, sss.USER_SHEET);
        sss.loadAndRegisterSheet(uri, sss.USER_SHEET);
        /* 途中省略 */
        return true;
    },

お、それっぽい。いかにも関係ありそうだ。

MDCで検索してみると、「タイルシートの追加」という、まさにそのまんまな項目がありました。
Using the Stylesheet Service - MDC

自分なりの結論

というわけで、以下の関数を使えば動的にスタイルシートが読み込めました。

function loadCss(cssName) {
    var sss = Components.classes['@mozilla.org/content/style-sheet-service;1'].
        getService(Components.interfaces.nsIStyleSheetService);
    var ios = Components.classes['@mozilla.org/network/io-service;1'].
        getService(Components.interfaces.nsIIOService);

    var uri = ios.newURI(cssName, null, null);
    if(! sss.sheetRegistered(uri, sss.USER_SHEET)) {
        sss.loadAndRegisterSheet(uri, sss.USER_SHEET);
    }
}

使い方はこんな感じ。読み込むスタイルシートURI文字列を渡す。

loadCss("chrome://myaddon/skin/mystyle.css");

見本としたstylechanger.jsでは、引数がnsIURI型でもOKだったりエラーチェックが入ってたりと色々実践的になってますが、そこまでは必要ないのでシンプルにしてみました。

最後に

うーむ。やっぱり検索パワーが足りなかったのかな。今回も結局は「loadAndRegisterSheet」という関数名が分かってしまえば、後はあっという間でした。

まあ、とにかく無事解決しました。めちゃうれしい。id:teramako さん、ありがとうございました。