Google Chrome Extensionを作ってみた-その7-

はじめに

今回はコンテキストメニューについてです。
コンテキストメニューを出すためのcreateメソッドの引数createPropertiesの内容を中心にして紹介します。

使ってみる

manifest.json

コンテキストメニューを使うには、manifest.jsonの"permissions"に"contextMenus"を追加します。
コンテキストメニューに対する処理はbackground.html内に記述します。アイコンは128を指定していますが、16x16が推奨サイズです。

{
	"name" : "ContextmenuSample",
	"version" : "1.0.0",
	"background_page" : "background.html",
	"permissions" : [
		"contextMenus",
		"http://*/*",
		"https://*/*"
	],
	"icons" : {
		"16" : "icon_128.png"
	}
}

コンテキストメニューを作るメソッド

コンテキストメニューを追加するには、createメソッドを使います。

integer chrome.contextMenus.create(object createProperties, function callback)

createメソッドはintegerを返します。生成したコンテキストメニューのidです。子メニューを付ける場合や、削除するのに必要になります。
引数は次の通りです。

引数 説明
createProperties 生成するコンテキストメニューの情報
callback コンテキストメニューの生成後に呼ばれるコールバック

createProperties

項目 タイプ 説明
type enumerated string
["normal", "checkbox", "radio", "separator"]
コンテキストメニューのタイプ
title strig コンテキスメニューの表示名称
checked boolean typeでcheckboxかradioを指定した場合にデフォルトで選択しておくか
contexts array of string
["all", "page", "frame", "selection", "link", "editable", "image", "video", "audio"]
どの表示要素の上でコンテキストメニューを表示するか
onclick function このコンテキストメニューがクリックされたら呼ばれるコールバック
parentId integer どの親の下に付けるか
documentUrlPatterns array of string URLパターンで表示/非表示を変える
targetUrlPatterns array of string documentUrlPatternsと似てる
img/audio/videoタグのsrcとaタグのhrefのurlによる縛り

ためしてみる

まずbackground.htmlに次の様に記述しました。

<html>
<head>
<script>
	function getClickHandler() {
		return function(info, tab) {
			alert("クリックされました");
		};
	};

	var parentId = chrome.contextMenus.create({
		"title" : "samplemenu",
		"type" : "normal",
		"contexts" : ["all"],
		"onclick" : getClickHandler()
	});
</script>
</head>
<body>
</body>
</html>

クラスメソッドのホームページで試してみます。
ページ上のどの場所でコンテキストメニューを出しても「samplemenu」というメニューが出ます。

次に、この「samplemenu」の子メニューを作ります。次のスクリプトを追加します。

	chrome.contextMenus.create({
		"title" : "childmenu1",
		"type" : "normal",
		"contexts" : ["link"],
		"parentId" : parentId,
		"onclick" : getClickHandler()
	});

どの場所でコンテキストメニューを開いても「samplemenu」は表示されますが、子メニューは"contexts"が"link"に設定されているのでどこでも表示されるというわけではありません。
リンク部分にマウスオーバーしてコンテキストメニューを開くと、子メニューの「childmenu1」も表示されます。

さらに、違う子メニューも作ります。

	chrome.contextMenus.create({
		"title" : "childmenu2",
		"type" : "normal",
		"contexts" : ["image"],
		"parentId" : parentId,
		"onclick" : getClickHandler()
	});

今度は、画像の上でしか「childmenu2」は表示されません。

最後に「childmenu3」「childmenu4」を作ります。

	chrome.contextMenus.create({
		"title" : "childmenu3",
		"type" : "normal",
		"contexts" : ["image"],
		"parentId" : parentId,
		"onclick" : getClickHandler(),
		"documentUrlPatterns" : ["*://*.google.co.jp/*"]
	});
	chrome.contextMenus.create({
		"title" : "childmenu4",
		"type" : "normal",
		"contexts" : ["image"],
		"parentId" : parentId,
		"onclick" : getClickHandler(),
		"targetUrlPatterns" : ["*://*.google.co.jp/*"]
	});

クラスメソッドのホームページ上の画像の上でコンテキストメニューを出しても、「childmenu3」「childmenu4」は表示されません。これは"documentUrlPatterns"でフィルタを掛けているからですね。

今度はgoogle画像検索のページで試してみます。
左上のロゴの上でコンテキストメニューを出すと全ての子メニューが表示されます。(画像にリンクも設定されているので「childmenu1」も表示される)

検索結果の画像の上でコンテキストメニューを出すと、"targetUrlPatterns"でフィルタが掛かっているので「samplemenu4」だけ表示されません。

という事で、"type"や"documentUrlPatterns"と"targetUrlPatterns"の動きが少しは紹介できたかなと思います。

まとめ

  • manifest.jsonで"permissions"に"contextMenus"を追加
  • chrome.contextMenus.createでコンテキストメニューを作る