Please note, this is a STATIC archive of website developer.mozilla.org from 03 Nov 2016, cach3.com does not collect or store any user information, there is no "phishing" involved.

Revision 1035076 of 2 つめの WebExtension

  • リビジョンの URL スラグ: Mozilla/Add-ons/WebExtensions/Walkthrough
  • リビジョンのタイトル: Walkthrough
  • リビジョンの ID: 1035076
  • 作成日:
  • 作成者: hashedhyphen
  • 現行リビジョン? いいえ
  • コメント テスト

このリビジョンの内容

この記事では 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ページの画像が変化するのが見えます。

 

 

 

このリビジョンのソースコード

<p>この記事では Firefox 用の WebExtension の作成を、最初から最後まで、一通り経験します。</p>

<p>この拡張機能は、Firefoxのツールバーに新しいボタンを追加します。ユーザがボタンをクリックすると、動物を選択できるポップアップを表示します。いったん動物を選択すると、ページコンテンツを、選択した動物の画像に置き換えます。</p>

<p>実装するには、次のことを行います:</p>

<ul>
 <li><strong>ブラウザのアクションを定義します、それはFirefoxツールバーに付属するボタンになります</strong><br />
  ボタン用に、次のものを提供します:
  <ul>
   <li>"beasts.png"というアイコン</li>
   <li>ボタン押下時に開くポップアップ。ポップアップには HTML, CSS, JavaScriptが含まれる</li>
  </ul>
 </li>
 <li><strong>コンテントスクリプト"beastify.js"を書きます。これはwebページの中へインジェクトされます。</strong><br />
  これが、実際にページを変更するコードになります。</li>
 <li><strong>webページ内の画像を置き換えるための、動物の画像をパッケージします。</strong><br />
  "web アクセス可となるリソース" 画像を作り、ページから参照できるようにします。</li>
</ul>

<p>拡張機能の全体構成は次のように図示できます:</p>

<p><img alt="" src="https://mdn.mozillademos.org/files/11467/beastify-anatomy.svg" style="display:block; height:664px; margin-left:auto; margin-right:auto; width:500px" /></p>

<p>これはきわめて単純な拡張機能ですが、WebExtensions API の基本コンセプトの多くを示しています:</p>

<ul>
 <li>ツールバーへのボタン追加</li>
 <li>HTML, CSS, JavaScriptを用いたポップアップパネルの定義</li>
 <li>web ページへのコンテントスクリプトの注入</li>
 <li>コンテントスクリプトと、拡張機能のその他の部分との通信</li>
 <li>拡張機能へ、web ページによって使用されるリソースを一緒にパッケージすること</li>
</ul>

<p><a href="https://github.com/mdn/webextensions-examples/tree/master/beastify">GitHub上で、完全なソースコード</a>を見ることができます。</p>

<h2 id="前提条件">前提条件</h2>

<p>{{ Page ("/ja/docs/Mozilla/Add-ons/WebExtensions/Prerequisites") }}</p>

<h2 id="WebExtensionを書く">WebExtensionを書く</h2>

<p>新規ディレクトリを作成し、そこへ移動します:</p>

<pre class="brush: bash">
mkdir beastify
cd beastify</pre>

<h3 id="manifest.json">manifest.json</h3>

<p>そして "manifest.json" と呼ばれるファイルを新規作成し、下記の内容を与えます:</p>

<pre class="brush: 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"
  ]

}
</pre>

