スポンサーリンク

Chromeアドオン開発のチュートリアル: ページの背景色を変えるアドオン(Getting Started Tutorial)

※この記事は,GoogleのGetting Started Tutorialを日本語訳したものです。


Chromeアドオンは,複数のコンポーネントによって成り立っています。

コンポーネント同士は,互いに関連性があります(cohesive)。


コンポーネントの種類としては,

  • その他のロジックを記述したファイル

などがあります。


アドオンのコンポーネントは,HTML,CSS,JavaScriptといったWeb開発の技術を用いて作成されます。

アドオンごとに機能が異なりますので,必要となってくるコンポーネントも変わってきます。



このチュートリアルでは,一つのアドオンを作ります。

developer.chrome.com のドメイン上にある任意のページ上で,ページの背景色を変更することが可能になるようなアドオンです。

これを作ろうとすると,多くのコアコンポーネントを扱うことになるので,それらの関係を理解するための入門用デモとしてうってつけです。


始めるにあたって,まずこのアドオンのファイルを格納するためのフォルダを新規作成してください。

なお完成版のアドオンはこちらからダウンロードできます。

マニフェストを作成する

アドオン開発は,まずはマニフェスト作りから始まるのです。

manifest.json というファイルを作成し,下記のコードを記述してください。
(あるいは,こちらからダウンロードすることもできます。)

  {
    "name": "Getting Started Example",
    "version": "1.0",
    "description": "Build an Extension!",
    "manifest_version": 2
  }


この時点ですでに,マニフェストのファイルが存在するフォルダを,デベロッパーモードでChromeに読み込ませることができます。

  • クロームで chrome://extensions を開き,アドオンの管理ページを開いてください。
    • ブラウザのメニューから「その他のツール→拡張機能」で開くこともできます。
  • 「デベロッパーモード」の隣にあるツマミをクリックして,デベロッパーモードを有効にします。
  • 「パッケージ化されていない拡張機能を読み込む」ボタンをクリックし,先程のアドオン開発用に作ったフォルダを選択します。

読み込めましたね?このアドオンのインストールに成功しました。

マニフェストにアイコンが定義されていないので,このアドオンを表すために,デフォルトのツールバーアイコンが表示されます。

処理を追加する

アドオンのインストールはできましたが,これではまだ,何も処理がありません。

そこで,アドオンのフォルダの中に,バックグラウンド・スクリプトを追加しましょう。

background.js という名前のファイルを作成するか,ここからダウンロードしてください。


バックグラウンドスクリプトもそうですが,アドオンを構成する重要なコンポーネントはどれも皆,マニフェストの中に登録され宣言されていなければなりません。

マニフェストの中に,バックグラウンド・スクリプトを宣言しておくと,アドオンはどのファイルをスクリプトとして参照すればよいのかがわかりますし,そのファイルがどういう風に振る舞うべきかもわかります。

  {
    "name": "Getting Started Example",
    "version": "1.0",
    "description": "Build an Extension!",
    "background": { // この部分を追記
      "scripts": ["background.js"],
      "persistent": false
    },
    "manifest_version": 2
  }

こうしておけば,アドオンはバックグラウンド・スクリプトの存在を識別できます。

(マニフェストを見てわかるように,そのスクリプトは非persistentであるような属性を持っています。)

そしてアドオンは,このスクリプトを読み込み,リッスンすべきイベントを判別します。


このアドオンは,インストールされた直後に,persistent な変数からの情報読み込みを必要とします。

そのために, background.js の中に,runtime.onInstalled というイベントをリッスンするコードを書きましょう。


onInstalled リスナの中で,アドオンはstorage API を経由して,値を保存します。

こうすることで,アドンを構成する他の様々なコンポーネントの中から,その保存された値にアクセスし,値を更新することもできるようになります。

