Firefox拡張機能


Firefoxの拡張機能

  • Firefox の拡張機能は、「アドオン」と呼ばれています
    • Chrome では「拡張機能」、Safari でも「機能拡張」、Internet Explorer では「アドオン」
    • 参考にしたサイトではFirefox バージョン 12 以降

作業


Firefox 拡張機能の構成内容

Firefox 拡張機能を作成する、その他の方法

この記事で説明するプロセスの他にも、Firefox の拡張機能を作成する方法がいくつかあります。Add-on Builder が使用する SDK ファイルは、Developer Hub (「参考文献」を参照) から直接ダウンロードすることができます。この SDK ファイルをダウンロードすると、アドオンを作成するときにお好みの IDE を使用できるようになります。

Add-on Builder の使用方法
https://builder.addons.mozilla.org/ に用意されている Add-on Builder (図 2) を使用するには、無料の登録プロセスを実行する必要があります。このプロセスを完了すれば、Add-on Builder にログインして独自のアドオンを作成することができます。
図 2. Add-on Builder

従来の方法 (つまり昔ながらの XUL を使用した方法) で、拡張機能を作成することもできます。ただし、この方法で拡張機能を作成することには、いくつかの欠点があります。それは、拡張機能のインストールに再起動が必要になること、そして拡張機能を作成するプロセスが複雑になることです。けれどもその見返りとして、Add-on Builder や Add-on SDK では不可能な方法でブラウザーに変更を加えることができます。例えば、XUL では、拡張機能のアイコンをアドオン・バー以外の場所に配置することができます。XUL 拡張機能については、Mozilla Developer Network (「参考文献」を参照) に詳しい説明が記載されています。

Add-on Builder で作成する Firefox 拡張機能は、CommonJS の慣例に従って必要なライブラリーを読み込みます。拡張機能では HTML、CSS、および JavaScript のファイルをどのように組み合わせることもできますが、すべての始まりは main.js ファイルです。

  • main.js : Firefox 拡張機能の中核です。このファイルは Firefox に対し、どのモジュールを読み込むかを指示するため、拡張機能の初期化タスクはこのファイルで行います。
    • Chrome 拡張機能の background.html ページと同じようなものです
    • 起動時に一度だけ実行されると、あとはバックグラウンドで実行され、この main.js ファイルと直接やりとりが行われることはありません。
作成する Firefox 拡張機能の内部には、表示するページを panels に多数含めることができます。この拡張機能ではそのようなページの 1 つとして、図 1 に示すポップアップとオプション選択を組み合わせたページを使用します。

さらに、Firefox でもコンテンツ・スクリプトを使用することができ、その方法は基本的に Chrome での場合と変わりません。
  • コンテンツ・スクリプト : Web ページとやりとりするためにそのページに注入される JavaScript ファイル
    • Firefox では、コンテンツ・スクリプトはページのコンテキスト内で効率的に実行されますが、セキュリティー上の問題を防ぐために、DOM へのアクセスおよび操作はプロキシーを介して行われます。
    • 拡張機能の残りの部分に対しては、コンテンツ・スクリプトは port を使用してやりとりすることができます。

この記事では、Add-on Builder インターフェースの詳細については説明しませんが、ファイル構造について説明しておくべき点が 2 つあります。まず、Lib ディレクトリーは、require を使用してライブラリーを読み込むときに Firefox が検索する場所です。したがって、Gawkblocker のコア JavaScript クラスは、このディレクトリーに配置します。そして Data ディレクトリーは、拡張機能で提供することになる画像、HTML、CSS、およびその他のアセットを配置する場所です。
アドオンを作成してテストするときに、Add-on Builder ヘルパーをインストールするよう求めるプロンプトが出されます。アドオン開発時には、このヘルパーがアドオンのアンインストールとインストールの処理を行います。
上に戻る

