マニュアル: Google Chrome拡張機能

投稿日: 更新日:

マニュアル

WebExtensions

Firefoxの話ですが、 Google Chromeが採用しているAPIとある程度互換性がある、 WebExtensions APIがあります。

そのため、Firefoxの拡張機能のドキュメントは、 Google Chromeのドキュメントを読むときに、ある程度参考になります。 翻訳されているものも多いため、概要を理解するには良いでしょう。

セキュリティ

以下のような制限があります。

  • コンテンツスクリプト
  • バックグラウンドスクリプト
    • Webページのコンテンツにアクセスできない。

なので、Webページのコンテンツにアクセスしつつ、 バックグラウンドスクリプトでbrowserActionを使う場合は、 この2つのスクリプトで通信をする必要があります。

制限事項


  • evalはそれに類するものは使用不可。
  • インラインJavaScriptは実行されない。
    • 対策
      • 関数定義は外部ファイルに移動。
      • イベントハンドラはaddEventListenerを使用。
        • onloadはDOMContentLoadedイベントをハンドリング。
        • DOM構築前でよければ"run_at": "document_start"を使用。
      • Chrome 46からはbase64エンコードされて、ハッシュ付きならOKの模様。
  • ローカルのスクリプトとリソースのみ読み込まれる。
    • 対策
      • ファイルをダウンロードしてパッケージに含める。
      • CSPを適切に設定すればリモートのスクリプトも使える?
  • Content Security Policyの変更が可能。
    • manifest.jsonのキーはcontent_security_policy
    • Content Scriptsと題していろいろ書かれている。

Scaffold(足場)

0から作ると大変なことも多いので、このようなツールを使うといいかもしれません。

マニフェストファイル

必須項目

  • manifest_version(number): マニフェストファイルのバージョン。現在は'2'(数値)
  • name(string): 拡張機能の名前(45文字以下)。Chrome Web Storeなどで使われる。
  • version(string): バージョン文字列。自動更新システムが認識するため、厳密な規定あり。ユーザが認識する文字列を指定する時は、version_nameを使う(後述)
    • 1〜4つのドット区切りの整数
    • それぞれの整数は0〜65535の範囲であること。
    • '0'以外は'0'で始まるものはNG(例: '032')
    • バージョンの比較時は、左側から比較する。存在しないフィールドは'0'として扱う。
      • 例1: '1.2.0'は'1.1.9.9999'より新しい。
      • 例2: '1.1.9.9999'は'1.1'より新しい。

バージョン

  • version_name: 画面表示に使用するバージョン。"beta", "rc"などを含めたいときに便利。

パーミッション

Declare Permissions - Google Chrome

APIを使用する権限を表します。 "permissions"をキーとして、配列で記載します。

事前に定義されたものの他に、URLも記載できます。 Webページ内で実行したい場合は、Inject Declarativelyの方がいいかも。。。

アクション

ユーザがツールバー(URLバーの右側)で操作するもの。

  • browser_action: 常に有効にする場合
  • page_action: ページの内容によって有効にするかどうかが変わる場合

Content Script

Webページ上で動くもの。

  • content_scripts(array):
    • matches(array): マッチするサイト
      • ワイルドカードが使用可能。詳細はmatch_patterns参照。
    • css(array): 読み込まれるCSSファイル
    • js(array): 読み込まれるJavaScriptファイル

Background Script

バックグラウンドで動くもの。

  • background(object):
    • scripts(array): 動くスクリプト
    • persistent(boolean): 通常はfalse
      • chrome.webRequestというネットワークリクエストを解析するAPI以外では使わなさそうです。

オプション画面

Give Users Options - Google Chrome

  • options_page(string): オプション画面のHTML。新しいタブでオプション画面を表示する。
  • options_ui(object): 拡張機能管理ページの中で埋め込み表示
    • page: オプション画面のHTML。
    • open_in_tab:
      • true: 新しいタブで表示(options_page指定と同じ?)
      • false: 埋め込み表示

オプション画面は内容を書き込むため、storageパーミッションは事実上必須。

タブ

タブのタイトルとURL、ファビコンURLを取得するには、permissionsに、tabsをつける必要がある。 単にアクティブなタブを取得するだけなら不要。

