AIを使って、自分だけのChrome拡張機能を作ってみました。
今回は、テキストをドラッグ&ドロップするだけで検索(Google、Youtube、X)やクリップボードコピーができる機能を作成しました。
以下のレポジトリに作成したものをあげています。
https://github.com/fe2030/drag-search-copy
利用したもの
・ChatGPT(プロンプト作成、相談)
・Antigravity(実際に作成)
作成に使用したプロンプト
最初にAIに投げたプロンプトは以下の通りです。かなりAIとの壁打ちを入念におこない詳細に要件を定義しました。
あなたは熟練したChrome拡張機能の開発者です。 以下の要件定義書に基づき、Chrome拡張機能「Drag search©」のソースコードを作成してください。
成果物の定義
形式: ファイル単位で完全に実装されたコードのみを出力すること(解説や会話文は不要)。
ファイル構成: 以下の3ファイルのみを作成。 (1) manifest.json (2) service-worker.js (3) superdrag.js
拡張機能の概要
目的: テキストを選択・ドラッグし、ドロップした方向に応じて「検索」または「コピー」を行う軽量ツール。
UI: 設定画面は不要。動作はChromeの標準的なスーパードラッグ拡張に準拠する。
技術基盤: Manifest V3
動作ロジック(方向とアクション) ユーザーがテキストをドラッグ&ドロップした際、マウスの移動方向(上下左右)に応じて以下のアクションを実行してください。
上 (Up): Google検索 (https://www.google.com/search?q=...) を新しいタブ(前面)で開く。
下 (Down): X (Twitter) 検索 (https://x.com/search?q=...) を新しいタブ(前面)で開く。
左 (Left): YouTube検索 (https://www.youtube.com/results?search_query=...) を新しいタブ(前面)で開く。
右 (Right): クリップボードにテキストをコピーし、画面上に「コピー」というポップアップを表示する。
技術実装要件(詳細)
A. 全体・共通仕様
権限 (permissions): tabs, storage, scripting, clipboardWrite
ホスト権限 (host_permissions): http:///, https:///(すべてのURLで動作可能にする)
文字コード: UTF-8
URLエンコード: 検索文字列はすべて encodeURIComponent で処理し、受け取り側で decodeURIComponent する。
B. manifest.json の要件
manifest_version: 3
offline_enabled: 不要
content_scripts: superdrag.js を document_end のタイミングで全ページに注入する設定を記述。
C. superdrag.js (Content Script) の実装要件 DOM操作とイベントハンドリングを行うメインロジックです。
(1) イベント監視と適用範囲
MutationObserver を使用し、動的に追加される要素を含め、ページ内のすべての要素に dragstart, dragover, drop, dragend ハンドラを付与する。
初期ロード時は document.querySelectorAll('*') に対して付与。
document.body が存在しない場合は 100ms 後に再試行するロジックを入れる。
除外条件: INPUT, TEXTAREA, contentEditable=true の要素内では処理を行わない。また、ファイルドロップ(e.dataTransfer.files.length > 0)の場合は何もしない。
(2) ドラッグ処理 (Start / Over / End)
dragstart:
e.dataTransfer.setData('text/plain', data) を設定。
データは window.getSelection().toString() を最優先とし、空なら e.target.href 等を試行。それでも空なら処理を中断。
ドラッグ開始位置 (dragStartPoint) を記録。
dragover:
e.preventDefault(), e.stopPropagation() を実行。
e.dataTransfer.dropEffect = 'move' を設定。
現在位置と dragStartPoint を比較し、方向(Up/Down/Left/Right)を決定してグローバル変数に保持。
重要: dragStartPoint はここで更新してはならない(常に開始点との比較を行うため)。
方向判定閾値は 4px とする。斜め移動の場合は移動量が大きい軸を優先。
dragend:
すべての状態変数(開始位置、現在方向、データ)を null にリセットしてクリーンアップする。
(3) ドロップ処理 (Drop)
e.preventDefault(), e.stopPropagation() を実行。
ドロップされたテキストデータを取得(空なら中断)。
右方向(コピー)の場合:
navigator.clipboard.writeText を非同期で実行。失敗時は textarea を生成して document.execCommand('copy') でフォールバックする堅牢な実装にする。
成功後、ドロップ位置(マウス座標)付近に「コピー」と書かれた小さなポップアップを表示する。
ポップアップ仕様: position: fixed, 黒背景・白文字, z-index最大, 100ms後に自動削除。
コピー処理はService Workerを介さず完結させる。
上・下・左方向(検索)の場合:
chrome.runtime.sendMessage を使用して Service Worker へデータを送信する。
送信データ形式: { c: encodeURIComponent(dropData), direction: direction, foregroundOverride: e.shiftKey }
送信前に chrome.runtime の存在チェックを行い、エラーならログ出力して中断。
D. service-worker.js (Background) の実装要件 タブの作成と検索URLの生成を担当します。
メッセージ受信: chrome.runtime.onMessage.addListener で Content Script からのメッセージを受け取る。
URL生成: 受け取った文字列をデコードし、方向に応じた検索URL(Google/X/YouTube)を生成する。
タブ作成:
chrome.tabs.create を使用。
常に現在のタブの右隣に開く (index: current.index + 1)。
常に前面で開く (active: true)。
エラーハンドリング:
chrome.runtime.lastError をチェックし、エラーがあれば console.error に出力する。
同期的なリスナーであるため return true は記述しない。
コード出力のお願い
各ファイルの内容を省略せず、完全なコードとして出力してください。
コードブロックの前にファイル名を明記してください。
実装は堅牢に行い、未定義変数の参照エラーなどが起きないように try-catch や存在チェックを適切に入れてください。
生成されたファイルの解説
AIは以下の3つのファイルを生成してくれました。それぞれの役割は以下の通りです。
1. manifest.json(設計図・身分証明書)
役割:拡張機能の基本設定と権限の申請
家を建てる時の「設計図」や、役所に提出する「申請書」のようなものです。Chromeに対して「この拡張機能はこういう名前で、こういう権限が必要で、このファイルを使います」と宣言しています。
-
主な仕事:
-
権限の確保: 「タブを開く(
tabs)」「クリップボードに書き込む(clipboardWrite)」といった、強力な機能を使う許可をブラウザに求めます。 -
ファイルの割り当て: 「裏方には
service-worker.jsを使いなさい」「表示されるWebページにはsuperdrag.jsを埋め込みなさい」と指示します。 -
適用範囲: どのURLで動くか(今回は
<all_urls>なので全サイト)を指定します。
-
権限の確保: 「タブを開く(
2. superdrag.js(現場監督・センサー)
役割:Webページ内でのドラッグ操作の監視と実行
あなたが普段見ているWebページ(GoogleやYahoo、ブログなど)の中に入り込んで直接仕事をするファイルです。ユーザーのマウス操作を常に監視しています。
-
主な仕事:
-
監視 (Event Listener): ページ上のテキストがドラッグされたか (
dragstart)、どこに動いているか (dragover)、どこで離されたか (drop) を常に見張っています。 - 方向判定: ドラッグ開始地点と現在のマウス位置を比較して、「これは上への移動だ」「これは右だ」と計算します。
- コピー実行 (右ドロップ): 右にドロップされたときは、その場でクリップボードにテキストをコピーし、「コピー」という黒いポップアップを表示します。
-
通信 (検索時): 上・下・左(検索)の場合は、自分では新しいタブを開けない(または開くのが得意ではない)ため、裏方の
service-worker.jsに「このテキストをGoogleで検索して!」とメッセージを送ります。
-
監視 (Event Listener): ページ上のテキストがドラッグされたか (
3. service-worker.js(裏方・司令塔)
役割:ブラウザ自体の制御(新しいタブを開く)
特定のWebページに属さず、ブラウザの裏側で待機しているファイルです。superdrag.js からの依頼を受けて、ブラウザ全体に関わる操作を行います。
-
主な仕事:
-
待受 (Listener):
superdrag.jsから「検索して!」というメッセージが来るのを待っています。 -
URL作成: 受け取ったテキストを、Google (
google.com/search...) や YouTube (youtube.com/results...) の検索用URLに変換します。 -
タブを開く: Chromeの機能 (
chrome.tabs.create) を使って、新しいタブを前面に作成し、そこに検索結果を表示させます。
-
待受 (Listener):
インストール方法と使い方
作成した拡張機能を実際にChromeで動かすための手順です。
1. デベロッパーモードを有効にする
- Chromeのアドレスバーに
chrome://extensions/と入力して開きます。 - 画面右上にある「デベロッパーモード」のスイッチを ON にします。
2. 拡張機能を読み込む
- 「パッケージ化されていない拡張機能を読み込む」ボタンをクリックします。
- 作成した3つのファイル(
manifest.jsonなど)が保存されているフォルダを選択します。
これで拡張機能がインストールされます。
⚠️ 注意点:既存のページについて
拡張機能をインストール(または有効化)する前から開いていたタブでは、この機能は動作しません。機能を使いたい場合は、ページを再読み込み(リロード)するか、新しくタブを開き直してください。
余談:Chrome拡張機能のソースコードを見る方法
Chromeウェブストアからインストールした拡張機能のソースコードも、実はローカルPC上で確認することができます。
Windowsの場合のパス:
C:\Users\<ユーザー名>\AppData\Local\Google\Chrome\User Data\Default\Extensions\<拡張機能ID>
Macの場合のパス:
~/Library/Application Support/Google/Chrome/Default/Extensions/<拡張機能ID>
手順:
- Chromeで
chrome://extensionsを開きます。 - 確認したい拡張機能の「ID」をコピーします(例:
ghbmnnjooekpmoecnnnilnnbdlolhkhi)。 - 上記のパスの
<拡張機能ID>の部分を、コピーしたIDに置き換えてフォルダを開きます。
中にはバージョンごとのフォルダがあり、その中にmanifest.jsonや.jsファイルなどが格納されています。「この拡張機能、どうやって動いてるんだろう?」と気になった時は、中身を覗いてみると勉強になるかもしれません。