この記事では Firefox 用の WebExtension の作成を、最初から最後まで、一通り経験します。
この拡張機能は、Firefoxのツールバーに新しいボタンを追加します。ユーザがボタンをクリックすると、動物を選択できるポップアップを表示します。いったん動物を選択すると、ページコンテンツを、選択した動物の画像に置き換えます。
実装するには、次のことを行います:
- ブラウザのアクションを定義します、それはFirefoxツールバーに付属するボタンになります
ボタン用に、次のものを提供します:- "beasts.png"というアイコン
- ボタン押下時に開くポップアップ。ポップアップには HTML, CSS, JavaScriptが含まれる
- コンテントスクリプト"beastify.js"を書きます。これはwebページの中へインジェクトされます。
これが、実際にページを変更するコードになります。 - webページ内の画像を置き換えるための、動物の画像をパッケージします。
"web アクセス可となるリソース" 画像を作り、ページから参照できるようにします。
拡張機能の全体構成は次のように図示できます:
これはきわめて単純な拡張機能ですが、WebExtensions API の基本コンセプトの多くを示しています:
- ツールバーへのボタン追加
- HTML, CSS, JavaScriptを用いたポップアップパネルの定義
- web ページへのコンテントスクリプトの注入
- コンテントスクリプトと、拡張機能のその他の部分との通信
- 拡張機能へ、web ページによって使用されるリソースを一緒にパッケージすること
GitHub上で、完全なソースコードを見ることができます。
前提条件
{{ Page ("/ja/docs/Mozilla/Add-ons/WebExtensions/Prerequisites") }}
WebExtensionを書く
新規ディレクトリを作成し、そこへ移動します:
mkdir beastify cd beastify
manifest.json
そして "manifest.json" と呼ばれるファイルを新規作成し、下記の内容を与えます:
{ "manifest_version": 2, "name": "Beastify", "version": "1.0", "applications": { "gecko": { "id": "[email protected]" } }, "permissions": [ "https://*/*", "https://*/*" ], "browser_action": { "default_icon": "button/beasts.png", "default_title": "Beastify", "default_popup": "popup/choose_beast.html" }, "web_accessible_resources": [ "beasts/frog.jpg", "beasts/turtle.jpg", "beasts/snake.jpg" ] }
- 最初の3つのキー:
manifest_version
,name
,version
は必須で、拡張機能用の基本的なメタデータを含んでいます。 permissions
は拡張機能で必要となるパーミッションをリスト化しておきます。単に、すべての HTTP と HTTPS ページを編集するためにパーミッションを問い合わせています:permissions
キーのドキュメントを見てください。ここにあるactiveTab
パーミッションの使用が好ましいですが、現在Firefoxでサポートされていません。browser_action
はツールバーボタンを指定します。ここでは3つの情報を提供しています:default_icon
は必須で、ボタン用のアイコンを指します。default_title
はオプションで、ツールチップに表示されるでしょう。default_popup
は、ユーザがボタンをクリックした時にポップアップを表示したい場合に使われます。我々はそのようにしており、そのためこのキーを含むようにして、拡張機能に同梱する HTML ファイルを指定できるようにしました。
web_accessible_resources
では、webページからアクセス可能にしたいファイルをリスト化します。この拡張機能は、ページ内の画像を拡張機能に同梱した画像に置き換えるため、ページからこれらの画像がアクセス可能にしておく必要があります。
指定するすべてのパスは、 manifest.json 自身からの相対パスとなる事に気をつけてください。
ツールバーボタン
ツールバーボタンにはアイコンが必要で、 manifest.json は "button/beasts.png" にてツールバーアイコンを持つことを約束します。
"button" ディレクトリを作って、"beasts.png" というアイコンをコピーします。我々のサンプルから使用できて、これはIconBeast Lite アイコン集から取ってきたもので、そのライセンス(英語)条件の下で使用できます。
ポップアップを使わない場合、ユーザがボタンをクリックした時にクリックイベントが割り当てられます。ポップアップを使う場合、クリックイベントは割り当てられず、ただしその代わりに、ポップアップが開きます。私たちはポップアップが欲しいので、次で作成しましょう。
ポップアップ
ポップアップ機能は、ユーザが3つの動物から1つ選択できるようにします。
拡張機能のルートの下に、 "popup" というディレクトリを新規作成します。これはポップアップ用のコードを保管しておく場所です。ポップアップは次の3ファイルから構成されます:
choose_beast.html
パネルのコンテンツを決めるchoose_beast.css
コンテンツのスタイルを指定choose_beast.js
アクティブなタブ内でコンテントスクリプトを実行することで、ユーザの選択を取り扱う
choose_beast.html
HTMLファイルは次のようになる:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <link rel="stylesheet" href="choose_beast.css"/> </head> <body> <div class="beast">Frog</div> <div class="beast">Turtle</div> <div class="beast">Snake</div> <script src="choose_beast.js"></script> </body> </html>
単に、動物の選択ごとに要素を持っています。単にwebページの様に、CSS と JS ファイルをこのページにインクルードしている事に注意してください。
choose_beast.css
CSS はポップアップのサイズを固定し、3つの選択肢がスペースを埋めることを保証し、基本的なスタイリングを与えます:
html, body { height: 100px; width: 100px; margin: 0; } .beast { height: 30%; width: 90%; margin: 3% auto; padding-top: 6%; text-align: center; font-size: 1.5em; background-color: #E5F2F2; cursor: pointer; } .beast:hover { background-color: #CFF2F2; }
choose_beast.js
ポップアップ用の JavaScript では、クリックイベントをリッスンします。3つの動物の上でクリックされた場合、アクティブなタブにコンテントスクリプトを注入します。いったんコンテントスクリプトがロードされたら、動物の選択のメッセージを送ります:
document.addEventListener("click", function(e) { if (!e.target.classList.contains("beast")) { return; } var chosenBeast = e.target.textContent; chrome.tabs.executeScript(null, { file: "content_scripts/beastify.js" }); chrome.tabs.query({active: true, currentWindow: true}, function(tabs) { chrome.tabs.sendMessage(tabs[0].id, {beast: chosenBeast}); }); });
これは3つの WebExtension API 関数を使っています:
chrome.tabs.executeScript
は "content_scripts/beastify.js" にあるコンテントスクリプトをアクティブなタブに注入しますchrome.tabs.query
はアクティブなタブを取得しますchrome.tabs.sendMessage
はアクティブなタブ内で実行されるコンテントスクリプトにメッセージを送ります。メッセージはbeast
プロパティにある選択した動物が入っています。
コンテントスクリプト
拡張機能のルートフォルダの下に、"content_scripts" という名のディレクトリを新規作成し、その中に "beastify.js" という名のファイルを作成し、下記のコンテンツを記述します:
// Assign beastify() as a listener for messages from the extension. chrome.runtime.onMessage.addListener(beastify); function beastify(request, sender, sendResponse) { removeEverything(); insertBeast(beastNameToURL(request.beast)); chrome.runtime.onMessage.removeListener(beastify); } function removeEverything() { while (document.body.firstChild) { document.body.firstChild.remove(); } } function insertBeast(beastURL) { var beastImage = document.createElement("img"); beastImage.setAttribute("src", beastURL); beastImage.setAttribute("style", "width: 100vw"); beastImage.setAttribute("style", "height: 100vh"); document.body.appendChild(beastImage); } function beastNameToURL(beastName) { switch (beastName) { case "Frog": return chrome.extension.getURL("beasts/frog.jpg"); case "Snake": return chrome.extension.getURL("beasts/snake.jpg"); case "Turtle": return chrome.extension.getURL("beasts/turtle.jpg"); } }
コンテントスクリプトは拡張機能からの(特に、上記 "choose_beast.js" からの)メッセージに対するリスナーを追加します リスナー内で、これは次のことを行います:
document.body 内のすべての要素を削除します。
- 動物名を、画像を指定する URL に変換します。
- URLを指定する
<img>
要素を作り、DOM に挿入する - メッセージリスナを削除する
動物
最後に、動物の画像を入れておく必要があります。
"beasts" という名のディレクトリを作成し、その中に3つの画像を、適切な名前をつけて追加します。GitHub リポジトリから画像を取得できます、あるいはここからでも:
パッケージ化とインストール
正しいファイルが正しい場所にあるかどうか、再チェックします:
beastify/ beasts/ frog.jpg snake.jpg turtle.jpg button/ beasts.png content_scripts/ beastify.js popup/ choose_beast.css choose_beast.html choose_beast.js manifest.json
Firefox 拡張機能は XPI ファイルとしてパッケージ化されます、これは単に"xpi" の拡張子つきのZIPファイルです。
つまづきポイントとしては、ZIP ファイルは拡張機能の中のファイルを、一つのZIPにしたものである必要があり、格納ディレクトリをZIP化したものではありません。なので動物化のファイルから、一つのXPIを作るには、 コマンドシェルで"beastify" ディレクトリに移動して、次のようにタイプします:
# in beastify/ zip -r ../beastify.xpi *
XPI をインストールするには、単に Firefox で開きます:
- ファイルメニューから開くを選ぶ、または Ctrl/Cmd+O を押す
- 選択ダイアログから "beastify.xpi" を選択する
署名されていない拡張機能をインストールする旨の警告が出るでしょう、警告を受諾します。
Firefoxツールバーにアイコンが出現するのが見えるでしょう。webページを開いて、アイコンをクリックし、動物を選択すると、webページの画像が変化するのが見えます。