Chrome extension の Content scripts と Service workers
webContent scripts
Content scripts はページのコンテキストで動くスクリプトで主に DOM 操作を行うのに用いられる。 Manifest の content_scripts フィールドの matches に一致したページで css や js が挿入される。 挿入タイミングは css が DOM の構築前で、 js は run_at によって指定できる。 デフォルトの document_idle では window.onload 以後に挿入されることが保証されている。
$ cat manifest.json
{
"manifest_version": 3,
"name": "test-extension",
"version": "1.0",
"content_scripts": [
{
"matches": ["https://*.sambaiz.net/*"],
"css": ["content.css"],
"js": ["content.js"]
}
]
}
$ cat content.css
time {
color: #ba4dab !important;
}
$ cat content.js
document.querySelectorAll('time').forEach((t) => {
t.innerText = `+++ ${t.innerText} +++`;
});
chrome.runtime.onMessage.addListener((message) => {
console.log(`content_script: ${JSON.stringify(message)}`);
})
デフォルトで ページや他の拡張機能とは分離された環境で動くが、 DOM は共有される。 他とのやり取りのために chrome.runtime.connect()して postMessage()したり、 chrome.runtime.sendMessage() API によってメッセージを送受信できるようになっているが、その他の API はほとんど呼べない。
ブラウザのwindow間の値渡し - sambaiz-net
Service workers
Service workers は必要なときにロードされ、 chrome.runtime.onInstalled() や chrome.action.onClicked() といった様々なイベントのハンドリングを行う。 Manifest V2 では background_script がこの役割を担っていたが、V3 で廃止された。 なお、V3 ではリクエスト先の設定が host_permissions に分離された。
Chrome ExtensionsとChrome Apps - sambaiz-net
直接 DOM 操作を行うことはできず、chrome.scripting.executeScript() でスクリプトを挿入したり、 Content scripts にメッセージを送って行うなどする必要がある。
$ cat manifest.json
{
"manifest_version": 3,
...
"background": {
"service_worker": "service-worker.js"
},
"action": {
"default_title": "Add @@@"
},
"permissions": [
"scripting",
"activeTab"
],
"host_permissions": [
"https://example.com/*"
]
}
$ cat service-worker.js
chrome.action.onClicked.addListener((tab) => {
chrome.scripting.executeScript({
target: {tabId: tab.id},
func: (c) => {
document.querySelectorAll('time').forEach((t) => {
t.innerText = `${c} ${t.innerText} ${c}`;
});
},
args: ['@@@']
});
chrome.tabs.query({active: true, currentWindow: true}, (tabs) => {
chrome.tabs.sendMessage(tabs[0].id, {
aaaa: tabs
})
});
});