LoginSignup
3
1

簡単なアウトプットした。Chrome Extensions(拡張機能)編

Posted at

簡単なアウトプット: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になっていたという経験がしばしばあります。

※みなさんはこういう経験がないかもしれませんが、私にはあります。

ということで、特定のリージョンを選択しているときに背景色を変えて
今どのリージョンを触っているかをわかるようにしました。

スクリーンショット 2023-12-18 22.40.32.png

構成

  • 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かけばいい感じにできそうです。

サクッと作成できて面白いので、今後もいろいろと作成してみようと思います。

3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1