What is the best practice for updating open tabs after your Chrome Extension updates (with content script)? - google-chrome-extension

My Extension's content script interacts with every open tab.
When I update my Extension any existing tabs will have the old content script and my Extension will not function.
I have tried putting an alert on the page asking users to refresh (triggered by catching an error), which is confusing to users. This answer (chrome extension API for refreshing the page) shows how to refresh all open tabs...and if placed in background.js in the onInstalled listener (reason === "update") we can force all open tabs to refresh. But this feels invasive and alarming to the user.
What is the best practice?

Related

Chrome extension: How to do not lose state of my extension when user changes/reloads the page

I'm currently developing an extension that comes in different parts:
- background script (Chrome background.js
- content script (Chrome content-script.js)
- popup script (popup.js and loaded from the iFrame)
- iframe.html (iframe to be loaded when user activate the extension)
It works great except that I lose all the settings/context (used in the popup script to display info in the iframe) when the user change of page or reload the page in the tab.
Technically I want to isolate the extension per tab (each tab can have its own config) but when a user navigate in a same tab the context should be kept.
Question is: what is the best way to achieve that?
I'm thinking about persisting all the context in the content script and reload it when the event chrome.tabs.onUpdated is fired. Is it the right approach?
I recommend you to read about chrome.storage. You can store data there, both background and content script have access to it.
And probably you will need chrome.runtime.sendMessage and chrome.runtime.onMessage to have conversation between background and content. Each time content script runs in a tab it can request background whether this tab have some existing data or not.

Can Chrome Extension’s new options_ui trigger a page action?

I’ve been placing a page action on the options page of my Chrome extension. options.js calls chrome.runtime.connect({"name":"someName"}), and background.js has
chrome.runtime.onConnect.addListener(function(port) {
chrome.pageAction.show(port.sender.tab.id);
});
Unfortunately, in the new options_ui with the recommended default (and someday mandatory) "open_in_tab":false, the Sender's tab won't be set. Is there a way to get the tab id in order to show the page action?
I could use tabs.query to get the chrome://extensions/ tab, but that requires the tabs permission, which I currently don’t need. Active tab seems like it would work, but it doesn’t provide the tab id and isn’t enabled by opening an option dialog (source).
(Why do I want the page action on my options page? The extension works with a website that is only available ~7-10 weeks per year. I’d like my users to be able to interact with the extension the rest of the time, so that they can get used to the process. But I don’t want to adjust the displayed extension permissions just to do so. I can accomplish this by having the options page pretend to be the website in question.)

How to open a new tab in a chrome extension and show data

I have a chrome extension which allows the user to perform actions and build up data. How can I get my chrome extension to open a new tab to allow my user to interact with the data they've accumulated? I could build a separate web app service where I pass the users data to. I currently persist the users data in local storage but I want a way for them to view/edit that data.
Not sure what exactly to google to get a chrome extensions to launch a new page under it's url...
Edit:
Ideally I'd like for my user to press a button from the popup.html popup to open up the new tab, if possible.
I got it to work, basically from the popup.html page I can make this javascript call,
chrome.tabs.create({url: chrome.extension.getURL('dashboard.html')})
where 'dashboard.html' is file belonging to my chrome extension.

What can you do in background scripts that you can't do in other js files?

*By other js files, I mean the files you include in popup.html.
The following code works, so why should I use a background script?
Content script
chrome.extension.onMessage.addListener(
function(request, sender, sendResponse) {
//Some code
}
);
Script included in popup.html
chrome.tabs.query({active:true,windowId: chrome.windows.WINDOW_ID_CURRENT},
function(tab) {
chrome.tabs.sendMessage(tab[0].id, {method: "someMethod"},
function(response){
//Some code
});
});
This
Background pages live as long as the Chrome browser is active (and even longer if the "background" permission is set). Popup pages are only active when the badge's popup is open. The popup can only be opened by the user.
The background page's document is never visible, whilst the popup page becomes visible on click of the badge's button.
Besides that, there's no difference between background pages and popup pages. They run in the same extension's process, and have access to the same set of APIs.
If your extension only needs to be active while the popup is active, you don't need a background page. To save the state of the popup, just use the synchronous localStorage or the asynchronous chrome.storage API. When the variables you use are too complex to be stored using either API, a background page may be useful.
One example where the use of a background page is beneficial:
Imagine an extension that downloads a huge text file from a server. The creation of the resource is very resource-intensive for the server. Technically, everything can be done from within the popup. However, offloading the task to the background page allows the user to do other tasks while the file is downloading (if you use a popup only, the download will stop when the user closes the popup).
Though you didn't ask, I'd like to make you aware of event pages. They are similar to background pages, with one difference: Event pages are automatically closed when the extension is idle. In other words, event pages are only active when needed! By doing this, your extension will profit from the advantages of background pages without needlessly wasting the user's memory.
My last example is also a perfect example of when an event page has to be used. Besides doing the http request on behalf of the popup, the background page does nothing. If you use an event page instead of a background page, you get the best of both worlds: the popup page can be closed without interrupting the download, and the extension will not waste memory.
Documentation
Learn more about Background pages and Event pages
"Popup" in this answer refers to the optional panel of the chrome.browserAction or chrome.pageAction API, set by declaring the "default_popup" key in the manifest file, or programatically using the setPopup method.

Ignoring local URLs when using chrome.tabs.onUpdated

I'm writing a Chrome extension that analyzes the websites a user visits. I've decided to use chrome.tabs.onUpdated to run my analysis script instead of content_scripts in manifest.json, because chrome.tabs.onUpdated does a better job picking up page refreshes on AJAX heavy sites.
I don't need to analyze updates to new, empty tabs or to chrome-extension:// (local) pages, and in fact an error will be thrown if I do try to inject a script into those tabs. Is there a more automatic way to ignore those pages, or do I have to do it the manual way with Try/Catch blocks or by analyzing the URL? I'm sure I can do it manually, but it seems there should be a more automatic way to accomplish this.
You can ignore all local or internal chrome extension URLs by filtering out ones that start with 'chrome':
// Listen for changes on tabs
chrome.tabs.onUpdated.addListener(function(tabId, info, tab) {
log_console('tab', tab)
// If tab is not an internal chrome tab
if (!tab.url.startsWith('chrome')) {
console.log('Non-internal URL updated")
}
});
Note that you need the tabs permission in your manifest.json if you want to access the URL, otherwise tab.url will be undefined and this won't work. If you can't get the tabs permission, your best bet might be to just catch and handle the error when you try to inject.

Resources