■Digaに録画指示を送れるようにChromeの拡張機能を使ったのだけど、このコンテキスメニュー拡張は割と便利なので、URLのメモやツイッター連携とかやってみた。Javascriptで完結できれば良かったのだけど、そのあたりはまだむつかしいので、終端処理はサーバーのPHPで受け持つとして、Chromeは処理用のデータを抽出するところだけ。
あれこれ試行錯誤しているうちに、コンテキストメニューのスケルトンというかパターンが解ったような気がする。セキュリティ的に不安があることと、Chromeだけで完結していないのでストアでの公開とか、そういったことには不適切だけど、自分だけで使う分には十分だろうと思う。
manifest.jsonとしてはこんなものを用意した。
{
"manifest_version": 2,
"name": "URL Util",
"description": "URL Utility",
"version": "1.0",
"permissions": [ "tabs", "<all_urls>", "contextMenus" ],
"icons": { "16": "icon.png" },
"content_scripts": [
{
"matches": ["<all_urls>"],
"js": [ "contentscript.js" ]
}
],
"background": {
"scripts": [ "background.js", "subwindow.js" ],
"background_page": "subwindow.html",
"persistent": false
}
}
ページやリンクのURLを抽出してあれこれ加工するのでタイトルは'URL Util'としているだけ。twitterクライアントと連携させるためのページとしてsubwindow.htmlとsubwindow.jsを持っています。background.jsはメニュー処理の主機能で、subwindow.jsはsubwindow.html内部で呼び出されるスクリプトで、DHTMLを処理しています(あんまり大したことはやってない)。
コンテキストメニューの拡張はだいたい次のパターン。(background.js)
function onClickHandler(info, tab){
if(info.menuItemId == "sub_1") {
//sub_1が呼び出されたときの処理
}
if(info.menuItemId == "sub_2") {
//sub_2が呼び出されたときの処理
}
}
chrome.contextMenus.onClicked.addListener(onClickHandler);
chrome.runtime.onInstalled.addListener(function() {
chrome.contextMenus.create({
"title": "Tweet This Page",
"contexts": ["all"],
"id": "sub_1",
});
chrome.contextMenus.create({
"title": "Memo This Page",
"contexts": ["link"],
"id": "sub_2",
});
}
メニューの構築はchrome.runtime.onInstalled.addListener内部で行っていて、メニューが選択された時のコンテキスト情報がonClickHandlerにinfoとして渡されます。infoはmenuItemIdを持っていて、それを読むと何のメニューが呼ばれたのかが解るわけです。あとはたとえばXMLHttpRequestでサーバーを呼び出したり、window.openで副ウィンドウを生成したりするわけです。
副ウィンドウへの情報の引き渡しはスマートにもともとのブラウザから情報をもらうこともできるようですが、そこまではまだ使いこなせておらず、単純にwindow.openで引数に与えていたりしています。
window.open('subwindow.html?'+encURI, "TEST SCRIPT", "width=500, height= 280");
subwindow.htmlはふつうのファイルで、subwindow.htmlで取り込んだスクリプトで'?'以降の引数を分離して処理しています。