一から作ってみた時の作業記録みたいなもの。
ディレクトリを作る
適当にディレクトリを作る
manifest.jsonを作る
以下のような内容でプラグインを作ってディレクトリに入れる。
{
"name": "テストプラグイン",
"version": "0.1",
"description": "テストプラグイン説明",
"manifest_version": 2
}
manifest.xmlの詳しい書き方は公式サイト参照。
拡張機能を入れてみる
Chromeでchrome://extensions/
にアクセスし、右上から「デベロッパーモード」を有効にする。
「パッケージ化されていない拡張機能を読み込む」から先程作ったディレクトリを指定する。
拡張のアイコンを設定してみる
manifest.jsonファイルに以下のように書き足す。
{
:,
"icons": {
"16": "images/icon16.png",
"32": "images/icon32.png",
"48": "images/icon48.png",
"128": "images/icon128.png"
}
}
アイコンはもちろん対象の場所に用意する。
その後再度「読み込む」。
するとアイコンが適用される。
ちなみに各アイコンのサイズは以下の通りらしい。
サイズ | 使われる場所 |
---|---|
16x16 | 拡張機能ページのfavicon |
32x32 | Windowsの場合、変倍がかかってしまうのでこのアイコンを48x48アイコンの代わりに利用しているらしい |
48x48 | 拡張機能の管理ページに表示されるアイコン |
128x128 | Chrome ウェブストアで表示されるアイコン |
ログだけ出力する機能を作る
適当にGitHubのユーザー名を書き換えるだけのものを作ってみる。
manifest.jsonファイルに以下のように書き足す。
{
:,
"background": {
"scripts": ["js/background.js"],
"persistent": false
}
}
そして以下のようなJavaScriptを書く。
chrome.runtime.onInstalled.addListener(function (details) {
console.log(details.reason);
});
その後再度「読み込む」。
すると「バックグラウンドページ」からDevToolsを起動するとupdate
とログが出力されている。
chrome.runtime.onInstalled
は拡張機能がインストールされた時に呼ばれるイベントで、この時に初期化をしたりする。
これはバックグラウンドページと呼ばれている。
お察しの通り、配列なので複数のスクリプトを列挙することもできる。
persistent
は基本的にfalse
にして残り続けないようにする。
GitHubのページで動くようにする
github.comのタブの情報が得られるように、manifest.jsonファイルに以下のように書き足す。
{
:,
"permissions": ["tabs", "https://github.com/*"]
}
詳細な権限の一覧は公式サイト参照。実はtabs
が入っていないようだけど…
URLのマッチングについてはこちら。
background.jsをこんな感じで書き換える。
chrome.tabs.onUpdated.addListener(function (tabId, changeInfo, tab) {
if (changeInfo.status === 'complete') {
console.log(tabId);
console.log(changeInfo);
console.log(tab);
}
});
するとページをリロードする毎にこんな感じのログが出力される。
GitHubのauthorを書き換えてみる
authorノードの情報を取得する。
authorを右クリック→検証。
更にDev Toolsから右クリック→Copy→Copy selector。
background.jsからタブ内でbase.jsを呼ぶようにする。
chrome.tabs.onUpdated.addListener(function (tabId, changeInfo, tab) {
if (changeInfo.status === 'complete') {
chrome.tabs.executeScript(tab.id, { file: "js/base.js" });
}
});
chrome.tabs.executeScriptは、そのタブで指定したスクリプトを実行させる。
バックグラウンドページのスクリプトはそのページのスクリプトとは分離されていてページ内の情報を読み書きできないので、こういうかたちになる。
base.jsでは先程取得したセレクタをそのままquerySelectorに貼り付けて利用する。
var authorNode = document.querySelector('#js-repo-pjax-container > div.pagehead.repohead.instapaper_ignore.readability-menu.experiment-repo-nav > div > h1 > span.author > a');
if (authorNode) {
authorNode.innerHTML = 'hoge';
}
設定画面を作ってみる
次は設定画面を作ってみる。hogeだけだと微妙なので自分で設定できるようにする(そういう問題ではないが)。
{
:,
"options_page": "html/option.html"
}
適当にHTMLの設定画面を作る。
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css" integrity="sha384-WskhaSGFgHYWDcbwN70/dfYBj47jz9qbsMId/iRN3ewGhXQFZCSftd1LZCfmhktB" crossorigin="anonymous">
<title>設定</title>
</head>
<body>
<div class="container">
<h1>設定</h1>
<form>
<div class="form-group">
<label for="author">Author</label>
<input class="form-control" type="text" name="author" id="author">
</div>
<div class="form-group">
<button class="btn btn-default" name="save" type="button">更新</button>
</div>
</form>
</div>
</body>
</html>
「拡張機能のオプション」ができているので、そこから「↗」マークをクリックする。
次に、設定を読み書きしたいのでローカルストレージを利用する。
manifest.jsonに権限を追加してローカルストレージにアクセスできるようにする。
{
:,
"permissions": ["tabs", "https://github.com/*", "storage"]
}
オプションのページでJavaScriptを読み込む。
:
<script type="text/javascript" src="/js/option.js"></script>
<title>設定</title>
:
読み込み先のJavaScriptを書く。
document.addEventListener('DOMContentLoaded', function () {
chrome.storage.local.get("github_author", function (item) {
const author = item.github_author;
if (author) {
document.querySelector('[name="author"]').value = author;
}
});
document.querySelector('[name="save"]').addEventListener('click', function (e) {
const author = document.querySelector('[name="author"]').value;
chrome.storage.local.set({ "github_author": author }, function () {
alert('saved');
});
});
});
上半分でローカルストレージに値があったらフォームに初期値として入力している。
下半分で「保存」ボタン押下時にローカルストレージに値を保存している。
これで設定画面が機能するようになった。
ちなみにchrome.storage.local
の場合、ローカルに保存されるのでマシンごとに値が異なる。
アカウントごとに同期したい場合は変わりにchrome.storage.sync
を使うと良いらしい。
仕上げにbase.jsで値をローカルストレージから呼ぶように変更する。
var authorNode = document.querySelector(
"#js-repo-pjax-container > div.pagehead.repohead.instapaper_ignore.readability-menu.experiment-repo-nav > div > h1 > span.author > a"
);
if (authorNode) {
chrome.storage.local.get("github_author", function(item) {
const author = item.github_author;
if (author) {
authorNode.innerHTML = author;
}
});
}
拡張機能を再読込し、github.comのページにアクセスしてみる。
すると設定画面で設定した値に書き換わるようになる。
右上のメニューに出してみる
更にmanifest.jsonに書き足す。
{
:,
"browser_action": {
}
}
するとこんな感じでアイコンが出る。何も指定していないので無反応。
ポップアップするHTMLを指定する。
{
:,
"browser_action": {
"default_popup": "html/popup.html"
}
}
popup.htmlの中身はとりあえずほぼ同じにする。
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css" integrity="sha384-WskhaSGFgHYWDcbwN70/dfYBj47jz9qbsMId/iRN3ewGhXQFZCSftd1LZCfmhktB"
crossorigin="anonymous">
<script type="text/javascript" src="/js/option.js"></script>
<title>設定</title>
</head>
<body>
<div class="container" style="width: 200px">
<form>
<div class="form-group">
<label for="author">Author</label>
<input class="form-control" type="text" name="author" id="author">
</div>
<div class="form-group">
<button class="btn btn-default" name="save" type="button">更新</button>
</div>
</form>
</div>
</body>
</html>
右クリックメニューを出してみる
次に右クリックメニュー(コンテキストメニュー)に追加してみる。
更に権限を足す。
{
:,
"permissions": [..., "contextMenus"]
}
background.jsに以下のように書き足す。
var parentId = chrome.contextMenus.create({
"id": "sampleParent",
"title" : "サンプル親"
});
するとこんな感じになる。
更にサブメニューを追加してみる。
chrome.contextMenus.create({
"id": "sampleChild",
"title" : "サンプル子",
"parentId" : parentId
});
するとこんな感じ。
クリックした時のイベント登録はこんな感じ。
これでサンプル子をクリックした時にアラートダイアログが表示される。
chrome.contextMenus.onClicked.addListener( function(info, tab) {
alert(info.menuItemId + "をクリック");
});
参考
Getting Started Tutorial - Google Chrome
C:\Users\user_name\AppData\Local\Google\Chrome\User Data\Default\Extensions
にも自分のブラウザに入っている拡張機能がたくさんあるので、それらを参考にすると良いかもしれない。