💉

拡張機能の作り方(コンテンツスクリプトのチュートリアル)

に公開

概要

次にコンテンツスクリプトのチュートリアルを開始します。コンテンツスクリプトは対象サイトで実行される CSS、JavaScript ファイルのことです。拡張機能から対象サイトの DOM にアクセスして、ページの情報を読み取り、変更を加え、拡張機能に情報を渡すことができます。

この節では開いているページにあるタグ数をカウントする拡張機能を作っていきます。対象ページに新しいボタンを挿入し、ボタンが押されたタイミングで対象ページの DOM を読み取り、alertで表示します。サイトを自由にカスタマイズすることができるので、拡張機能といえばコンテンツスクリプトの機能をイメージする方も多いはずです。Web ページの読み取りと書き換えはコンテンツスクリプトの主な役割なので、この節では簡単な拡張機能作成を通じて慣れていきましょう。ここでは次のようなことを学びます。

  • コンテンツスクリプトを挿入して対象サイトに新たな DOM を追加する
  • マッチパターンを使用して対象サイトを制限する

拡張機能の作成

それでは空のフォルダを作成してください。フォルダ名はtag-counterにします。

manifest.jsonの作成

まずはフォルダの中にmanifest.jsonを作成し、ディレクトリのルートに保存します。manifest.jsonには次の内容を書いてください。

manifest.json
{
  "name": "Hi Popup",
  "description": "ポップアップを表示する拡張機能",
  "version": "1.0",
  "manifest_version": 3,
  "icons": {
    "16": "images/icon-16.png",
    "32": "images/icon-32.png",
    "48": "images/icon-48.png",
    "128": "images/icon-128.png"
  },
  "content_scripts": [
    {
      "matches": ["<all_urls>"],
      "css": ["content.css"],
      "js": ["content.js"]
    }
  ]
}

"icons"キーについて説明します。先ほど作成した拡張機能では"16"キーにのみ画像のパスを指定しました。ここからは 16x16 サイズのアイコン以外にも、32x32、48x48、128x128 サイズのアイコンも指定します。拡張機能を作り始めるとアイコン画像を設定するのが後回しになって見栄えが悪いまま開発を進めることになりがちです。アイコンがちゃんと指定されていた方がやる気が出るので、できればアイコンの作成と指定は初めにしておきましょう。それぞれのサイズに役割は次のようになっています。

アイコンのサイズ 表示される箇所
16x16 ツールバーに表示されるアイコン、コンテキストメニューのファビコン
32x32 Windows のときのショートかっとを作成したときのアイコンなど
48x48 拡張機能の管理ページ
128x128 インストール時、Chrome ウェブストア

今回使用するアイコン画像はこちらをダウンロードしてご利用ください。ファイル名はそれぞれ、icon-16.pngicon-32.pngicon-48.pngicon-128.pngにします。ダウンロードが完了したら、tag-counterフォルダの中にimagesフォルダを作成し、imagesフォルダの中に画像を配置してください。

icon-16.png icon-32.png icon-48.png icon-128.png

"content_scripts"キーではコンテンツスクリプトのファイルを指定します。

"matches"キーではコンテンツスクリプトを挿入するサイトをマッチパターンで指定します。ここで使われている<all_urls>は特別な値で、すべての URL を対象にコンテンツスクリプトを挿入します。対象とするサイトを制限する場合はhttps://*.google.com/**://zenn.dev/articles/*のようにスキーム、ドメイン、パスを指定したり、ワイルドカードを使用して柔軟に対象サイトを制限することができます。マッチパターンの詳しい解説は次章で行います。

"css"キーと"js"キーは"matches"キーで指定したパターンに一致するイトに挿入するコンテンツスクリプトのパスを記述しています。挿入できるコンテンツスクリプトは CSS ファイルと JavaScript ファイルがあります。ここでは CSS、JavaScript ともに 1 つのファイルしか挿入していませんが、複数のファイルを挿入することもできます。

content.jsの作成

次にコンテンツスクリプトとして挿入する CSS ファイルを作成していきます。content.jsというファイルを作成し、次のコードを入力してください。

content.js
// ボタンの要素を作成
const countButton = document.createElement('button');
countButton.id = 'tag-counter';
countButton.textContent = 'カウント';

