How to detect when another Chrome Extension overrides the same page - google-chrome-extension

An example would be if my extension overrides the newtab page and the user installs another extension that also overrides the newtab page. Currently, only one newtab extension shows up and it usually isn't mine.
What can I do to detect when such a conflict occurs and inform the user of such?
The management API doesn't tell me if the extensions override any pages, so I sadly can't use that.

This doesn't seem to be an exant feature of the API. I'd suggest you open a bug at http://crbug.com.
Failing that, you can perform the following nasty hack (which I haven't tested):
Have your new tab page send a message to your background page whenever it loads.
Listen for chrome.webNavigation.onBeforeNavigate events that deal with chrome://newtab:
chrome.webNavigation.onBeforeNavigate.addListener(function(details) {
/* send message */
}, { url: [{ urlEquals: 'chrome://newtab/' }] });
When webNavigation sees the browser load chrome://newtab but you don't see a message to your background page shortly afterwards, your new tab page is probably not being used. From there, you can send a notification, or open another tab/window with a notice.
Unfortunately, this requires the webNavigation permission, which is unfortunate if your extension doesn't otherwise need it. The warning that it carries ("This extension can access your tabs and browsing activity") might scare away some potential users, especially if there's no reason for it that is obvious to the user. (Then again, perhaps I'm being too optimistic about the security-conscientiousness of users.) If your extension currently uses the tabs API, then it already carries this notice anyway.

Related

How to prevent Chrome from automatically blocking audio capture

I'm developing an extension that requires audio access. Under normal circumstances, the user will choose either "Block" or "Allow", and that is fine. Both actions will put the extension in the appropriate place in settings/content/microphone. But while testing, I found if the user were to simply close out the Block/Allow popup by clicking on the "x" in the corner:
then I start to get PermissionDeniedErrors from navigator.mediaDevices.getUserMedia (which makes sense). But there are two big problems to this:
Chrome stops prompting the user if they want to block/allow - it just silently blocks it.
The blocked extension DOES NOT show up in settings/content/microphone. So there is no way for the user to unblock it.
Then some time later (hours? days?), the prompt will come back.
I was digging in the Preferences file to see if maybe something about the extension is in there that wasn't getting surfaced to the UI, and I found this:
From this, I am guessing that Chrome is detecting the "dismissals", and just automatically begins blocking the setting for a period of time ("embargo days").
Is there any kind of action: either programmatic or user-based that can be taken to help direct users to unblock the extension?

Method to autoupdate Chrome Extension badge

I'm building a Chrome extension that makes the badge show a number returned from an API. I have the code working fine, but I have it listening for DOMContentLoaded, so it only updates when the user opens up the extension.
I would like the extension to check the API every time the browser loads a page. I do not need to change anything in the page, I just want to use it for timing.
I'm not sure what I should be using, should I be using background pages, event pages, or something else? What would be the best way to go about this?
Thanks in advance!
The api you want for “every time the browser loads a page” is chrome.tabs.onUpdated. You’d have:
chrome.tabs.onUpdated.addListener(function(tabId,changeInfo,tab) {
chrome.browserAction.setBadgeText({"text":"ABCD","tabId":tabId});
});
An easy approach for development is to use a background page, get it working, and then figure out what changes you need to convert it to an event page. With this stub however, nothing is stopping you from making it an event page.

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.)

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