はじめに
JavascriptでページのタイトルとURLを取得するのに、content_scriptsとbackground.js でやり取りをしたらよいと思っていたわけですが、メニュータブの browser.contextMenus.onClicked.addListener((info, tab) .. の tab があるのを気付きかき方を変えてみることにしました。
manifest.json - "permissions": ["tabs"]
tabの変数に何が入ってるのかをデバッガーで確認してみました。初めに調べた時には title や url は見つからなかったのですが、permissionが足りないだけと分かり manifest.json を変更して調べなおしました。
manifest.json
{
"manifest_version": 2,
"name": "Sample Tool",
"description": "Sample Tool for Firefox",
"version": "1.0",
"homepage_url": "https://sample.com",
"icons": {
"48": "icons/sample.png"
},
"applications": {
"gecko": {
"id": "sample@sample.com",
"strict_min_version": "42.0",
"update_url":"https://sample.com/"
}
},
"background": {
"scripts": [
"background.js"
]
},
"options_ui": {
"page": "options.html"
},
"permissions": [
"contextMenus",
"storage",
"tabs",
"http://*/*"
],
"content_scripts": [
{
"matches": [
"https://*/*",
"http://*/*"
],
"js": [
"sample.js"
]
}
]
}
すると、title や url が見つかります。ここを使うと苦労しないでデータがとれそうです。
runtime.Port とタブ切り替え
せっかくなので、Portを使った方法も試してみます。TCPIPのPortみたいに、タブ毎に区別できるようなので、送信先のタブを切り替えて postMessageをして応答を待つことにします。
- 接続した port を tab.id で区別
- メニュー選択時の tab.idをもとに、postMessage先を切り替え
- 更新データは onClickedではなくて、onMessage で取得できてる。
background.js
browser.contextMenus.create({
id: "copyUrlForQiita",
title: "copy url for qiita",
contexts: ["all"]
});
var ports = []
var urlForQiita
function connected(p) {
ports[p.sender.tab.id] = p
ports[p.sender.tab.id].onMessage.addListener(function(m) {
urlForQiita = m.title;
console.log("onMessage.addListener:" + urlForQiita);
});
}
browser.runtime.onConnect.addListener(connected);
browser.contextMenus.onClicked.addListener((info, tab) => {
if (info.menuItemId === "copyUrlForQiita") {
ports[tab.id].postMessage({action: "copyUrlForQiita"});
console.log("onClicked.addListener:" + urlForQiita);
//var urlForQiita = "[" + tab.title + "](" + tab.url + ")"
}
});
sample.js(content_scripts)
console.log("sample.js is loaded");
var myPort = browser.runtime.connect({name:"port-from-sample"});
myPort.onMessage.addListener(function(m) {
var urlForQiita = "[" + document.title + "](" + document.URL + ")"
myPort.postMessage({title: urlForQiita});
});
気を付けるのは、クリックしたときではなくて、応答があったタイミングで取れてるいうことになります。