Chrome拡張機能を初めて作ったので作り方の備忘録です。
きっかけは、コーディングしたWebページをデバッグする際に使っていた自作のスクリプト。これまではHTMLファイルにscriptタグを挿入して実行していましたが、ブラウザのボタンから実行できた方が便利です。そこで、既存のスクリプトからコピペで簡単に「Chrome拡張機能化」できるようなテンプレートを作っておくことにしました。この記事では、その自作テンプレートcxt-templateについて書きます。対応するプラットフォームは、Manifest V3 for Chrome Extensions (MV3)です。
ソース: https://github.com/kazhashimoto/cxt-template
cxt-templateはそれ自体がChrome拡張として動作し、提供する機能とUIは単純です。
- 表示中のページのコンテンツに「ユーザー定義のスクリプト」のコードをinjectして実行する。※スタブとして記述されているscriptは、console.logに1行出力するだけのものです。
- 表示中のページのコンテンツに「ユーザー定義のCSS」をinjectする
- オプション項目の設定値の保存と読み込み
- UI: オプションページ(サンプル)
- UI: Chromeツールバーに表示される拡張アイコンのトグル(ON/OFF表示)
この拡張機能に対するボタンのアイコンイメージは提供しません。ツールバーには、Chromeがデフォルトで設定した"cxt-template"の頭文字"C"が表示されるだけです。
インストール
適当なディレクトリにリポジトリをcloneします。
$ git clone https://github.com/kazhashimoto/cxt-template.git
Chromeを起動して、以下の手順でcxt-templateを拡張機能として読み込みます。
-
chrome://extensions/
にアクセスし、拡張機能の管理ページを開きます。(画面の詳細はこちら) - 「デベロッパーモード」をONにします。
- 「パッケージ化されていない拡張機能を読み込む」をクリックします。
- ファイル読み込みのダイアログで、ローカルに展開したリポジトリの
./cxt-template/extension
ディレクトリを選択します。
適当なWebサイトを開いてDevToolsを起動し、cxt-templateのボタンをクリックすると、スタブのscriptが実行されたことを示すメッセージがconsole.logに出力されます。右側のObjectの内容はoptionsの初期値です。
### start process ### ▶︎Object
ファイル構成
テンプレートのファイル一式は、extensionフォルダにあります。ファイル構成は下表のとおりです。
ファイル名 | 説明 |
---|---|
background.js | Chrome拡張のservice workerに使われるbackgroundスクリプトです。 |
content.css | Chrome拡張からターゲットのWebページのコンテンツに挿入される「ユーザー定義のスタイルシート」です。 |
content.js | Chrome拡張からターゲットのWebページのコンテンツに挿入される「ユーザー定義のscript」です。 |
manifest.json | Chrome拡張のmanifestファイルです。 |
options.css | オプションページのスタイルシートです。 |
options.html | Chrome拡張のオプションページのHTMLファイルです。 |
options.js | オプションページのロジックを実装するJavaScriptファイルです。 |
Permissions
manifest.jsonで指定しているpermissionは以下の3つです。
"permissions": [
"activeTab", "scripting", "storage"
],
permission | 目的 |
---|---|
activeTab | ユーザーが拡張アイコンをクリックして呼び出した時、現在アクティブなタブへのアクセス権を一時的に与えるため。 |
scripting | chrome.scriptingAPIを使用して、ターゲットのWebページのコンテンツにスクリプトやスタイルシートを挿入するため |
storage | chrome.storage APIを使用して、optionの設定値を保存・読み込みするため |
ユーザー定義のscript
ユーザー定義のscriptはcontent.jsの関数内に記述します。
content.jsは以下の構造になっています。機能の組み込みにコーディングが必要な箇所は、コメントに示した[1],[2],[3]の部分です。
(function(classname, init_options, process) {
// ....
})('_example', // [1] <body>に追加するclass名
function(options) {
// [2] オプションの初期値を設定するコードをここに書く
},
function(options, active) {
// [3] 機能を実装するコードの本体をここに書く
if (!active) {
// アイコンの状態がOFFになって呼ばれた時
// OFFの時の処理をここに書く
return;
}
// 以下、アイコンの状態がONの時のコード
});
class名[1]は次のようにbody要素に設定されます。
表示中のタブについて、ユーザーがツールバーのcxt-templateアイコンを最初にクリックした時、もしくは状態がOFF表示のアイコンをクリックした時:
<body class="_example _example-active">
状態がON表示のアイコンをクリックした時:
<body class="_example">
オプションページ
options.htmlは、サンプルとして2つのcheckboxと2つのカラーピッカーを含んでいます。
ユーザーが「保存」ボタンをクリックすると、以下のプロパティを持つオブジェクトの設定値がChromeのstorageに書き込まれます。
{
items: {item1: true, item2: true},
colors: {color1: #ff0000, color2: #0000ff}
}
ツールバーのcxt-templateアイコンがクリックされると、storageからオプションの設定値が読み込まれ、上記[3]に示したユーザー定義scriptを実行する関数の1番目のパラメーターにセットされます。
function(options, active)
storageに保存されたオプションがない場合、[3]のscriptに渡されるoptionにはプリセット値(上記[2]で初期化した値)が入っています。プリセット値かどうかは、プロパティpreset
の値(true/false)で確認できます。
if (options.preset) { // optionsには初期値が入っている
...
} else { // optionsにはstorageから読み込まれた値が入っている
...
}
実施例
cxt-templateを使ってサクッと書いたChrome拡張のサンプルimg-markerです。img-markerは、カレントのタブに表示されたページのコンテンツに含まれるimg要素、および背景画像が設定された要素について枠線を表示します。