これで Tinderbox のステータスを表示する拡張機能が完成しました、次はこれを他のユーザに配布できるようにします、やり方としては、Mozilla のコードに統合する方法 (この場合、我々の作ったものは拡張機能ではなく、デフォルトの Mozilla 配布物の一部になります) と、拡張機能を Mozilla から実行可能なインストーラパッケージにして、ユーザが拡張機能を使用中の Mozilla に追加するようにする方法があります。
ほとんどの拡張機能はインストーラパッケージとして配布されているので、我々も同様にしましょう。なお、拡張機能を Mozilla のコードベースに統合する方法はこのチュートリアルの範疇ではありませんが、mozilla.org の hacking documentation に多くの情報があります、
Mozilla のインストーラーパッケージは XPIs (「ジッピーズ」と発音します) と呼ばれます。これはクロスプラットフォームインストーラ (cross-platform installer) の略です。パッケージはただの ZIP アーカイブで、インストールされるファイルに加えて、インストールを実行する JavaScript スクリプトと、chrome レジストリ用の、インストールされるコンポーネントについて記述した RDF ファイルを含んでいます。
この拡張機能は、インストールすると Mozilla 中のファイルを変更します、動的 XUL オーバーレイ を使って拡張機能の内容をインストール済みの Mozilla に書き加えるようにするためには、拡張機能をパッケージ化する前に、変更部分を別のファイルに分ける必要があります、
XUL オーバーレイは XUL ファイルの一種で、他の XUL ファイルに挿入されるべき要素を含んでいます、挿入は、挿入先の XUL ファイルがアプリケーションの UI へレンダリングされる時に行なわれます、静的オーバーレイでは、XUL ファイルの先頭に記述された XUL ファイルへの参照によって挿入が行なわれます (スタイルシートや JavaScript スクリプトと同様です)、動的オーバーレイでは、chrome レジストリに XUL ファイルへの参照を追加することで挿入が行なわれます。
コードの可読性、保守性、拡張性を高めるために、オーバーレイを使って巨大な XUL ファイルをいくつかのファイルへ分割することができます、(ひとつのファイルがアプリケーションウィンドウ全体の構造を記述し、それ以外がウィンドウの特定の部分を実装する) 、動的オーバーレイは、変更したい XUL ファイル自体に変更を加えずに、その XUL ファイルを変更したのと同じ効果を得るためにも使われます、この機能は拡張機能をインストールするときに使われます、では、まず始めにファイルを静的オーバーレイにし、次にそれを動的オーバーレイにしていきましょう。
ファイルを静的オーバーレイにするには、navigator.xul
と同じディレクトリに tinderstatusOverlay.xul
というファイルを作り、navigator.xul
に追加していたコードをすべてそこに移します。
<?xml version="1.0"?> <?xml-stylesheet href="chrome://navigator/content/tinderstatus.css" type="text/css"?> <overlay id="tinderstatusOverlay" xmlns="https://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> <script type="application/x-javascript" src="chrome://navigator/content/tinderstatus.js" /> <statusbar id="status-bar"> <statusbarpanel class="statusbarpanel-iconic" id="tinderbox-status" insertbefore="offline-status" status="none"/> </statusbar> </overlay>
tinderstatusOverlay.xul
は、そのファイルが XML であることを示す XML 宣言から始まります (すべての XUL ファイルは XML 宣言を含む必要があります) 、次の行は、以前 navigator.xul
に追加したスタイルシートへの参照です、次は XUL の overlay
要素です。この要素は XUL オーバーレイファイルのトップレベル要素で、これによりファイルがオーバーレイであることが分かります、その中身は前に navigator.xul
に追加したスクリプトへの参照です、その次には statusbarpanel
要素を含む statusbar
要素があります。
このオーバーレイの中の statusbar
要素の id
属性の値は、navigator.xul
の statusbar
要素の id
属性と同じです。navigator.xul
がレンダリングされてブラウザの UI になるとき、オーバーレイファイルの statusbar
要素のすべての属性と子要素が UI の DOM に追加されます、これにより、オーバーレイファイルで定義した要素が、あたかも navigator.xul
で定義されているかのような UI が表示されます、
statusbarpanel
要素に属性 insertbefore
を追加したのに注意してください。この属性では、statusbar
の中の、我々の要素の次に現れる statusbarpanel
要素を指定しています。これにより、我々の要素が statusbar
の中でどの要素の前にくるかという、他の statusbarpanel
に対する相対的な位置を指定することができます。
insertbefore
を省略すると、要素は statusbar
の 最後に追加され、通常は resizer grippy 【訳注: ウィンドウ右下の、ウィンドウのサイズを変えるのに使う部分】 の前に来るでしょう、また、insertbefore
の代わりに insertafter
を使えば、他の要素の後ろに要素を配置することもできます。
我々が navigator.xul
に対して行った変更の代わりにこのオーバーレイを使うには、今までの変更を元に戻し、オーバーレイへの参照を navigator.xul
の先頭に追加します、
... <?xml-stylesheet href="chrome://navigator/skin/" type="text/css"?> <?xml-stylesheet href="chrome://navigator/content/tinderstatus.css" type="text/css"?> <?xul-overlay href="chrome://navigator/content/navigatorOverlay.xul"?> <?xul-overlay href="chrome://navigator/content/navExtraOverlay.xul"?> <?xul-overlay href="chrome://navigator/content/linkToolbarOverlay.xul"?> <?xul-overlay href="chrome://navigator/content/tinderstatusOverlay.xul"?> <?xul-overlay href="chrome://communicator/content/conten...extOverlay.xul"?> <?xul-overlay href="chrome://communicator/content/sideba...barOverlay.xul"?> <?xul-overlay href="chrome://communicator/content/communicatorOverlay.xul"?> <?xul-overlay href="chrome://communicator/content/bookma...rksOverlay.xul"?> ... <!-- Navigator --> <script type="application/x-javascript" src="chrome://navigator/content/browser.js"/> <script type="application/x-javascript" src="chrome://navigator/content/navigator.js"/> <script type="application/x-javascript" src="chrome://navigator/content/navigatorDD.js"/> <script type="application/x-javascript" src="chrome://navigator/content/sessionHistoryUI.js"/> <script type="application/x-javascript" src="chrome://navigator/content/tinderstatus.js"/> <!-- hook for stringbundle overlays --> ... <statusbar id="status-bar" class="chromeclass-status" ondragdrop="nsDragAndDrop.drop(event, contentAreaDNDObserver);"> <statusbarpanel id="component-bar"/> <statusbarpanel id="statusbar-display" label="&statusText.label;" flex="1"/> <statusbarpanel class="statusbarpanel-progress"> <progressmeter class="progressmeter-statusbar" id="statusbar-icon" mode="normal" value="0"/> </statusbarpanel> <statusbarpanel class="statusbarpanel-iconic" id="tinderbox-status" status="none"/> <statusbarpanel class="statusbarpanel-iconic" id="offline-status"/> <statusbarpanel class="statusbarpanel-iconic" id="security-button" onclick="BrowserPageInfo(null, 'securityTab')"/> </statusbar> ...