// アドオンのインストール時のイベントをリッスンする
chrome.runtime.onInstalled.addListener(function() {

  // ストレージAPIを経由して値を保存する
  chrome.storage.sync.set({color: '#3aa757'}, function() {

    // ログ表示
    console.log("The color is green.");

  });

});


ここではストレージAPIを使っていますが,ほぼどんなAPIを使う場合にも必要になるのが,利用するAPIの "permissions" をマニフェストの中で宣言しておくことです。

マニフェストの中で宣言しておくことで,アドオンはそのAPIを利用可能になります。

  {
    "name": "Getting Started Example",
    "version": "1.0",
    "description": "Build an Extension!",
    "permissions": ["storage"], // ここを追記
    "background": {
      "scripts": ["background.js"],
      "persistent": false
    },
    "manifest_version": 2
  }


アドオンの管理ページを再度開き,今作っているアドオンのところにあるリロードボタンを押してください。

「ビューを検証」という文言の隣に,「バックグラウンドページ」というリンクができているはずです。



「バックグラウンドページ」のリンクをクリックすると,この部分が有効化され,Chromeの開発者ツールが開きます。

そこでもう一度,Chromeブラウザ上でアドオン管理ページを開き,今作っているアドオンのところにあるリロードボタンを押してみてください。

Chrome開発者ツール上で,"The color is green." というコンソールログが出力されます。

ユーザ・インタフェースを導入する

拡張機能は様々な形態のUI(ユーザ・インタフェース)を持つことができます。


今回の拡張機能の場合は,ポップアップという形でのUIになります。

フォルダ上に popup.html という名前のファイルを作成するか,こちらからダウンロードしてください。


この拡張機能では,背景色を変更するためのボタンが必要です。

  <!DOCTYPE html>
  <html>
    <head>

      <style>
        button {
          height: 30px;
          width: 30px;
          outline: none;
        }
      </style>

    </head>
    <body>

      <button id="changeColor"></button>

    </body>
  </html>

バックグラウンド・スクリプトと同じように,このファイルもマニフェストに登録する必要があります。

page_action という項目内に,このファイルがポップアップとして動作するように記載しましょう。

  {
    "name": "Getting Started Example",
    "version": "1.0",
    "description": "Build an Extension!",
    "permissions": ["storage"],
    "background": {
      "scripts": ["background.js"],
      "persistent": false
    },

    "page_action": { // この部分
      "default_popup": "popup.html",
    },

    "manifest_version": 2
  }


さらに page_action の default_icon という項目内に,ツールバー用のアイコンを指定することができます。

画像フォルダをこちらからダウンロードして,解凍し,拡張機能のフォルダ内に設置してください。

マニフェストを更新し,拡張機能から見てこれらの画像がどう使われるかを指定しましょう。

  {
    "name": "Getting Started Example",
    "version": "1.0",
    "description": "Build an Extension!",
    "permissions": ["storage"],
    "background": {
      "scripts": ["background.js"],
      "persistent": false
    },
    
    "page_action": {
      "default_popup": "popup.html",

      "default_icon": { // この部分
        "16": "images/get_started16.png",
        "32": "images/get_started32.png",
        "48": "images/get_started48.png",
        "128": "images/get_started128.png"
      }
    },

    "manifest_version": 2
  }


拡張機能はさらに,アドオンの管理ページ上などで画像を表示します。

パーミッションの警告時の表示や,favicon としての表示もあります。

これらの用途での画像表示は,マニフェスト内の icons という項目内に記載・指定されます。

  {
    "name": "Getting Started Example",
    "version": "1.0",
    "description": "Build an Extension!",
    "permissions": ["storage"],
    "background": {
      "scripts": ["background.js"],
      "persistent": false
    },
    "page_action": {
      "default_popup": "popup.html",
      "default_icon": {
        "16": "images/get_started16.png",
        "32": "images/get_started32.png",
        "48": "images/get_started48.png",
        "128": "images/get_started128.png"
      }
    },
    
    "icons": { // この部分
      "16": "images/get_started16.png",
      "32": "images/get_started32.png",
      "48": "images/get_started48.png",
      "128": "images/get_started128.png"
    },
    
    "manifest_version": 2
  }


