簡単なアウトプット:Chrome Extensions(拡張機能)編
まえがき
早速ですが、Chrome Extensions(以下、拡張機能と記載)を作成してみました。
作成理由としては以下のとおりです。
-
いままで作成してみよう、と思っていたのですが食わず嫌いで手をつけていませんでした。
この機会に調べて見たくなったから。 -
非常に手軽に、かつ無料でアウトプットできるので、初学者含めて万人に参考になりうる記事がかけるとと思ったから。
-
実際に地味に困ったことがあったので、解決したくなったから。
準備
拡張機能を作成するにあたり以下を準備する必要があります。
- GoogleChrome
作成
実際に作成していきます。
主な参考は、公式のサイトを見ていきます。
https://developer.chrome.com/docs/extensions/get-started?hl=ja
※2−3年前に拡張機能を作成しようとした際は、公式ドキュメント含めて記事がほとんどなかった記憶です。
この数年に充実しました。
基本的にmanifest.json
を用意すれば、最低限のものは作成可能です。
しかしそれだと何もできないです。
例えば、hello worldをポップアップで表示するには、以下の様に用意します。
※公式サイト引用
manifest.json
hello.html
中身はそれぞれ、
{
"manifest_version": 3,
"name": "Hello Extensions",
"description": "Base Level Extension",
"version": "1.0",
"action": {
"default_popup": "hello.html",
"default_icon": "hello_extensions.png"
}
}
<html>
<body>
<h1>Hello Extensions</h1>
</body>
</html>
拡張機能のアクション アイコン(ツールバー アイコン)をクリックすると、ポップアップが表示されるようになります。
自分のほしい機能を作成する
さて今回、この拡張機能を作成し、自分の欲しい物を作ります。
それは、AWSの「リージョンわかるくん」です。
AWSを利用するにあたり、意識しなければいけないことにリージョン(=地域)というものがあります。
ざっくりいうと、AWSは各サービス(S3とかLambdaとか)を利用するときに、どのリージョンのものを利用するかと
設定しなければなりません。
例えば、TokyoのLambdaを設定しはじめた場合
OhioのLambdaを開いても何も表示されません。
この様にリージョンは大事なものです。
しかし、AWSを触っているうちにいつの間にかTokyoのリージョンにしていたつもりが
Oregonになっていたという経験がしばしばあります。
※みなさんはこういう経験がないかもしれませんが、私にはあります。
ということで、特定のリージョンを選択しているときに背景色を変えて
今どのリージョンを触っているかをわかるようにしました。
構成
manifest.json
-
popup.html
css/styles.css
js/content.js
js/popup.js
動きの解説
ファイルの中身は以下に提示しますが、まずはどのファイルがどの様に動いているかを提示します。
-
popup.html
にて、各リージョンに設定したい色を決めます。例えば、Tokyoは赤とか。すると、それをpopup.js
が取得して、chrome.storage.local.
に保存します。 -
content.js
は、ブラウザ上のリージョンが記載されている部分からリージョン名を取得して、先程設定した色をブラウザ上に設定します。
各コードはコチラ。
manifest.json
{
"name": "watch_region!!",
"version": "1.0.0",
"manifest_version": 3,
"author": "nu0640042@gmail.com",
"description": "FOR JAPANESE ONLY. AWSのリージョンを監視する拡張機能です",
"permissions": ["storage"],
"action": {
"default_popup": "popup.html"
},
"content_scripts": [
{
"matches": ["https://*.aws.amazon.com/*"],
"js": ["js/content.js"],
"run_at": "document_end",
"all_frames": true
}
]
}
popup.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="css/styles.css" />
<title>Watch Region</title>
</head>
<body>
<h1>好きな色を選ぶんじゃ!!</h1>
<form>
<div class="input-container">
<label for="colorPickerTokyo">東京(TOKYO):</label>
<input type="color" id="colorPickerTokyo" name="TOKYO_color" />
<button class="clear-btn" data-target="colorPickerTokyo">クリア</button>
</div>
<div class="input-container">
<label for="colorPickerUSEast1">バージニア北部(us-east-1):</label>
<input type="color" id="colorPickerUSEast1" name="us-east-1_color" />
<button class="clear-btn" data-target="colorPickerUSEast1">
クリア
</button>
</div>
<div class="input-container">
<label for="colorPickerUSEast2">オハイオ(us-east-2):</label>
<input type="color" id="colorPickerUSEast2" name="us-east-2_color" />
<button class="clear-btn" data-target="colorPickerUSEast2">
クリア
</button>
</div>
<div class="input-container">
<label for="colorPickerUSWest1">北カリフォルニア(us-west-1):</label>
<input type="color" id="colorPickerUSWest1" name="us-west-1_color" />
<button class="clear-btn" data-target="colorPickerUSWest1">
クリア
</button>
</div>
<div class="input-container">
<label for="colorPickerUSWest2">オレゴン(us-west-2):</label>
<input type="color" id="colorPickerUSWest2" name="us-west-2_color" />
<button class="clear-btn" data-target="colorPickerUSWest2">
クリア
</button>
</div>
<button type="submit">保存</button>
<div class="note">※保存するとブラウザが更新されます</div>
</form>
<script src="js/popup.js"></script>
</body>
</html>
css/styles.css
body {
font-family: 'Arial', sans-serif;
padding: 10px;
background-color: #f5f5f5;
}
form {
background-color: #fff;
padding: 20px;
border-radius: 8px;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
max-width: 300px;
margin: auto;
}
.input-container {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 10px;
}
label {
flex: 1;
margin-right: 10px;
font-size: 14px;
font-weight: bold;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
input[type="color"] {
flex: 0 0 40px;
}
button {
display: block;
width: 100%;
padding: 10px;
background-color: #4285f4;
color: #fff;
border: none;
border-radius: 4px;
cursor: pointer;
transition: background-color 0.3s;
}
button:hover {
background-color: #357abf;
}
.clear-btn {
width: auto;
background-color: #4285F4;
/* Googleのブルー */
color: white;
border: none;
border-radius: 4px;
padding: 5px 10px;
cursor: pointer;
margin-left: 10px;
}
.clear-btn:hover {
background-color: #357ABD;
/* 暗いブルー */
}
.note {
font-size: 10px;
color: #ff0000;
margin-top: 10px;
border-radius: 4px;
}
js/content.js
const REGIONS = {
TOKYO: "ap-northeast-1",
VIRGINIA: "us-east-1",
OHIO: "us-east-2",
CALIFORNIA: "us-west-1",
OREGON: "us-west-2",
};
function findMatchingRegion(url) {
for (let regionName in REGIONS) {
if (url.includes(REGIONS[regionName])) {
return regionName;
}
}
return false;
}
const currentURL = window.location.href;
const matchedRegion = findMatchingRegion(currentURL);
chrome.storage.local.get(
[
"TOKYO_COLOR",
"VIRGINIA_COLOR",
"OHIO_COLOR",
"CALIFORNIA_COLOR",
"OREGON_COLOR",
],
function (result) {
if (matchedRegion) {
let colorKey = `${matchedRegion}_color`.toUpperCase();
if (result[colorKey]) {
const container = document.getElementById("h");
const newDiv = document.createElement("div");
newDiv.style.height = "5px";
newDiv.style.backgroundColor = result[colorKey];
container.parentNode.insertBefore(newDiv, container);
}
}
}
);
js/popup.js
const DEFAULT_COLOR = "#F2F3F3";
// ページが読み込まれたときに実行
document.addEventListener("DOMContentLoaded", function () {
// カラー情報をストレージから取得
chrome.storage.local.get(
[
"TOKYO_COLOR",
"VIRGINIA_COLOR",
"OHIO_COLOR",
"CALIFORNIA_COLOR",
"OREGON_COLOR",
],
function (result) {
document.getElementById("colorPickerTokyo").value =
result.TOKYO_COLOR || DEFAULT_COLOR;
document.getElementById("colorPickerUSEast1").value =
result.VIRGINIA_COLOR || DEFAULT_COLOR;
document.getElementById("colorPickerUSEast2").value =
result.OHIO_COLOR || DEFAULT_COLOR;
document.getElementById("colorPickerUSWest1").value =
result.CALIFORNIA_COLOR || DEFAULT_COLOR;
document.getElementById("colorPickerUSWest2").value =
result.OREGON_COLOR || DEFAULT_COLOR;
}
);
});
document.querySelector("form").addEventListener("submit", function (event) {
event.preventDefault(); // フォームのデフォルトの送信動作を防ぐ
// 各カラーピッカーの値を取得
let tokyoColor = document.getElementById("colorPickerTokyo").value;
let useast1Color = document.getElementById("colorPickerUSEast1").value;
let useast2Color = document.getElementById("colorPickerUSEast2").value;
let uswest1Color = document.getElementById("colorPickerUSWest1").value;
let uswest2Color = document.getElementById("colorPickerUSWest2").value;
// 値をchrome.storage.localに保存
chrome.storage.local.set({
TOKYO_COLOR: tokyoColor,
VIRGINIA_COLOR: useast1Color,
OHIO_COLOR: useast2Color,
CALIFORNIA_COLOR: uswest1Color,
OREGON_COLOR: uswest2Color,
});
chrome.tabs.query({ active: true, currentWindow: true }, function (tabs) {
let currentTab = tabs[0];
// アクティブなタブをリロード
chrome.tabs.reload(currentTab.id);
});
});
ローカル環境での設定の仕方
-
chrome://extensions/
をchromeのURLの部分に貼り付けエンター - 右上の
デベロッパーモード
を有効化 -
パッケージ化されていない拡張機能を読み込む
で作成したファイルを選択
もうちょっとコード少なくできると思いますが、それでもこれだけの量で設定することができました。
取り合えず、htmlとJavaScript、CSSかけばいい感じにできそうです。
サクッと作成できて面白いので、今後もいろいろと作成してみようと思います。