この記事では 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 自身からの相対パスとなる事に気をつけてください。
ツールバーボタン
The toolbar button needs an icon, and our manifest.json promised that we would have an icon for the toolbar at "button/beasts.png".
Create the "button" directory and copy an icon named "beasts.png". You could use the one from our example, which is taken from the IconBeast Lite icon set and used under the terms of its license.
If you don't supply a popup, then a click event is dispatched to your extension when the user clicks the button. If you do supply a popup, the click event is not dispatched, but instead, the popup is opened. We want a popup, so let's create that next.
ポップアップ
The function of the popup is to enable the user to choose one of three beasts.
Create a new directory called "popup" under the extension root. This is where we'll keep the code for the popup. The popup will consist of three files:
choose_beast.html
defines the content of the panelchoose_beast.css
styles the contentchoose_beast.js
handles the user's choice by running a content script in the active tab
choose_beast.html
The HTML file looks like this:
<!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>
We just have an element for each animal choice. Note that we include the CSS and JS files from this file, just like a web page.
choose_beast.css
The CSS fixes the size of the popup, ensures that the three choices fill the space, and gives them some basic styling:
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
In the JavaScript for the popup, we listen for click events. If the click was on one of our three animal choices, we inject a content script into the active tab. Once the content script is loaded, we send it a message with the animal choice:
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}); }); });
It uses three WebExtension API functions:
chrome.tabs.executeScript
to inject a content script found at "content_scripts/beastify.js" into the active tabchrome.tabs.query
to get the active tabchrome.tabs.sendMessage
to send a message to content scripts running in the active tab. The message contains the chosen animal as thebeast
property.
コンテントスクリプト
拡張機能のルートフォルダの下に、"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ページの画像が変化するのが見えます。