俺々拡張作成法 - 例題:Firebug を「カクカク化」して $x の第 2 引数でコンテキストノードを指定できるようにする。 - IT戦記

Firebug を「カクカク化」して $x の第 2 引数でコンテキストノードを指定できるようにする。 - IT戦記に対してブクマコメントでう〜ん、どうも健全な拡張開発って感じじゃないな..../本来ならuserChrome.jsか拡張の拡張を作るべきだと思う/あとでなんか書くかもと書いたら

[firefox][firebug][javascript][extension]id:teramako 僕は、手元の環境をグチャグチャにするのが好きで、グチャグチャにするのが勉強になるんじゃないかなーとか思ってるんです><ごめんなさい><確かに人に薦めるのはどうかなーってのもわかります><

http://b.hatena.ne.jp/amachang/20071213#bookmark-6788550

正直、ガリガリ弄れちゃうamachang氏が羨ましい><
臆病なオイラは他人の拡張をグチャグチャに弄るのは怖くてできないのです><
だから出来るだけ他所から手を加える。って事でオイラ的簡易拡張作成法の紹介。といっても拡張製作者は誰もがやってそうな方法で、多くの人がテスト的に作るのにこの方法を使っていると思う。こちらの方法なら他の拡張の中身を弄らずに済むし、いらなくなったら無効または削除してしまえば良い。

コンテンツ作成

好きなディレクトリに以下のような構成のディレクトリを作ることにする。

+--myextension
   +--install.rdf
   +--chrome.manifest
   +--chrome
      +--content
         +--firebug_overlay.xul
         +--firebug_overlay.js

そして、install.rdf,chrome.manifest,firebug_overlay.xul,firebug_overlay.jsのファイルを作成する。

install.rdf

<?xml version="1.0"?>
<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
     xmlns:em="http://www.mozilla.org/2004/em-rdf#">

    <Description about="urn:mozilla:install-manifest">
        <em:name>myextension</em:name><!-- 拡張の名前 -->
        <em:version>1.0</em:version><!-- 拡張のバージョン -->
        <em:description>俺々拡張</em:description><!-- 拡張の概要 -->
        <em:creator>teramako</em:creator><!-- 自分の名前 -->
        <em:id>myextension@teramako.ddo.jp</em:id><!-- 自分のドメインに書き換えよう -->
        <em:type>2</em:type>

        <em:targetApplication>
            <!-- Firefox -->
            <Description>
                <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
                <em:minVersion>1.5</em:minVersion>
                <em:maxVersion>2.0.0.*</em:maxVersion>
            </Description>
        </em:targetApplication>
    </Description>
</RDF>

install.rdfの内容は固定的なのでテンプレート化しておくと良いかも。

chrome.manifest

content myextension chrome/content/
overlay chrome://firebug/content/browserOverlay.xul chrome://myextension/content/firebug_overlay.xul

firebug_overlay.xul

<?xml version="1.0"?>
<overlay xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
  <script type="application/x-javascript" src="chrome://myextension/content/firebug_overlay.js" />
</overlay>

firebug_overlay.js

(function() {
    var _FirebugCommandLineAPI = FirebugCommandLineAPI;
    window.FirebugCommandLineAPI = function(context) {
        var baseWindow = context.window;
        _FirebugCommandLineAPI.apply(this, arguments);
        this.$x = function (xpath, context) {
            return FBL.getElementsByXPath(context || baseWindow.document, xpath); 
        };
    }
    FBL.getElementsByXPath = function(context, xpath) {
        var nodes = [];
     
        try {
            var doc = context.nodeType == 9 ? context : context.ownerDocument;
            var result = doc.evaluate(xpath, context, null, XPathResult.ANY_TYPE, null);
            for (var item = result.iterateNext(); item; item = result.iterateNext()) nodes.push(item);
        }
        catch (exc) {}
     
        return nodes;
    };
})();

関連付け

プロファイルディレクト/extensions以下にinstall.rdfで指定したid(em:id要素の内容)のファイル名で作成した拡張へのパスを記述する。
D:\workspace\myextensionに作っている場合は

myextension@teramako.ddo.jp

D:\workspace\myextension\

のようになる。最後のディレクトリを表す\または/を忘れないように。

Firefoxの(再)起動

(再)起動して、アドオンを確認する。

俺々拡張がインストールされている
アドオン画面で確認

自分の作ったのが表示されていれば作成成功だ。

変更を楽にするための設定

あと、about:configから
nglayout.debug.disable_xul_cache,javascript.options.strict,javascript.options.showInConsoleをそれぞれtrueにしておくと良い。詳しくはXUL Apps > Tips > XULアプリの開発環境を整える - outsider reflexを参考に。
特にnglayout.debug.disable_xul_cachetrueにしておくと再起動せずともファイルの変更が反映されるので手間が省ける。

本物の拡張作成

myextensionディレクトリの中身をzipで固めてxpiに拡張子を変えてしまえばインストール可能な拡張機能となる。本当はchromeディレクトリ以下のものをjarファイル(zip)に固めてからxpiファイルを作った方が良いけど、そうするとchrome.manifestファイルの内容を少々書き換えないといけなくて面倒なので割愛。

オイラはまだその域に達してないけど、慣れるとIDEの助けも借りて3分で作れるようになる。実際にプレゼンの場でやった人がいる。

最後に


これはオイラがJavaScript Shell 1.4を参考に作った拡張。かなり微妙なできだけど、特権コードを使えるのでXPCOMのテストとか内部の関数確認に使っている。
teramako - JavaScript Shellに置いてあるので適当に弄ってくださいなw