クリップボード

permissionsclipboardWrite または clipboardReadをつける必要がある。

少なくともChrome 71まではDocument.execCommandを使うのがよい。 以下の記事で書かれているように、テキストエリアを作成 →全選択→document.execCommand("copy")を使用する。

chrome.clipboardというAPIがあるが、Chrome 71から導入(現在の安定版はChrome 69)のもので、 現在は開発中となっている。

また、説明には「オープン標準ができるまでの一時的な解決案」と書かれている。 これはClipboard APIのことと思われる。

コンテキストメニュー

以下の作業が必要。

  • パーミッション contextMenus を追加
  • バックグラウンドページを追加

バックグラウンドで書く件については以下の記事に記載。

開発手法

Promise/await/async

ほとんどが非同期で動く、callback付きで定義されているメソッドのため、 Promiseでラップして、await/asyncを使う機会が多いです。 まずこれを学ぶのが良いと思います。

パッケージ化されていない拡張機能を読み込む

  1. 拡張機能の画面を開く
    • macOSの場合「︙」→「その他のツール」→「拡張機能」で出る。
    • 適当な拡張機能を右クリック→「拡張機能を管理」→「拡張機能の名前の左の"←"」の方がいいかも。
  2. 「パッケージ化されていない拡張機能を読み込む」を押す。
  3. ダイアログが出るので、manifest.jsonがあるディレクトリを選択。

再読込するときは、拡張機能の画面のリロードボタンを押す。

公開


  • 事前準備
    • クレジットカード(初回のみ$5必要)
    • スクリーンショット(1〜5枚, 1280x800)
    • アイコン
      • 96x96 + パディング16px = 128x128
    • アプリの詳細説明(言語ごと対応可能)
  • 手順
    1. ZIP形式で固める
    2. ダッシュボードに行く
    3. ZIPのアップロード
    4. スクリーンショット、アイコン、詳細説明の記入など諸々作業
    5. プレビューして問題なければ公開
      • 公開は数分で行われるようですが、キャッシュのためかすぐに反映されないため、シークレットモードで確認すると良さそうです。

API

storage

オプションの保存を行う。

  • chrome.storage.sync
    • Chrome Syncによる同期を行うもの。
    • Syncを有効化していないときは、localとしてふるまう。
      • Even if a user disables syncing, storage.sync will still work. In this case, it will behave identically to storage.local.
    • 容量および操作回数の制限が大きいのに注意(chrome.storage.sync参照)
  • chrome.storage.local
    • ローカルのみ保存を行うもの。
    • 容量は5MBだが、それ以外の制限はない。
  • chrome.storage.managed
    • 管理者が設定したポリシー(書き込み不可)。通常は意識しない。

いずれもAPIとしては共通(callbackを受け取る)のため、 非同期メソッドとして対処が必要。

注意点

単純なことですが、何度も間違えたので書いておきます。 {key: value}のようなオブジェクトを格納する場合、 getとsetは以下のように書きます。 (例示のためPromiseは使わない)

// set
chrome.sync.set({key: value}, function() {
  ...
});

// get
chrome.sync.get({key: default_value}, function(items) {
  const value = items.key; // items == valueと勘違いしてしまう
});

国際化

chrome.i18n - Google Chrome

  • manifest.json
    • "default_locale": デフォルトのロケール。基本的には"en"
  • _locales/${localeCode}/messages.json
    • localcode: ロケールコード。英語は'en'、日本語は'ja'
    • キー: chrome.i18n.getMessageの最初の引数に使うキー
      • message(必須): 取得するメッセージ
      • description: 翻訳者に対する説明。アプリ内では使わない。
  • manifest.json, CSS中に__MSG___で囲むと、メッセージが使用可能。

HTMLの国際化

別記事にしました。

逆引きマニュアル: Google Chrome拡張機能: HTMLの国際化 - Hideki Ikemoto's Site

国際化のテスト

  • Windows: --langオプションを使用
  • Linux: LANGUAGE環境変数を使用
  • macOS
    1. 「システム環境設定」を開く
    2. 「言語と地域」を開く
    3. Chromeを再起動

macOSだけめんどくさいですね(OSの機能そのままですが)。

公式サイト

外部サイト

逆引きマニュアル