Commiunicating from a WebExtension add-on to an SDK based add-on

I have two extensions, one written in SDK and the other one (newer one) is written in WebExtension platform. I need to send messages back and forth between these two extensions. There doesn’t seem to be possible at the moment.

Is it somehow possible to have a workaround till this feature is officially implemented? Probably from SDK extension part as it is more powerful in terms of API access.

Certainly it is possible, but I think you’d have to step outside the “high-level” APIs. Of course, whenever you start using low-level, potentially unsupported/deprecated, APIs you have to consider whether you should even be using that type of addon.

Just what two things do you wish to communicate between? The chrome portion of the addons is just javascript and you can exchange information in any number of ways that don’t require special messaging. If you want to communicate between content and chrome then you have use (or at least ‘‘should’’ use) a messaging API.

It helps to understand the different types of “content” script that different types of addons use: WebExtensions use content scripts and has a number of APIs to communicate with chrome such as sendMessage/onMessage; SDK also has content scripts in a different scope and communicates with chrome using the port API; generic addons such as Jetpack and XUL overlays can inject scripts into content which then behave largely as page scripts. Different types of scipts in content usually can’t directly access each other using javascript (SDK content scripts injected into the same page with the same command can), but they can exchange information by methods such as custom events or the DOM postMessage API.

Any addon can also create frame scripts, which are in the content process and can directly access content objects but still have chrome privileges (with a few exceptions). They have their own inter-process messaging system. WebExtensions and SDK addons will have to require (chrome?) to do this. Prior to multi-process Firefox, and still when it is disabled, the chrome portion of an addon could directly access content objects and scripts simply using javascript. This can still be done from addons using shims, but is strongly discouraged because it is extremely slow when multiprocess Firefox is operating and may occasionally cause hangs or crashes.

I just need to send a JSON compatible object back and forth between these two add-ons. chrome.runtime.sendMessage/onMessage functions that you have pointed out are not accessible from outside of WebExtension scope. Frame scripting might work but this technique is really messy for this purpose (especially since there is no easy way to unload them). I was hoping to get a simpler workaround.

Is it possible for instance to access the background page of the WebExtension from my SDK add-on and implement a custom messaging module?

You still haven’t said what you really want to do, but the last sentence gives me some hints. I’m going to suggest that you use an observer notification. It isn’t part of the WebExtensions or SDK API, but it effectively gives you the ability to directly call a function anywhere (in the chrome process) from anywhere. Notice there is a big red warning at the top of the documentation page. This functionality is not part of WebExtensions or SDK, but what are you going to do. It is unlikely that there will ever be a specific API to communicate between the two different addon types so you’ll have to step outside them into APIs that may well be deprecated one day.

Depending on exactly whether you want to send information between different tabs, different windows, to or between content scripts, or just plain broadcast it all over, you might also find custom events useful. They won’t propagate between the content and chrome process, but they inherently stay in one window and they are unlikely to be deprecated. Observer notifications go to all windows which can be good or bad depending on your needs.

Of course for really simple communication, you can just tag on to a shared object such as window, although Mozilla reviewers won’t be your friend if you do this. A javascript code module gives you a space of your own that is shared between all contexts (in the same process) that import it. It isn’t messaging as such, but you can share state, data, and even code. You could write a simple messaging API in a JSM, but that would usually be overkill.

Well, what I want to achieve is to send and receive JSON compatible objects from one background page to the other background page. These extensions do not inject scripts into pages, so basically there is not a common window/page’s context to be used for communication (through window.postMessage or a common object access).

This observer notification method you mentioned seems interesting. So can i really define observerService.addObserver in the context of my WebExtension? I though WebExtension has no access to the Components object.

Maybe can’t access that from WebExtensions. Anyone know? Might have to try using events. Anyone know if you can dispatch an event directly from WebExtensions? Can you do anything from WebExtensions? I guess the point is that you can’t. Maybe someone else will have to answer this question …

There’s this bug: Provide to other addon types a way to communicate with WebExtensions addons. Note that in this case the WebExtension is part of the legacy add-on, not a separate add-on, so I don’t know if this meets the requirements for this question.

you could probably do it by sharing preferences in firefox (about:config). Have both addons listen for changes in their own declared prefs and act when they are updated. Stringify your objects and store them in the desired pref in the other addon.

For example you have the following preferences in each addon
webext.prefA sdkext.prefB

have the sdkext stringify your object and store it in webext.prefA and register an observer for changes on its own prefB and vice versa.

you can check for the existance of these prefs to determine if the other addon is installed and only register the observers if this is the case.

I say probably because I have not looked into web extension side of things but I know this can be done on the sdk side. If you can access any preference outside of you addons own declared ones in web extensions it will work. Granted it is not the most elegant solution.

That requires WebExtensions to be able to listen to prefs, which they cannot by design. They can’t even read them.

However the embedded WebExtension aproach mentioned above has now landed, which should allow any extension to communicate with a WebExtension (from Firefox 50 on).