この段階で,いま作っている拡張機能をリロードすると,グレイスケールのアイコン付きで拡張機能が表示されます。


しかし,機能的にはまだ何も新しいものを追加されたことになっていません。

マニフェスト内で page_action が宣言されていますが,
いつどんなタイミングでユーザが popup.html を使用できるのかがまだ指定されていないので,
拡張機能がブラウザ上にポップアップを表示できないのです。

そこで,バックグラウンド・スクリプトの runtime.onInstalled のイベントリスナの中に,
declarativeContent API を使って
いつポップアップファイルを使用できるのか明示的に宣言しましょう。

  chrome.runtime.onInstalled.addListener(function() {
    chrome.storage.sync.set({color: '#3aa757'}, function() {
      console.log('The color is green.');
    });
    
    
    // この部分
    chrome.declarativeContent.onPageChanged.removeRules(undefined, function() {

      chrome.declarativeContent.onPageChanged.addRules(
        [{
          conditions: [
  
            new chrome.declarativeContent.PageStateMatcher({
               pageUrl: {
                 hostEquals: 'developer.chrome.com'
               },
            })

          ],
  
          actions: [
            new chrome.declarativeContent.ShowPageAction()
          ]
        }]
      );

    });


  });


拡張機能は, declarativeContent API を使用するために,マニフェスト中でパーミッション設定が必要です。

  {
    "name": "Getting Started Example",
  ...
    "permissions": ["declarativeContent", "storage"], // この部分
  ...
  }


こうすることで,ここまでブラウザのツールバー上でグレースケールだったアイコンが,フルカラーで表示されるようになります。

URLに "developer.chrome.com" が含まれるようなページにユーザが遷移した時に,
このアイコンはフルカラーになり,
ユーザはそれをクリックしてpopup.htmlを呼び出すことができます。


ポップアップUI導入の最後のステップは,UI内のボタンに色設定の機能をもたせることです。

拡張機能のフォルダに popup.js というファイルを作成するか,こちらからダウンロードしてください。

その中には,下記のようなコードを記述します。

  let changeColor = document.getElementById('changeColor');

  chrome.storage.sync.get('color', function(data) {

    changeColor.style.backgroundColor = data.color;
    changeColor.setAttribute('value', data.color);

  });

このコードは,popup.htmlの中からボタン要素を抽出し,
ストレージの中から色の設定値を取り出しています。

そして色の設定値をボタンの背景色に適用しています。


このロジック popup.js を,popup.htmlの中にscriptタグとして含めましょう。

<!DOCTYPE html>
<html>
...
  <body>
    <button id="changeColor"></button>

    <script src="popup.js"></script>

  </body>
</html>

拡張機能をリロードすると,緑色のボタンが見えるはずです。

これは,ボタンに背景色が適用されているということです。

タブ内の背景色を操作するロジック

ここまでで,拡張機能から見てポップアップが利用可能になりました。

developer.chrome.com上でポップアップを表示し,色のついたボタンを表示する,という所までできました。


ここから先,ユーザとのインタラクションに応じて,あと少しロジックの追加が必要です。

popup.jsに下記のようなコードを追記しましょう。

  let changeColor = document.getElementById('changeColor');
  ...

  // ここから追記
  changeColor.onclick = function(element) {
  
    let color = element.target.value;

    chrome.tabs.query(

      {
        active: true, 
        currentWindow: true
      }, 

      function(tabs) {
        chrome.tabs.executeScript(
          tabs[0].id,
          {
            code : 'document.body.style.backgroundColor = "' 
                      + color 
                      + '";'
          }
        );
      }

    );
  };


上記のコードは,ボタンのonclickイベントを追加しています。

