0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Chromeの拡張機能をAIで作ってみた!

Posted at

AIを使って、自分だけのChrome拡張機能を作ってみました。
今回は、テキストをドラッグ&ドロップするだけで検索(Google、Youtube、X)やクリップボードコピーができる機能を作成しました。
以下のレポジトリに作成したものをあげています。
https://github.com/fe2030/drag-search-copy

利用したもの

・ChatGPT(プロンプト作成、相談)
・Antigravity(実際に作成)

作成に使用したプロンプト

最初にAIに投げたプロンプトは以下の通りです。かなりAIとの壁打ちを入念におこない詳細に要件を定義しました。

あなたは熟練したChrome拡張機能の開発者です。 以下の要件定義書に基づき、Chrome拡張機能「Drag search&copy」のソースコードを作成してください。
成果物の定義
形式: ファイル単位で完全に実装されたコードのみを出力すること(解説や会話文は不要)。
ファイル構成: 以下の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で検索して!」とメッセージを送ります

3. service-worker.js(裏方・司令塔)

役割:ブラウザ自体の制御(新しいタブを開く)
特定のWebページに属さず、ブラウザの裏側で待機しているファイルです。superdrag.js からの依頼を受けて、ブラウザ全体に関わる操作を行います。

  • 主な仕事:
    • 待受 (Listener): superdrag.js から「検索して!」というメッセージが来るのを待っています。
    • URL作成: 受け取ったテキストを、Google (google.com/search...) や YouTube (youtube.com/results...) の検索用URLに変換します。
    • タブを開く: Chromeの機能 (chrome.tabs.create) を使って、新しいタブを前面に作成し、そこに検索結果を表示させます。

インストール方法と使い方

作成した拡張機能を実際にChromeで動かすための手順です。

1. デベロッパーモードを有効にする

  1. Chromeのアドレスバーに chrome://extensions/ と入力して開きます。
  2. 画面右上にある「デベロッパーモード」のスイッチを ON にします。

2. 拡張機能を読み込む

  1. 「パッケージ化されていない拡張機能を読み込む」ボタンをクリックします。
  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>
手順:

  1. Chromeで chrome://extensions を開きます。
  2. 確認したい拡張機能の「ID」をコピーします(例: ghbmnnjooekpmoecnnnilnnbdlolhkhi)。
  3. 上記のパスの <拡張機能ID> の部分を、コピーしたIDに置き換えてフォルダを開きます。
    中にはバージョンごとのフォルダがあり、その中に manifest.json.js ファイルなどが格納されています。「この拡張機能、どうやって動いてるんだろう?」と気になった時は、中身を覗いてみると勉強になるかもしれません。
0
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
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?