<ul>
 <li>最初の3つのキー: <strong><code>manifest_version</code></strong>, <strong><code>name</code></strong>, <strong><code>version</code></strong>は必須で、拡張機能用の基本的なメタデータを含んでいます。</li>
 <li><strong><code>permissions</code></strong> は拡張機能で必要となるパーミッションをリスト化しておきます。単に、すべての HTTP と HTTPS ページを編集するためにパーミッションを問い合わせています: <code><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/permissions">permissions</a></code> キーのドキュメントを見てください。ここにある <code>activeTab</code> パーミッションの使用が好ましいですが、現在Firefoxでサポートされていません。</li>
 <li><strong><code>browser_action</code></strong> はツールバーボタンを指定します。ここでは3つの情報を提供しています:
  <ul>
   <li><strong><code>default_icon</code></strong> は必須で、ボタン用のアイコンを指します。</li>
   <li><strong><code>default_title</code></strong> はオプションで、ツールチップに表示されるでしょう。</li>
   <li><strong><code>default_popup</code></strong> は、ユーザがボタンをクリックした時にポップアップを表示したい場合に使われます。我々はそのようにしており、そのためこのキーを含むようにして、拡張機能に同梱する HTML ファイルを指定できるようにしました。</li>
  </ul>
 </li>
 <li><strong><code>web_accessible_resources</code></strong> では、webページからアクセス可能にしたいファイルをリスト化します。この拡張機能は、ページ内の画像を拡張機能に同梱した画像に置き換えるため、ページからこれらの画像がアクセス可能にしておく必要があります。</li>
</ul>

<p>指定するすべてのパスは、 manifest.json 自身からの相対パスとなる事に気をつけてください。</p>

<h3 id="ツールバーボタン">ツールバーボタン</h3>

<p>ツールバーボタンにはアイコンが必要で、 manifest.json は "button/beasts.png" にてツールバーアイコンを持つことを約束します。</p>

<p>"button" ディレクトリを作って、"beasts.png" というアイコンをコピーします。<a href="https://github.com/mdn/webextensions-examples/blob/master/beastify/button/beasts.png">我々のサンプルから</a>使用できて、これは<a href="https://www.iconbeast.com/free">IconBeast Lite アイコン集</a>から取ってきたもので、その<a href="https://www.iconbeast.com/faq/">ライセンス(英語)</a>条件の下で使用できます。</p>

<p>ポップアップを使わない場合、ユーザがボタンをクリックした時にクリックイベントが割り当てられます。ポップアップを使う場合、クリックイベントは割り当てられず、ただしその代わりに、ポップアップが開きます。私たちはポップアップが欲しいので、次で作成しましょう。</p>

<h3 id="ポップアップ">ポップアップ</h3>

<p>ポップアップ機能は、ユーザが3つの動物から1つ選択できるようにします。</p>

<p>拡張機能のルートの下に、 "popup" というディレクトリを新規作成します。これはポップアップ用のコードを保管しておく場所です。ポップアップは次の3ファイルから構成されます:</p>

<ul>
 <li><strong><code>choose_beast.html</code></strong> パネルのコンテンツを決める</li>
 <li><strong><code>choose_beast.css</code></strong> コンテンツのスタイルを指定</li>
 <li><strong><code>choose_beast.js</code></strong> アクティブなタブ内でコンテントスクリプトを実行することで、ユーザの選択を取り扱う</li>
</ul>

<h4 id="choose_beast.html">choose_beast.html</h4>

<p>HTMLファイルは次のようになる:</p>

<pre class="brush: html">
&lt;!DOCTYPE html&gt;

&lt;html&gt;
  &lt;head&gt;
    &lt;meta charset="utf-8"&gt;
    &lt;link rel="stylesheet" href="choose_beast.css"/&gt;
  &lt;/head&gt;

  &lt;body&gt;
    &lt;div class="beast"&gt;Frog&lt;/div&gt;
    &lt;div class="beast"&gt;Turtle&lt;/div&gt;
    &lt;div class="beast"&gt;Snake&lt;/div&gt;

    &lt;script src="choose_beast.js"&gt;&lt;/script&gt;
  &lt;/body&gt;

&lt;/html&gt;</pre>

<p>単に、動物の選択ごとに要素を持っています。単にwebページの様に、CSS と JS ファイルをこのページにインクルードしている事に注意してください。</p>

<h4 id="choose_beast.css">choose_beast.css</h4>

<p>CSS はポップアップのサイズを固定し、3つの選択肢がスペースを埋めることを保証し、基本的なスタイリングを与えます:</p>

<pre class="brush: css">
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;
}</pre>

<h4 id="choose_beast.js">choose_beast.js</h4>