// ボタンをページに挿入する
document.body.appendChild(countButton); // ①

// ボタンがクリックされたらh1、h2、h3タグの個数をカウントしてアラートで表示
countButton.addEventListener('click', () => {
  const h1Tags = document.querySelectorAll('h1'); // ②
  const h2Tags = document.querySelectorAll('h2'); // ②
  const h3Tags = document.querySelectorAll('h3'); // ②

  const h1Num = h1Tags.length;
  const h2Num = h2Tags.length;
  const h3Num = h3Tags.length;

  alert(`<h1>: ${h1Num}個、<h2>: ${h2Num}個、<h3>: ${h3Num}`)
})

ここで大事なポイントはウェブ開発でdocumentを使って DOM にアクセスするように、コンテンツスクリプトでもdocumentを使って開いているページの DOM にアクセスができることです。documentを使うためにmanifest.jsonで書いたこと以外は何も特別な設定はしていません。コンテンツスクリプトは Web ページ挿入されているので Web ページの情報にアクセスすることができます。

コンテンツスクリプトでは Web ページの情報を読み取るだけでなく、Web ページに新たな DOM を追加することもできます。① では JavaScript ファイルで作成したボタン要素をページに挿入しています。② でも通常の Web 開発のようにdocument.querySelectorAll()を使って、Web ページの DOM を読み取っています。

content.cssの作成

次にコンテンツスクリプトとして挿入する CSS ファイルを作成します。新しいファイルを作ってcontent.cssという名前にします。この名前はmajifest.json"css"キーで指定したファイル名と一致させる必要があります。次に下の内容を記述します。

content.css
#tag-counter {
  position: fixed;
  top: 20px;
  left: 20px;
  z-index: 9999;
}

CSS で指定した ID はcontent.jsで作成したボタン要素の ID です。コンテンツスクリプトの JS ファイルで動的に作成した要素であっても、対象ページに元から存在する要素であっても、コンテンツスクリプトの CSS ファイルで装飾できます。

拡張機能のインストール

次に拡張機能を Chrome にインストールします。こちらで解説した手順で拡張機能をインストールしてください。
https://zenn.dev/dotdotdot/articles/first-extension#拡張機能を読み込む

動作確認

Wikipedia のページを開いてみましょう。
https://ja.wikipedia.org/wiki/Google_Chrome

するとコンテンツスクリプトで挿入したボタン要素が出現していることがわかります。次にこのボタンをクリックします。

アラートでタグの個数が表示されました。

機能変更

コードを書き換えてみましょう。ページ内に<a>タグがいくつあるのかをカウントしてみます。content.jsを次のように書き換えてください。

content.js
countButton.addEventListener('click', () => {
   const h1Tags = document.querySelectorAll('h1');
   const h2Tags = document.querySelectorAll('h2');
   const h3Tags = document.querySelectorAll('h3');
+  const aTags = document.querySelectorAll('a');

   const h1Num = h1Tags.length;
   const h2Num = h2Tags.length;
   const h3Num = h3Tags.length;
+  const aNum = aTags.length

-  alert(`<h1>: ${h1Num}個、<h2>: ${h2Num}個、<h3>: ${h3Num}`);
+  alert(`<h1>: ${h1Num}個、<h2>: ${h2Num}個、<h3>: ${h3Num}個、<a>: ${aNum}`);
 })

次にchrome://extensions/へ移動して拡張機能ページへ行き、拡張機能を再度読み込みします。次に Wikipedia のページを開き、再度読み込みを行います。コンテンツスクリプトでは拡張機能の読み込みだけでなく、対象ページも再度読み込みを行う点に注意してください。

左上に表示されている「カウント」ボタンをクリックします。すると<a>タグの個数も表示されるようになりました。

まとめ

これで 2 つ目のサンプル拡張機能が完成しました。この節で学んだことは次のものです。

  • コンテンツスクリプトで対象ページの情報を読み込んだり、新たな要素を追加する
  • マッチパターンでコンテンツスクリプトを挿入するサイトを指定する
  • コンテンツスクリプトを編集したら、拡張機能と対象ページの 2 つを読み込む。

Discussion