Building an Extension
出典: MDC
目次 |
[編集] 序章
このチュートリアルでは、基本的な拡張機能を作る手順を段階を追って説明していきます。まずはFirefoxのステータスバーパネルに「Hello, World!」を表示してみましょう。
注意 このチュートリアルは、Firefox 1.5 の拡張機能の作成方法です。それ以前のバージョンの作成方法については、別のチュートリアルを参照してください。
[編集] 開発環境を準備する
拡張機能は、ZIPファイルの形式で固めて配布するか、さもなくば 拡張子がxpiのファイル(実体はZIP形式です)をバンドルします。XPIファイルの構造は下記のとおりです。
extension.xpi:
/install.rdf
/components/*
/components/cmdline.js
/defaults/
/defaults/preferences/*.js
/plugins/*
/chrome.manifest
/chrome/icons/default/*
/chrome/
/chrome/content/
自作のソースをzipに固めるのにMakefileやシェルスクリプトを書きたくないのであれば、上記と同じようにファイルを配置してみるのが一番簡単です。たとえ準備ができているとしても、一度このように広げて確認してみると、Firefox 1.5 のアドオンの仕組みがずっと簡単になります。
それでは始めましょう。まずハードディスク上に、拡張機能用のフォルダ(例:「C:\extensions\myExtension\」や「~/extensions/myExtension/」等)を作って下さい。このフォルダの中に「chrome」という名前のフォルダを作成します。この「chrome」の中に「content」というフォルダを作成します。(UNIX系のシステムであれば、拡張機能のrootディレクトリから「mkdir -p chrome/content」と叩くだけで2つのディレクトリが作成できます。)
次に、あなたの拡張機能用フォルダ(root とします)に、chrome フォルダと並んで 2つの新規ファイルを作成します。1つは「chrome.manifest」で、もう1つは「install.rdf」です。
開発環境の準備に関するもっと多くの助言が、Mozillazine Knowledge Base にもありますので、そちらも参考にしてください。
[編集] インストールマニフェストを作る
拡張機能の root フォルダに作った 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:id>sample@foo.net</em:id>
<em:version>1.0</em:version>
<em:type>2</em:type>
<!-- Target Application this extension can install into,
with minimum and maximum supported versions. -->
<em:targetApplication>
<Description>
<em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
<em:minVersion>1.0+</em:minVersion>
<em:maxVersion>1.5.0.*</em:maxVersion>
</Description>
</em:targetApplication>
<!-- Front End MetaData -->
<em:name>Sample!</em:name>
<em:description>A test extension</em:description>
<em:creator>Your Name Here</em:creator>
<em:homepageURL>http://www.foo.com/</em:homepageURL>
</Description>
</RDF>
- sample@foo.net - この拡張機能の ID です。これはあなたの拡張機能を識別するためのメールアドレス形式の値です(「あなたのメールアドレス」を書くところではありませんよ?)。他の機能拡張とかぶらないよう、ユニークな値にします。GUIDを使う事もできます。
- <em:type>2</em:type> の指定 -- この「2」は拡張機能であることを表しています。 (他の値の意味については Install Manifests#type を参照のこと)。
- {ec8030f7-c20a-464f-9b0e-13a3a9e97384} - Firefoxのアプリケーション ID です。
- 1.0+ - この拡張機能が動作するFirefoxの最小バージョン。あなたが動作確認して、バグを修正する責任を持とうとする最小のバージョンを指定して下さい。
- 1.5.0.* - この拡張機能が動作するFirefoxの最大バージョン。この値を現時点の最新版よりも大きな値にしないように!
Install Manifests には必須のプロパティもオプションのプロパティも全て網羅されています。
ファイルを保存します。
[編集] XUL でブラウザを拡張する
Firefox のユーザインタフェースは XUL と JavaScript で書かれます。XUL はボタン、メニュー、ツールバー、ツリーといったユーザインタフェースの部品を提供するための XML の文法です。ユーザーの行動は JavaScript を使って関数のように結び付いています。
ブラウザを拡張するために、我々は部品を加えるか修正することでブラウザのユーザーインタフェースの一部を修正します。我々は新しい XUL DOM 要素をブラウザウインドウに挿入することによって部品を追加し、スクリプトにイベントハンドラを付加することによって修正します。
ブラウザは browser.xul ($FIREFOX_INSTALL_DIR/chrome/browser.jar に含まれる content/browser/browser.xul)と呼ばれる XUL ファイルに実装されています。browser.xul では、ステータスバーについてこんな風に定義されているのを見つける事ができます。
<statusbar id="status-bar"> ... <statusbarpanel>s ... </statusbar>
<statusbar id="status-bar"> は、XUL オーバーレイ方式のための「マージポイント」です。
[編集] XUL オーバレイ方式
XUL オーバレイ方式とは、動的に他の UI 部品を XUL ドキュメントに紐付ける方法です。XUL オーバーレイ方式は、拡張子「.xul」のファイルに XUL のかたまりを記述しておくと、「マスター」ドキュメントにあるマージポイントで紐付けて追加してくれます。これらのかたまりで部品を追加したり削除したり変更したりが可能になるのです。
XUL オーバレイ方式の例
<?xml version="1.0"?>
<overlay id="sample"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<statusbar id="status-bar">
<statusbarpanel id="my-panel" label="Hello, World"/>
</statusbar>
</overlay>
status-bar という名前の <statusbar> で、ブラウザウィンドウの中のくっつけたい「マージポイント」を指定しています。
<statusbarpanel> はその子要素で、マージポイントに追加したい部品です。
上記のサンプルコードを sample.xul という名前のファイルに書いて、先ほど作った chrome/content に保存して下さい。
オーバーレイを使っての部品の追加やユーザーインターフェースの修正に関する詳細は、下記を参照して下さい。
[編集] Chrome URIの書式
XUL ファイルは、 "Chrome パッケージ" と呼ばれる ユーザーインターフェースコンポーネントのかたまりの一部です。これらは「file://」といったURIではなく、「chrome://」といった URI で呼び出されます(これはプラットフォームの依存度を下げるためです)。XUL ファイルの URI を インストールされたアプリケーションに引き継ぐために、Mozillaの開発者がこの解決策を考えつきました。
ブラウザのウィンドウは chrome://browser/content/browser.xul です。試しにこの URL を Firefox のロケーションバーに打ち込んでみてください!
Chrome URI はいくつかの要素から成り立っています。
- 第1に URI スキーマ (chromeの部分) 、これでFirefox のネットワーキングライブラリに「これは Chrome URIである」と伝えることでその内容がロードされますので、特別に処理される必要があります。
- 第2に、ユーザインタフェースコンポーネントの包みを識別するパッケージ名(上記の例では browserの部分)。これは拡張同士の競合を避けるために、可能な限りあなたのアプリケーションに特有であるべきです。
- 第3に、リクエストするデータの種類。これには3種類あります。
- 最後に、ロードするファイルへのパスです。
つまり、chrome://foo/skin/bar.png だと、foo テーマの skin セクションの bar.png というファイルを呼び出すのです。
あなたが Chrome URI を使って内容をロードするとき、 Firefox はこれらのURIを実際のディスク上のソースファイル(もしくはJARパッケージ)に変換するのに、Chromeレジストリを使用します。
[編集] Chrome Manifestの作成
Chrome Manifest に関するさらに詳細な情報と、それがサポートするプロパティについては、Chrome Manifest を参照して下さい。
先ほど root フォルダに chrome というディレクトリと並べて作成した chrome.manifest を開いて下さい。
下記の一文を追加します。
content sample chrome/content/
(最後のスラッシュ "/" を忘れない事! さもないと、拡張機能はロードされません。)
注意: Firefox/Thunderbird 2 とそれ以前のバージョンでは混合/大文字をサポートしていないので、必ず小文字のパッケージ名 ("sample") を使ってください。 - bug 132183
ここで指定しているのは、
- chrome パッケージの物の種類
- chrome パッケージの名前
- chrome パッケージファイルの場所
つまりこの行は、「chrome パッケージ名が sample」で「content ファイルが chrome/content (chrome.manifestの相対パス) にある」という事を表しているのです。
「content」「locale」「skin」に相当するファイルは、それぞれchrome のサブディレクトリである「content」「locale」「skin」のディレクトリ下に配置しなくてはならない事を注意してください。
ファイルを保存して下さい。あなたが拡張機能を入れて Firefox を起動した時に(このチュートリアルの後で)、chrome パッケージが登録されます。
[編集] オーバーレイの登録
Firefoxでオーバーレイを表示する時はいつでも、そのオーバーレイをブラウザウィンドウにマージする必要があります。ですから、 chrome.manifest ファイルに次の一文を追加して下さい。
overlay chrome://browser/content/browser.xul chrome://sample/content/sample.xul
これはFirefox に、「 browser.xul をロードする時に sample.xul を browser.xul にマージする」という意味です。
[編集] テスト
最初に、我々はあなたの拡張機能の存在を Firefox に伝えなくてはなりません。昔、Firefox 1.0 の頃にはこれは、あなたの拡張機能を XPI としてパッケージ化して、ユーザインタフェースを通じてそれをインストールする事を意味していました。これが実に辛い。でも、今はもっとずっと簡単です。
- あなたの環境の プロファイルフォルダを開いてください。
- そこにある extensions という名前のフォルダを開いて下さい。(なければ作成して下さい。)
- 新しいテキストファイルを作成して、その中にあなたの機能拡張フォルダのパス(例:「C:\extensions\myExtension\」とか「~/extensions/myExtension」とか。)を書いて、そのファイルをあなたの拡張機能のIDと同じ名前(例:「sample@foo.net」)で保存して下さい。
これで拡張機能のテストの準備ができました!
Firefoxを起動します。Firefox はあなたの拡張機能のディレクトリへのテキストリンクを検出して、そして拡張機能をインストールしてくれます。ブラウザウインドウが表示されると、ステータスバーパネルの右側でテキスト「Hello, World!」と表示されているのが見えるでしょう。
戻って「.xul」ファイルを修正した場合も、ファイルを閉じて Firefox を再起動すれば、その結果が反映されます。
[編集] パッケージ化
あなたの拡張機能が動作する今、あなたは配備とインストールのためにそれをパッケージすることができます。
あなたの拡張機能のフォルダのコンテンツ(rootフォルダ自体を圧縮するのではなく、中身だけ)をZipで圧縮し、そのZipファイルの拡張子を「.xpi」に変更します。Windows XP ではもっと簡単で、root フォルダの下の全てのファイル・ディレクトリを選択して右クリックして、「送る」->「圧縮(zip形式)フォルダ」を選択します。これで拡張子「.zip」のファイルができます。あとはファイル名を変更すればおしまい!
次に「.xpi」ファイルをあなたのサーバーにアップロードして、MIMEタイプが「application/x-xpinstall」になっている事を確認して下さい。これであなたはリンクを張って、みんながダウンロードしてFirefoxにインストールする事を可能にできます。
[編集] addons.mozilla.org の利用
Mozilla Update は、あなたが無料であなたの拡張機能を配布する事ができるサイトです。あなたの拡張機能は、非常に人気が高くなっても安定的にダウンロードできるように、Mozillaのミラーサーバー上にも格納されます。Mozillaのサイトはまた、ユーザーにより容易なインストレーションを提供し、さらにあなたが新バージョンをアップロードした時には、既存のユーザーにその新バージョンを自動で提供します。さらに Mozilla Update では、ユーザーのコメントをあなたにフィードバックさせる事も可能です。あなたがあなたの拡張機能を Mozilla Update で配布する事は、強く推奨されているのです!
[1]を訪ねて、アカウントを作って機能拡張を配布してみて下さい。
注意: あなたの拡張機能は、もし丁寧な説明文と動作のスクリーンショットがあれば、より早く知られて、もっとダウンロードされるでしょう。
[編集] 拡張機能のWindowsレジストリへの登録
Windows では、拡張機能の情報をレジストリに登録する事ができます。これによって拡張機能は次回自動的に呼び出されてアプリケーションが起動されます。これはアプリケーションインストーラに拡張機能として容易にインテグレーションフックを加えることを許すものです。詳細はWindowsレジストリへの拡張機能の登録を参照の事。
[編集] XUL オーバーレイ方式の追加情報
UI部品をマージポイントに追加するだけでなく、XUL のかたまりをオーバーレイの中で使う事もできます。
- マージポイントの属性の変更
- (例:「<statusbar id="status-bar" hidden="true"/>」(ステータスバーを隠す))
- マスタードキュメントからマージポイントの削除
- (例:「<statusbar id="status-bar" removeelement="true"/>」)
- 追加した部品の位置の操作
<statusbarpanel position="1" .../> <statusbarpanel insertbefore="other-id" .../> <statusbarpanel insertafter="other-id" .../>
[編集] 新しいユーザーインターフェースコンポーネントの作成
自分で作ったウィンドウとダイアログボックスを「.xul」ファイルを分けて作ったり、UI部品を操作するためのDOMメソッドを「.js」ファイルに実装する事で、機能として提供できます。また、「.css」ファイルにスタイルを定義しておけば、色の設定など、見た目を触る事もできます。
XUL開発のためのもっと詳しい情報は、XULの文章を参照して下さい。
[編集] Defaults ファイル
Defaults ファイルは、拡張機能の root フォルダの下の defaults/ というフォルダにあって、ユーザーのプロファイルを後押しするのに使います。デフォルトの情報はdefaults/preferences/ の下の「.js」ファイルに格納されます。ファイルをここに置いておけば Firefoxのプリファレンスシステムが起動時に自動的に読み込んでくれますので、あなたのプログラムはプリファレンスAPIを通じてデフォルトの情報を参照する事が可能です。
[編集] XPCOM コンポーネント
Firefox は拡張機能で XPCOM コンポーネントの利用をサポートしています。ですからあなたは JavaScript や C++ で(Gecko SDKを使って) 簡単にあなたのコンポーネントを作る事ができます。
自作の「.js」「.dll」ファイルはcomponents/ ディレクトリに置いて下さい。そうすれば拡張機能をインストールした最初のFirefox起動時に、自動的に登録されます。
詳細については How to Build an XPCOM Component in Javascript および Creating XPCOM Components bookを参照してください。
[編集] アプリケーションコマンドラインの操作
カスタム XPCOMコンポーネントの可能な用途のひとつは、Firefox または Thunderbird にコマンドラインハンドラを追加することです。このテクニックを使えば、あなたの拡張機能をアプリケーションとして実行できます:
firefox.exe -myapp
詳細については、Chrome: Command Lineと forum Discussion を参照して下さい。
[編集] Localization (地域化)
複数言語をサポートするために、あなたは エンティティや文字列のバンドル を使ってコンテンツから文字列を分離するべきです。開発時にやっておけば、後から戻ってきてやるよりもずっと楽ですよ!
拡張機能の地域化の情報は、「locale」ディレクトリの中に格納します。例えば、サンプル機能拡張に国依存の情報を追加したい場合、ディレクトリ「chrome」(「content」ディレクトリがあるのと同じ場所です)の中に「locale」ディレクトリを作り、そこにファイル「chrome.manifest」を作成して下記の一文を記述します。
locale sample sampleLocale chrome/locale/
XULで地域化した属性値を与えるためには、その値を「.ent」ファイル(または「.dtd」ファイル)に記述します。これは「locale」ディレクトリに、こんな感じで書いておきます。
<!ENTITY button.label "Click Me!"> <!ENTITY button.accesskey "C">
そうしたら、今度はあなたが書いた XUL ドキュメントの先頭(但し "<?xml version"1.0"?>" よりは下)に下記のように書きます。
<!DOCTYPE window SYSTEM "chrome://packagename/locale/filename.ent">
ここで window というのは地域名 であり、XUL文書のルート要素となります。SYSTEM プロパティは、エンティティファイルへの chrome URI です。例えばサンプルの拡張機能で言うと、ルート要素はoverlayです。
エンティティを使うために、XUL を下記のように修正して下さい。
<button label="&button.label;" accesskey="&button.accesskey;"/>
Chrome レジストリは確かに指定された地域名に対応するローカリゼーションバンドルからエンティティをロードしている事が確認できましたね。
スクリプトの中で文字列を使う時には、「.properties」ファイルを作成して、下記の書式で1つ1行で指定します。
key=value
スクリプト中で値を取得するには、nsIStringBundleService/nsIStringBundleや、<stringbundle> タグを使用します。
[編集] ブラウザを理解する
ブラウザウィンドウや他のXULウィンドウの検査をするのには、DOMインスペクタを使用します。 (これはFirefoxの「標準」インストールには含まれませんので、「カスタムインストール」で再インストールして「開発者ツール」を選択すれば、ブラウザのツールメニューに「DOM Inspector」が表示されます)
DOMインスペクタのツールバーの左上の「ノードファインダボタン」を押してから、検査したいウィンドウのオブジェクトをクリックすると、視覚的に選択したものの情報が表示されます。この時、DOMインスペクタのDOMツリービューは、あなたがクリックしたものの所にジャンプルするでしょう。
DOMインスペクタの右側のパネルでマージポイントとあなたがオーバーレイから追加した要素を見つけるのにも使います。もしあなたがマージした要素が見つけられないのであれば、マスターのXULウィンドウが呼び出された(loadイベントが発行された)タイミングで、あなたのオーバーレイでスクリプト割り付けて要素を追加する必要があるかもしれません。
[編集] 拡張機能のデバッグ
デバッグ用の分析ツール
- DOMインスペクタ - 属性・DOM構造・CSSスタイルルールの検査が実施されます。(例えば、あなたのスタイルルールが特定の要素では効いてなさそうな場合に調査する、非常に便利なツールです!)
- Venkman - ブレークポイントを JavaScript にセットして、スタック呼び出しを検証します。
-
arguments.callee.callerin JavaScript - ファンクションのスタックにアクセスします。
printf デバッグ
- Firefox をコマンドラインから -console オプションをつけて起動します。使う時には
dump("string")で文字列を出力できます。(詳細はリンク先を見てください) - JavaScript コンソールにログ出力するのには、
nsIConsoleServiceを使用します。
さらに上のデバッグ
- デバッグビルド版のFirefoxを動かして、Firefoxなり あなたのC++のモジュールなりにブレークポイントをセットします。経験豊かな開発者にとっては、このやり方がしばしば問題を診断する最速の方法です。詳細は Build Documentation および Developing Mozilla を参照してください。
- Debugging a XULRunner Applicationにもっと詳しい情報があります。
[編集] クイック・スタート
機能する簡単な拡張機能を作るために Extension Wizard オンラインツールを使えます。
Extension Wizard を使って作ったのと同じような Hello World 拡張機能 の一行一行の説明が another tutorial from MozillaZine Knowledge Base にあります。