Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I add a Chrome extension listener both onStartup and onInstalled?

The chrome.runtime API has a few events that I can use to add a listener to a context menu. At the moment I'm using chrome.runtime.onStartup like so:

chrome.runtime.onStartup.addListener(function() {
  chrome.contextMenus.create({
    'title': 'Add: %s',
    'contexts': ['selection']
  });
});

chrome.contextMenus.onClicked.addListener(onClickHandler);

The problem is that chrome.runtime.onStartup will work when the user starts or restarts Chrome, and chrome.runtime.onInstalled will work when the extension or Chrome is first installed or updated.

If I only do onStartup, then my context menu won't be there when my extension or Chrome is next updated. If I only do onInstalled, then my context menu won't persist after the user restarts Chrome.

How can I handle both cases?

like image 261
Benjamin Humphrey Avatar asked May 03 '15 12:05

Benjamin Humphrey


1 Answers

This is actually an interesting question, since the behavior differs depending on whether you're using an event page or a persistent background page.

Note that this answer is specific to contextMenu API!

Persistent background page

You should simply put your code on the top level.

Then it will execute every time your extension's background page is loaded.

If you have a persistent background page, that's exactly what you want: execute once when the extension starts for whatever reason.

If you want to make sure you don't create a duplicate item, include an id attribute in create().

Google has a corresponding sample.

Event page

Event page is loaded much more often than a regular one throughout the lifetime of an extension. And anyway, context menu API requires special treatment with event pages.

First off, including an id attribute in contextMenus.create() is a requirement for event pages. Also, because code is unloaded when idle, you have to use chrome.contextMenus.onClicked instead of an onclick attribute.

Documentation recommends using onInstalled:

If you need to do some initialization when your extension is installed or upgraded, listen to the runtime.onInstalled event. This is a good place to register for declarativeWebRequest rules, contextMenu entries, and other such one-time initialization.

Indeed, that's what they do in the sample.

I tested it, and indeed the context menus persist through restart of the extension and the browser. This difference is not explicitly documented, though.

Bug Alert! In view of Rob W's comment about this bug, the method is not 100% reliable if the extension happens to be disabled.

like image 67
Xan Avatar answered Nov 10 '22 14:11

Xan