👨‍💻

縦にタブを表示するリストChrome拡張をつくりました

2024/09/11に公開

初心者の私が最近初めてつくった「縦にタブ一覧を表示するChrome拡張」についてのお話です。

つくった理由

私は普段、リビングに設置したPCを使って作業をしています。ワイヤレスタッチパッド付きキーボードで少し離れて操作すること自体は問題ないのですが、ディスプレイから離れた位置で作業をしているため、いくつか課題がありました:

  1. Chromeのタブが小さく見づらい
  2. たくさんのタブを開くとさらに見づらくなる
  3. タブの一覧を縦表示で見やすくしたい
  4. タブの一覧から直接タブに移動したり、閉じたりしたい

つくった経緯

まず、生成AIに相談したところ、Chrome拡張機能で実現可能だとアドバイスをもらいました。そこで、以下のようなフォルダ構造で必要なファイルを用意しました:

tabido
│  icon16.png
│  icon48.png
│  icon128.png
│  manifest.json
│  popup.html
│  popup.js

icon16.png、icon48.png、icon128.pngは、Chrome拡張機能のアイコン用みたいです。

そのほかの各ファイルの役割と内容をこんな感じです。

manifest.json

{
    "manifest_version": 3,  // Chrome拡張機能の最新仕様バージョン
    "name": "Vertical Tab List",  // 拡張機能の名前
    "version": "1.0",  // 拡張機能のバージョン
    "description": "Displays a vertical list of tabs and allows switching between them.",  // 拡張機能の説明
    "permissions": ["tabs"],  // タブ情報へのアクセス権限を要求
    "action": {
      "default_popup": "popup.html"  // クリック時に表示されるポップアップHTMLファイル
    },
    "icons": {  // 拡張機能のアイコン(各サイズ)
      "16": "icon16.png",
      "48": "icon48.png",
      "128": "icon128.png"
    }
}

このファイルは拡張機能の設定を定義しています。主なポイントは:

  • manifest_version: 最新のChrome拡張機能の仕様であるバージョン3を使用
  • permissions: タブ情報にアクセスするための権限を要求
  • action: 拡張機能のアイコンをクリックしたときに表示されるポップアップを指定

popup.html

<!DOCTYPE html>
<html>
<head>
  <title>Vertical Tab List</title>
  <style>
    body {
      width: 400px;
      max-height: 600px;
      overflow-y: auto;  // 縦方向のスクロールを可能にする
      font-family: Arial, sans-serif;
      background-color: #f5f5f5;
      padding: 10px;
    }
    .tab-container {
      display: flex;
      justify-content: space-between;
      align-items: stretch;
      margin-bottom: 8px;
      height: 50px;  // コンテナの高さを固定
    }
    .tab-button {
      flex-grow: 1;
      width: calc(100% - 40px);  // 閉じるボタンの幅を考慮
      text-align: left;
      padding: 10px 15px;
      border: none;
      border-radius: 4px 0 0 4px;
      background-color: #3498db;
      color: #ffffff;
      font-size: 20px;
      cursor: pointer;
      transition: background-color 0.3s ease;
      overflow: hidden;
      text-overflow: ellipsis;  // 長いタイトルは省略表示
      white-space: nowrap;
    }
    .tab-button:hover {
      background-color: #2980b9;  // ホバー時の色変更
    }
    .tab-button:active {
      background-color: #2473a6;  // クリック時の色変更
    }
    .close-button {
      width: 40px;
      height: 100%;
      border: none;
      border-radius: 0 4px 4px 0;
      background-color: #e74c3c;
      color: #ffffff;
      font-size: 20px;
      cursor: pointer;
      transition: background-color 0.3s ease;
      display: flex;
      justify-content: center;
      align-items: center;
    }
    .close-button:hover {
      background-color: #c0392b;  // ホバー時の色変更
    }
  </style>
</head>
<body>
  <div id="tabList"></div>  <!-- タブリストを表示するコンテナ -->
  <script src="popup.js"></script>
</body>
</html>