第 1 回では、ある程度の移植性を持った Gawkblocker のコア・クラス・ファイルのようなものを作成しました。今回はこのクラス・ファイルを Firefox 拡張機能で使用したいので、実際にそのクラス・ファイルにどの程度の移植性があるかがわかります。
明らかに、このクラス・ファイルには以下の重要な変更を加える必要があります。
localStorage の代わりに、Firefox の simple-storage 拡張 API を使用すること
exports に GB オブジェクトを追加すること
第 1 回のクラス・ファイルでは、セッション間で保持するデータを処理するために、localStorage のラッパーとして Storage Manager オブジェクト (SM と命名) を定義しました。そのコードは、Firefox 拡張機能の内部では動作しません。代わりに Firefox には、データを自動的に保持することが可能な simple-storage という API があります。第 1 回の Storage Manager オブジェクトは、リスト 1 に示すコードへと簡単に更新することができます。

GB オブジェクトは変更する必要がありませんが、CommonJS の慣例に従って、このオブジェクトを exports に追加する必要があります。そのタスクに対処するのが、リスト 2 の最後の行です。
リスト 2. exports に GB オブジェクトを追加する

これらの変更はごくわずかなので、Firefox でも Chrome でも動作するように GB オブジェクトを変更するのは簡単です (そのための作業は、読者の皆さんがお望みであれば独自のプロジェクトとして行ってください)。
ファイル名を GB.js に変更してから Lib ディレクトリーにアップロードして、main.js 内でのこのオブジェクトの使用方法を確認できるようにしてください。

Chrome では、URL を背景ページと照らし合わせて、その URL がブロックの対象であるかどうかを調べました。Firefox の場合、このチェックは main.js ファイルの内部で行います。main.js が何らかの処理を行うためには、その前に一連の require ステートメントによって、使用する予定のモジュールと API を読み込む必要があります (リスト 3 を参照)。

