アクティブなタブにスクリプトを挿入する

拡張機能のツールバー アイコンをクリックすると、現在のページのスタイルを簡素化できます。

概要

このチュートリアルでは、Chrome 拡張機能と Chrome ウェブストアのドキュメント ページのスタイル設定を簡素化して読みやすくする拡張機能を作成します。

このガイドでは、次の方法について説明します。

  • 拡張機能 Service Worker をイベント コーディネーターとして使用する。
  • "activeTab" 権限を通じてユーザーのプライバシーを保護します。
  • ユーザーが拡張機能のツールバー アイコンをクリックしたときにコードを実行します。
  • Scripting API を使用してスタイルシートの挿入と削除を行います。
  • キーボード ショートカットを使用してコードを実行します。

始める前に

このガイドは、基本的なウェブ開発経験があることを前提としています。拡張機能の開発ワークフローの概要については、Hello World をご覧ください。

拡張機能を作成する

まず、拡張機能のファイルを格納する focus-mode という新しいディレクトリを作成します。必要に応じて、GitHub からソースコード全体をダウンロードすることもできます。

ステップ 1: 拡張機能のデータとアイコンを追加する

manifest.json というファイルを作成し、次のコードを含めます。

{
  "manifest_version": 3,
  "name": "Focus Mode",
  "description": "Enable focus mode on Chrome's official Extensions and Chrome Web Store documentation.",
  "version": "1.0",
  "icons": {
    "16": "images/icon-16.png",
    "32": "images/icon-32.png",
    "48": "images/icon-48.png",
    "128": "images/icon-128.png"
  }
}

これらのマニフェスト キーについて詳しくは、拡張機能のメタデータアイコンについて詳しく説明した「すべてのタブでスクリプトを実行する」チュートリアルをご覧ください。

images フォルダを作成し、そのフォルダにアイコンをダウンロードします。

ステップ 2: 拡張機能を初期化する

拡張機能は、拡張機能のサービス ワーカーを使用して、バックグラウンドでブラウザのイベントをモニタリングできます。Service Worker はイベントを処理する特別な JavaScript 環境で、不要になったら終了します。

まず、Service Worker を manifest.json ファイルに登録します。

{
  ...
  "background": {
    "service_worker": "background.js"
  },
  ...
}

background.js というファイルを作成し、次のコードを追加します。

chrome.runtime.onInstalled.addListener(() => {
  chrome.action.setBadgeText({
    text: "OFF",
  });
});

Service Worker が最初にリッスンするイベントは runtime.onInstalled() です。この方法では、拡張機能が初期状態を設定したり、インストール時に一部のタスクを完了したりできます。拡張機能は、Storage APIIndexedDB を使用してアプリケーションの状態を保存できます。今回は 2 つの状態のみを処理するため、アクションのバッジのテキスト自体を使用して、拡張機能が「オン」か「オフ」かをトラッキングします。

ステップ 3: 拡張機能のアクションを有効にする

拡張機能の操作では、拡張機能のツールバー アイコンを制御します。そのため、ユーザーが拡張機能アイコンをクリックするたびに、この例のようにコードが実行されるか、ポップアップが表示されます。次のコードを追加して、manifest.json ファイルで拡張機能アクションを宣言します。

{
  ...
  "action": {
    "default_icon": {
      "16": "images/icon-16.png",
      "32": "images/icon-32.png",
      "48": "images/icon-48.png",
      "128": "images/icon-128.png"
    }
  },
  ...
}

ActiveTab 権限を使用してユーザーのプライバシーを保護する

activeTab 権限は、アクティブなタブのコードを実行する一時的な権限を拡張機能に付与します。また、現在のタブの機密プロパティへのアクセスも許可します。

この権限は、ユーザーが拡張機能を呼び出した場合に有効になります。この場合、ユーザーは拡張機能のアクションをクリックして拡張機能を呼び出します。

💡? 独自の拡張機能で activeTab 権限を有効にするのは、他にどのようなユーザー操作ですか?

  • キーボード ショートカットの組み合わせを押す。
  • コンテキスト メニュー項目を選択する。
  • アドレスバーからの候補を受け入れている。
  • 拡張機能のポップアップを開いています。

"activeTab" 権限により、ユーザーはフォーカスされたタブで拡張機能の実行を意図的に選択できます。これにより、ユーザーのプライバシーが保護されます。もう 1 つのメリットは、権限の警告がトリガーされないことです。

"activeTab" 権限を使用するには、マニフェストの権限の配列に追加します。

{
  ...
  "permissions": ["activeTab"],
  ...
}

