My Flow of Extension is:
- User goes to options page (options.js) and adds a url (e.g. youtube.com). This url is stored in storage and sends a message 'NewURL' to background.js
- background.js on getting 'NewURL' message, injects JS called injected.js into all tabs where url matches (i.e. all open youtube.com tabs)
- This injected script is basically listening to message (message.type = StartTimer)and logging whenever the message is received
- popup.js has start timer button which sends message 'StartTimer' to all the listeners
I see that injected.js prints the message on getting injected but after that it does not log 'StartTimer' when popup.js start time button is clicked.
Now in code
options.js
const saveBtn = document.getElementById("save-btn")
saveBtn.addEventListener("click", () => {
chrome.storage.local.set({
block_urls: block_urls
})
chrome.runtime.sendMessage({ type: "NewURL"})
alert('Settings Saved!')
})
background.js
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
console.log('chrome.runtime.onMessage.addListener: ', message)
if (message.type === "NewURL") {
console.log('background.js: NewURL')
injectJS()
}
})
function injectJS() {
let blockUrlList = []
chrome.storage.local.get(["block_urls"], async (res) => {
blockUrlList = "block_urls" in res ? res.block_urls : []
try {
let qryOptions = { "url": blockUrlList.map(p => `*://*.${p}/*`)}
let tabs = await chrome.tabs.query(qryOptions)
tabs.forEach((tab) => {
console.log('injecting into tab', tab.id, tab.url)
chrome.scripting.executeScript({
target: {tabId: tab.id},
files: ['content/injected.js']
})
});
} catch(err) {
console.log('No matching tab', err)
}
})
}
injected.js
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
if (message.type === "StartTimer") {
console.log('injected.js: start timer')
} else if(message.type === "StopTimer"){
console.log('injected.js: stop timer')
}
});
console.log("you have been injected")
popup.js
const startTimerBtn = document.getElementById("start-timer-btn")
startTimerBtn.addEventListener("click", () => {
chrome.runtime.sendMessage({ type: "StartTimer"})
})
I see in console of the open tab the message "you have been injected". However, I do not see subsequently 'injected.js: start timer'
Also I have two additional questions
- How do I prevent injecting multiple times in one of the open tab
- When a new tab is opened (or this tab is refreshed), how is javascript re-injected?