このHTMLファイルはポップアップの構造とスタイルを定義しています。CSSでは、タブリストの見た目を整えています:

  • ボタンのサイズを大きくし、見やすさを向上
  • タブボタンと閉じるボタンを横並び用意し、つかいやすく

popup.js

document.addEventListener('DOMContentLoaded', function() {
  // すべてのウィンドウとタブの情報を取得
  chrome.windows.getAll({populate: true}, function(windows) {
    const tabList = document.getElementById('tabList');
    
    windows.forEach(function(window) {
      window.tabs.forEach(function(tab) {
        // タブごとにコンテナを作成
        const tabContainer = document.createElement('div');
        tabContainer.className = 'tab-container';

        // タブを表示するボタンを作成
        const tabButton = document.createElement('button');
        tabButton.className = 'tab-button';
        tabButton.textContent = `${tab.title} (Window ${window.id})`;
        
        // タブボタンのクリックイベント:対応するタブにフォーカスを移動
        tabButton.addEventListener('click', function() {
          chrome.windows.update(window.id, {focused: true});
          chrome.tabs.update(tab.id, {active: true});
        });

        // タブを閉じるボタンを作成
        const closeButton = document.createElement('button');
        closeButton.className = 'close-button';
        closeButton.textContent = 'X';
        
        // 閉じるボタンのクリックイベント:タブを閉じる
        closeButton.addEventListener('click', function(e) {
          e.stopPropagation();  // タブボタンのクリックイベントが発火するのを防ぐ
          chrome.tabs.remove(tab.id, function() {
            tabContainer.remove();  // DOMからタブ要素を削除
          });
        });

        // ボタンをコンテナに追加
        tabContainer.appendChild(tabButton);
        tabContainer.appendChild(closeButton);

        // コンテナをタブリストに追加
        tabList.appendChild(tabContainer);
      });
    });
  });
});

このJavaScriptファイルが拡張機能の主要な機能を実装しています:

  1. 全てのウィンドウとタブの情報を取得
  2. 各タブに対して、タイトルを表示するボタンと閉じるボタンを作成
  3. タブボタンをクリックすると対応するタブにフォーカスを移動
  4. 閉じるボタンをクリックするとタブを閉じる

Chrome拡張機能の登録方法

開発した拡張機能をChromeに登録する方法は以下の通りです:

  1. Chromeブラウザを開き、アドレスバーに chrome://extensions/ と入力します。

  2. 右上の「デベロッパーモード」をオンにします。

  3. 「パッケージ化されていない拡張機能を読み込む」ボタンをクリックします。

  4. 開発した拡張機能のフォルダ(今回の場合は tabido フォルダ)を選択します。

これで拡張機能が読み込まれ、Chromeの拡張機能リストに表示されます。

利用制限について

この方法で登録した拡張機能には、いくつかの制限があります:

  1. ローカル利用限定: この方法で読み込んだ拡張機能は、そのPCでのみ利用可能です。他のPCやデバイスで使用することはできません。

  2. 自動更新なし: Chrome ウェブストアを通じて公開された拡張機能とは異なり、自動更新機能がありません。更新する場合は、手動で新しいバージョンを読み込む必要があります。

  3. セキュリティ警告: Chromeは、パッケージ化されていない拡張機能に対してセキュリティ警告を表示することがあります。

  4. 同期不可: Googleアカウントを通じて他のデバイスと同期することができません。

使用方法と感想

今回の拡張機能は、上記の方法でChromeに読み込むことで使用できるようになりました。使ってみた感想は以下の通りです:

  • Chromeを複数起動していても、全てのタブが表示できました。
  • Windows 10とChrome OS Flexの両方で問題なく動作しました。
  • Chrome OS Flexでは、ファイラーや設定などのアプリもタブとして表示され、閉じることができるのには驚きました。

この拡張機能のおかげで、リビングでのPC作業がより快適になりました。タブの管理が容易になり、作業効率が向上しています。

まとめ

Chrome拡張機能は比較的簡単に開発でき、かつ強力な機能を実現できるツールだと感じました。

とても便利です。

以 上

Discussion