リスト 3 のステートメントは順番に、main.js に以下のオブジェクトを読み込ように指示します。
Data ディレクトリーにアクセスするために使用するオブジェクト
タブを処理するためのオブジェクト
メイン・クラスからエクスポートした GB オブジェクト
ポップアップ・ウィンドウを格納する popupPanel オブジェクト。このコードは、ポップアップ・ウィンドウも作成します。
さらに作成するポップアップ・ウィンドウは、オプション選択ページとしても機能するため、いくつかのリスナーをセットアップする必要があります。Chrome では、背景ページにアクセスして、このページに対して実行する処理を指示しましたが、Firefox ではそれと同じ目的で、main.js にメッセージを送信します。例えば、リスト 4 に記載するリスナーは、ユーザーがブロック対象として選択したサイトのデフォルト・ランディング・ページを設定します。
リスト 4. ユーザーがブロック対象として選択したサイトのデフォルト・ランディング・ページを設定するリスナー
popupPanel.port.on("watchthis", function () {
   GB.setWatchThisInstead(http://www.youtube.com/watch?v=N-uyWAe0NhQ);
   console.log("watchthis");
});
後でポップアップ・ページについて説明するところで、メッセージをこの port に渡します。
main.js ファイルでは、Gawkblocker がタブにアクセスして、ユーザーがブロック対象としている URL があるかどうか、ある場合にはどの URL であるかを調べる処理も行います。リスト 5 に、タブの更新をリッスンするコードを記載します。

関数およびパフォーマンスについては、Chrome での場合と同様です。API の使用方法 (メソッドを呼び出して、コールバックを渡すという方法) も Chrome での場合と変わりません。
最後に、この機能の小さなラベルをブラウザーの右下隅に追加するための Widget を作成します (リスト 6 を参照)。

main.js ファイルに必要なコードをすべて配置した後は、ポップアップ・ページに対する変更について詳しく探ります。
上に戻る


Chrome 拡張機能でのポップアップ・ページは、ブロック済みドメインのリストに過ぎませんでした。このポップアップ・ページの設計に手を加えるには、今が絶好のタイミングです。Firefox 拡張機能では、オプション選択ページの機能をポップアップ・ページにマイグレーションします。その上で、クリック・ハンドラーをポップアップ・ページに表示されるタイトルに追加し、ドメイン・リストとオプション選択の div を切り替えられるようにします。このオプション選択の機能によって、ユーザーのサイトからブロック・リストにアクセスして、ブロック済みサイトに対するリダイレクト・アドレスを指定できるようになります。図 3 に、Gawkblocker ポップアップ・ページのオプション選択を示します。
図 3. Gawkblocker ポップアップ・ページのオプション選択
Gawkblocker ポップアップ・ページのオプション選択を表示する Add-on Builder のスクリーン・キャプチャー
リスト 4 の port をセットアップするときには、main.js の watchthis をリッスンすることを忘れないでください。リスト 7 では addon.port.emit を使用して、そのメッセージをポップアップ・ページから送信します。


同じく port を使用してリストをリッスンすることで、main.js からブロック対象サイトのリストを取得します。main.js では、ポップアップ・ページからレディー状態であることが通知された時点で、リストを送信します (リスト 8 を参照)。


ポップアップ・オブジェクトの中で、ページをリッスンして、それを変更します (リスト 9 を参照)。

ポップアップ・ページは、main.js にブロック対象サイトのリストを要求します。リストを取得すると、そのリストを繰り返し処理して、ブロック対象サイトに関する詳細をポップアップ・ウィンドウ内の表示 div に追加します。
上に戻る
リダイレクト先のランディング・ページ
Chrome では、ブロック対象サイトへのリクエストのリダイレクト先が、拡張機能に含まれるランディング・ページとなるようにしました。Firefox ではそれとは異なり、直接、ソース (ランディング・ページに組み込まれた「Hey You! Don't Watch That! Watch This!」という YouTube の URL) へとリダイレクトされるようにします。
main.js に、リスト 10 に示すリダイレクトの初期条件を設定します。



Add-on Builder を使用したテスト
Add-on Builder を使用する場合、Firefox では作業中に拡張機能を簡単にテストすることができます。エラー・コンソール、テスト・ボタン、そして拡張機能が保存されるたびに自動的にその最新の拡張機能をリロードする Add-on Builder ヘルパーが用意されています。図 5 に、Add-on Builder ヘルパーの動作を示します。
図 5. Add-on Builder のユーティリティー

拡張機能の配布
作成した拡張機能を大勢の人々に配布する準備ができたら、そこで、いくつかの選択肢のなかから配布方法を選ぶことになります。プロファイルでアドオンを公開アドオンとしてマークした場合は、潜在的ユーザーにリンクを送信することで、そのユーザーがそのリンクからアドオンをインストールすることができます。あるいは、パッケージ化した拡張機能をダウンロードによって配布するという方法、拡張機能を addons.mozilla.org にアップロードするという方法もあります。

  • ブラウザーの UI のどこかにその拡張機能の存在を示すようにする難易度はどの程度か?
    • ブラウザーの一番下にアドオン・バーを表示するのは、Chrome での場合と比べ、それほど難しいことではありません。Firefox アドオンでは、main.js ファイル内で Widget を作成することで、アドオン・バーが表示されるようにしました。
  • ブラウザーのセッション間でデータを保持するために必要なものは何か?
    • それには、Firefox 固有の simple-storage API を使用します。1 つの Storage Manager クラスを Chrome と Firefox の両方に共通で動作させるには、何らかの機能検出メカニズムを実装します。
  • 拡張機能を構成するコンポーネント同士はどのような方法でやりとりするのか?
    • この種の通信を作成するには port を使用し、リスナーとエミッターをセットアップします。
  • ユーザーのデータのどこまでアクセスできるようにするのか?
    • ユーザーからの明示的な許可がなくても、少なくともユーザーがアクセスするすべての URL にアクセスすることはできます。これはかなりの程度です。
最終更新:2015年06月07日 09:50