これで解決!Chrome拡張機能 にコンテストメニューを表示する

2020年11月25日水曜日

Chrome拡張機能

t f B! P L

Chrome(クローム)拡張機能で、ページ上で右クリックした時に表示されるコンテストメニューに、独自のメニューを追加する方法を紹介します。

はじめに

下のイメージのように、Chrome(クローム)拡張機能で、ページ上で右クリックした時に表示されるコンテストメニューに、独自のメニューの追加する方法を紹介します。

拡張機能でコンテストメニューを追加するために、次のファイルを編集していきます。

  • manifest.json
  • Background Page ( 今回はEvent Pageとして作成 )
  • アイコン(コンテストメニューに表示するアイコン)

manifest.json

manifest.jsonに、次の3つの設定を追加します。

権限 (permissions)

Chrome拡張機能でコンテストメニューを表示するためには、activeTabcontextMenusが必要です。
manifest.jsonpermissionsセクションに次のように設定しましょう。

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

Background Page

コンテストメニューの追加や、メニューがクリックされた時の処理を行う、Background Pageの設定を行います。
今回はEvent Page として作成するため、persistentfalseを指定します。

{
  ...
  "background": {
    "scripts": ["background.js"],
    "persistent": false
  },
  ...
}

ここで少し、`Background Page` と `Event Page` の違いについて触れておきましょう。

元々、Chrome拡張機能で常駐処理というと、Background Pageしかありませんでした。
Background Pageは「Chromeの起動中にずっと常駐して動き続ける」ため、いくつもの拡張機能を追加すると、メモリ消費が多くなり、動作が重くなる問題が発生していました。

そこで、必要になったときだけ起動して処理を行うのがEvent Pageです。
Event Pageは、次に上げるようなイベントで読み込まれ、それ以外の時はアンロードされているため、消費メモリが少なくなります。

  1. 拡張のインストールまたはアップデート時
  2. イベントリスナーを登録したイベントが発火したとき

アイコン

拡張機能で追加したコンテストメニューには、次のイメージのように、アプリのアイコンが表示されます。

アイコンは、manifest.jsoniconsセクションで設定します。

iconsセクションには、サイズが「16x16」「48x48」「128x128」のサイズを指定できますが、今回の目的では「48x48」だけ設定しておけばOKです。

{
  ...
  "icons": {
    "48": "images/icon_48.png"
  },
  ...
}

また、上記で設定したパスに、実際の画像ファイルも配置しておいてください。

Background Pageの実装

Background Pageでは、拡張機能インストール時にコンテストメニューを追加する処理と、メニュークリック時の処理を実装します。

background.jsというファイルを作成し、次の内容を処理を記述します。

/**
 * 拡張機能インストール時の処理
 * インストール時のイベント関数で、コンテキストメニューを登録します。
 */
chrome.runtime.onInstalled.addListener(function() {
  const menu = chrome.contextMenus.create({
    type: "normal",
    id: "contextmenu1",
    title: "サンプルメニュー1"
  });
});

/**
  * メニューが選択されたときの処理
  * 選択されたメニューが関数の引数に渡される。
  * 複数のメニューを登録した場合は、item.menuItemIdでクリックされたメニューが取得できる
  */
 chrome.contextMenus.onClicked.addListener(function(item){
  console.log("メニューがクリックされたよ (menuItemId=" + item.menuItemId + ")");
});

ひとまず完了

ここまでの作業で、コンテキストメニューを表示する実装は完了です。
デベロッパーモードで読み込んで試してみましょう。

拡張機能をデベロッパーオードで読み込みには、次の手順を実施します。

  1. Chromeを立ち上げてアドレスバーに「chrome://extensions/」を入力
  2. デベロッパーモードをON
  3. 「パッケージ化されていない拡張機能を読み込む」をクリック
  4. 拡張機能のソースが格納されているフォルダを選択

複数のメニューを追加する

コンテストメニューを複数登録する場合は、登録するメニューの数だけ、chrome.contextMenus.create(...)メソッドを呼び出すだけです。

idは、重複するとエラーになるため、他のメニューと重複しないように設定しましょう。

chrome.runtime.onInstalled.addListener(function() {
  // 1つめのメニューを登録
  const menu1 = chrome.contextMenus.create({
    type: "normal",
    id: "contextmenu1",
    title: "サンプルメニュー1"
  });

  // 2つめのメニューを登録
  const menu2 = chrome.contextMenus.create({
    type: "normal",
    id: "contextmenu2",
    title: "サンプルメニュー2"
  });
});

複数のコンテストメニューを登録すると、次のイメージのように、アプリ名の親メニューの下に、作成したメニューが追加されます。

Chrome(クローム)拡張機能の仕様で、複数のコンテストメニューを登録すると、親メニューが自動的に表示入るため、操作性を重要視するアプリケーションなどでは、極力コンテストメニューは1つに絞った方がよいかもしれません。

親子メニューを作成する

次は、親子関係のメニューを作成してみましょう。

子メニューの登録時に、parentIdに親メニューのidを指定すると、親子関係のメニューが作成できます。

chrome.runtime.onInstalled.addListener(function() {
  //親メニューの追加
  const parent = chrome.contextMenus.create({
    type: "normal",
    id: "parent",
    title: "親メニュー"
  });

  //子メニューを追加(1つ目)
  const child1 = chrome.contextMenus.create({
    type: "normal",
    id: "child1",
    parentId: "parent",
    title: "サブメニュー1"
  });
  //子メニューを追加(2つ目)
  const child2 = chrome.contextMenus.create({
    type: "normal",
    id: "child2",
    parentId: "parent",
    title: "サブメニュー2"
  });
});

上のコードを実行すると、次のイメージのような感じになります。

コンテストメニューの表示/非表示を制御する

条件によって、コンテキストメニューの表示/非表示を制御したいといったケースもあるでしょう。

メニューの表示は、chrome.contextMenus.updateメソッドの、visibleオプションを指定することで制御できます。visible: falseとすると、コンテストメニューが非表示になります。

chrome.contextMenus.update("menuのid", {
  visible: false  // falseで非表示
});

コンテストメニューの活性(enabled)制御

enabledオプションで、メニューの活性・非活性を制御することもできます。
ある条件の時は、メニューがクリックできないように制御したい時に便利です。

chrome.contextMenus.update("menuのid", {
  enabled: false  // falseで非活性
});

メニューのタイプを変更する

typeオプションで、コンテキストメニューの表示タイプを次のとおり指定できます。

itemType 説明 サンプルイメージ
normal 標準のメニュー(デフォルト値)
checkbox チェックボックス
radio 複数の選択肢から1つ選ぶラジオボタン
separator 区切り線

コンテストメニューを表示する要素を指定する

contextsオプションで、右クリックした要素によってコンテキストメニュー表示する・しないを指定できます。
なお、contextsオプションは配列で複数指定可能です。

  const child1 = chrome.contextMenus.create({
    type: "normal",
    id: "child1",
    title: "メニューサンプル",
    contexts: ["all"]   // allを指定するとすべての要素の上でコンテストメニューを表示
  });

`contexts`オプションに指定できる値は次のとおりです。

"all", "page", "frame", "selection", "link", "editable", "image", "video", "audio", "launcher", "browser_action", "page_action", or "action"

まとめ

Chrome(クローム)拡張機能で、コンテキストメニューを追加する方法を解説しました。

選択された要素に対し、コンテストメニューで独自の処理を行ったり、いろんなアイデアの拡張機能アプリができそうですね!

参考にしたサイト

https://developer.chrome.com/apps/contextMenus#method-create

スポンサーリンク

QooQ