Hello,
The documentation on migrating to service workers has a section about registering event listeners [0]. My understanding is that it's saying event listeners must be registered at the top level of the service worker script, or they are not guaranteed to be registered.
I'm aware of a thread about service worker life-cycle [1] but I think this is a more specific question, hence starting a new one. Apologies if that is not cricket.
The extension I maintain needs to inject content scripts into every page, and communicate with those scripts when certain events occur, in order to fully function. It checks to see if it has permissions to do so, and registers appropriate event listeners if so. It doesn't register the listeners if it doesn't have permission to access all pages (in that case it falls back to user activation via the browserAction).
Here's some simplified code from the top level of the background script...
---
chrome.permissions.contains({ origins: '<all_urls>'}, function(result) {
if (result === true) {
chrome.tabs.onActivated.addListener(tabActivatedHandler)
chrome.webNavigation.onBeforeNavigate.addListener(beforeNavigateHandler)
chrome.webNavigation.onCompleted.addListener(navigationCompletedHandler)
chrome.webNavigation.onHistoryStateUpdated.addListener(historyStateUpdatedHandler)
}
})
---
It sounds like the documentation [0] is saying that I can't nest these handler registrations, as they may not run because they are in an async call - is that the case?
It would be wasteful to have to register these handlers regardless of if the extension has the required permissions to use them, and have them firing all the time, and checking on every event whether the extension has permission to proceed. Is that what is intended? Am I missing a more efficient way to do this? The documentation [0] alludes to there being other ways to register event listeners, but doesn't say what they are.
In reality, the extension actually listens to permissions-added/-removed events, and uses the handlers for those to register or unregister the listeners above. It sounds like that would work OK, as long as the permissions-added/-removed listeners are registered at the top level of the background script - is that correct? Even if so, at start-up, the extension needs to decide if it should register the event handlers or not:
---
function permissionsCheck() {
chrome.permissions.contains({ origins: '<all_urls>'}, function(result) {
if (result === true) {
permissionsGained()
} else {
permissionsLost()
}
})
}
// Register the event listeners on start-up (should be OK, as this is at the top level)
chrome.permissions.onAdded.addListener(permissionsCheck)
chrome.permissions.onRemoved.addListener(permissionsCheck)
// Also need to perform the check on start-up, to register events if needed.
// Would this work?
permissionsCheck()
---
Again, from the documentation [0], it sounds like that, because permissionsCheck() makes an async call via chrome.permissions.contains(), that async code is not guaranteed to run, which means the event handlers may not be registered at start-up - is that the case?
best regards,
Matthew
[0] Top Level Event Listeners: <
https://developer.chrome.com/extensions/migrating_to_service_workers#event_listeners>
[1] Manifest V3, Service Worker lifecycle and async operations <
https://groups.google.com/a/chromium.org/forum/#!searchin/chromium-extensions/manifest$20v3$20event|sort:date/chromium-extensions/3IQ-CvD8ICQ/ZRprnQpFAAAJ>