そこでは,動的に組み上げたJSコードをタブ内に注入しています。これにより,ページの背景色がボタンの背景色と同じ色になります。


このように動的にJSコードを注入すれば,Webページ上に不必要なコードを追記する必要がなく,ユーザの開いたページ上で任意のJSコードを実行することができます。


上記のコードを実行するためには,マニフェストに activeTab のパーミッションを追記します。

これにより,拡張機能は tabs API にアクセスすることが可能になり,tabs.executeScript を実行できるようになります。

  {
    "name": "Getting Started Example",
  ...
    "permissions": ["activeTab", "declarativeContent", "storage"],
  ...
  }

これで,今回作ろうとしていた拡張機能の動作が実装できました。

拡張機能をリロードし,Webページをリロードしてから,ポップアップを開き,ボタンを押して緑色にしてみましょう。


もう少し変化を加えてみます。ユーザはきっと,背景色を緑色だけでなく,他の色にも変化させてみたいはずです。

ユーザが選択可能なオプションを増やしてみる

今のところ,この拡張機能は,背景色を緑色に変えることしかできません。

オプションページを追加することによって,ユーザが拡張機能の動作をもっと変えられるようにし,ブラウザーの動作をより一層カスタマイズできるようにしてみましょう。

フォルダ上に options.html というファイルを作り,下記のコードを記述してください。こちらからダウンロードもできます。

  <!DOCTYPE html>
  <html>
    <head>

      <style>
        button {
          height: 30px;
          width: 30px;
          outline: none;
          margin: 10px;
        }
      </style>

    </head>
    <body>

      <div id="buttonDiv">
      </div>

      <div>
        <p>背景色を選んでください。</p>
      </div>

    </body>
    <script src="options.js"></script>
  </html>


このオプションページをマニフェストに登録します。

  {
    "name": "Getting Started Example",
    ...
    
    // ここ
    "options_page": "options.html",

    ...
    "manifest_version": 2
  }


拡張機能をリロードし,詳細をクリックします。

詳細ページを下にスクロールし,拡張機能のオプション(Extension options)を選んでオプションページを表示します。今は空白のページとして表示されるはずです。


最後のステップは,オプションページにロジックを追加することです。

options.jsというファイルを作り,下記のコードを記述してください。こちらからダウンロードもできます。

  let page = document.getElementById('buttonDiv');
  
  const kButtonColors = ['#3aa757', '#e8453c', '#f9bb2d', '#4688f1'];


  function constructOptions(kButtonColors) {

    for (let item of kButtonColors) {

      let button = document.createElement('button');

      button.style.backgroundColor = item;

      button.addEventListener('click', function() {
        chrome.storage.sync.set({color: item}, function() {
          console.log('color is ' + item);
        })
      });

      page.appendChild(button);
    }

  }
  constructOptions(kButtonColors);

4つの色の選択肢があって,オプションページ内にボタンが生成され,onclickイベントリスナも作られます。

ユーザがボタンをクリックすると,拡張機能のstorage内の値(グローバル値)を書き換えます。

この拡張機能の全ファイルは,色情報の値をグローバル値としてのstorageから取り出していますので,他に何も更新すべき値はありません。

補足

Googleのドキュメント翻訳に関するライセンス・ポリシー:

Site Policies | Google Developers
https://developers.google.com/terms/site-policies

  • When you see a page with this notice you are free to use nearly everything on the page in your own creations. For example, you could quote the text in a book, cut-and-paste sections to your blog, record it as an audiobook for the visually impaired, or even translate it into Swahili. Really. That's what open content licenses are all about. We just ask that you give us attribution when you reuse our work. (スワヒリ語に翻訳しても良い)
  • You may also find the following notice on the bottom of some pages: Except as otherwise noted, the content of this page is licensed under the Creative Commons Attribution 3.0 License, and code samples are licensed under the Apache 2.0 License. For details, see our Site Policies.