We have a Firefox/Chrome web extension which contains both background and content scripts. The background script maintains a cache of shared key/value pairs which are needed by the content scripts. It is not difficult to access them via the browser.runtime.SendMessage functionality.
However, we need access to these key/value pairs as quickly as possible on page load, before any scripts run on the original page. This is generally not possible because the async nature of SendMessage means that the background script will not respond to requests made by the content scripts fast enough.
We've been looking for solutions along the following lines:
1. Sync/blocking lookup
It doesn't appear that there are any mechanisms for this.
2. Initializing the content script
We can register content scripts using browser.contentScripts.register and potentially pass a copy of the entire cache in via javascript. However, this is called only once and all subsequent tabs/pages will load whatever was specified in it. We might be able - with great difficulty - create a listener for global cache changes and re-register a new content script each time.
Are there any better approaches than this?
Update: By adding a listener to browser.webNavigation.onBeforeNavigate, I am now able to inject a global variable which displays in the console output:
In background.js:
browser.webNavigation.onBeforeNavigate.addListener(function(details) {
browser.tabs.executeScript(
details.tabId,
{
code: `window.scope.somevariable=true;
console.log("I executed in content script:", "somevariable", window.scope.somevariable);`
}
);
});
In my library which was injected by register, I am also able to print window.scope out to the console and I see the variable there.
However... when I try to access the variable programmatically, it returns "undefined".
In content script:
// this displays "somevariable" among the window scope properties:
console.log("window.scope", window.scope);
// this displays "undefined":
console.log("somevariable", window.scope.somevariable);
Why can the registered js library output the variable to the console window but can't actually read it?