Re-enter content scripts after upgrade

I have a chrome extension that injects an iframe into every open tab. I have chrome.runtime.on installed listener in my background.js that manually enters the necessary scripts as follows (API details are here: http://developer.chrome.com/extensions/runtime.html#event-onInstalled ):

background.js

var injectIframeInAllTabs = function(){ console.log("reinject content scripts into all tabs"); var manifest = chrome.app.getDetails(); chrome.windows.getAll({},function(windows){ for( var win in windows ){ chrome.tabs.getAllInWindow(win.id, function reloadTabs(tabs) { for (var i in tabs) { var scripts = manifest.content_scripts[0].js; console.log("content scripts ", scripts); var k = 0, s = scripts.length; for( ; k < s; k++ ) { chrome.tabs.executeScript(tabs[i].id, { file: scripts[k] }); } } }); } }); }; 

This works great when I first install the extension. I want to do the same when the extension is updated. If I also run the same script when updating, I do not see the new iframe increment. Not only that, if I try to send a message to my content script AFTER the update, none of the messages will go to the content script. I saw that other people also come across the same issue in SO ( Chrome: message content-script in runtime.onInstalled ). What is the correct way to remove old content scripts and enter new ones after updating the chrome extension?

+6
source share
2 answers

When the extension is updated, Chrome automatically disables all the "old" content scripts from the conversation to the background page, and also throws an exception if the old content script tries to contact the runtime. This was the missing piece for me. All that I did was in chrome.runtime.onInstalled in bg.js , I call the same method as in the question. This adds another iframe that says the correct runtime. At some point in time, old content scripts try to talk to runtimes that are not running. I will catch this exception and simply destroy the old script content. Also note that each iframe is introduced into its own “isolated world” (the isolated world is described here: http://www.youtube.com/watch?v=laLudeUmXHM ), so the newly adopted iframe cannot clear the old lingering iframe.

Hope this helps someone in the future!

+3
source

It is not possible to “delete” old content scripts (other than reloading the page in question using window.location.reload, which would be bad)

If you want to be more flexible about what code you are executing in your script content, use the "code" parameter in the executeScript function, which allows you to pass a line with javascript code. If the content of the script is only one big function (i.e. content_script_function) that lives in background.js

in background.js:

 function content_script_function(relevant_background_script_info) { // this function will be serialized as a string using .toString() // and will be called in the context of the content script page // do your content script stuff here... } function execute_script_in_content_page(info) { chrome.tabs.executeScript(tabid, {code: "(" + content_script_function.toString() + ")(" + JSON.stringify(info) + ");"}); } chrome.tabs.onUpdated.addListener( execute_script_in_content_page.bind( { reason: 'onUpdated', otherinfo: chrome.app.getDetails() }); chrome.runtime.onInstalled.addListener( execute_script_in_content_page.bind( { reason: 'onInstalled', otherinfo: chrome.app.getDetails() }); ) 

Where actual_background_script_info contains information about the original page, that is, what version it has, whether there was an update event and why this function is called. The script content page still saves all the relevant state. Thus, you have full control over how to handle the "update" event.

+2
source

Source: https://habr.com/ru/post/952676/


All Articles