はじめに
Chrome拡張は action
、background
、content_script
の異なるコンテキストで実行されます。このうち content_script
は matches
で指定したURLパターンのページで実行されます。ページのDOM操作ができる content_script
が実行されている場合のみ、action
を有効にしたかったので調査しました。
動作原理
-
background
→content_script
の通信はchrome.tabs.sendMessage
で行います -
chrome.tabs.sendMessage
は聴取するリスナが存在しない場合にエラーを発生させます(下図)
-
content_script
で聴取している場合はもちろんエラーが発生しません - つまり、エラー発生の有無で
content_script
有無によりaction
の有効・無効を切り替えることができます
コード
サンプルでは https://www.google.co.jp/*
で content_script
を実行させています。
アイコンファイルは用意してください。
manifest.json
{
"name": "特定のURLで有効",
"description": "content_scriptsが有効なURLでのみactionを有効にする",
"version": "1.0",
"manifest_version": 3,
"icons": {
"16": "icon_16x16.png",
"48": "icon_48x48.png"
},
"action": {},
"background": {
"service_worker": "service-worker.js"
},
"content_scripts": [
{
"matches": ["https://www.google.co.jp/*"],
"js": ["content-script.js"]
}
]
}
service-worker.js
// タブにメッセージを送り、リッスンされたときに有効化します
function update(tabId) {
chrome.tabs.sendMessage(tabId, { message: "echo" }).then((response) => {
chrome.action.enable();
chrome.action.setIcon({ path: "icon_16x16.png" });
}).catch((error) => {
chrome.action.disable();
chrome.action.setIcon({ path: "icon-gray_16x16.png" });
});
}
// タブがアクティブになったとき
chrome.tabs.onActivated.addListener((activeInfo) => {
update(activeInfo.tabId);
});
// タブか更新された(ページ遷移した)とき
chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => {
if (changeInfo.status === "complete") {
update(tabId);
}
});
// ウィンドウがアクティブになったとき
chrome.windows.onFocusChanged.addListener((windowId) => {
if (windowId === chrome.windows.WINDOW_ID_NONE) {
return;
}
chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => {
update(tabs[0].id);
});
});
content-script.js
// リッスンするイベントを登録、聴くだけ
chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) { });