ステップ 4: 現在のタブの状態を追跡する

ユーザーが拡張機能のアクションをクリックすると、拡張機能によって URL がドキュメント ページと一致するかどうかが確認されます。次に、現在のタブの状態を確認し、次の状態を設定します。background.js に次のコードを追加します。

const extensions = 'https://developer.chrome.com/docs/extensions'
const webstore = 'https://developer.chrome.com/docs/webstore'

chrome.action.onClicked.addListener(async (tab) => {
  if (tab.url.startsWith(extensions) || tab.url.startsWith(webstore)) {
    // Retrieve the action badge to check if the extension is 'ON' or 'OFF'
    const prevState = await chrome.action.getBadgeText({ tabId: tab.id });
    // Next state will always be the opposite
    const nextState = prevState === 'ON' ? 'OFF' : 'ON'

    // Set the action badge to the next state
    await chrome.action.setBadgeText({
      tabId: tab.id,
      text: nextState,
    });
  }
});

ステップ 5: スタイルシートを追加または削除する

次に、ページのレイアウトを変更します。focus-mode.css という名前のファイルを作成し、次のコードを含めます。

body > .scaffold > :is(top-nav, navigation-rail, side-nav, footer),
main > :not(:last-child),
main > :last-child > navigation-tree,
main .toc-container {
  display: none;
}

main > :last-child {
  margin-top: min(10vmax, 10rem);
  margin-bottom: min(10vmax, 10rem);
}

Scripting API を使用して、スタイルシートを挿入したり、削除したりします。まず、マニフェスト内で "scripting" 権限を宣言します。

{
  ...
  "permissions": ["activeTab", "scripting"],
  ...
}

最後に、background.js に次のコードを追加して、ページのレイアウトを変更します。

  ...
    if (nextState === "ON") {
      // Insert the CSS file when the user turns the extension on
      await chrome.scripting.insertCSS({
        files: ["focus-mode.css"],
        target: { tabId: tab.id },
      });
    } else if (nextState === "OFF") {
      // Remove the CSS file when the user turns the extension off
      await chrome.scripting.removeCSS({
        files: ["focus-mode.css"],
        target: { tabId: tab.id },
      });
    }
  }
});

💡? スタイルシートの代わりに Scripting API を使用してコードを挿入できますか?

はい。scripting.executeScript() を使用して JavaScript を挿入できます。

省略可: キーボード ショートカットを割り当てる

ショートカットを追加すると、フォーカス モードを簡単に有効または無効にできます。"commands" キーをマニフェストに追加します。

{
  ...
  "commands": {
    "_execute_action": {
      "suggested_key": {
        "default": "Ctrl+B",
        "mac": "Command+B"
      }
    }
  }
}

"_execute_action" キーは action.onClicked() イベントと同じコードを実行するため、追加のコードは必要ありません。

動作をテストする

プロジェクトのファイル構造が次のようになっていることを確認します。

フォーカス モード フォルダの内容: manifest.json、background.js、focus-mode.css、images フォルダです。

拡張機能をローカルで読み込む

パッケージ化されていない拡張機能をデベロッパー モードで読み込むには、Hello World の手順に沿って操作します。

ドキュメント ページで拡張機能をテストする

まず、次のいずれかのページを開きます。

拡張機能のアクションをクリックします。キーボード ショートカットを設定している場合は、Ctrl + B または Cmd + B キーを押すとテストできます。

元のページは次のようになります。

フォーカス モード拡張機能: オフ
フォーカス モード拡張機能: オフ

利用後:

フォーカス モード拡張機能: オン
フォーカス モード拡張機能: オン

機能強化の例

今日学んだ内容に基づいて、次のいずれかを目指してください。

  • CSS スタイルシートを改善しました。
  • 別のキーボード ショートカットを割り当てます。
  • お気に入りのブログやドキュメント サイトのレイアウトを変更できます。

構築を続けましょう。

これでチュートリアルは終了です🎉?。このシリーズの他のチュートリアルも完了して、スキルアップを続けましょう。

延長 ラボの内容
読書時間 特定のページセットに要素を自動的に挿入するため。
タブ マネージャー ブラウザのタブを管理するポップアップを作成するため。

引き続き探求を

この Chrome 拡張機能の作成がお役に立つことを願っています。拡張機能の開発に関する学習の続きを楽しみにしています。次の学習プログラムをおすすめします。

  • デベロッパー ガイドには、高度な拡張機能の作成に関するドキュメントへの追加リンクが多数あります。
  • 拡張機能では、オープンウェブで利用できない強力な API にアクセスできます。Chrome API のドキュメントで各 API を確認できます。