<p>ポップアップ用の JavaScript では、クリックイベントをリッスンします。3つの動物の上でクリックされた場合、アクティブなタブにコンテントスクリプトを注入します。いったんコンテントスクリプトがロードされたら、動物の選択のメッセージを送ります:</p>

<pre class="brush: js">
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});
  });

});
</pre>

<p>これは3つの WebExtension API 関数を使っています:</p>

<ul>
 <li><strong><code>chrome.tabs.executeScript</code></strong> は "content_scripts/beastify.js" にあるコンテントスクリプトをアクティブなタブに注入します</li>
 <li><strong><code>chrome.tabs.query</code></strong> はアクティブなタブを取得します</li>
 <li><strong><code>chrome.tabs.sendMessage</code></strong> はアクティブなタブ内で実行されるコンテントスクリプトにメッセージを送ります。メッセージは <code>beast</code> プロパティにある選択した動物が入っています。</li>
</ul>

<h3 id="コンテントスクリプト">コンテントスクリプト</h3>

<p>拡張機能のルートフォルダの下に、"content_scripts" という名のディレクトリを新規作成し、その中に "beastify.js" という名のファイルを作成し、下記のコンテンツを記述します:</p>

<pre class="brush: 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");
  }
}

</pre>

<p>コンテントスクリプトは拡張機能からの(特に、上記 "choose_beast.js" からの)メッセージに対するリスナーを追加します リスナー内で、これは次のことを行います:</p>

<ul>
 <li><code>document.body 内のすべての要素を削除します。</code></li>
 <li>動物名を、画像を指定する URL に変換します。</li>
 <li>URLを指定する <code>&lt;img&gt;</code> 要素を作り、DOM に挿入する</li>
 <li>メッセージリスナを削除する</li>
</ul>

<h3 id="動物">動物</h3>

<p>最後に、動物の画像を入れておく必要があります。</p>

<p>"beasts" という名のディレクトリを作成し、その中に3つの画像を、適切な名前をつけて追加します。<a href="https://github.com/mdn/webextensions-examples/tree/master/beastify/beasts">GitHub リポジトリ</a>から画像を取得できます、あるいはここからでも:</p>

<p><img alt="" src="https://mdn.mozillademos.org/files/11459/frog.jpg" style="display:inline-block; height:200px; margin:20px; width:200px" /><img alt="" src="https://mdn.mozillademos.org/files/11461/snake.jpg" style="display:inline-block; height:200px; margin:20px; width:200px" /><img alt="" src="https://mdn.mozillademos.org/files/11463/turtle.jpg" style="display:inline-block; height:200px; margin:20px; width:200px" /></p>

<h2 id="パッケージ化とインストール">パッケージ化とインストール</h2>

<p>正しいファイルが正しい場所にあるかどうか、再チェックします:</p>

<pre>
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</pre>

<p>Firefox 拡張機能は XPI ファイルとしてパッケージ化されます、これは単に"xpi" の拡張子つきのZIPファイルです。</p>

<p>つまづきポイントとしては、ZIP ファイルは拡張機能の中のファイルを、一つのZIPにしたものである必要があり、格納ディレクトリをZIP化したものではありません。なので動物化のファイルから、一つのXPIを作るには、 コマンドシェルで"beastify" ディレクトリに移動して、次のようにタイプします:</p>

<pre class="brush: bash">
   # in beastify/
   zip -r ../beastify.xpi *</pre>

<p>XPI をインストールするには、単に Firefox で開きます:</p>

<ul>
 <li>ファイルメニューから開くを選ぶ、または Ctrl/Cmd+O を押す</li>
 <li>選択ダイアログから "beastify.xpi" を選択する</li>
</ul>

<p>署名されていない拡張機能をインストールする旨の警告が出るでしょう、警告を受諾します。</p>

<p>Firefoxツールバーにアイコンが出現するのが見えるでしょう。webページを開いて、アイコンをクリックし、動物を選択すると、webページの画像が変化するのが見えます。</p>

<p>&nbsp;</p>

<p>&nbsp;</p>

<p>&nbsp;</p>
このリビジョンへ戻す