After the Chrome extension I'm working on is installed, or upgraded, the content scripts (specified in the manifest) are not re-injected so a page refresh is required to make the extension work. Is there a way to force the scripts to be injected again?
I believe I could inject them again programmatically by removing them from the manifest and then handling which pages to inject in the background page, but this is not a good solution.
I don't want to automatically refresh the user's tabs because that could lose some of their data. Safari automatically refreshes all pages when you install or upgrade an extension.
can't you add
?ver=2.10
at the end of css or js you upgraded?The only way to force a content script to be injected without refreshing the page is via programatic injection.
You can get all tabs and inject code into them using the chrome tabs API. For example you can store a manifest version in local storage and every time check if the manifest version is old one (in background page), if so you can get all active tabs and inject your code programmatically, or any other solution that will make you sure that the extension is updated.
Get all tabs using:
chrome.tabs.query
and inject your code into all pages
chrome.tabs.executeScript(tabId, {file: "content_script.js"});
There's a way to allow a content script heavy extension to continue functioning after an upgrade, and to make it work immediately upon installation.
Install
The install method is to simply iterate through all tabs in all windows, and inject some scripts programmatically into tabs with matching URLs.
Obviously, you have to do it in a background page or event page script declared in manifest.json:
background.js:
Upgrade
The upgrade method relies on the fact that the content scripts are left injected after an extension is disabled, uninstalled or upgraded.
When the port connection is made, an onDisconnect handler is added. This waits a second after the disconnect event, then attempts to reconnect. If it fails, another onDisconnect is fired so the process happens again, until a connection is made. It's not perfect, but it works.
The content script: