Addon-SDKでFirefoxのアドオンを書くための開発環境を作る
はじめに
久しぶりに、Add-on SDKを触ってFirefoxのアドオンを作成したのでその時の環境作りについてメモです。
内容は以下のような感じ
- Addon SDKの概要
- Addon SDK APIのモジュールについて
- WebStorm
- Addon SDK APIの補完について
- XPCOM APIのインターフェイスについて
- アドオンのデバッグ(デバッガ)
Addon SDK
Firefoxのアドオン開発をするには、Add-on SDKを使うのが比較的入りやすいです。
- 一応 日本語 のページ もありますが古いので、リファレンスは本家を見た方がいいです。もしくは
cfx docs
を叩く - Add-on SDK (Jetpack SDK) – あすかぜ・ねっと
Firefox 21からAddon SDKのAPIがFirefoxに取り込まれているので、Addon SDKでビルドしたアドオン以外でもAddon SDKのAPIが利用できるようになっています。
High-Level APIsと書かれてるモジュール(モジュール自体もJavaScriptで書かれてるので中見ると便利です)で、基本的な事はできるようになってます。
タブの操作、クリップボード操作、コンテキストメニュー、hotkeysでのショートカット設定、panelというポップアップのUI作成、
Greasemonkey的なURLのマッチングをしてスクリプトを動かすpage-mod、特定のURLを読み込ませてその中で動くスクリプトを送り込んで値などを取ってくるpage-worker、
通知を行うnotifications等があります。
データの保存は、jsonでシンプルにオブジェクトを保存するsimple-storageやpackage.jsonに記録したい項目と入力の種類を書いておけば設定画面も一緒に作ってくれるsimple-prefs、使いづらいことに定評のあるIndexedDB APIをラップしたindexed-db
等があります。
また、Unit Testingというモジュールが最初からあり、cfx init
でデフォルトテンプレートした段階で cfx test
でテストを書ける環境が揃ってます。
test/httpd を使うとローカルサーバを立てられたりするので便利です。
(もう少しテストの書式が一般的だといい気がするけど。。)
また、AddonSDKでの実行はlocal.jsonやcfx testの引数で指定したプロファイルをコピーして実行されるので、テストでプロファイルを壊しても、毎回キレイな状態から始まる(*要出典)のでテストしやすい環境があると思います。
Travis CIとかと似たような感じ?
Firefoxの機能自体に関係ないものだと、promiseやuuid、set的な使い方をするcollection等もあったりします。
足りない機能は、通常のFirefoxアドオンと同じようにXPCOMを叩けば使えるモジュールを使える)ので、Addon SDKだからできないという事は大分少ないと思います。
XPCOMを叩くときはxpcomモジュールや、通常のアドオンと同じようにComponents.classes
などを使う、Chrome Authorityが使えます。
以下みたいにAddonSDKのモジュールを公開してる人(中の人ですが)もいます。
モジュールはpackage.jsonの dependencies
に書くことでアドオンから利用できるようになっています。
(この辺のモジュールをnpmとかcocoapodsみたいに共有する仕組みが欲しい…)
補足:
- Add-on SDK update for Firefox 22 (and 23, and 24) | Mozilla Add-ons Blog
- Firefox 23 にて、Add-on SDKでもChrome URLを登録できる(XULなWindowsが使える)ようになる – Enjoy*Study
開発環境
公式ドキュメントはまあまあ充実していますが、他のブログ等のリソースが少ない問題があります。(これはJetpackがたどってきた歴史やMozillaにも問題がある気がしますが)
ドキュメントは前述したように org
ドメインの方を見ましょう
以下は、WebStormを少し前提に書きますが、扱う内容自体は一般的な内容なので他のエディタ次第でも似たような事ができるはずです。
Webstorm
Addon SDKのモジュール郡では、分割代入やlet,constなどECMAScript 6の内容や、Mozilla JavaScript固有の書き方等が頻繁に使われています。
WebStormでは、利用するJavaScriptのバージョンを Setting -> JavaScript
から選択できるので、ECMAScript 6 (Harmony) を選択しておくと大体問題ないです。
(一部、for eachとかアレですが、基本的にビルドインモジュールは編集しないので問題ないです)
毎回CLIから cfx run
と叩いて起動するのは面倒なので、以下の様なシェルスクリプトを作って、それをExternal Toolsに設定して呼び出して起動させています。
Setting -> External Tools
に以下のように登録
Program : /path/to/cfx-wrapper.sh
Parameters : -a "path/to/addon-sdk/" -w "$ProjectFileDir$"
WebStormのコンソールに結果が表示される(Console APIの内容も)ので、CLIを叩かなくても、runを繰り返せます。
Addon SDK APIの補完
AddonSDKのソースコードを見るとわかります、addon-sdk / lib / sdk / にSDKで使えるモジュールが定義されています。
見るとわかりますが、殆どJavaScriptで書かれているため、JavaScriptを静的解析できるエディタなら、モジュールの補完に利用できます。
WebStormの場合、 Setting -> JavaScript -> Libraries
から addon-sdk/lib/sdk/
のディレクトリを登録する事で先ほどのJavaScriptを解析した結果を補完に利用できます。
Setting -> Direcotories
に 先ほどの addon-sdk/lib/sdk/
のディレクトリを追加することでも同じようにAddonSDK APIの補完が効きます(Librariesに追加するほうが汎用性がありますが)
JavaScriptで書かれているので、モジュールが実際にどういう処理をしているのかも簡単に確認できるのは利点です。
JSDoc
AddonSDK APIは比較的問題なく(Chrome Script < -> Content Scriptは理解するまで分かりにくいですが…)、馴染めると思います。
しかし、ビルドインモジュールで足りない場合はXPCOMを叩く必要があります。
例えば、ファイルのダウンロードをするモジュールは今のところないので、自分で nsIWebBrowserPersist::saveURI
などを使ってやる必要があります。
- ダウンロードマネージャに進捗状況を表示させつつダウンロードする | Mozilla Developer Street (modest)
dlMgr.addDownload
とかにprivacyの引数が増えてるのでそのままでは動かないです…
これらのAPIを叩く場合は、XPCOM Interfaceに載っているようなインタフェースを知る必要が出てきます。
当然、受け取る引数もAddonSDK APIとは違い、nsIURLやnsIFileなど、XPCOM Interfaceのものを扱う必要がでてきて一気に難易度が上がります。
表題に戻って、これらのXPCOM InterfaceをJSDoc(ver3)に変換して少しでもエディタが解釈できる形に落としこみたいと思います。
XPCOMはXPIDLという言語で書かれたインターフェイスファイルが公開されていて、そこにAPIのインターフェイスがのっているのでそれを利用します。
公式に、pyxpidlというものが公開されていて、これはXPIDLの内容をC++とJavaのインターフェイスファイルを生成してくれます。(何でJSDocないの…)
これを改造してXPIDL -> JSDocに変換できるようにしたazu/XPIDL-JSDOCというものを適当に作りました。
(汚いというレベルじゃないので、誰かちゃんと作って欲しい…)
- Gecko/XULRunner SDK をダウンロードしてxulrunner-sdk/sdk/binに上書きしたら適当に動きます。
こういう感じのJSDocを書き出します。
(propertyの型もちゃんと設定したかったけど、Pythonわからなくて諦めた)
/**
* nsIURL IDL
* @typedef {Object} nsIURL
* @property filePath attribute AUTF8String filePath;
* @property query attribute AUTF8String query;
* @property directory attribute AUTF8String directory;
* @property fileName attribute AUTF8String fileName;
* @property fileBaseName attribute AUTF8String fileBaseName;
* @property fileExtension attribute AUTF8String fileExtension;
* @property GetCommonBaseSpec AUTF8String getCommonBaseSpec (in nsIURI aURIToCompare);
* @property GetRelativeSpec AUTF8String getRelativeSpec (in nsIURI aURIToCompare);
*/
var nsIURL = {};
WebStorm7EAP以降なら、@typedefに対応してるみたいですがこの書き方が正解なのかよく分からない…
例えば、先ほどのファイル保存する機能を持ったモジュールを作ろうとした時に、ファイル保存するXPCOMのAPIは nsIURL
を引数に取るので以下のように、引数に nsIURL
の型を取るといった定義を書けるようになります。
(正直APIの補完にはあんまり使えないと思います。)
- io.js 実際につくったやつ
/**
* ``saveURL`` Util
* @param {Window} window
* @param {nsIURL} sourceURI
* @param {nsIURL} fileURI
* @param {string} filename
* @return {promise} promise
*/
var saveFile = function (window, sourceURI, fileURI, filename){
}
ちなみに、io.jsの方を見るとわかりますが返り値はAddonSDKのpromiseを返してます。
少なくてもエディタが何らかの補助をしてくれるなら、事故率は減るのでやっぱりキチンとしたXPCOMのJSDocが欲しいです。。
デバッグ
Addon SDKで作成したアドオンのデバッグは、Firefox buildinのデバッガを使って行う事ができます。
また、 console.log()
等のConsole APIを使ったprintデバッグもできます。
FirefoxにもChromeのようにネイティブのデバッグツールが色々増えていて、名前がややこしいですが以下の様な使い分けです。
- ウェブページのデバッグ(Content) -> Browser Console
- アドオンのデバッグ(Chrome) -> Browser Debugger
アドオンのデバッグにはChrome権限で動いてるスクリプトが見られる Browser Debugger
の方を使います。
デバッガ の使い方は以下を見るといいかもしれません。
おわり
久々に、Addon SDKを触ってアドオンを作りましたが、デバッガやテスト環境、ある程度使い方がわかりやすいモジュールが揃っているので、アドオンを作る敷居は以前に比べれば低くなってきたかなと思います。
(デバッガー周りはまだ挙動不審なことが事がありますが)
今回、Addon SDKを触りだした理由はGreasemonkey以上(具体的にはDownload APIが欲しかった)のことをやろうとして、
最初はKeySnail上でささっと作りましたが、簡単なツールバーボタンのようなUIや Content(ウェブページ) < -> Chrome(アドオン) を行き来するようなものを必要になって、
userChrome.jsのようなスクリプトだと逆に面倒になりそうだったので、Add-on SDKでアドオンとして作りました。
Greasemonkeyライクな事はpage-modやpage-workerを使えばできますし、
panelやwidgetを使えば簡単なUIは作れるので、Greasemonkey以上の事を簡単にやりたいときに触ってみるといいんじゃないかなーと思います。
お知らせ欄
JavaScript Primerの書籍版がAmazonで購入できます。
JavaScriptに関する最新情報は週一でJSer.infoを更新しています。
GitHub Sponsorsでの支援を募集しています。